diff options
author | Treeki <treeki@gmail.com> | 2012-02-27 18:54:32 +0100 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2012-02-27 18:54:32 +0100 |
commit | 21d7e41b006b88aa79821610661fefc8fe14b7ca (patch) | |
tree | d9abd10293781666afc31fc4af5b6de503e2867c | |
parent | e45c4a7a24a6a58804261d73c14f008bff1b5a68 (diff) | |
download | kamek-21d7e41b006b88aa79821610661fefc8fe14b7ca.tar.gz kamek-21d7e41b006b88aa79821610661fefc8fe14b7ca.zip |
switching between multiple maps
Diffstat (limited to '')
-rwxr-xr-x | include/game.h | 2 | ||||
-rw-r--r-- | kamek_pal.x | 3 | ||||
-rw-r--r-- | src/koopatlas/core.cpp | 113 | ||||
-rw-r--r-- | src/koopatlas/core.h | 8 | ||||
-rw-r--r-- | src/koopatlas/mapdata.h | 9 | ||||
-rw-r--r-- | src/koopatlas/pathmanager.cpp | 42 |
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); |