#include "worldmap.h" 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("Unlinking allocator\n"); allocator.unlink(); SpammyReport("dWMMap_c::onCreate() completed\n"); return true; } int dWMMap_c::onDelete() { delete[] nodes; return true; } int dWMMap_c::onExecute() { return true; } int dWMMap_c::onDraw() { SpammyReport("dWMMap_c::onDraw() called\n"); 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(); }