summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2012-02-27 18:54:32 +0100
committerTreeki <treeki@gmail.com>2012-02-27 18:54:32 +0100
commit21d7e41b006b88aa79821610661fefc8fe14b7ca (patch)
treed9abd10293781666afc31fc4af5b6de503e2867c
parente45c4a7a24a6a58804261d73c14f008bff1b5a68 (diff)
downloadkamek-21d7e41b006b88aa79821610661fefc8fe14b7ca.tar.gz
kamek-21d7e41b006b88aa79821610661fefc8fe14b7ca.zip
switching between multiple maps
Diffstat (limited to '')
-rwxr-xr-xinclude/game.h2
-rw-r--r--kamek_pal.x3
-rw-r--r--src/koopatlas/core.cpp113
-rw-r--r--src/koopatlas/core.h8
-rw-r--r--src/koopatlas/mapdata.h9
-rw-r--r--src/koopatlas/pathmanager.cpp42
6 files changed, 158 insertions, 19 deletions
diff --git a/include/game.h b/include/game.h
index 6b6a9bd..b22631f 100755
--- a/include/game.h
+++ b/include/game.h
@@ -24,6 +24,7 @@ inline T clamp(T value, T one, T two) { return (value < one) ? one : ((value > t
extern "C" {
int strlen(const char *str);
char *strcpy(char *dest, const char *src);
+int strncmp(const char *str1, const char *str2, int num);
float atan(float x);
float atan2(float y, float x);
@@ -2628,6 +2629,7 @@ extern int currentScreenSizeID;
extern float GlobalScreenWidth, GlobalScreenHeight;
+void DoSceneChange(u16 name, u32 sceneSettings, u32 unk);
extern u32 GlobalTickCount;
diff --git a/kamek_pal.x b/kamek_pal.x
index 6a7c8c4..576f974 100644
--- a/kamek_pal.x
+++ b/kamek_pal.x
@@ -23,6 +23,8 @@ SECTIONS {
BombExplodeState = 0x80B12A48;
NoFreezie = 0x800A0B08;
+ DoSceneChange__FUsUiUi = 0x800E1F50;
+
SinFIdx__Q24nw4r4mathFf = 0x80237D10;
CosFIdx__Q24nw4r4mathFf = 0x80237D80;
SinCosFIdx__Q24nw4r4mathFPfPff = 0x80237DE0;
@@ -946,6 +948,7 @@ SECTIONS {
strlen__FPCc = 0x802DC98C;
strlen = 0x802DC98C;
strcpy = 0x802E1C28;
+ strncmp = 0x802E1EC0;
atan = 0x802E7F04;
atan2 = 0x802E8900;
diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp
index 7eaa339..f7acf00 100644
--- a/src/koopatlas/core.cpp
+++ b/src/koopatlas/core.cpp
@@ -47,7 +47,8 @@ dScKoopatlas_c *dScKoopatlas_c::build() {
bool WMInit_StartLoading(void*);
bool WMInit_LoadSIAnims(void*);
bool WMInit_EndLoading(void*);
-bool WMInit_LoadResources(void*);
+bool WMInit_LoadResources1(void*);
+bool WMInit_LoadResources2(void*);
bool WMInit_SetupWait(void*);
bool WMInit_SetupExtra(void*);
bool WMInit_SetupWipe(void*);
@@ -56,14 +57,15 @@ ChainedFunc initFunctions[] = {
WMInit_StartLoading,
WMInit_LoadSIAnims,
WMInit_EndLoading,
- WMInit_LoadResources,
+ WMInit_LoadResources1,
+ WMInit_LoadResources2,
WMInit_SetupWait,
WMInit_SetupExtra,
WMInit_SetupWipe
};
dScKoopatlas_c::dScKoopatlas_c() : state(this) {
- initChain.setup(initFunctions, 7);
+ initChain.setup(initFunctions, 8);
setInitChain(initChain);
}
@@ -154,13 +156,28 @@ bool WMInit_EndLoading(void *ptr) {
return true;
}
-bool WMInit_LoadResources(void *ptr) {
- SpammyReport("WMInit_LoadResources returning true\n");
+bool WMInit_LoadResources1(void *ptr) {
+ SpammyReport("WMInit_LoadResources1 returning true\n");
dScKoopatlas_c *wm = (dScKoopatlas_c*)ptr;
- return
- wm->mapData.load("/Maps/yat.kpbin") &&
- wm->levelInfoLoader.load("/NewerRes/LevelInfo.bin");
+
+ bool result1 = wm->mapListLoader.load("/Maps/List.txt");
+ bool result2 = wm->levelInfoLoader.load("/NewerRes/LevelInfo.bin");
+ return result1 && result2;
+}
+
+bool WMInit_LoadResources2(void *ptr) {
+ SpammyReport("WMInit_LoadResources2 returning true\n");
+
+ dScKoopatlas_c *wm = (dScKoopatlas_c*)ptr;
+
+ if (wm->mapPath == 0) {
+ wm->mapPath = wm->getMapNameForIndex(wm->currentMapID);
+ if (wm->mapPath == 0)
+ wm->mapPath = wm->getMapNameForIndex(0);
+ }
+
+ return wm->mapData.load(wm->mapPath);
}
bool WMInit_SetupWait(void *ptr) {
@@ -339,13 +356,12 @@ int dScKoopatlas_c::onCreate() {
SpammyReport("setting NewerMapDrawFunc\n");
*CurrentDrawFunc = NewerMapDrawFunc;
- // level info
- /*SpammyReport("loading level info file\n");
- levelInfoFile.open("/NewerRes/LevelInfo.bin");
- SpammyReport("preparing level info\n");
- levelInfo.load(levelInfoFile.ptr());*/
-
SpammyReport("onCreate() completed\n");
+
+ // Prepare this first
+ SaveBlock *save = GetSaveFile()->GetBlock(-1);
+ currentMapID = save->current_world;
+
return true;
}
@@ -361,6 +377,7 @@ int dScKoopatlas_c::onDelete() {
DVD_FreeFile(GetDVDClass2(), "SI_star");
levelInfoLoader.unload();
+ mapListLoader.unload();
return true;
}
@@ -831,6 +848,74 @@ void dScKoopatlas_c::startLevel(dLevelInfo_c::entry_s *entry) {
}
+u32 dScKoopatlas_c::iterateMapList(u32(*callback)(u32,const char *,int,int), u32 userData, int *ptrIndex) {
+ u8 *ptr = (u8*)mapListLoader.buffer;
+ u8 *strStart = ptr;
+ u8 *end = ptr + mapListLoader.size;
+ int index = 0;
+
+ while (true) {
+ u8 chr = *ptr;
+ if (chr == 13) {
+ ++ptr;
+ continue;
+ }
+
+ if (chr == 10 || chr == 0 || ptr >= end) {
+ if (strStart == ptr) {
+ // Blank string, ignore
+ ++strStart;
+ ++ptr;
+ continue;
+ }
+
+ // Change the linefeed to a NUL so we can use the line as a C string later
+ if (ptr < end)
+ *ptr = 0;
+
+ u32 ret = callback(userData, (const char*)strStart, ptr - strStart, index);
+ if (ptrIndex)
+ *ptrIndex = index;
+ if (ret > 0)
+ return ret;
+
+ strStart = ++ptr;
+ ++index;
+
+ if (ptr >= end)
+ break;
+
+ } else {
+ ++ptr;
+ }
+ }
+
+ return 0;
+}
+
+static u32 _cb_getIndex(u32 userData, const char *str, int size, int index) {
+ if (index == userData)
+ return (u32)str;
+ else
+ return 0;
+}
+
+static u32 _cb_searchName(u32 userData, const char *str, int size, int index) {
+ if (strncmp(str, (const char*)userData, size) == 0)
+ return (u32)(index+1);
+ else
+ return 0;
+}
+
+const char *dScKoopatlas_c::getMapNameForIndex(int index) {
+ return (const char *)iterateMapList(&_cb_getIndex, (u32)index, 0);
+}
+
+int dScKoopatlas_c::getIndexForMapName(const char *name) {
+ return ((int)iterateMapList(&_cb_searchName, (u32)name, 0)) - 1;
+}
+
+
void NewerMapDrawFunc() {
Reset3DState();
SetCurrentCameraID(0);
diff --git a/src/koopatlas/core.h b/src/koopatlas/core.h
index 9ca1935..6a76cc4 100644
--- a/src/koopatlas/core.h
+++ b/src/koopatlas/core.h
@@ -92,9 +92,17 @@ class dScKoopatlas_c : public dScene_c {
dWMHud_c *hud;
dWMMap_c *map;
+ int currentMapID;
+ const char *mapPath;
dKPMapData_c mapData;
dWMPathManager_c pathManager;
+ dDvdLoader_c mapListLoader;
+
+ u32 iterateMapList(u32(*callback)(u32,const char *,int,int), u32 userData, int *ptrIndex = 0);
+ const char *getMapNameForIndex(int index);
+ int getIndexForMapName(const char *name);
+
dDvdLoader_c levelInfoLoader;
dLevelInfo_c levelInfo;
diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h
index e75925d..913c933 100644
--- a/src/koopatlas/mapdata.h
+++ b/src/koopatlas/mapdata.h
@@ -67,10 +67,17 @@ struct dKPNode_s {
NodeTypes type;
union {
struct { u8 levelNumber[2]; };
- struct { char *destMap; u8 thisID, foreignID, transition; };
+ struct { const char *destMap; u8 thisID, foreignID, transition; };
};
+ dKPPath_s *getAnyExit() {
+ for (int i = 0; i < 4; i++)
+ if (exits[i])
+ return exits[i];
+ return 0;
+ }
+
dKPPath_s *getOppositeExitTo(dKPPath_s *path);
};
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
index 609b3a2..923d08c 100644
--- a/src/koopatlas/pathmanager.cpp
+++ b/src/koopatlas/pathmanager.cpp
@@ -11,10 +11,35 @@ void dWMPathManager_c::setup() {
pathLayer = dScKoopatlas_c::instance->mapData.pathLayer;
SaveBlock *save = GetSaveFile()->GetBlock(-1);
- if (save->current_path_node >= pathLayer->nodeCount) {
- currentNode = pathLayer->nodes[0];
+
+ // Figure out what path node to start at
+ if (dScKoopatlas_c::instance->settings & 0x10000000) {
+ // Start off from a "Change"
+ u8 changeID = dScKoopatlas_c::instance->settings & 0xFF;
+
+ bool found = false;
+
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ dKPNode_s *node = pathLayer->nodes[i];
+
+ if (node->type == dKPNode_s::CHANGE && node->thisID == changeID) {
+ found = true;
+ currentNode = node;
+
+ startMovementTo(node->getAnyExit());
+ }
+ }
+
+ if (!found) {
+ OSReport("Couldn't find target node %d!\n", changeID);
+ }
+
} else {
- currentNode = pathLayer->nodes[save->current_path_node];
+ if (save->current_path_node >= pathLayer->nodeCount) {
+ currentNode = pathLayer->nodes[0];
+ } else {
+ currentNode = pathLayer->nodes[save->current_path_node];
+ }
}
// unlock all needed paths
@@ -100,7 +125,16 @@ void dWMPathManager_c::moveThroughPath() {
player->pos.x = to->x;
player->pos.y = -to->y;
- if (to->type != dKPNode_s::PASS_THROUGH) {
+ if (to->type == dKPNode_s::CHANGE) {
+ // Go to another map
+ isMoving = false;
+
+ SaveBlock *save = GetSaveFile()->GetBlock(-1);
+ save->current_world = dScKoopatlas_c::instance->getIndexForMapName(to->destMap);
+
+ DoSceneChange(WORLD_MAP, 0x10000000 | to->foreignID, 0);
+
+ } else if (to->type != dKPNode_s::PASS_THROUGH) {
// Stop here
player->startAnimation(0, 1.2, 10.0, 0.0);