#include "worldmap.h" extern "C" void LoadMapScene(); dScNewerWorldMap_c *dScNewerWorldMap_c::instance = 0; dScNewerWorldMap_c *dScNewerWorldMap_c::build() { // return new dScNewerWorldMap_c; OSReport("Creating WorldMap\n"); void *buffer = AllocFromGameHeap1(sizeof(dScNewerWorldMap_c)); dScNewerWorldMap_c *c = new(buffer) dScNewerWorldMap_c; OSReport("Created WorldMap @ %p\n", c); instance = c; return c; } #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 YESNO_SETUP_DONE(ynw) (*((bool*)(((u32)(ynw))+0x294))) #define YESNO_VISIBLE(ynw) (*((bool*)(((u32)(ynw))+0x295))) #define YESNO_CLOSE(ynw) (*((bool*)(((u32)(ynw))+0x296))) #define YESNO_OPENING(ynw) (*((bool*)(((u32)(ynw))+0x297))) #define YESNO_REFUSED(ynw) (*((bool*)(((u32)(ynw))+0x298))) #define YESNO_CANCELLED(ynw) (*((bool*)(((u32)(ynw))+0x299))) #define YESNO_CANCELLED2(ynw) (*((bool*)(((u32)(ynw))+0x29A))) #define YESNO_CURRENT(ynw) (*((int*)(((u32)(ynw))+0x284))) #define YESNO_TYPE(ynw) (*((int*)(((u32)(ynw))+0x28C))) #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 STKI_SETUP_DONE(si) (*((bool*)(((u32)(si))+0x310))) #define STKI_SHADOW(si) (*((void**)(((u32)(si))+0x310))) #define STKI_2DPLAYER(si,idx) (((void**)(((u32)(si))+0x2E4))[(idx)]) #define STKI_ITEM(si,idx) (((void**)(((u32)(si))+0x2F4))[(idx)]) #define STKI_SHOW(si) (*((bool*)(((u32)(si))+0x8DD))) #define SIS_SETUP_DONE(sis) (*((bool*)(((u32)(sis))+0x260))) #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))) // Todo: remove level menu related states from here #define STATE_START_DVD 0 #define STATE_LOAD_RES 1 #define STATE_END_DVD 2 #define STATE_SETUP_WAIT 3 #define STATE_LIMBO 4 #define STATE_CONTINUE_WAIT 5 #define STATE_NORMAL 6 // Empty slot: 7 #define STATE_CSMENU 8 #define STATE_TITLE_CONFIRM_OPEN_WAIT 9 #define STATE_TITLE_CONFIRM_SELECT 10 #define STATE_TITLE_CONFIRM_HIT_WAIT 11 #define STATE_PLAYER_CHANGE_WAIT 12 #define STATE_EASY_PAIRING_WAIT 13 #define STATE_POWERUPS_WAIT 14 #define STATE_SAVE_OPEN 15 #define STATE_SAVE_SELECT 16 #define STATE_SAVE_WINDOW_CLOSE 17 #define STATE_SAVE_DO 18 #define STATE_SAVE_END_WINDOW 19 #define STATE_SAVE_END_CLOSE_WAIT 20 #define STATE_QUICKSAVE_OPEN 21 #define STATE_QUICKSAVE_SELECT 22 #define STATE_QUICKSAVE_WINDOW_CLOSE 23 #define STATE_QUICKSAVE_DO 24 #define STATE_QUICKSAVE_END_WINDOW 25 #define STATE_QUICKSAVE_END_CLOSE_WAIT 26 #define STATE_SAVE_ERROR 27 void dScNewerWorldMap_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); } int dScNewerWorldMap_c::onCreate() { LoadMapScene(); GameSetup__LoadScene(0); // lol, stolen from GAME_SETUP this->selectCursor = CreateParentedObject(SELECT_CURSOR, this, 0, 0); this->csMenu = CreateParentedObject(COURSE_SELECT_MENU, this, 0, 0); this->yesNoWindow = CreateParentedObject(YES_NO_WINDOW, this, 0, 0); this->numPeopleChange = CreateParentedObject(NUMBER_OF_PEOPLE_CHANGE, this, 0, 0); for (int i = 0; i < 4; i++) { void *ccsb = CreateParentedObject(CHARACTER_CHANGE_SELECT_BASE, this, i, 0); void *ccsc = CreateParentedObject(CHARACTER_CHANGE_SELECT_CONTENTS, this, i, 0); void *ccsa = CreateParentedObject(CHARACTER_CHANGE_SELECT_ARROW, this, i, 0); 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; } this->continueObj = CreateParentedObject(CONTINUE, this, 0, 0); this->stockItem = CreateParentedObject(STOCK_ITEM, this, 0, 0); this->stockItemShadow = CreateParentedObject(STOCK_ITEM_SHADOW, this, 0, 0); STKI_SHADOW(this->stockItem) = this->stockItemShadow; this->easyPairing = CreateParentedObject(EASY_PAIRING, this, 0, 0); CreateParentedObject(WORLD_CAMERA, this, 0, 0); this->state = STATE_START_DVD; *CurrentDrawFunc = NewerMapDrawFunc; // level info this->levelInfo = LoadFile(&this->levelInfoFH, "/NewerRes/LevelInfo.bin"); LevelInfo_Prepare(&this->levelInfoFH); // load the menu info SaveBlock *save = GetSaveFile()->GetBlock(-1); LoadModel(); wmData.load("/NewerRes/TestMap.wm"); WMDataHeader *hdr = (WMDataHeader*)wmData.fh.filePtr; if (save->current_path_node >= hdr->pointCount) { this->currentPoint = wmData.getPath(0)->startPoint; } else { this->currentPoint = hdr->pointList[save->current_path_node]; } return true; } int dScNewerWorldMap_c::onDelete() { FreeFile(&this->levelInfoFH); FreeScene(0); FreeScene(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"); return true; } int dScNewerWorldMap_c::onExecute() { if (QueryGlobal5758(0xFFFFFFFF)) return true; if (CheckIfWeCantDoStuff()) return true; /**************************************************************************/ // Read Wiimote Buttons int heldButtons = Remocon_GetButtons(GetActiveRemocon()); int nowPressed = Remocon_GetPressed(GetActiveRemocon()); /**************************************************************************/ // State Specific switch (this->state) { /**********************************************************************/ // STATE_START_DVD : Set up DVD case STATE_START_DVD: DVD_Start(); this->state = STATE_LOAD_RES; break; /**********************************************************************/ // STATE_LOAD_RES : Load extra stuff we need case STATE_LOAD_RES: 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(), "Object", "fruits_kusa_gake", 0); this->state = STATE_END_DVD; break; /**********************************************************************/ // STATE_END_DVD : Wait for files to load, end DVD // Also, load the WM Set files case STATE_END_DVD: { bool didEndDVD = false, didWMSetLoad = false; if (!DVD_StillLoading(GetDVDClass2())) { if (DVD_End()) { didEndDVD = true; } } didWMSetLoad = resMng.loadSet("SMGoldwood"); if (didEndDVD && didWMSetLoad) this->state = STATE_SETUP_WAIT; } break; /**********************************************************************/ // STATE_SETUP_WAIT : Waiting for the world map managers to be set up case STATE_SETUP_WAIT: { bool success = true; success &= CSMENU_SETUP_DONE(this->csMenu); success &= SELC_SETUP_DONE(this->selectCursor); success &= NPCHG_SETUP_DONE(this->numPeopleChange); success &= YESNO_SETUP_DONE(this->yesNoWindow); success &= CONT_SETUP_DONE(this->continueObj); success &= STKI_SETUP_DONE(this->stockItem); success &= SIS_SETUP_DONE(this->stockItemShadow); success &= EASYP_SETUP_DONE(this->easyPairing); if (success) { // ok, now we can set up other required shit // first up: player models for Stocked Items for (int i = 0; i < 4; i++) { void *obj = CreateChildObject(WM_2D_PLAYER, this, i, 0, 0); STKI_2DPLAYER(this->stockItem,i) = obj; NPCHG_2DPLAYER(this->numPeopleChange,i) = obj; } // next: items for the Powerup screen for (int i = 0; i < 7; i++) { void *obj = CreateChildObject(WM_ITEM, this, i, 0, 0); STKI_ITEM(this->stockItem,i) = obj; } // now, check if we need to handle Continue if (CheckIfContinueShouldBeActivated()) { this->state = STATE_CONTINUE_WAIT; CONT_UNK1(this->continueObj) = true; CONT_UNK2(this->continueObj) = true; CONT_UNK3(this->continueObj) = false; } else { this->state = STATE_NORMAL; } // and now Player setup this->player = (daWMPlayer_c*)CreateParentedObject(WM_PLAYER, this, 0, 2); this->player->modelHandler->mdlClass->setPowerup(2); this->player->modelHandler->mdlClass->startAnimation(0, 1.2f, 10.0f, 0.0f); this->player->pos = this->currentPoint->position; } } break; /**********************************************************************/ // STATE_CONTINUE_WAIT : Waiting for the Continue anim to finish case STATE_CONTINUE_WAIT: if (CONT_DONE(this->continueObj)) { CONT_UNK1(this->continueObj) = 0; CONT_UNK2(this->continueObj) = 0; CONT_UNK3(this->continueObj) = 0; for (int i = 0; i < 4; i++) { int idx = SearchForIndexOfPlayerID(i); Player_Lives[Player_ID[idx]] = CONT_LIVES(this->continueObj, i); } this->state = STATE_NORMAL; } break; /**********************************************************************/ // STATE_NORMAL : Nothing related to the menu is going on case STATE_NORMAL: { HandleMovement(); if (nowPressed & WPAD_ONE) { STKI_SHOW(this->stockItem) = true; this->state = STATE_POWERUPS_WAIT; } } break; /**********************************************************************/ // STATE_CSMENU : The course select menu is currently being shown case STATE_CSMENU: // 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 switch (CSMENU_CURRENT(this->csMenu)) { case 0: // Star Coins //OSReport("Star Coins was pressed\n"); this->state = STATE_NORMAL; break; case 1: // Add/Drop Players //OSReport("Add/Drop Players was pressed\n"); this->state = STATE_PLAYER_CHANGE_WAIT; NPCHG_ACTIVE(this->numPeopleChange) = true; WpadShit(10); break; case 2: // Save or Quick Save //OSReport("Save or Quick Save was pressed\n"); if (GetSaveFile()->GetBlock(-1)->bitfield & 2) { this->state = STATE_SAVE_OPEN; YESNO_TYPE(this->yesNoWindow) = 1; YESNO_VISIBLE(this->yesNoWindow) = 1; } else { this->state = STATE_QUICKSAVE_OPEN; YESNO_TYPE(this->yesNoWindow) = 15; YESNO_VISIBLE(this->yesNoWindow) = 1; } break; case 3: // Title Screen //OSReport("Title Screen was pressed\n"); this->state = STATE_TITLE_CONFIRM_OPEN_WAIT; YESNO_VISIBLE(this->yesNoWindow) = true; YESNO_TYPE(this->yesNoWindow) = 10; break; } } else { // Ok, change back to STATE_NORMAL this->state = STATE_NORMAL; } } break; /**********************************************************************/ // STATE_TITLE_CONFIRM_OPEN_WAIT : Waiting for the "Go to Title Screen" // YesNoWindow to finish opening case STATE_TITLE_CONFIRM_OPEN_WAIT: if (!YESNO_OPENING(this->yesNoWindow)) { this->state = STATE_TITLE_CONFIRM_SELECT; } break; /**********************************************************************/ // STATE_TITLE_CONFIRM_SELECT : Let the user choose an option on the // "Go to Title Screen" YesNoWindow. case STATE_TITLE_CONFIRM_SELECT: if (nowPressed & WPAD_LEFT) { // Select "OK!" YESNO_CURRENT(this->yesNoWindow) = 1; } else if (nowPressed & WPAD_RIGHT) { // Select "Cancel" YESNO_CURRENT(this->yesNoWindow) = 0; } else if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { // Pick the current option YESNO_CLOSE(this->yesNoWindow) = true; if (YESNO_CURRENT(this->yesNoWindow) != 1) YESNO_REFUSED(this->yesNoWindow) = true; this->state = STATE_TITLE_CONFIRM_HIT_WAIT; } else { // Cancel using B or 1 if (CheckIfMenuShouldBeCancelledForSpecifiedWiimote(0)) { YESNO_CANCELLED(this->yesNoWindow) = true; YESNO_CURRENT(this->yesNoWindow) = true; this->state = STATE_TITLE_CONFIRM_HIT_WAIT; } } break; /**********************************************************************/ // STATE_TITLE_CONFIRM_HIT_WAIT : Process the user's chosen option on // the "Go to Title Screen" YesNoWindow. Also, wait for the // animation to be complete. case STATE_TITLE_CONFIRM_HIT_WAIT: if (!YESNO_OPENING(this->yesNoWindow)) { if (YESNO_CURRENT(this->yesNoWindow) == 1) { this->state = STATE_NORMAL; } else { this->state = STATE_LIMBO; StartTitleScreenStage(false, 0); } } break; /**********************************************************************/ // STATE_PLAYER_CHANGE_WAIT : Wait for the user to do something on the // Add/Drop Players screen. case STATE_PLAYER_CHANGE_WAIT: 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; this->state = STATE_EASY_PAIRING_WAIT; } } else { if (!NPCHG_ACTIVE(this->numPeopleChange)) { this->state = STATE_NORMAL; } } break; /**********************************************************************/ // STATE_EASY_PAIRING_WAIT : Wait for the user to exit Easy Pairing. case STATE_EASY_PAIRING_WAIT: 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; } this->state = STATE_PLAYER_CHANGE_WAIT; WpadShit(10); } break; /**********************************************************************/ // STATE_POWERUPS_WAIT : Wait for the user to exit the Powerups screen. case STATE_POWERUPS_WAIT: if (!STKI_SHOW(this->stockItem)) { this->state = STATE_NORMAL; } break; /**********************************************************************/ // STATE_SAVE_OPEN : Waiting for the "Save?" YesNoWindow to open case STATE_SAVE_OPEN: if (!YESNO_OPENING(this->yesNoWindow)) { this->state = STATE_SAVE_SELECT; } break; /**********************************************************************/ // STATE_SAVE_SELECT : Let the user choose an option on the // "Save?" YesNoWindow. case STATE_SAVE_SELECT: if (nowPressed & WPAD_LEFT) { // Select "OK!" YESNO_CURRENT(this->yesNoWindow) = 1; } else if (nowPressed & WPAD_RIGHT) { // Select "Cancel" YESNO_CURRENT(this->yesNoWindow) = 0; } else if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { // Pick the current option YESNO_CLOSE(this->yesNoWindow) = true; if (YESNO_CURRENT(this->yesNoWindow) != 1) YESNO_CANCELLED2(this->yesNoWindow) = true; this->state = STATE_SAVE_WINDOW_CLOSE; } else { // Cancel using B or 1 if (CheckIfMenuShouldBeCancelledForSpecifiedWiimote(0)) { YESNO_CANCELLED(this->yesNoWindow) = true; YESNO_CURRENT(this->yesNoWindow) = 1; this->state = STATE_SAVE_WINDOW_CLOSE; } } break; /**********************************************************************/ // STATE_SAVE_WINDOW_CLOSE : Process the user's chosen option on the // "Save?" YesNoWindow. Also, wait for the animation to be complete. case STATE_SAVE_WINDOW_CLOSE: if (!YESNO_VISIBLE(this->yesNoWindow)) { if (YESNO_CURRENT(this->yesNoWindow) == 1) { this->state = STATE_NORMAL; } else { this->state = STATE_SAVE_DO; SaveGame(0, false); } } break; /**********************************************************************/ // STATE_SAVE_DO : Save the game. case STATE_SAVE_DO: if (!GetSaveFile()->CheckIfWriting()) { if (GetSaveHandler()->CurrentError == 0) { YESNO_TYPE(this->yesNoWindow) = 2; YESNO_VISIBLE(this->yesNoWindow) = true; this->state = STATE_SAVE_END_WINDOW; } else { this->state = STATE_SAVE_ERROR; } } break; /**********************************************************************/ // STATE_SAVE_END_WINDOW : Handle the Save End window. case STATE_SAVE_END_WINDOW: if (!YESNO_OPENING(this->yesNoWindow)) { if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { YESNO_CLOSE(this->yesNoWindow) = true; this->state = STATE_SAVE_END_CLOSE_WAIT; } } break; /**********************************************************************/ // STATE_SAVE_END_CLOSE_WAIT : Wait for the Save End window to close. case STATE_SAVE_END_CLOSE_WAIT: if (!YESNO_OPENING(this->yesNoWindow)) { this->state = STATE_NORMAL; } break; /**********************************************************************/ // STATE_QUICKSAVE_OPEN : Waiting for the "Save?" YesNoWindow to open case STATE_QUICKSAVE_OPEN: if (!YESNO_OPENING(this->yesNoWindow)) { this->state = STATE_QUICKSAVE_SELECT; } break; /**********************************************************************/ // STATE_QUICKSAVE_SELECT : Let the user choose an option on the // "Save?" YesNoWindow. case STATE_QUICKSAVE_SELECT: if (nowPressed & WPAD_LEFT) { // Select "OK!" YESNO_CURRENT(this->yesNoWindow) = 1; } else if (nowPressed & WPAD_RIGHT) { // Select "Cancel" YESNO_CURRENT(this->yesNoWindow) = 0; } else if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { // Pick the current option YESNO_CLOSE(this->yesNoWindow) = true; if (YESNO_CURRENT(this->yesNoWindow) != 1) YESNO_CANCELLED2(this->yesNoWindow) = true; this->state = STATE_QUICKSAVE_WINDOW_CLOSE; } else { // Cancel using B or 1 if (CheckIfMenuShouldBeCancelledForSpecifiedWiimote(0)) { YESNO_CANCELLED(this->yesNoWindow) = true; YESNO_CURRENT(this->yesNoWindow) = 1; this->state = STATE_QUICKSAVE_WINDOW_CLOSE; } } break; /**********************************************************************/ // STATE_QUICKSAVE_WINDOW_CLOSE : Process the user's chosen option on // the "Save?" YesNoWindow. Also, wait for the animation to be complete case STATE_QUICKSAVE_WINDOW_CLOSE: if (!YESNO_VISIBLE(this->yesNoWindow)) { if (YESNO_CURRENT(this->yesNoWindow) == 1) { this->state = STATE_NORMAL; } else { this->state = STATE_QUICKSAVE_DO; SaveGame(0, true); } } break; /**********************************************************************/ // STATE_QUICKSAVE_DO : Save the game. case STATE_QUICKSAVE_DO: if (!GetSaveFile()->CheckIfWriting()) { if (GetSaveHandler()->CurrentError == 0) { YESNO_TYPE(this->yesNoWindow) = 16; YESNO_VISIBLE(this->yesNoWindow) = true; this->state = STATE_QUICKSAVE_END_WINDOW; } else { this->state = STATE_SAVE_ERROR; } } break; /**********************************************************************/ // STATE_QUICKSAVE_END_WINDOW : Handle the Save End window. case STATE_QUICKSAVE_END_WINDOW: if (!YESNO_OPENING(this->yesNoWindow)) { if (Wiimote_TestButtons(GetActiveWiimote(), WPAD_A | WPAD_TWO)) { YESNO_CLOSE(this->yesNoWindow) = true; YESNO_REFUSED(this->yesNoWindow) = true; this->state = STATE_QUICKSAVE_END_CLOSE_WAIT; } } break; /**********************************************************************/ // STATE_QUICKSAVE_END_CLOSE_WAIT : Wait for Save End window to close case STATE_QUICKSAVE_END_CLOSE_WAIT: if (!YESNO_OPENING(this->yesNoWindow)) { if (YESNO_CURRENT(this->yesNoWindow) == 1) { this->state = STATE_NORMAL; } else { this->state = STATE_LIMBO; StartTitleScreenStage(false, 0); } } break; } return true; } int dScNewerWorldMap_c::onDraw() { this->model.scheduleForDrawing(); return true; } // Todo: move to .LZ files and dDvd::loader_c void dScNewerWorldMap_c::LoadModel() { OSReport("Loading Goldwood model...\n"); modelFile.openCompressed("/NewerRes/Maps/SMGoldwood.brres"); nw4r::g3d::ResFile resfile(modelFile.ptr()); if (!resfile.CheckRevision()) OSReport("Warning: Revision check failed!\n"); resfile.Init(); if (!resfile.Bind(resfile)) OSReport("Warning: ResFile bind failed!\n"); void *mdl = resfile.GetResMdl("GoldwoodBase"); OSReport("Obtained ResMdl: %p\n", mdl); OSReport(this->allocator.link(-1, GameHeaps[0], 0, 0x20) ? "Success\n" : "Fail\n"); OSReport(this->model.setup(&mdl, &this->allocator, 0, 1, 0) ? "Success\n" : "Fail\n"); SetupTextures_Map(&model, 1); this->allocator.unlink(); OSReport("Done loading model!\n"); Mtx asdf; MTXIdentity(asdf); this->model.setDrawMatrix(asdf); } void dScNewerWorldMap_c::HandleMovement() { int heldButtons = Remocon_GetButtons(GetActiveRemocon()); int nowPressed = Remocon_GetPressed(GetActiveRemocon()); if (isMoving) { MoveThroughPath(); } else { if (nowPressed & WPAD_LEFT && currentPoint->exits.asDirection.left.isValid()) StartMovementTo(LEFT); else if (nowPressed & WPAD_RIGHT && currentPoint->exits.asDirection.right.isValid()) StartMovementTo(RIGHT); else if (nowPressed & WPAD_UP && currentPoint->exits.asDirection.up.isValid()) StartMovementTo(UP); else if (nowPressed & WPAD_DOWN && currentPoint->exits.asDirection.down.isValid()) StartMovementTo(DOWN); if (nowPressed & WPAD_TWO) ActivatePoint(); } } void dScNewerWorldMap_c::MoveThroughPath() { // figure out how much to move on each step Vec from, to; if (this->reverseThroughPath) { from = this->currentSegment->end; to = this->currentSegment->start; } else { from = this->currentSegment->start; to = this->currentSegment->end; } Vec move; move.x = to.x - from.x; move.y = to.y - from.y; move.z = to.z - from.z; VECNormalize(&move, &move); VECScale(&move, &move, this->currentSegment->stepsPerFrame); this->player->pos.x += move.x; this->player->pos.y += move.y; this->player->pos.z += move.z; // have we reached the end? bool xAtEnd = false; bool yAtEnd = false; bool zAtEnd = false; if (move.x > 0) { xAtEnd = (this->player->pos.x >= to.x); } else { xAtEnd = (this->player->pos.x <= to.x); } if (move.y > 0) { yAtEnd = (this->player->pos.y >= to.y); } else { yAtEnd = (this->player->pos.y <= to.y); } if (move.z > 0) { zAtEnd = (this->player->pos.z >= to.z); } else { zAtEnd = (this->player->pos.z <= to.z); } if (xAtEnd && yAtEnd && zAtEnd) { MapReport("reached end of segment %d\n", this->currentSegmentID); int nextSegment = this->currentSegmentID + (this->reverseThroughPath ? -1 : 1); if (nextSegment == -1 || nextSegment == this->currentPath->segCount) { MapReport("reached end of path\n"); this->currentPoint = this->nextPoint; this->player->pos = this->currentPoint->position; this->player->startAnimation(0, 1.2, 10.0, 0.0); this->isMoving = false; SaveBlock *save = GetSaveFile()->GetBlock(-1); //save->current_world = newPage; ? save->current_path_node = wmData.getPointID(this->currentPoint); } else { this->MoveToSegment(nextSegment); } } } void dScNewerWorldMap_c::StartMovementTo(WMDirection direction) { this->isMoving = true; WMPathEntrance *thisExit = ¤tPoint->exits.asArray[direction]; MapReport("Using an exit in direction %d\n", direction); this->currentPath = thisExit->path; if (thisExit->isEndSide) { this->nextPoint = thisExit->path->startPoint; this->reverseThroughPath = true; this->MoveToSegment(thisExit->path->segCount - 1); } else { this->nextPoint = thisExit->path->endPoint; this->reverseThroughPath = false; this->MoveToSegment(0); } } void dScNewerWorldMap_c::MoveToSegment(int id) { MapReport("Moving to segment %d\n", id); this->currentSegmentID = id; this->currentSegment = this->currentPath->segments[id]; // calculate rotation Vec from, to; if (this->reverseThroughPath) { from = this->currentSegment->end; to = this->currentSegment->start; } else { from = this->currentSegment->start; to = this->currentSegment->end; } MapReport("From: %f,%f,%f To: %f,%f,%f\n", from.x, from.y, from.z, to.x, to.y, to.z); this->player->pos = from; // update rotation if (!this->currentSegment->useLastDir) { this->player->rot.x = 0; this->player->rot.y = this->currentSegment->direction; this->player->rot.z = 0; if (this->reverseThroughPath && !this->currentSegment->alwaysSameDir) { this->player->rot.y = ((this->currentSegment->direction) + 0x8000) & 0xFFFF; } } this->player->startAnimation(this->currentSegment->animationType, this->currentSegment->animationSpeed, 10.0, 0.0); } void dScNewerWorldMap_c::ActivatePoint() { MapReport("Point activated!\n"); this->player->startAnimation(170, 1.2, 10.0, 0.0); if (this->currentPoint->type == WMPathPoint::LEVEL_TYPE) { int w = this->currentPoint->params[0] - 1; int l = this->currentPoint->params[1] - 1; LevelInfo_Entry *level = LevelInfo_Search(this->levelInfo, w, l); StartLevel(level); } } void NewerMapDrawFunc() { int keepCamera = GetCurrentCameraID(); // All drawing uses scene 1, since that's the only one loaded by GAME_SETUP. // Todo: Newer-specific scenes? // Stage 1 SetupLYTDrawing(); DrawAllLayoutsBeforeX(129); GXDrawDone(); // is all GXDrawDone really needed..? // Stage 2 Reset3DState(); SetCurrentCameraID(0); LinkScene(0); SceneCalcWorld(0); SceneCameraStuff(0); ChangeAlphaUpdate(false); CalcMaterial(); DrawOpa(); DrawXlu(); UnlinkScene(0); GXDrawDone(); //Reset3DState(); //T3D::DrawQueue(); // Stage 3 Reset3DState(); SetupLYTDrawing(); DrawAllLayoutsAfterXandBeforeY(128, 146); GXDrawDone(); // Stage 4 RemoveAllFromScnRoot(); Reset3DState(); SetCurrentCameraID(1); DoSpecialDrawing1(); LinkScene(1); SceneCalcWorld(1); SceneCameraStuff(1); CalcMaterial(); DrawOpa(); DrawXlu(); // Stage 5 if (GAMEMGR_GET_AFC(GameMgr)) { for (int i = 0; i < 4; i++) { RenderEffects(0, 11+i); } for (int i = 0; i < 4; i++) { RenderEffects(0, 7+i); } } RenderEffects(0, 2); // need to investigate how this thing works DrawAllLayoutsAfterX(145); ClearLayoutDrawList(); // this is REALLY IMPORTANT! UnlinkScene(1); // End SetCurrentCameraID(0); }