summaryrefslogtreecommitdiff
path: root/src/wm_map.cpp
blob: 4520a001db7132b2e43ab650d205dbed82d7b968 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#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);

	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
	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::draw() {
	model.scheduleForDrawing();
}