summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-03-15 05:44:38 +0100
committerTreeki <treeki@gmail.com>2011-03-15 05:44:38 +0100
commit562543f0c7658f11595f37c886861efaf76b5d5a (patch)
tree3ff106b802bd37cbf5af8bcc6943d2aeeddc5d3e
parent4b440c0ac3040267be036e536c3e1ad69a5ef49d (diff)
downloadkamek-562543f0c7658f11595f37c886861efaf76b5d5a.tar.gz
kamek-562543f0c7658f11595f37c886861efaf76b5d5a.zip
working scene support in dWMMap_c. todo: a proper tool for editing/previewing
-rw-r--r--SMGoldwood.filesetbin74 -> 109 bytes
-rw-r--r--scenedata.binbin0 -> 157 bytes
-rw-r--r--scenegen.py42
-rw-r--r--src/wm_map.cpp103
-rw-r--r--src/wm_map.h47
-rw-r--r--src/worldmap.cpp43
-rw-r--r--src/worldmap.h21
-rw-r--r--worldmap.yaml6
8 files changed, 203 insertions, 59 deletions
diff --git a/SMGoldwood.fileset b/SMGoldwood.fileset
index a685631..5db5362 100644
--- a/SMGoldwood.fileset
+++ b/SMGoldwood.fileset
Binary files differ
diff --git a/scenedata.bin b/scenedata.bin
new file mode 100644
index 0000000..534b7b6
--- /dev/null
+++ b/scenedata.bin
Binary files 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 <common.h>
+#include <rvl/mtx.h>
+#include <g3dhax.h>
+#include <game.h>
+
+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