#include "worldmap.h" #include #include #include #include #include #include #include #include #include #include void dPathTest_c::loadTex() { nw4r::g3d::ResFile rf(dScNewerWorldMap_c::instance->resMng['3D00']); resTex = rf.GetResTex("W2Road"); alpha = 255; } void dPathTest_c::drawOpa() { } void dPathTest_c::drawXlu() { GXClearVtxDesc(); GXSetVtxDesc(GX_VA_POS, GX_DIRECT); GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); m3d::DisableIndirectTexturing(); GXSetNumChans(0); GXSetNumTexGens(1); //GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_NRM, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GXSetNumTevStages(0); GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO); GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C1, GX_CC_C0, GX_CC_C0, GX_CC_ZERO); GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO); GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_A1, GX_CA_ZERO); GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); //GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR); GXSetZCompLoc(0); GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetZMode(GX_TRUE, GX_LEQUAL, GX_FALSE); GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, (GXColor){0,0,0,0}); GXSetFogRangeAdj(0, 0, 0); GXSetCullMode(GX_CULL_NONE); GXSetDither(GX_TRUE); GXSetTevColor(GX_TEVREG0, (GXColor){128,128,128,128}); GXSetTevColor(GX_TEVREG1, (GXColor){128,128,128,128}); nw4r::g3d::Camera cam(GetCameraByID(GetCurrentCameraID())); Mtx camMtx; cam.GetCameraMtx(&camMtx); //MTXInverse(camMtx, camMtx); Mtx viewMatrix; getViewMatrix(&viewMatrix); //camMtx[0][3] = 0.0f; //camMtx[1][3] = 0.0f; //camMtx[2][3] = 0.0f; //MTXConcat(viewMatrix, camMtx, viewMatrix); // TESTING CRAP!! // Just copying what my old 3D engine had for now GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); GXSetZCompLoc(GX_TRUE); GXSetNumTevStages(1); GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); GXSetNumChans(1); //GXSetChanAmbColor(GX_COLOR0A0, (GXColor){128,128,128,255}); GXSetChanMatColor(GX_COLOR0A0, (GXColor){0,0,0,(u8)alpha}); GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_NONE); GXSetNumTexGens(1); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GXSetTevOp(GX_TEVSTAGE0, GX_BLEND); GXTexObj to; m3d::InitTexObjWithResTex(&to, &resTex, GX_REPEAT, GX_REPEAT, GX_LINEAR, GX_LINEAR); GXLoadTexObj(&to, GX_TEXMAP0); GXLoadPosMtxImm(camMtx, GX_PNMTX0); GXSetCurrentMtx(GX_PNMTX0); GXBegin(GX_QUADS, GX_VTXFMT0, 4); GXPosition3f32(-400, 90, -400); GXTexCoord2f32(0, 0); GXPosition3f32(400, 90, -400); GXTexCoord2f32(1, 0); GXPosition3f32(400, 90, 400); GXTexCoord2f32(1, 1); GXPosition3f32(-400, 90, 400); GXTexCoord2f32(0, 1); GXEnd(); } dWMMap_c *dWMMap_c::instance = 0; dWMMap_c *dWMMap_c::build() { OSReport("Creating WM_Map\n"); void *buffer = AllocFromGameHeap1(sizeof(dWMMap_c)); dWMMap_c *c = new(buffer) dWMMap_c; OSReport("Created WM_Map @ %p\n", c); instance = c; return c; } int dWMMap_c::onCreate() { SpammyReport("dWMMap_c::onCreate() called\n"); // Get the resource void *scnRes = dScNewerWorldMap_c::instance->resMng['SCN0']; if (scnRes == 0) { OSReport("Oops, couldn't get SCN0, try again later\n"); return false; } data = (WMSceneDataHeader*)scnRes; SpammyReport("Loaded resource: %d nodes\n", data->nodeCount); // load up all the nodes, and fix up all the name offsets while we're at it SpammyReport("Allocating node array\n"); nodes = new WMSceneNode[data->nodeCount]; // link the mHeapAllocator so it can be used for models SpammyReport("Linking allocator\n"); allocator.link(-1, GameHeaps[0], 0, 0x20); for (int i = 0; i < data->nodeCount; i++) { WMSceneNode *node = &nodes[i]; WMSceneDataNode *nodeData = &data->nodes[i]; nodeData->modelName = (const char*)((u32)data + (u32)nodeData->modelName); node->loadFrom(nodeData, &allocator); } SpammyReport("Making path test\n"); pathTest.loadTex(); pathTest.setup(&allocator); SpammyReport("Unlinking allocator\n"); allocator.unlink(); SpammyReport("dWMMap_c::onCreate() completed\n"); return true; } int dWMMap_c::onDelete() { delete[] nodes; pathTest.free(); return true; } int dWMMap_c::onExecute() { /* TESTING */ int heldButtons = Remocon_GetButtons(GetActiveRemocon()); if (heldButtons & WPAD_UP) pathTest.alpha += 8; if (heldButtons & WPAD_DOWN) pathTest.alpha -= 8; nodes[0].updateAlpha("World2_PathsSinkytoPyramid", pathTest.alpha); return true; } int dWMMap_c::onDraw() { SpammyReport("dWMMap_c::onDraw() called\n"); //pathTest.scheduleForDrawing(); for (int i = 0; i < data->nodeCount; i++) { SpammyReport("Drawing node %d\n", i); nodes[i].draw(); } SpammyReport("dWMMap_c::onDraw() completed\n"); return true; } /* SCENE NODES */ void WMSceneNode::loadFrom(WMSceneDataNode *data, mHeapAllocator_c *allocator) { MapReport("Loading node: %c%c%c%c [%c%c%c%c:%s]\n", data->nodeKey>>24,data->nodeKey>>16,data->nodeKey>>8,data->nodeKey, data->brresKey>>24,data->brresKey>>16,data->brresKey>>8,data->brresKey, data->modelName); baseData = data; void *brres = dScNewerWorldMap_c::instance->resMng[data->brresKey]; nw4r::g3d::ResFile resfile(brres); resMdl = resfile.GetResMdl(data->modelName); MapReport("Obtained ResMdl: %p\n", resMdl); MapReport(model.setup(resMdl, allocator, 0, 1, 0) ? "Success\n" : "Fail\n"); // todo: more types SpammyReport("Setting up lightmaps\n"); if (data->lmType == 0) SetupTextures_Map(&model, 1); else if (data->lmType == 1) SetupTextures_MapObj(&model, 1); SpammyReport("Lightmaps done\n"); model.setDrawMatrix(data->matrix); SpammyReport("Node is ready\n"); } void WMSceneNode::updateAlpha(const char *materialName, u8 alpha) { // get the material // too lazy to use dynamic buffers for the ResMatTevColor stuff... //OSReport("trying to update %s to %d\n", materialName, alpha); u8 *mat = (u8*)resMdl.GetResMat(materialName); //OSReport("got mat: %p\n", mat); s32 *matDLOffsetPtr = (s32*)(mat + 0x3C); s32 matDLOffset = *matDLOffsetPtr; u8 *matTevColorDL = mat + matDLOffset + 0x20; u8 *setTevKonst4Cmd = matTevColorDL + 0x5E; //OSReport("got DL offset: %d. DL is at %p. cmd is at %p.\n", matDLOffset, matTevColorDL, setTevKonst4Cmd); setTevKonst4Cmd[2] = (setTevKonst4Cmd[2] & 0xF0) | (alpha >> 4); setTevKonst4Cmd[3] = (setTevKonst4Cmd[3] & 0x0F) | (alpha & 0xF0); } void WMSceneNode::draw() { model.scheduleForDrawing(); }