#include "koopatlas/core.h" #include "koopatlas/camera.h" #include "koopatlas/player.h" #include "music.h" extern "C" void LoadMapScene(); dScKoopatlas_c *dScKoopatlas_c::instance = 0; CREATE_STATE_E(dScKoopatlas_c, Limbo); CREATE_STATE(dScKoopatlas_c, ContinueWait); CREATE_STATE_E(dScKoopatlas_c, Normal); CREATE_STATE(dScKoopatlas_c, CompletionMsg); CREATE_STATE_E(dScKoopatlas_c, CompletionMsgHideWait); CREATE_STATE_E(dScKoopatlas_c, CSMenu); CREATE_STATE_E(dScKoopatlas_c, TitleConfirmOpenWait); CREATE_STATE_E(dScKoopatlas_c, TitleConfirmSelect); CREATE_STATE_E(dScKoopatlas_c, TitleConfirmHitWait); CREATE_STATE_E(dScKoopatlas_c, PlayerChangeWait); CREATE_STATE_E(dScKoopatlas_c, EasyPairingWait); CREATE_STATE_E(dScKoopatlas_c, PowerupsWait); CREATE_STATE_E(dScKoopatlas_c, ShopWait); CREATE_STATE_E(dScKoopatlas_c, CoinsWait); CREATE_STATE_E(dScKoopatlas_c, SaveOpen); CREATE_STATE_E(dScKoopatlas_c, SaveSelect); CREATE_STATE_E(dScKoopatlas_c, SaveWindowClose); CREATE_STATE_E(dScKoopatlas_c, SaveDo); CREATE_STATE_E(dScKoopatlas_c, SaveEndWindow); CREATE_STATE_E(dScKoopatlas_c, SaveEndCloseWait); #ifdef QUICK_SAVE CREATE_STATE_E(dScKoopatlas_c, QuickSaveOpen); CREATE_STATE_E(dScKoopatlas_c, QuickSaveSelect); CREATE_STATE_E(dScKoopatlas_c, QuickSaveWindowClose); CREATE_STATE_E(dScKoopatlas_c, QuickSaveDo); CREATE_STATE_E(dScKoopatlas_c, QuickSaveEndWindow); CREATE_STATE_E(dScKoopatlas_c, QuickSaveEndCloseWait); #endif CREATE_STATE_E(dScKoopatlas_c, SaveError); dScKoopatlas_c *dScKoopatlas_c::build() { // return new dScKoopatlas_c; MapReport("Creating WorldMap\n"); void *buffer = AllocFromGameHeap1(sizeof(dScKoopatlas_c)); dScKoopatlas_c *c = new(buffer) dScKoopatlas_c; MapReport("Created WorldMap @ %p\n", c); instance = c; return c; } bool WMInit_StartLoading(void*); bool WMInit_LoadStaticFiles(void*); bool StockWMInit_LoadEffects(void*); bool WMInit_LoadSIAnims(void*); bool WMInit_EndLoading(void*); bool WMInit_LoadResources1(void*); bool WMInit_LoadResources2(void*); bool WMInit_SetupWait(void*); bool WMInit_SetupExtra(void*); bool WMInit_SetupWipe(void*); ChainedFunc initFunctions[] = { WMInit_StartLoading, WMInit_LoadStaticFiles, StockWMInit_LoadEffects, WMInit_LoadSIAnims, WMInit_EndLoading, WMInit_LoadResources1, WMInit_LoadResources2, WMInit_SetupWait, WMInit_SetupExtra, WMInit_SetupWipe }; dScKoopatlas_c::dScKoopatlas_c() : state(this) { initChain.setup(initFunctions, 9); setInitChain(initChain); } #define SELC_SETUP_DONE(sc) (*((bool*)(((u32)(sc))+0xD38))) #define EASYP_SETUP_DONE(ep) (*((bool*)(((u32)(ep))+0x278))) #define EASYP_ACTIVE(ep) (*((bool*)(((u32)(ep))+0x279))) #define CSMENU_SETUP_DONE(csm) (*((bool*)(((u32)(csm))+0x270))) #define CSMENU_ACTIVE(csm) (*((bool*)(((u32)(csm))+0x271))) #define CSMENU_CHOICE_OK(csm) (*((bool*)(((u32)(csm))+0x272))) #define CSMENU_UNK(csm) (*((bool*)(((u32)(csm))+0x273))) #define CSMENU_CURRENT(csm) (*((int*)(((u32)(csm))+0x268))) #define NPCHG_SETUP_DONE(npc) (*((bool*)(((u32)(npc))+0x67C))) #define NPCHG_ACTIVE(npc) (*((bool*)(((u32)(npc))+0x67E))) #define NPCHG_HIDE_FOR_EASYP(npc) (*((bool*)(((u32)(npc))+0x67F))) #define NPCHG_READY(npc) (*((bool*)(((u32)(npc))+0x680))) #define NPCHG_CCSB(npc,idx) (((void**)(((u32)(npc))+0x74))[(idx)]) #define NPCHG_CCSC(npc,idx) (((void**)(((u32)(npc))+0x84))[(idx)]) #define NPCHG_CCSA(npc,idx) (((void**)(((u32)(npc))+0x94))[(idx)]) #define NPCHG_CCI(npc,idx) (((void**)(((u32)(npc))+0xA4))[(idx)]) #define NPCHG_2DPLAYER(npc,idx) (((void**)(((u32)(npc))+0x64C))[(idx)]) #define CCSB_ACTIVE(ccsb) (*((bool*)(((u32)(ccsb))+0x29C))) #define CCSC_ACTIVE(ccsc) (*((bool*)(((u32)(ccsc))+0x2A1))) #define PLAYER2D_SHOW_EASY_PAIRING(p2d) (*((bool*)(((u32)(p2d))+0x264))) #define CONT_LIVES(cont,idx) (((int*)(((u32)(cont))+0x2B8))[(idx)]) #define CONT_SETUP_DONE(cont) (*((bool*)(((u32)(cont))+0x2D4))) #define CONT_UNK1(cont) (*((bool*)(((u32)(cont))+0x2D5))) #define CONT_UNK2(cont) (*((bool*)(((u32)(cont))+0x2D6))) #define CONT_DONE(cont) (*((bool*)(((u32)(cont))+0x2D7))) #define CONT_UNK3(cont) (*((bool*)(((u32)(cont))+0x2E0))) bool WMInit_StartLoading(void *ptr) { SpammyReport("WMInit_StartLoading called\n"); DVD_Start(); return true; } bool WMInit_LoadStaticFiles(void *ptr) { return dKPMusic::loadInfo(); } bool WMInit_LoadSIAnims(void *ptr) { SpammyReport("WMInit_LoadSIAnims called\n"); DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_kinoko", 0); DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_fireflower", 0); DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_iceflower", 0); DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_penguin", 0); DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_propeller", 0); DVD_LoadFile(GetDVDClass(), "WorldMap", "SI_star", 0); DVD_LoadFile(GetDVDClass(), "Maps", "SI_hammer", 0); DVD_LoadFile(GetDVDClass(), "Object", "cobCourse", 0); DVD_LoadFile(GetDVDClass(), "Object", "I_kinoko_bundle", 0); DVD_LoadFile(GetDVDClass(), "Object", "lakitu", 0); DVD_LoadFile(GetDVDClass(), "Object", "star_coin", 0); DVD_LoadFile(GetDVDClass(), "Object", "StarRing", 0); return true; } bool WMInit_EndLoading(void *ptr) { SpammyReport("WMInit_EndLoading called\n"); if (DVD_StillLoading(GetDVDClass2())) { SpammyReport("WMInit_EndLoading returning false\n"); return false; } DVD_End(); SpammyReport("WMInit_EndLoading returning true\n"); return true; } bool WMInit_LoadResources1(void *ptr) { SpammyReport("WMInit_LoadResources1 returning true\n"); dScKoopatlas_c *wm = (dScKoopatlas_c*)ptr; return wm->mapListLoader.load("/Maps/List.txt"); } 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); if (!strcmp(wm->mapPath, "/Maps/WSEL.kpbin")) wm->warpZoneHacks = true; else wm->warpZoneHacks = false; OSReport("Load map: %s\n", wm->mapPath); } if (wm->mapData.load(wm->mapPath)) { return true; } else return false; } bool WMInit_SetupWait(void *ptr) { SpammyReport("WMInit_SetupWait called\n"); dScKoopatlas_c *wm = (dScKoopatlas_c*)ptr; bool success = true; success &= CSMENU_SETUP_DONE(wm->csMenu); success &= SELC_SETUP_DONE(wm->selectCursor); success &= NPCHG_SETUP_DONE(wm->numPeopleChange); success &= wm->yesNoWindow->layoutLoaded; success &= CONT_SETUP_DONE(wm->continueObj); success &= wm->stockItem->layoutLoaded; success &= wm->stockItemShadow->layoutLoaded; success &= EASYP_SETUP_DONE(wm->easyPairing); return success; } bool WMInit_SetupExtra(void *ptr) { SpammyReport("WMInit_SetupExtra called\n"); // ok, now we can set up other required shit dScKoopatlas_c *wm = (dScKoopatlas_c*)ptr; // check if we need to handle Continue if (CheckIfContinueShouldBeActivated()) { SpammyReport("continue is activated\n"); wm->state.setState(&wm->StateID_ContinueWait); } else { SpammyReport("continue is not activated\n"); wm->state.setState(&wm->StateID_Normal); } // first up: player models for Stocked Items for (int i = 0; i < 4; i++) { void *obj = CreateChildObject(WM_2D_PLAYER, wm, i, 0, 0); wm->stockItem->player2d[i] = obj; NPCHG_2DPLAYER(wm->numPeopleChange,i) = obj; } // next: items for the Powerup screen for (int i = 0; i < 8; i++) { void *obj = CreateChildObject(WM_ITEM, wm, i, 0, 0); wm->stockItem->newItemPtr[i] = obj; } // need Player before we can set up paths SpammyReport("creating player\n"); wm->player = (daWMPlayer_c*)CreateParentedObject(WM_PLAYER, wm, 0, 2); wm->player->modelHandler->mdlClass->setPowerup(Player_Powerup[0]); wm->player->bindPats(); wm->player->modelHandler->mdlClass->startAnimation(0, 1.2f, 10.0f, 0.0f); // since we've got all the resources, set up the path data too SpammyReport("preparing path manager\n"); wm->pathManager.setup(); // and put the player into position dKPNode_s *cNode = wm->pathManager.currentNode; wm->player->pos = (Vec){cNode->x, -cNode->y, wm->player->pos.z}; // is last param correct? must check :/ SpammyReport("creating MAP\n"); wm->map = (dWMMap_c*)CreateParentedObject(WM_MAP, wm, 0, 0); SpammyReport("creating HUD\n"); wm->hud = (dWMHud_c*)CreateParentedObject(WM_HUD, wm, 0, 0); // note: world_camera is not created here // because we require it earlier // it is created in dScKoopatlas_c::onCreate SpammyReport("creating SHOP\n"); wm->shop = (dWMShop_c*)CreateParentedObject(WM_SHOP, wm, 0, 2); SpammyReport("creating Star Coin Menu\n"); wm->coins = (dWMStarCoin_c*)CreateParentedObject(WM_STARCOIN, wm, 0, 0); SpammyReport("SetupExtra done\n"); return true; } bool WMInit_SetupWipe(void *ptr) { SpammyReport("WMInit_SetupWipe called\n"); dScKoopatlas_c *wm = (dScKoopatlas_c*)ptr; if (wm->hasUninitialisedProcesses()) { SpammyReport("WMInit_SetupWipe returning false\n"); #ifdef WM_SPAMMY_DEBUGGING fBase_c *p = wm->findNextUninitialisedProcess(); SpammyReport("Not done yet: %p [%d]\n", p, p->name); #endif return false; } SpammyReport("WMInit_SetupWipe returning true\n"); return true; } /*void dScKoopatlas_c::startLevel(LevelInfo::Entry *entry) { for (int i = 0; i < 4; i++) { bool isThere = QueryPlayerAvailability(i); int id = Player_ID[i]; Player_Active[i] = isThere ? 1 : 0; if (!isThere) Player_Flags[i] = 0; } StartLevelInfo sl; sl.unk1 = 0; sl.unk2 = 0xFF; sl.unk3 = 0; sl.unk4 = 0; sl.purpose = 0; sl.world1 = entry->world; sl.world2 = entry->world; sl.level1 = entry->level; sl.level2 = entry->level; // hopefully this will fix the Star Coin issues SetSomeConditionShit(entry->world, entry->level, 2); ActivateWipe(WIPE_MARIO); DoStartLevel(GetGameMgr(), &sl); }*/ void dScKoopatlas_c::startMusic() { dKPMusic::play(GetSaveFile()->GetBlock(-1)->currentMapMusic); } int dScKoopatlas_c::onCreate() { OSReport("KP scene settings: %08x\n", settings); SpammyReport("onCreate() called\n"); SpammyReport("LoadMapScene()\n"); LoadMapScene(); SpammyReport("GameSetup__LoadScene(0)\n"); GameSetup__LoadScene(0); // lol, stolen from GAME_SETUP SpammyReport("Setting Active Players\n"); for (int i = 0; i < 4; i++) { bool isThere = QueryPlayerAvailability(i); int id = Player_ID[i]; Player_Active[i] = isThere ? 1 : 0; if (!isThere) Player_Flags[i] = 0; } SpammyReport("select cursor\n"); this->selectCursor = CreateParentedObject(SELECT_CURSOR, this, 0, 0); SpammyReport("cs menu\n"); this->csMenu = CreateParentedObject(COURSE_SELECT_MENU, this, 0, 0); SpammyReport("yes no window\n"); this->yesNoWindow = (dYesNoWindow_c*)CreateParentedObject(YES_NO_WINDOW, this, 0, 0); SpammyReport("number of people change\n"); this->numPeopleChange = CreateParentedObject(NUMBER_OF_PEOPLE_CHANGE, this, 0, 0); for (int i = 0; i < 4; i++) { SpammyReport("ccsb %d\n", i); void *ccsb = CreateParentedObject(CHARACTER_CHANGE_SELECT_BASE, this, i, 0); SpammyReport("ccsc %d\n", i); void *ccsc = CreateParentedObject(CHARACTER_CHANGE_SELECT_CONTENTS, this, i, 0); SpammyReport("ccsa %d\n", i); void *ccsa = CreateParentedObject(CHARACTER_CHANGE_SELECT_ARROW, this, i, 0); SpammyReport("ccsi %d\n", i); void *cci = CreateParentedObject(CHARACTER_CHANGE_INDICATOR, this, i, 0); NPCHG_CCSB(this->numPeopleChange, i) = ccsb; NPCHG_CCSC(this->numPeopleChange, i) = ccsc; NPCHG_CCSA(this->numPeopleChange, i) = ccsa; NPCHG_CCI(this->numPeopleChange, i) = cci; } SpammyReport("continue\n"); this->continueObj = CreateParentedObject(CONTINUE, this, 0, 0); SpammyReport("stock item\n"); this->stockItem = (dStockItem_c*)CreateParentedObject(STOCK_ITEM, this, 0, 0); SpammyReport("stock item shadow\n"); this->stockItemShadow = (dStockItemShadow_c*)CreateParentedObject(STOCK_ITEM_SHADOW, this, 0, 0); stockItem->shadow = stockItemShadow; SpammyReport("easy pairing\n"); this->easyPairing = CreateParentedObject(EASY_PAIRING, this, 0, 0); SpammyReport("world camera\n"); CreateParentedObject(WORLD_CAMERA, this, 0, 0); SpammyReport("setting NewerMapDrawFunc\n"); *CurrentDrawFunc = NewerMapDrawFunc; SpammyReport("onCreate() completed\n"); // Prepare this first SaveBlock *save = GetSaveFile()->GetBlock(-1); currentMapID = save->current_world; isFirstPlay = (currentMapID == 0) && (settings & 0x80000000); // Are we coming from Kamek cutscene? If so, then do.. some stuff! isAfterKamekCutscene = (settings & 0x40000000); if (isAfterKamekCutscene) { currentMapID = 6; // KoopaPlanet save->current_world = 6; } if (MaybeFinishingLevel[0] == 7 && MaybeFinishingLevel[1] == 24) { currentMapID = 7; // KoopaPlanetUnd save->current_world = 7; isAfter8Castle = true; } isEndingScene = (settings & 0x20000000); if (isEndingScene) { currentMapID = 0; save->current_world = 0; save->current_path_node = 0; } somethingAboutSound(_8042A788); return true; } extern "C" void PlaySoundWithFunctionB4(void *spc, nw4r::snd::SoundHandle *handle, int id, int unk); int dScKoopatlas_c::onDelete() { if (!keepMusicPlaying) dKPMusic::stop(); FreeScene(0); FreeScene(1); CleanUpEffectThings(); FreeEffects(1); FreeBreff(1); FreeBreft(1); DVD_FreeFile(GetDVDClass2(), "SI_kinoko"); DVD_FreeFile(GetDVDClass2(), "SI_fireflower"); DVD_FreeFile(GetDVDClass2(), "SI_iceflower"); DVD_FreeFile(GetDVDClass2(), "SI_penguin"); DVD_FreeFile(GetDVDClass2(), "SI_propeller"); DVD_FreeFile(GetDVDClass2(), "SI_star"); DVD_FreeFile(GetDVDClass2(), "SI_hammer"); DVD_FreeFile(GetDVDClass2(), "cobCourse"); DVD_FreeFile(GetDVDClass2(), "I_kinoko_bundle"); DVD_FreeFile(GetDVDClass2(), "lakitu"); DVD_FreeFile(GetDVDClass2(), "star_coin"); DVD_FreeFile(GetDVDClass2(), "StarRing"); mapListLoader.unload(); CleanUpEffectThings(); return true; } bool dScKoopatlas_c::canDoStuff() { if (QueryGlobal5758(0xFFFFFFFF)) return false; if (CheckIfWeCantDoStuff()) return false; if (state.getCurrentState() == &StateID_Limbo) return false; return true; } bool dScKoopatlas_c::mapIsRunning() { if (QueryGlobal5758(0xFFFFFFFF)) return false; if (CheckIfWeCantDoStuff()) return false; if (state.getCurrentState() != &StateID_Normal) return false; return true; } int dScKoopatlas_c::onExecute() { dKPMusic::execute(); if (!canDoStuff()) return true; //SpammyReport("Executing state: %s\n", state.getCurrentState()->getName()); state.execute(); return true; } void dScKoopatlas_c::executeState_Limbo() { } void dScKoopatlas_c::beginState_ContinueWait() { GameMgrP->_AFC = 1; CONT_UNK1(this->continueObj) = true; CONT_UNK2(this->continueObj) = true; CONT_UNK3(this->continueObj) = false; } void dScKoopatlas_c::executeState_ContinueWait() { // Waiting for the Continue anim to finish if (CONT_DONE(this->continueObj)) { CONT_UNK1(this->continueObj) = 0; CONT_UNK2(this->continueObj) = 0; CONT_UNK3(this->continueObj) = 0; static const int things[] = {0,1,3,2,4}; for (int i = 0; i < 4; i++) { int idx = SearchForIndexOfPlayerID(things[i]); Player_Lives[Player_ID[idx]] = CONT_LIVES(this->continueObj, i); } state.setState(&StateID_Normal); } } void dScKoopatlas_c::endState_ContinueWait() { GameMgrP->_AFC = 0; } void dScKoopatlas_c::executeState_Normal() { if (pathManager.completionMessagePending) { OSReport("Going to set CompletionMsg\n"); state.setState(&StateID_CompletionMsg); return; } if (pathManager.doingThings()) return; int nowPressed = Remocon_GetPressed(GetActiveRemocon()); // Nothing related to the menu is going on if (nowPressed & WPAD_ONE) { stockItem->show = true; state.setState(&StateID_PowerupsWait); hud->hideAll(); } else if (nowPressed & WPAD_PLUS) { CSMENU_ACTIVE(this->csMenu) = true; state.setState(&StateID_CSMenu); hud->hideAll(); #ifdef NEWER_DEBUG } else if (nowPressed & WPAD_MINUS) { pathManager.unlockAllPaths(2); } else if (nowPressed & WPAD_A) { pathManager.unlockAllPaths(0); SaveBlock *save = GetSaveFile()->GetBlock(-1); for (int w = 0; w < 6; w++) for (int l = 0; l < 6; l++) save->SetLevelCondition(w, l, COND_COIN_ALL); #endif } } void dScKoopatlas_c::executeState_CSMenu() { // The course select menu is currently being shown // First off, check to see if it's been hidden if (!CSMENU_ACTIVE(this->csMenu)) { // That means something happened if (CSMENU_CHOICE_OK(this->csMenu)) { // Player pressed a button SaveBlock *save = GetSaveFile()->GetBlock(-1); switch (CSMENU_CURRENT(this->csMenu)) { case 0: // Star Coins coins->show(); state.setState(&StateID_CoinsWait); break; case 1: // Add/Drop Players MapReport("Add/Drop Players was pressed\n"); state.setState(&StateID_PlayerChangeWait); NPCHG_ACTIVE(this->numPeopleChange) = true; WpadShit(10); break; case 2: // Save or Quick Save MapReport("Save or Quick Save was pressed\n"); #ifdef QUICK_SAVE if (GetSaveFile()->GetBlock(-1)->bitfield & 2) { #endif state.setState(&StateID_SaveOpen); yesNoWindow->type = 1; yesNoWindow->visible = true; #ifdef QUICK_SAVE } else { state.setState(&StateID_QuickSaveOpen); yesNoWindow->type = 15; yesNoWindow->visible = 1; } #endif break; case 3: // Title Screen MapReport("Title Screen was pressed\n"); state.setState(&StateID_TitleConfirmOpenWait); yesNoWindow->visible = true; yesNoWindow->type = 10; break; } } else { // Ok, change back to STATE_Normal hud->unhideAll(); state.setState(&StateID_Normal); } } } void dScKoopatlas_c::executeState_TitleConfirmOpenWait() { // Waiting for the "Go to Title Screen" YesNoWindow to finish opening if (!yesNoWindow->animationActive) { state.setState(&StateID_TitleConfirmSelect); } } /**********************************************************************/ // STATE_TitleConfirmSelect : Let the user choose an option on the // "Go to Title Screen" YesNoWindow. void dScKoopatlas_c::executeState_TitleConfirmSelect() { int nowPressed = Remocon_GetPressed(GetActiveRemocon()); if (nowPressed & WPAD_LEFT) { // Select "OK!" yesNoWindow->current = 1; } else if (nowPressed & WPAD_RIGHT) { // Select "Cancel" yesNoWindow->current = 0; } else if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { // Pick the current option yesNoWindow->close = true; if (yesNoWindow->current != 1) yesNoWindow->keepOpen = true; state.setState(&StateID_TitleConfirmHitWait); } else { // Cancel using B or 1 if (CheckIfMenuShouldBeCancelledForSpecifiedWiimote(0)) { yesNoWindow->cancelled = true; yesNoWindow->current = true; state.setState(&StateID_TitleConfirmHitWait); } } } /**********************************************************************/ // STATE_TitleConfirmHitWait : Process the user's chosen option on // the "Go to Title Screen" YesNoWindow. Also, wait for the // animation to be complete. void dScKoopatlas_c::executeState_TitleConfirmHitWait() { if (!yesNoWindow->animationActive) { if (yesNoWindow->current == 1) { state.setState(&StateID_Normal); hud->unhideAll(); } else { state.setState(&StateID_Limbo); StartTitleScreenStage(false, 0); } } } /**********************************************************************/ // STATE_PlayerChangeWait : Wait for the user to do something on the // Add/Drop Players screen. void dScKoopatlas_c::executeState_PlayerChangeWait() { int nowPressed = Remocon_GetPressed(GetActiveRemocon()); if (NPCHG_READY(this->numPeopleChange)) { if (nowPressed & WPAD_PLUS) { // activate easy pairing. FUN !! NPCHG_HIDE_FOR_EASYP(this->numPeopleChange) = 1; for (int i = 0; i < 4; i++) { void *obj = NPCHG_2DPLAYER(this->numPeopleChange, i); void *ccsb = NPCHG_CCSB(this->numPeopleChange, i); void *ccsc = NPCHG_CCSC(this->numPeopleChange, i); PLAYER2D_SHOW_EASY_PAIRING(obj) = 1; CCSB_ACTIVE(ccsb) = 1; CCSC_ACTIVE(ccsc) = 1; } EASYP_ACTIVE(this->easyPairing) = 1; state.setState(&StateID_EasyPairingWait); } } else { if (!NPCHG_ACTIVE(this->numPeopleChange)) { for (int i = 0; i < 4; i++) { bool isThere = QueryPlayerAvailability(i); int id = Player_ID[i]; Player_Active[i] = isThere ? 1 : 0; if (!isThere) Player_Flags[i] = 0; } state.setState(&StateID_Normal); hud->unhideAll(); } } } /**********************************************************************/ // STATE_EasyPairingWait : Wait for the user to exit Easy Pairing. void dScKoopatlas_c::executeState_EasyPairingWait() { if (!EASYP_ACTIVE(this->easyPairing)) { NPCHG_HIDE_FOR_EASYP(this->numPeopleChange) = 0; for (int i = 0; i < 4; i++) { void *obj = NPCHG_2DPLAYER(this->numPeopleChange, i); void *ccsb = NPCHG_CCSB(this->numPeopleChange, i); void *ccsc = NPCHG_CCSC(this->numPeopleChange, i); PLAYER2D_SHOW_EASY_PAIRING(obj) = 0; CCSB_ACTIVE(ccsb) = 0; CCSC_ACTIVE(ccsc) = 0; } state.setState(&StateID_PlayerChangeWait); WpadShit(10); } } /**********************************************************************/ // STATE_PowerupsWait : Wait for the user to exit the Powerups screen. void dScKoopatlas_c::executeState_PowerupsWait() { if (!stockItem->show) { player->modelHandler->mdlClass->setPowerup(Player_Powerup[0]); player->bindPats(); state.setState(&StateID_Normal); hud->unhideAll(); } } /**********************************************************************/ // STATE_ShopWait : Wait for the user to exit the Shop screen. void dScKoopatlas_c::executeState_ShopWait() { if (!shop->visible) { state.setState(&StateID_Normal); hud->unhideAll(); } } /**********************************************************************/ // STATE_StarCoin : Wait for the user to exit the Star Coin screen. void dScKoopatlas_c::executeState_CoinsWait() { if (!coins->visible) { state.setState(&StateID_Normal); hud->unhideAll(); } } /**********************************************************************/ // STATE_SaveOpen : Waiting for the "Save?" YesNoWindow to open void dScKoopatlas_c::executeState_SaveOpen() { if (!yesNoWindow->animationActive) { state.setState(&StateID_SaveSelect); } } /**********************************************************************/ // STATE_SaveSelect : Let the user choose an option on the // "Save?" YesNoWindow. void dScKoopatlas_c::executeState_SaveSelect() { int nowPressed = Remocon_GetPressed(GetActiveRemocon()); if (nowPressed & WPAD_LEFT) { // Select "OK!" yesNoWindow->current = 1; } else if (nowPressed & WPAD_RIGHT) { // Select "Cancel" yesNoWindow->current = 0; } else if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { // Pick the current option yesNoWindow->close = true; if (yesNoWindow->current != 1) yesNoWindow->hasBG = true; state.setState(&StateID_SaveWindowClose); } else { // Cancel using B or 1 if (CheckIfMenuShouldBeCancelledForSpecifiedWiimote(0)) { yesNoWindow->cancelled = true; yesNoWindow->current = 1; state.setState(&StateID_SaveWindowClose); } } } /**********************************************************************/ // STATE_SaveWindowClose : Process the user's chosen option on the // "Save?" YesNoWindow. Also, wait for the animation to be complete. void dScKoopatlas_c::executeState_SaveWindowClose() { if (!yesNoWindow->visible) { if (yesNoWindow->current == 1) { state.setState(&StateID_Normal); hud->unhideAll(); } else { state.setState(&StateID_SaveDo); SaveGame(0, false); } } } /**********************************************************************/ // STATE_SaveDo : Save the game. void dScKoopatlas_c::executeState_SaveDo() { if (!GetSaveFile()->CheckIfWriting()) { if (GetSaveHandler()->CurrentError == 0) { yesNoWindow->type = 2; yesNoWindow->visible = true; state.setState(&StateID_SaveEndWindow); } else { state.setState(&StateID_SaveError); } } } /**********************************************************************/ // STATE_SaveEndWindow : Handle the Save End window. void dScKoopatlas_c::executeState_SaveEndWindow() { if (!yesNoWindow->animationActive) { if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { yesNoWindow->close = true; state.setState(&StateID_SaveEndCloseWait); } } } /**********************************************************************/ // STATE_SaveEndCloseWait : Wait for the Save End window to close. void dScKoopatlas_c::executeState_SaveEndCloseWait() { if (!yesNoWindow->animationActive) { state.setState(&StateID_Normal); hud->unhideAll(); } } #ifdef QUICK_SAVE /**********************************************************************/ // STATE_QuickSaveOpen : Waiting for the "Save?" YesNoWindow to open void dScKoopatlas_c::executeState_QuickSaveOpen() { if (!yesNoWindow->animationActive) { state.setState(&StateID_QuickSaveSelect); } } /**********************************************************************/ // STATE_QuickSaveSelect : Let the user choose an option on the // "Save?" YesNoWindow. void dScKoopatlas_c::executeState_QuickSaveSelect() { int nowPressed = Remocon_GetPressed(GetActiveRemocon()); if (nowPressed & WPAD_LEFT) { // Select "OK!" yesNoWindow->current = 1; } else if (nowPressed & WPAD_RIGHT) { // Select "Cancel" yesNoWindow->current = 0; } else if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { // Pick the current option yesNoWindow->close = true; if (yesNoWindow->current != 1) yesNoWindow->hasBG = true; state.setState(&StateID_QuickSaveWindowClose); } else { // Cancel using B or 1 if (CheckIfMenuShouldBeCancelledForSpecifiedWiimote(0)) { yesNoWindow->cancelled = true; yesNoWindow->current = 1; state.setState(&StateID_QuickSaveWindowClose); } } } /**********************************************************************/ // STATE_QuickSaveWindowClose : Process the user's chosen option on // the "Save?" YesNoWindow. Also, wait for the animation to be complete void dScKoopatlas_c::executeState_QuickSaveWindowClose() { if (!yesNoWindow->visible) { if (yesNoWindow->current == 1) { state.setState(&StateID_Normal); hud->unhideAll(); } else { state.setState(&StateID_QuickSaveDo); SaveGame(0, true); } } } /**********************************************************************/ // STATE_QuickSaveDo : Save the game. void dScKoopatlas_c::executeState_QuickSaveDo() { if (!GetSaveFile()->CheckIfWriting()) { if (GetSaveHandler()->CurrentError == 0) { yesNoWindow->type = 16; yesNoWindow->visible = true; state.setState(&StateID_QuickSaveEndWindow); } else { state.setState(&StateID_SaveError); } } } // STATE_QuickSaveEndWindow : Handle the Save End window. void dScKoopatlas_c::executeState_QuickSaveEndWindow() { if (!yesNoWindow->animationActive) { if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { yesNoWindow->close = true; yesNoWindow->keepOpen = true; state.setState(&StateID_QuickSaveEndCloseWait); } } } void dScKoopatlas_c::executeState_QuickSaveEndCloseWait() { // Wait for Save End window to close if (!yesNoWindow->animationActive) { if (yesNoWindow->current == 1) { state.setState(&StateID_Normal); hud->unhideAll(); } else { state.setState(&StateID_Limbo); StartTitleScreenStage(false, 0); } } } #endif void dScKoopatlas_c::executeState_SaveError() { } void dScKoopatlas_c::startLevel(dLevelInfo_c::entry_s *entry) { StartLevelInfo sl; sl.replayTypeMaybe = 0; sl.entrance = 0xFF; sl.areaMaybe = 0; sl.unk4 = 0; sl.purpose = 0; sl.world1 = entry->worldSlot; sl.world2 = entry->worldSlot; sl.level1 = entry->levelSlot; sl.level2 = entry->levelSlot; ActivateWipe(WIPE_MARIO); DoStartLevel(GetGameMgr(), &sl); } 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 = 0; ++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 dScKoopatlas_c::showSaveWindow() { hud->hideAll(); state.setState(&StateID_SaveOpen); yesNoWindow->type = 1; yesNoWindow->visible = true; } void dScKoopatlas_c::beginState_CompletionMsg() { OSReport("CompletionMsg beginning with type %d\n", pathManager.completionMessageType); static const int ynTypes[8] = { /*NULL*/ -1, /*COINS*/ 14, /*EXITS*/ 7, /*WORLD*/ 8, /*COINS EXC W9*/ 9, /*GLOBAL COINS*/ 11, /*GLOBAL EXITS*/ 27, /*EVERYTHING*/ 21 }; yesNoWindow->type = ynTypes[pathManager.completionMessageType]; yesNoWindow->visible = true; mustFixYesNoText = 10; // hacky shit } void dScKoopatlas_c::endState_CompletionMsg() { pathManager.completionMessagePending = false; pathManager.completionMessageType = 0; } void dScKoopatlas_c::executeState_CompletionMsg() { // hacky shit if (mustFixYesNoText > 0) { mustFixYesNoText--; int type = pathManager.completionMessageType; if (type >= CMP_MSG_COINS && type <= CMP_MSG_WORLD) { // get the stuff we need: base BMG string static const int bmgs[4] = {-1, 65, 58, 59}; const wchar_t *baseText = GetBMG()->findStringForMessageID(0, bmgs[type]); // title int w = pathManager.completionMessageWorldNum; int l = ((w == 5) || (w == 7)) ? 101 : 100; dLevelInfo_c::entry_s *titleEntry = dLevelInfo_c::s_info.searchByDisplayNum(w, l); const char *title = dLevelInfo_c::s_info.getNameForLevel(titleEntry); // assemble the string wchar_t text[512]; wcscpy(text, baseText); int pos = wcslen(text); text[pos++] = ' '; while (*title) { char chr = *(title++); if (chr != '-') text[pos++] = chr; } text[pos++] = '!'; text[pos++] = 0; yesNoWindow->T_question_00->SetString(text); yesNoWindow->T_questionS_00->SetString(text); } } if (!yesNoWindow->animationActive) { if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { yesNoWindow->close = true; state.setState(&StateID_CompletionMsgHideWait); } } } void dScKoopatlas_c::executeState_CompletionMsgHideWait() { if (!yesNoWindow->visible) state.setState(&StateID_Normal); } void NewerMapDrawFunc() { Reset3DState(); SetCurrentCameraID(0); DoSomethingCameraRelatedWithEGGScreen(0, &dWorldCamera_c::instance->screen); LinkScene(0); SceneCalcWorld(0); SceneCameraStuff(0); ChangeAlphaUpdate(false); DrawOpa(); DrawXlu(); UnlinkScene(0); // Something SetupLYTDrawing(); DrawAllLayoutsBeforeX(0x81); RenderEffects(0, 3); RenderEffects(0, 2); GXDrawDone(); RemoveAllFromScnRoot(); Reset3DState(); SetCurrentCameraID(1); DoSpecialDrawing1(); LinkScene(1); SceneCalcWorld(1); SceneCameraStuff(1); CalcMaterial(); DrawOpa(); DrawXlu(); UnlinkScene(1); SetCurrentCameraID(0); for (int i = 0; i < 4; i++) RenderEffects(0, 0xB+i); for (int i = 0; i < 4; i++) RenderEffects(0, 7+i); GXDrawDone(); // Leaving out some stuff here DrawAllLayoutsAfterX(0x80); ClearLayoutDrawList(); SetCurrentCameraID(0); }