From 562543f0c7658f11595f37c886861efaf76b5d5a Mon Sep 17 00:00:00 2001 From: Treeki Date: Tue, 15 Mar 2011 05:44:38 +0100 Subject: working scene support in dWMMap_c. todo: a proper tool for editing/previewing --- SMGoldwood.fileset | Bin 74 -> 109 bytes scenedata.bin | Bin 0 -> 157 bytes scenegen.py | 42 ++++++++++++++++++++++ src/wm_map.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/wm_map.h | 47 ++++++++++++++++++++++++ src/worldmap.cpp | 43 ++-------------------- src/worldmap.h | 21 ++--------- worldmap.yaml | 6 ++++ 8 files changed, 203 insertions(+), 59 deletions(-) create mode 100644 scenedata.bin create mode 100644 scenegen.py create mode 100644 src/wm_map.cpp create mode 100644 src/wm_map.h diff --git a/SMGoldwood.fileset b/SMGoldwood.fileset index a685631..5db5362 100644 Binary files a/SMGoldwood.fileset and b/SMGoldwood.fileset differ diff --git a/scenedata.bin b/scenedata.bin new file mode 100644 index 0000000..534b7b6 Binary files /dev/null and b/scenedata.bin differ diff --git a/scenegen.py b/scenegen.py new file mode 100644 index 0000000..84fccc9 --- /dev/null +++ b/scenegen.py @@ -0,0 +1,42 @@ +import struct + +class Node: + pass + +BaseNode = Node() +BaseNode.mtx = [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0] +BaseNode.brres_key = '3D00' +BaseNode.model_name = 'GoldwoodBase' +BaseNode.lm_type = 0 + +TreeNode = Node() +TreeNode.mtx = [1.0,0.0,0.0,60.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0] +TreeNode.brres_key = '3D00' +TreeNode.model_name = 'RedTree' +TreeNode.lm_type = 1 + + + +nodes = {} +nodes['Base'] = BaseNode +nodes['Tr00'] = TreeNode + +header = struct.pack('>4sI', b'MScn', len(nodes)) +entrydata = b'' +stringtable = b'' +currentoffset = 8 + (0x40 * len(nodes)) + +for key,node in nodes.items(): + #nodekey, brreskey, lmtype, nameoffset, matrix + + entrydata += struct.pack('>4s4sII', key.encode('Shift-JIS'), node.brres_key.encode('Shift-JIS'), node.lm_type, currentoffset) + for f in node.mtx: + entrydata += struct.pack('>f', f) + + stringtable += node.model_name.encode('Shift-JIS') + stringtable += b'\0' + currentoffset += len(node.model_name) + 1 + + +open('scenedata.bin', 'wb').write(header + entrydata + stringtable) + diff --git a/src/wm_map.cpp b/src/wm_map.cpp new file mode 100644 index 0000000..83ed637 --- /dev/null +++ b/src/wm_map.cpp @@ -0,0 +1,103 @@ +#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() { + // 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; + + // load up all the nodes, and fix up all the name offsets while we're at it + nodes = new WMSceneNode[data->nodeCount]; + + // link the mHeapAllocator so it can be used for models + 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); + } + + allocator.unlink(); + + return true; +} + + +int dWMMap_c::onDelete() { + delete[] nodes; + + return true; +} + + +int dWMMap_c::onExecute() { + return true; +} + + +int dWMMap_c::onDraw() { + for (int i = 0; i < data->nodeCount; i++) { + nodes[i].draw(); + } + + 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); + + void *mdl = resfile.GetResMdl(data->modelName); + MapReport("Obtained ResMdl: %p\n", mdl); + + MapReport(model.setup(&mdl, allocator, 0, 1, 0) ? "Success\n" : "Fail\n"); + + // todo: more types + if (data->lmType == 0) + SetupTextures_Map(&model, 1); + else if (data->lmType == 1) + SetupTextures_MapObj(&model, 1); + + model.setDrawMatrix(data->matrix); +} + + +void WMSceneNode::draw() { + model.scheduleForDrawing(); +} + diff --git a/src/wm_map.h b/src/wm_map.h new file mode 100644 index 0000000..2ca55a0 --- /dev/null +++ b/src/wm_map.h @@ -0,0 +1,47 @@ +#include +#include +#include +#include + +struct WMSceneDataNode { + u32 nodeKey; + u32 brresKey; + u32 lmType; + const char *modelName; // Actually an offset before dWMMap_c loads the data + Mtx matrix; +}; + +struct WMSceneDataHeader { + u32 magic; + u32 nodeCount; + WMSceneDataNode nodes[1]; // dynamic length array +}; + + +// todo: make this subclass mdl_c maybe? dunno... +class WMSceneNode { +public: + WMSceneDataNode *baseData; + m3d::mdl_c model; + + void loadFrom(WMSceneDataNode *data, mHeapAllocator_c *allocator); + void draw(); +}; + + +class dWMMap_c : public dBase_c { +public: + int onCreate(); + int onDelete(); + int onExecute(); + int onDraw(); + + mHeapAllocator_c allocator; + + WMSceneDataHeader *data; + WMSceneNode *nodes; + + static dWMMap_c *build(); + static dWMMap_c *instance; +}; + diff --git a/src/worldmap.cpp b/src/worldmap.cpp index cd43a47..dd027f0 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -174,6 +174,9 @@ bool WMInit_SetupExtra(void *ptr) { wm->player->modelHandler->mdlClass->startAnimation(0, 1.2f, 10.0f, 0.0f); wm->player->pos = wm->currentPoint->position; + // is last param correct? must check :/ + wm->map = (dWMMap_c*)CreateParentedObject(WM_MAP, wm, 0, 0); + return true; } @@ -299,8 +302,6 @@ int dScNewerWorldMap_c::onCreate() { levelInfoFile.open("/NewerRes/LevelInfo.bin"); levelInfo.load(levelInfoFile.ptr()); - LoadModel(); - return true; } @@ -753,45 +754,7 @@ int dScNewerWorldMap_c::onExecute() { return true; } -int dScNewerWorldMap_c::onDraw() { - this->model.scheduleForDrawing(); - - return true; -} - - - -// Todo: move to .LZ files and dDvd::loader_c and WM_MAP - -void dScNewerWorldMap_c::LoadModel() { - MapReport("Loading Goldwood model...\n"); - modelFile.openCompressed("/Maps/SMGoldwood_bLZ.brres"); - nw4r::g3d::ResFile resfile(modelFile.ptr()); - - if (!resfile.CheckRevision()) - MapReport("Warning: Revision check failed!\n"); - - resfile.Init(); - - if (!resfile.Bind(resfile)) - MapReport("Warning: ResFile bind failed!\n"); - - void *mdl = resfile.GetResMdl("GoldwoodBase"); - MapReport("Obtained ResMdl: %p\n", mdl); - - MapReport(this->allocator.link(-1, GameHeaps[0], 0, 0x20) ? "Success\n" : "Fail\n"); - MapReport(this->model.setup(&mdl, &this->allocator, 0, 1, 0) ? "Success\n" : "Fail\n"); - - SetupTextures_Map(&model, 1); - - this->allocator.unlink(); - MapReport("Done loading model!\n"); - - Mtx asdf; - MTXIdentity(asdf); - this->model.setDrawMatrix(asdf); -} void dScNewerWorldMap_c::HandleMovement() { diff --git a/src/worldmap.h b/src/worldmap.h index 8813e6d..d48f36c 100644 --- a/src/worldmap.h +++ b/src/worldmap.h @@ -21,6 +21,7 @@ #include "levelinfo.h" #include "worldmapdata.h" #include "wmresourcemng.h" +#include "wm_map.h" enum WMDirection { LEFT, @@ -40,18 +41,6 @@ void NewerMapDrawFunc(); -class dWMMap_c : public dBase_c { -public: - int onCreate(); - int onDelete(); - int onExecute(); - int onDraw(); - - static dWMMap_c *build(); - static dWMMap_c *instance; -}; - - class dWorldCamera_c : public dBase_c { public: int onCreate(); @@ -112,13 +101,8 @@ public: dWMResourceMng_c resMng; dWMPathData_c pathData; - mHeapAllocator_c allocator; - File modelFile; - m3d::mdl_c model; - - void LoadModel(); - daWMPlayer_c *player; + dWMMap_c *map; bool isMoving; WMPathPoint *currentPoint; @@ -143,7 +127,6 @@ public: int onCreate(); int onDelete(); int onExecute(); - int onDraw(); static dScNewerWorldMap_c *build(); static dScNewerWorldMap_c *instance; diff --git a/worldmap.yaml b/worldmap.yaml index 9b5af6d..292006f 100644 --- a/worldmap.yaml +++ b/worldmap.yaml @@ -2,6 +2,7 @@ source_files: - ../src/worldmap.cpp - ../src/wm_player.cpp + - ../src/wm_map.cpp - ../src/world_camera.cpp - ../src/worldmapdata.cpp - ../src/wmresourcemng.cpp @@ -27,6 +28,11 @@ hooks: src_addr_pal: 0x8098EEC8 target_func: 'dWorldCamera_c::build(void)' + - name: BuildWMMap + type: add_func_pointer + src_addr_pal: 0x80984710 + target_func: 'dWMMap_c::build(void)' + # fix the STOCK_ITEM references - name: StockItemFix type: patch -- cgit v1.2.3