mirror of
https://github.com/pret/pmd-red.git
synced 2026-03-21 17:46:39 -05:00
1116 lines
32 KiB
C
1116 lines
32 KiB
C
#include "global.h"
|
|
#include "globaldata.h"
|
|
#include "constants/bg_music.h"
|
|
#include "constants/friend_area.h"
|
|
#include "constants/ground_map.h"
|
|
#include "constants/main_menu.h"
|
|
#include "structs/str_dungeon_setup.h"
|
|
#include "adventure_info.h"
|
|
#include "bg_control.h"
|
|
#include "bg_palette_buffer.h"
|
|
#include "code_800558C.h"
|
|
#include "code_800C9CC.h"
|
|
#include "code_800D090_1.h"
|
|
#include "code_8094F88.h"
|
|
#include "code_80958E8.h"
|
|
#include "code_8099360.h"
|
|
#include "code_80A26CC.h"
|
|
#include "cpu.h"
|
|
#include "debug.h"
|
|
#include "decompress_at.h"
|
|
#include "def_filearchives.h"
|
|
#include "dungeon_info.h"
|
|
#include "event_flag.h"
|
|
#include "exclusive_pokemon.h"
|
|
#include "friend_area.h"
|
|
#include "friend_areas_map.h"
|
|
#include "game_options.h"
|
|
#include "graphics_memory.h"
|
|
#include "ground_main.h"
|
|
#include "main_loops.h"
|
|
#include "main_menu1.h"
|
|
#include "main_menu2.h"
|
|
#include "memory.h"
|
|
#include "moves.h"
|
|
#include "music.h"
|
|
#include "music_util.h"
|
|
#include "palette_util.h"
|
|
#include "play_time.h"
|
|
#include "pokemon.h"
|
|
#include "pokemon_3.h"
|
|
#include "quick_save_read.h"
|
|
#include "quick_save_write.h"
|
|
#include "random.h"
|
|
#include "rescue_team_info.h"
|
|
#include "run_dungeon.h"
|
|
#include "save.h"
|
|
#include "save_read.h"
|
|
#include "sprite.h"
|
|
#include "string_format.h"
|
|
#include "text_1.h"
|
|
#include "text_2.h"
|
|
#include "text_3.h"
|
|
#include "text_util.h"
|
|
#include "world_map.h"
|
|
|
|
typedef struct unkTalkTable
|
|
{
|
|
u32 unk0;
|
|
s16 species;
|
|
} unkTalkTable;
|
|
|
|
static EWRAM_DATA s32 sTitleBrightness = 0; // NDS=210FAC0
|
|
// TODO: I think there's a 2nd s32 here for the bottom screen TitleBrightness.
|
|
|
|
static EWRAM_INIT OpenedFile *sTitlePaletteFile = NULL;
|
|
static EWRAM_INIT u32 sUnknown_203B03C = 0;
|
|
static EWRAM_INIT TeamBasicInfo sTeamBasicInfo_203B040 = {
|
|
.unk0 = 0,
|
|
.StarterID = MONSTER_CHARMANDER,
|
|
.PartnerID = MONSTER_SQUIRTLE,
|
|
.StarterName = {""},
|
|
.PartnerNick = {""},
|
|
};
|
|
|
|
static const unkTalkTable sBaseKindTable[17] = {
|
|
[ 0] = { .unk0 = 0, .species = MONSTER_PIKACHU },
|
|
[ 1] = { .unk0 = 1, .species = MONSTER_MEOWTH },
|
|
[ 2] = { .unk0 = 2, .species = MONSTER_EEVEE },
|
|
[ 3] = { .unk0 = 3, .species = MONSTER_SKITTY },
|
|
[ 4] = { .unk0 = 4, .species = MONSTER_SQUIRTLE },
|
|
[ 5] = { .unk0 = 5, .species = MONSTER_TOTODILE },
|
|
[ 6] = { .unk0 = 6, .species = MONSTER_MUDKIP },
|
|
[ 7] = { .unk0 = 7, .species = MONSTER_PSYDUCK },
|
|
[ 8] = { .unk0 = 8, .species = MONSTER_CHARMANDER },
|
|
[ 9] = { .unk0 = 9, .species = MONSTER_TORCHIC },
|
|
[10] = { .unk0 = 10, .species = MONSTER_CYNDAQUIL },
|
|
[11] = { .unk0 = 11, .species = MONSTER_CUBONE },
|
|
[12] = { .unk0 = 12, .species = MONSTER_MACHOP },
|
|
[13] = { .unk0 = 13, .species = MONSTER_BULBASAUR },
|
|
[14] = { .unk0 = 14, .species = MONSTER_CHIKORITA },
|
|
[15] = { .unk0 = 15, .species = MONSTER_TREECKO },
|
|
[16] = { .unk0 = 0, .species = MONSTER_NONE },
|
|
};
|
|
|
|
static const unkTalkTable sTalkKindTable[5] = {
|
|
[0] = { .unk0 = 1, .species = MONSTER_SQUIRTLE },
|
|
[1] = { .unk0 = 1, .species = MONSTER_TOTODILE },
|
|
[2] = { .unk0 = 3, .species = MONSTER_TORCHIC },
|
|
[3] = { .unk0 = 3, .species = MONSTER_CHIKORITA },
|
|
[4] = { .unk0 = 2, .species = MONSTER_NONE },
|
|
};
|
|
|
|
static void LoadAndRunDungeon_Async(DungeonSetupStruct *r0);
|
|
static void LoadAndRunQuickSaveDungeon_Async(DungeonSetupStruct *param_1);
|
|
static void LoadTitleScreen(void);
|
|
static void MainLoops_RunFrameActions(u32 unused);
|
|
static void NDS_LoadOverlay_GroundMain();
|
|
static void RemoveAllMoneyAndItems(void);
|
|
static void RemoveMoneyAndRandomItems(void);
|
|
static u32 RunGameMode_Async(u32 param_1);
|
|
static u32 xxx_script_related_8001334(u32 startMode);
|
|
static u8 sub_8001170(void);
|
|
static void sub_80011CC(DungeonSetupSubstruct *info, u8 dungId);
|
|
static void sub_80011E8(DungeonSetupSubstruct *info);
|
|
|
|
// arm9.bin::0200E0A8
|
|
void GameLoop_Async(void)
|
|
{
|
|
u32 tmp;
|
|
u8 tmp3 = 1;
|
|
u32 nextMenu;
|
|
u32 flag;
|
|
|
|
InitHeap();
|
|
NDS_DebugInit();
|
|
ResetSoundEffectCounters();
|
|
NDS_LoadOverlay_GroundMain();
|
|
ResetDialogueBox();
|
|
LoadMonsterParameters();
|
|
sub_8097670();
|
|
InitializePlayTime();
|
|
LoadGameOptions();
|
|
SetWindowBGColor();
|
|
LoadExclusivePokemon();
|
|
LoadFriendAreas();
|
|
LoadItemParameters();
|
|
LoadRescueTeamInfo();
|
|
LoadWazaParameters();
|
|
sub_80950BC();
|
|
LoadMailInfo();
|
|
sub_800CD64(0x8000, FALSE);
|
|
sub_8012284();
|
|
InitializeGameOptions(TRUE);
|
|
SetWindowTitle(_("PKDi ver 1.0 [Apr 28 2006] 16:37:54"));
|
|
sub_800DAAC();
|
|
SetSavingIconCoords(NULL);
|
|
|
|
tmp = 0;
|
|
if (ReadSaveFromPak(&tmp))
|
|
ThoroughlyResetScriptVars();
|
|
|
|
xxx_script_related_8001334(STARTMODE_14);
|
|
xxx_script_related_8001334(STARTMODE_15);
|
|
ClearScriptVarArray(NULL, EVENT_LOCAL);
|
|
xxx_script_related_8001334(STARTMODE_16);
|
|
|
|
if (GetScriptVarValue(NULL, EVENT_LOCAL) == 0)
|
|
xxx_script_related_8001334(STARTMODE_17);
|
|
|
|
while (TRUE) {
|
|
sUnknown_203B03C = 0;
|
|
sub_800A8F8(2);
|
|
ResetSprites(TRUE);
|
|
UpdateFadeInTile(0);
|
|
InitFontPalette();
|
|
sub_800CDA8(2);
|
|
ShowWindows(NULL, TRUE, TRUE);
|
|
gUnknown_2026E4E = 0x1000;
|
|
LoadTitleScreen();
|
|
SetBG2RegOffsets(0, 0);
|
|
SetBG3RegOffsets(0, 0);
|
|
|
|
sTitleBrightness = 0;
|
|
while (sTitleBrightness < 32) {
|
|
s32 i;
|
|
|
|
sTitleBrightness++;
|
|
|
|
for (i = 0; i < 240; i++) {
|
|
SetBGPaletteBufferColorRGB(i, &((RGB_Struct*)sTitlePaletteFile->data)[i], sTitleBrightness, NULL);
|
|
}
|
|
|
|
MainLoops_RunFrameActions(0);
|
|
}
|
|
|
|
if (tmp3) {
|
|
PrepareSavePakRead();
|
|
while ((tmp3 = ReadSavePak()))
|
|
MainLoops_RunFrameActions(0);
|
|
FinishReadSavePak();
|
|
}
|
|
|
|
tmp3 = 1;
|
|
StartNewBGM(MUS_FILE_SELECT);
|
|
flag = TRUE;
|
|
sub_80095CC(0, 20);
|
|
InitMainMenu();
|
|
|
|
while (TRUE) {
|
|
if (sub_80363E0()) {
|
|
if (gRealInputs.pressed & L_BUTTON) {
|
|
flag = FALSE;
|
|
SetBGOBJEnableFlags(19);
|
|
}
|
|
else if (!flag && !(gRealInputs.held & L_BUTTON)) {
|
|
flag = TRUE;
|
|
SetBGOBJEnableFlags(0);
|
|
}
|
|
|
|
if (!flag) {
|
|
MainLoops_RunFrameActions(0);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
SetUpMenu();
|
|
MainLoops_RunFrameActions(0);
|
|
nextMenu = UpdateMenu();
|
|
CleanUpMenu();
|
|
|
|
if (nextMenu == 2)
|
|
break;
|
|
if (nextMenu == 4)
|
|
break;
|
|
if (nextMenu == MENU_NEW_GAME)
|
|
break;
|
|
}
|
|
|
|
DeleteMainMenu();
|
|
|
|
while (sTitleBrightness > 0) {
|
|
s32 i;
|
|
|
|
sTitleBrightness--;
|
|
|
|
for (i = 0; i < 240; i++) {
|
|
SetBGPaletteBufferColorRGB(i, &((RGB_Struct*)sTitlePaletteFile->data)[i], sTitleBrightness, NULL);
|
|
}
|
|
|
|
MainLoops_RunFrameActions(0);
|
|
}
|
|
|
|
CloseFile(sTitlePaletteFile);
|
|
|
|
switch (nextMenu) {
|
|
case 2: {
|
|
s32 mailIndex = GetFirstIndexofMailType(7);
|
|
if (mailIndex != -1) {
|
|
DeleteMailAtIndex(mailIndex);
|
|
tmp3 = RunGameMode_Async(2);
|
|
}
|
|
else
|
|
tmp3 = RunGameMode_Async(1);
|
|
|
|
break;
|
|
}
|
|
case 4: {
|
|
tmp3 = RunGameMode_Async(3);
|
|
break;
|
|
}
|
|
case MENU_NEW_GAME: {
|
|
sub_80122A8();
|
|
nullsub_33();
|
|
tmp3 = RunGameMode_Async(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// arm9.bin::0200E02C
|
|
static void MainLoops_RunFrameActions(u32 unused)
|
|
{
|
|
DrawDialogueBoxString_Async();
|
|
sub_8005838(NULL, 0);
|
|
nullsub_8(gGameOptionsRef->touchScreen);
|
|
|
|
sub_8005180();
|
|
// Extra call here in blue. Seems to be for 2nd screen sprites
|
|
|
|
sub_80060EC();
|
|
UpdateSoundEffectCounters();
|
|
WaitForNextFrameAndAdvanceRNG();
|
|
LoadBufferedInputs();
|
|
|
|
CopySpritesToOam();
|
|
sub_8005304();
|
|
// 2 extra calls here in blue. They seem to be copies of the 2 above funcs, but for 2nd screen sprites
|
|
|
|
TransferBGPaletteBuffer();
|
|
xxx_call_update_bg_vram();
|
|
DoScheduledMemCopies();
|
|
xxx_call_update_bg_sound_input();
|
|
|
|
ResetSprites(FALSE);
|
|
// Extra call here in blue. Seems to be for 2nd screen sprites
|
|
}
|
|
|
|
typedef struct TitleMenuFile
|
|
{
|
|
/* 0x0 */ u16 tilemap[2 * 32 * 32];
|
|
/* 0x1000 */ u8 vramStuff[0x4B20];
|
|
} TitleMenuFile;
|
|
|
|
static void LoadTitleScreen(void)
|
|
{
|
|
const u8 * renBG[3] = {"titlen0", "titlen1", "titlen2"};
|
|
const u8 * renPal[3] = {"titlen0p", "titlen1p", "titlen2p"};
|
|
OpenedFile *bgFile;
|
|
s32 i, j;
|
|
TitleMenuFile *stru = MemoryAlloc(sizeof(TitleMenuFile), 0);
|
|
s32 rnd = RandInt(3);
|
|
|
|
sTitlePaletteFile = OpenFileAndGetFileDataPtr(renPal[rnd], &gTitleMenuFileArchive);
|
|
bgFile = OpenFileAndGetFileDataPtr(renBG[rnd], &gTitleMenuFileArchive);
|
|
DecompressATFile(&stru->tilemap, 0, bgFile);
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
for (j = 0; j < 32; j++) {
|
|
u16 *ptr = stru->tilemap;
|
|
gBgTilemaps[2][i][j] = ptr[i * 32 + j];
|
|
gBgTilemaps[3][i][j] = ptr[i * 32 + j + (32 * 32)];
|
|
}
|
|
}
|
|
|
|
ScheduleBgTilemapCopy(2);
|
|
ScheduleBgTilemapCopy(3);
|
|
|
|
CpuCopy((u32 *)(VRAM + 0x8000), stru->vramStuff, sizeof(stru->vramStuff));
|
|
CloseFile(bgFile);
|
|
MemoryFree(stru);
|
|
}
|
|
|
|
#include "data/main_loops.h"
|
|
|
|
// arm9.bin::0200ED08
|
|
s32 sub_8000728(void)
|
|
{
|
|
return sUnknown_203B03C;
|
|
}
|
|
|
|
// arm9.bin::0200DB58
|
|
static void QuickSave_Async(u32 mode)
|
|
{
|
|
s32 saveStatus;
|
|
s32 counter;
|
|
|
|
saveStatus = 0;
|
|
counter = 0;
|
|
UpdateFadeInTile(0);
|
|
ResetDialogueBox();
|
|
InitFontPalette();
|
|
sub_800CDA8(2);
|
|
sub_80095CC(0, 20);
|
|
ShowWindows(NULL, TRUE, TRUE);
|
|
sub_8009408(0, 20);
|
|
gUnknown_2026E4E = 0x1000;
|
|
sub_8099648();
|
|
SetWindowBGColor();
|
|
sub_8099690(0);
|
|
sub_8099744();
|
|
sub_8099750();
|
|
SetCharacterMask(3);
|
|
sub_8005838(NULL, 0);
|
|
sub_80060EC();
|
|
CreateDialogueBoxAndPortrait(sSaveTextQuicksaving, 0, 0, 0x20);
|
|
|
|
while (TRUE) {
|
|
MainLoops_RunFrameActions(0);
|
|
|
|
if (saveStatus < SAVE_COMPLETED) {
|
|
sub_8014490();
|
|
MainLoops_RunFrameActions(0);
|
|
ShowWindows(NULL, TRUE, TRUE);
|
|
MainLoops_RunFrameActions(0);
|
|
break;
|
|
}
|
|
|
|
switch (saveStatus) {
|
|
case SAVE_COMPLETED: {
|
|
s32 local_18 = 0;
|
|
DungeonLocation dl = { .id = DUNGEON_OUT_ON_RESCUE, .floor = 0 };
|
|
|
|
SetDungeonLocationInfo(&dl);
|
|
|
|
sub_80140DC();
|
|
if (mode < 4)
|
|
saveStatus = WriteSavetoPak(&local_18, 1);
|
|
else
|
|
saveStatus = SAVE_FAILED;
|
|
|
|
if (saveStatus == SAVE_COMPLETED)
|
|
saveStatus = sub_80121E0(0xF1206);
|
|
|
|
sub_8014114();
|
|
|
|
if (saveStatus == SAVE_COMPLETED) {
|
|
switch (mode) {
|
|
case 1:
|
|
case 3: {
|
|
CreateDialogueBoxAndPortrait(sSaveTextYourAdventureHasBeenSaved, 0, 0, 0x321);
|
|
counter = 60;
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
break;
|
|
}
|
|
case 0:
|
|
case 2:
|
|
default: {
|
|
CreateDialogueBoxAndPortrait(sSaveTextYourAdventureHasBeenSavedLong, 0, 0, 0x321);
|
|
counter = 60;
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (saveStatus == SAVE_NOT_WRTTEN) {
|
|
CreateDialogueBoxAndPortrait(sSaveTextTheDataCouldNotBeWritten, 0, 0, 0);
|
|
saveStatus = SAVE_UNK3;
|
|
}
|
|
else {
|
|
CreateDialogueBoxAndPortrait(sSaveTextFailed, 0, 0, 0x301);
|
|
saveStatus = SAVE_FAILED;
|
|
}
|
|
break;
|
|
}
|
|
case SAVE_NOT_WRTTEN: {
|
|
if (counter < 1)
|
|
saveStatus = SAVE_FAILED;
|
|
else {
|
|
u16 pressed = gRealInputs.pressed;
|
|
counter--;
|
|
if (pressed & 3)
|
|
saveStatus = SAVE_FAILED;
|
|
}
|
|
break;
|
|
}
|
|
case SAVE_FAILED: {
|
|
s32 temp;
|
|
|
|
if (sub_80144A4(&temp) == 0)
|
|
saveStatus = SAVE_NO_STATUS;
|
|
break;
|
|
}
|
|
case SAVE_UNK3: {
|
|
break;
|
|
}
|
|
default: {
|
|
saveStatus = SAVE_NO_STATUS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// arm9.bin::0200D998
|
|
static void sub_80008C0_Async(u32 errorKind)
|
|
{
|
|
s32 saveStatus = SAVE_COMPLETED;
|
|
s32 counter = 0;
|
|
|
|
UpdateFadeInTile(0);
|
|
ResetDialogueBox();
|
|
InitFontPalette();
|
|
sub_800CDA8(2);
|
|
sub_80095CC(0, 20);
|
|
ShowWindows(NULL, TRUE, TRUE);
|
|
sub_8009408(0, 20);
|
|
gUnknown_2026E4E = 0x1000;
|
|
sub_8099648();
|
|
SetWindowBGColor();
|
|
sub_8099690(0);
|
|
sub_8099744();
|
|
sub_8099750();
|
|
SetCharacterMask(3);
|
|
|
|
switch (errorKind) {
|
|
case 0: {
|
|
CreateDialogueBoxAndPortrait(sSaveTextError, 0, 0, 0x20);
|
|
saveStatus = SAVE_FAILED;
|
|
break;
|
|
}
|
|
case 1: {
|
|
CreateDialogueBoxAndPortrait(sSaveTextCantResume, 0, 0, 0x301);
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
break;
|
|
}
|
|
case 2: {
|
|
CreateDialogueBoxAndPortrait(sSaveTextMayNotResume, 0, 0, 0x301);
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
break;
|
|
}
|
|
case 3: {
|
|
CreateDialogueBoxAndPortrait(sSaveTextMayNotResume, 0, 0, 0x301);
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
break;
|
|
}
|
|
}
|
|
|
|
while (TRUE) {
|
|
MainLoops_RunFrameActions(0);
|
|
|
|
if (saveStatus < 0)
|
|
break;
|
|
|
|
switch (saveStatus) {
|
|
case 0: {
|
|
if (counter <= 0)
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
else {
|
|
u16 pressed = gRealInputs.pressed;
|
|
counter--;
|
|
if (pressed & 3)
|
|
saveStatus = SAVE_NOT_WRTTEN;
|
|
}
|
|
break;
|
|
}
|
|
case 1: {
|
|
s32 temp;
|
|
if (sub_80144A4(&temp) == 0)
|
|
saveStatus = SAVE_NO_STATUS;
|
|
break;
|
|
}
|
|
case 2: {
|
|
break;
|
|
}
|
|
default: {
|
|
saveStatus = SAVE_NO_STATUS;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
sub_8014490();
|
|
MainLoops_RunFrameActions(0);
|
|
ShowWindows(NULL ,TRUE, TRUE);
|
|
MainLoops_RunFrameActions(0);
|
|
}
|
|
|
|
// arm9.bin::0200D1E0
|
|
static u32 RunGameMode_Async(u32 a0)
|
|
{
|
|
s32 mode = GetScriptVarValue(NULL, START_MODE);
|
|
bool8 ret = FALSE;
|
|
|
|
ResetSoundEffectCounters();
|
|
FadeOutAllMusic(0x10);
|
|
if (mode == STARTMODE_CONTINUE_QUICKSAVE) {
|
|
if (a0 == 2) {
|
|
mode = STARTMODE_8;
|
|
}
|
|
else if (a0 == 3) {
|
|
mode = STARTMODE_11;
|
|
SetScriptVarValue(NULL, START_MODE, 11);
|
|
sub_8096BD0();
|
|
QuickSave_Async(3);
|
|
}
|
|
}
|
|
else if (mode != STARTMODE_NEW_GAME && mode != STARTMODE_11) {
|
|
mode = STARTMODE_CONTINUE_GAME;
|
|
}
|
|
|
|
ClearScriptVarArray(NULL, EVENT_S08E01);
|
|
while (TRUE) {
|
|
s32 r5;
|
|
struct FriendAreasMapSetupStruct friendAreasSetup;
|
|
struct WorldMapSetupStruct worldMapSetup;
|
|
DungeonSetupStruct dungeonSetup;
|
|
s16 scriptDungeon;
|
|
|
|
if (mode == STARTMODE_FRIEND_AREAS) {
|
|
u8 friendAreaId = MapIdToFriendAreaId(GetScriptVarValue(NULL,GROUND_ENTER));
|
|
|
|
friendAreasSetup.friendAreasMapPtr = MemoryAlloc(sizeof(*friendAreasSetup.friendAreasMapPtr),8);
|
|
friendAreasSetup.startingFriendAreaId = friendAreaId;
|
|
friendAreasSetup.unk5 = CheckQuest(QUEST_CAN_DEPOSIT_PARTNER);
|
|
ShowFriendAreasMap_Async(&friendAreasSetup);
|
|
MemoryFree(friendAreasSetup.friendAreasMapPtr);
|
|
if (friendAreasSetup.chosenAreaId != NUM_FRIEND_AREAS) {
|
|
s32 mapId;
|
|
u32 areaId = friendAreasSetup.chosenAreaId;
|
|
if (areaId != FRIEND_AREA_NONE) {
|
|
mapId = FriendAreaIdToMapId(areaId);
|
|
}
|
|
else {
|
|
mapId = MAP_TEAM_BASE;
|
|
}
|
|
SetScriptVarValue(NULL,GROUND_ENTER,mapId);
|
|
SetScriptVarValue(NULL,GROUND_ENTER_LINK,0);
|
|
}
|
|
mode = STARTMODE_GROUND;
|
|
continue;
|
|
}
|
|
else if (mode == STARTMODE_DUNGEON_FROM_WORLD_MAP) {
|
|
s32 i;
|
|
|
|
s32 scriptDungeonId = (s16) GetScriptVarValue(NULL, DUNGEON_SELECT);
|
|
u8 dungeonId = ScriptDungeonIdToDungeonId(scriptDungeonId);
|
|
for (i = 0; i < WORLD_MAP_UNK_6D_COUNT; i++) {
|
|
worldMapSetup.info.unk6D[i] = sub_80A28F0(i);
|
|
}
|
|
|
|
if (dungeonId == DUNGEON_INVALID) {
|
|
mode = STARTMODE_GROUND;
|
|
continue;
|
|
}
|
|
|
|
worldMapSetup.info.startLocation.id = DUNGEON_OUT_ON_RESCUE;
|
|
sub_80011CC(&worldMapSetup.info.unk4, dungeonId);
|
|
worldMapSetup.info.canChangeLeader = worldMapSetup.info.unk4.canChangeLeader;
|
|
switch ((s16) sub_80A2750(scriptDungeonId)) {
|
|
case 1:
|
|
if (sub_80990EC(&dungeonSetup.info, scriptDungeonId)) {
|
|
worldMapSetup.info.unk4.unkC = dungeonSetup.info.sub0.unkC;
|
|
worldMapSetup.info.mon = dungeonSetup.info.mon;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (sub_8096A08(worldMapSetup.info.unk4.unk0.id, &worldMapSetup.info.mon)) {
|
|
worldMapSetup.info.unk4.unkC = 1;
|
|
}
|
|
else {
|
|
worldMapSetup.info.unk4.unkC = 0;
|
|
}
|
|
break;
|
|
}
|
|
|
|
worldMapSetup.worldMap = MemoryAlloc(sizeof(*worldMapSetup.worldMap), 8);
|
|
ShowWorldMap_Async(&worldMapSetup);
|
|
MemoryFree(worldMapSetup.worldMap);
|
|
if (!worldMapSetup.dungeonEntered) {
|
|
mode = STARTMODE_GROUND;
|
|
continue;
|
|
}
|
|
SetScriptVarValue(NULL, DUNGEON_ENTER, scriptDungeonId);
|
|
sUnknown_203B03C = 2;
|
|
sub_800A8F8(4);
|
|
r5 = xxx_script_related_8001334(STARTMODE_DUNGEON_FROM_WORLD_MAP);
|
|
}
|
|
else if (mode == STARTMODE_8) {
|
|
r5 = 0;
|
|
}
|
|
else if (mode == STARTMODE_CONTINUE_QUICKSAVE) {
|
|
r5 = 2;
|
|
}
|
|
else {
|
|
if (mode == STARTMODE_11) {
|
|
RemoveAllMoneyAndItems();
|
|
}
|
|
else if (mode == STARTMODE_DUNGEON_LOST) {
|
|
RemoveMoneyAndRandomItems();
|
|
}
|
|
sUnknown_203B03C = 2;
|
|
sub_800A8F8(4);
|
|
r5 = xxx_script_related_8001334(mode);
|
|
if (r5 == 14) {
|
|
break;
|
|
}
|
|
else if (r5 == 5) {
|
|
mode = STARTMODE_FRIEND_AREAS;
|
|
continue;
|
|
}
|
|
else if (r5 == 6) {
|
|
mode = STARTMODE_DUNGEON_FROM_WORLD_MAP;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
dungeonSetup.info.sub0.unkD = 0;
|
|
dungeonSetup.info.sub0.unkC = 0;
|
|
MemoryFill8(&dungeonSetup.info.mon, 0, sizeof(dungeonSetup.info.mon));
|
|
dungeonSetup.info.mon.speciesNum = 0;
|
|
if (r5 == 7) {
|
|
if (!sub_80991E0(&dungeonSetup.info, &scriptDungeon)) {
|
|
r5 = 13;
|
|
mode = STARTMODE_DUNGEON_WON;
|
|
}
|
|
}
|
|
else if (r5 == 8) {
|
|
if (!sub_80991E0(&dungeonSetup.info, &scriptDungeon)) {
|
|
r5 = 13;
|
|
mode = STARTMODE_DUNGEON_WON;
|
|
}
|
|
else if (sub_8096A08(dungeonSetup.info.sub0.unk0.id, &dungeonSetup.info.mon)) {
|
|
dungeonSetup.info.sub0.unkC = 1;
|
|
}
|
|
}
|
|
else if (r5 == 10) {
|
|
if (!sub_80991E0(&dungeonSetup.info, &scriptDungeon)) {
|
|
r5 = 13;
|
|
mode = STARTMODE_DUNGEON_WON;
|
|
}
|
|
}
|
|
else if (r5 == 9) {
|
|
if (!sub_80991E0(&dungeonSetup.info, &scriptDungeon)) {
|
|
r5 = 11;
|
|
mode = STARTMODE_DUNGEON_LOST;
|
|
}
|
|
}
|
|
else if (r5 == 0) {
|
|
u32 var = sub_8011FA8();
|
|
if (var == 0xF1207) {
|
|
dungeonSetup.info.sub0.unkD = 1;
|
|
dungeonSetup.info.sub0.unk4 = 1;
|
|
dungeonSetup.info.sub0.missionKind = DUNGEON_MISSION_UNK0;
|
|
if (gUnknown_203B484->unk4.speciesNum != 0) {
|
|
dungeonSetup.info.sub0.unkC = 1;
|
|
dungeonSetup.info.mon = gUnknown_203B484->unk4;
|
|
}
|
|
else {
|
|
dungeonSetup.info.sub0.unkC = 0;
|
|
}
|
|
MemoryFill8(&gUnknown_203B484->unk4, 0, sizeof(gUnknown_203B484->unk4));
|
|
gUnknown_203B484->unk4.speciesNum = 0;
|
|
}
|
|
else if (var == 0xF1208) {
|
|
r5 = 1;
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
}
|
|
else {
|
|
r5 = 1;
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
}
|
|
|
|
if (r5 == 1) {
|
|
MemoryFill8(&gUnknown_203B484->unk4, 0, sizeof(gUnknown_203B484->unk4));
|
|
gUnknown_203B484->unk4.speciesNum = 0;
|
|
}
|
|
}
|
|
else if (r5 == 2) {
|
|
if (sub_8011C1C() == 2) {
|
|
u32 var = sub_8011FA8();
|
|
dungeonSetup.info.sub0.unk4 = 1;
|
|
dungeonSetup.info.sub0.unkD = 0;
|
|
if (var == 0xF1207) {
|
|
;
|
|
}
|
|
else if (var == 0xF1208) {
|
|
r5 = 1;
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
}
|
|
else {
|
|
r5 = 1;
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
}
|
|
}
|
|
else {
|
|
r5 = 3;
|
|
}
|
|
|
|
if (r5 == 3) {
|
|
u8 r4 = sub_8001170();
|
|
r5 = 1;
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
if (r4 != 63 && r4 != 99 && IsEnterWithoutGameSave(r4)) {
|
|
if (sub_8011C1C() == 2) {
|
|
r5 = 3;
|
|
mode = STARTMODE_CONTINUE_QUICKSAVE;
|
|
}
|
|
else {
|
|
r5 = 12;
|
|
mode = STARTMODE_10;
|
|
}
|
|
}
|
|
|
|
if (r5 == 1) {
|
|
sub_8011C1C();
|
|
}
|
|
}
|
|
else if (r5 == 4) {
|
|
r5 = 1;
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
sub_80008C0_Async(1);
|
|
}
|
|
else if (r5 == 1) {
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
}
|
|
}
|
|
|
|
if (r5 == 7 || r5 == 8 || r5 == 9 || r5 == 10 || r5 == 0 || r5 == 2 || r5 == 3) {
|
|
if (r5 != 0 && r5 != 2 && r5 != 3) {
|
|
u8 r6 = sub_8001170();
|
|
|
|
IncrementNumAdventures();
|
|
if (r5 == 9) {
|
|
u8 sp554;
|
|
|
|
if (sub_8099394(&sp554)) {
|
|
unkStruct_203B480 *mail = GetMailatIndex(sp554);
|
|
mail->rescuesAllowed = (mail->rescuesAllowed > 1) ? mail->rescuesAllowed - 1 : 0;
|
|
}
|
|
}
|
|
|
|
if (r6 == 63) {
|
|
QuickSave_Async(0);
|
|
}
|
|
else if (!IsEnterWithoutGameSave(r6)) {
|
|
QuickSave_Async(0);
|
|
}
|
|
}
|
|
|
|
sUnknown_203B03C = 1;
|
|
sub_800A8F8(3);
|
|
dungeonSetup.unk0 = 1;
|
|
sub_80011E8(&dungeonSetup.info.sub0);
|
|
LoadAndRunQuickSaveDungeon_Async(&dungeonSetup);
|
|
if (dungeonSetup.info.unk7C == 3) {
|
|
ret = TRUE;
|
|
break;
|
|
}
|
|
if (dungeonSetup.info.unk7C == -2) {
|
|
ret = TRUE;
|
|
break;
|
|
}
|
|
|
|
ClearScriptVarArray(NULL, EVENT_S08E01);
|
|
switch (dungeonSetup.info.unk7C) {
|
|
case 1:
|
|
case 4:
|
|
mode = STARTMODE_DUNGEON_WON;
|
|
SetScriptVarArrayValue(NULL, EVENT_S08E01, 0, (dungeonSetup.info.unk7E != 0) ? 2 : 1);
|
|
break;
|
|
case 2:
|
|
mode = STARTMODE_10;
|
|
break;
|
|
case -1:
|
|
mode = STARTMODE_DUNGEON_LOST;
|
|
sub_8096BD0();
|
|
break;
|
|
case 5:
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
break;
|
|
default:
|
|
mode = STARTMODE_11;
|
|
sub_8096BD0();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
// This func is probably used for running the dungeon in general (and updating RNG mechanics), not just quicksave.
|
|
// More documentation needed to be sure
|
|
// It'd also be cool to see what happens if a quicksave load fails and the dungeon is skipped entirely
|
|
// arm9.bin::0200D01C
|
|
static void LoadAndRunQuickSaveDungeon_Async(DungeonSetupStruct *setupStr)
|
|
{
|
|
u8 quickSaveValid;
|
|
s32 quickSaveStatus;
|
|
s32 local_1c; // 0x4800
|
|
s32 dungeonStructSize; // sizeof(Dungeon)
|
|
|
|
quickSaveValid = TRUE;
|
|
sUnknown_203B03C = 1;
|
|
|
|
sub_800A8F8(3);
|
|
ResetDialogueBox();
|
|
sub_8043D50(&local_1c, &dungeonStructSize);
|
|
|
|
setupStr->info.unk74 = MemoryAlloc(local_1c, 7); // size: 0x4800
|
|
setupStr->info.dungeon = MemoryAlloc(dungeonStructSize, 7); // size: sizeof(Dungeon)
|
|
|
|
if (setupStr->info.sub0.unk4) {
|
|
PrepareQuickSaveRead(setupStr->info.unk74, local_1c);
|
|
|
|
while (TRUE) {
|
|
if (!ReadQuickSave())
|
|
break;
|
|
MainLoops_RunFrameActions(0);
|
|
}
|
|
|
|
quickSaveValid = IsQuickSaveValid();
|
|
FinishQuickSaveRead();
|
|
StopBGMResetSoundEffectCounters();
|
|
|
|
if (quickSaveValid)
|
|
sub_80121E0(0xF1208);
|
|
else
|
|
sub_80121E0(0xF1209);
|
|
|
|
StartBGMusic();
|
|
}
|
|
else {
|
|
GeneratePelipperJobs();
|
|
sub_80961B4();
|
|
sub_808ED00();
|
|
}
|
|
|
|
if (quickSaveValid) {
|
|
LoadAndRunDungeon_Async(setupStr);
|
|
sub_8099648();
|
|
SetWindowBGColor();
|
|
sub_8099690(0);
|
|
}
|
|
else
|
|
setupStr->info.unk7C = 5;
|
|
|
|
if (setupStr->info.unk7C == -2)
|
|
sub_809542C(&setupStr->info.unk84);
|
|
|
|
if (setupStr->info.unk7C == 3 || setupStr->info.unk7C == -2) {
|
|
SetDungeonLocationInfo(&setupStr->info.unk80);
|
|
StopBGMusic();
|
|
|
|
if (setupStr->info.unk7C == -2)
|
|
PrepareQuickSaveWrite(setupStr->info.unk74, local_1c, 1);
|
|
else
|
|
PrepareQuickSaveWrite(setupStr->info.unk74, local_1c, 0);
|
|
|
|
while ((quickSaveStatus = WriteQuickSave(), (quickSaveStatus != 2))) {
|
|
if (quickSaveStatus == 3)
|
|
break;
|
|
if (quickSaveStatus == 1) {
|
|
MemoryFree(setupStr->info.dungeon);
|
|
MemoryFree(setupStr->info.unk74);
|
|
}
|
|
|
|
MainLoops_RunFrameActions(0);
|
|
}
|
|
FinishQuickSaveWrite();
|
|
}
|
|
else {
|
|
sub_808ED00();
|
|
MemoryFree(setupStr->info.dungeon);
|
|
MemoryFree(setupStr->info.unk74);
|
|
}
|
|
}
|
|
|
|
// arm9.bin::0200CFF4
|
|
void ReadTeamBasicInfo(TeamBasicInfo *dst)
|
|
{
|
|
*dst = sTeamBasicInfo_203B040;
|
|
}
|
|
|
|
// arm9.bin::0200CFA4
|
|
void WriteTeamBasicInfo(TeamBasicInfo *src)
|
|
{
|
|
sTeamBasicInfo_203B040 = *src;
|
|
}
|
|
|
|
// arm9.bin::0200CE48
|
|
void sub_8001064(void)
|
|
{
|
|
const unkTalkTable *psVar2;
|
|
u8 buffer2 [20];
|
|
u8 buffer1 [20];
|
|
|
|
if (GetLeaderMon1() == NULL) {
|
|
if (sTeamBasicInfo_203B040.StarterName[0] == '\0') {
|
|
CopyMonsterNameToBuffer(buffer1, sTeamBasicInfo_203B040.StarterID);
|
|
CopyStringtoBuffer(buffer2, buffer1);
|
|
CreateLeaderPartnerData(sTeamBasicInfo_203B040.StarterID, TRUE, buffer2);
|
|
}
|
|
else
|
|
CreateLeaderPartnerData(sTeamBasicInfo_203B040.StarterID, TRUE, sTeamBasicInfo_203B040.StarterName);
|
|
}
|
|
|
|
if (GetPartnerMon() == NULL) {
|
|
if (sTeamBasicInfo_203B040.PartnerNick[0] == '\0') {
|
|
CopyMonsterNameToBuffer(buffer1, sTeamBasicInfo_203B040.PartnerID);
|
|
CopyStringtoBuffer(buffer2, buffer1);
|
|
CreateLeaderPartnerData(sTeamBasicInfo_203B040.PartnerID, FALSE, buffer2);
|
|
}
|
|
else
|
|
CreateLeaderPartnerData(sTeamBasicInfo_203B040.PartnerID, FALSE, sTeamBasicInfo_203B040.PartnerNick);
|
|
}
|
|
|
|
if (sTeamBasicInfo_203B040.StarterID != MONSTER_NONE) {
|
|
psVar2 = &sBaseKindTable[0];
|
|
while (psVar2->species != MONSTER_NONE && sTeamBasicInfo_203B040.StarterID != psVar2->species) {
|
|
psVar2++;
|
|
}
|
|
SetScriptVarValue(NULL, BASE_KIND, psVar2->unk0);
|
|
}
|
|
|
|
if (sTeamBasicInfo_203B040.PartnerID != MONSTER_NONE) {
|
|
psVar2 = &sTalkKindTable[0];
|
|
while (psVar2->species != MONSTER_NONE && sTeamBasicInfo_203B040.PartnerID != psVar2->species) {
|
|
psVar2++;
|
|
}
|
|
SetScriptVarValue(NULL, PARTNER_TALK_KIND, psVar2->unk0);
|
|
}
|
|
}
|
|
|
|
// arm9.bin::0200CDD4
|
|
static u8 sub_8001170(void)
|
|
{
|
|
s16 local_10;
|
|
s16 rescueDungeonId;
|
|
u8 auStack_b;
|
|
u8 dungeonID = NUM_DUNGEONS + 1;
|
|
|
|
if (sub_80992E0(&local_10, &rescueDungeonId))
|
|
dungeonID = ScriptDungeonIdToDungeonId(local_10);
|
|
else if (!sub_8099328(&dungeonID) && !sub_8099360(&dungeonID) && sub_8099394(&auStack_b))
|
|
dungeonID = DUNGEON_OUT_ON_RESCUE;
|
|
|
|
return dungeonID;
|
|
}
|
|
|
|
// arm9.bin::0200CDA4
|
|
static void sub_80011CC(DungeonSetupSubstruct *info, u8 dungId)
|
|
{
|
|
info->unk0.id = dungId;
|
|
info->unk0.floor = 0;
|
|
|
|
sub_80011E8(info);
|
|
|
|
info->missionKind = DUNGEON_MISSION_UNK0;
|
|
info->unk4 = 0;
|
|
info->unkC = 0;
|
|
info->unkD = 0;
|
|
}
|
|
|
|
// arm9.bin::0200CD1C
|
|
static void sub_80011E8(DungeonSetupSubstruct *info)
|
|
{
|
|
info->canChangeLeader = CheckQuest(QUEST_CAN_CHANGE_LEADER);
|
|
info->canRecruit = CheckQuest(QUEST_CAN_RECRUIT);
|
|
info->unlockedEvolutions = CheckQuest(QUEST_UNLOCKED_EVOLUTIONS);
|
|
info->hasInventory = CheckQuest(QUEST_SET_TEAM_NAME);
|
|
info->unkA = CheckQuest(QUEST_UNK5);
|
|
|
|
if (CheckQuest(QUEST_LEGEND_HO_OH) && CheckQuest(QUEST_LEGEND_MEWTWO) && CheckQuest(QUEST_LEGEND_MEW))
|
|
info->canRecruitRescueTeamMazeBosses = TRUE;
|
|
else
|
|
info->canRecruitRescueTeamMazeBosses = FALSE;
|
|
}
|
|
|
|
// arm9.bin::0200CC4C
|
|
static void RemoveMoneyAndRandomItems(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < INVENTORY_SIZE; i++) {
|
|
if (RandInt(100) < 50)
|
|
ZeroOutItem(&gTeamInventoryRef->teamItems[i]);
|
|
}
|
|
|
|
FillInventoryGaps();
|
|
|
|
for (i = 0; i < NUM_MONSTERS; i++) {
|
|
Pokemon *mon = &gRecruitedPokemonRef->pokemon[i];
|
|
if (PokemonExists(mon) && PokemonIsOnTeam(mon))
|
|
mon->heldItem.id = ITEM_NOTHING;
|
|
}
|
|
|
|
gTeamInventoryRef->teamMoney = 0;
|
|
}
|
|
|
|
// arm9.bin::0200CB88
|
|
static void RemoveAllMoneyAndItems(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < INVENTORY_SIZE; i++) {
|
|
ZeroOutItem(&gTeamInventoryRef->teamItems[i]);
|
|
}
|
|
|
|
FillInventoryGaps();
|
|
|
|
for (i = 0; i < NUM_MONSTERS; i++) {
|
|
Pokemon *mon = &gRecruitedPokemonRef->pokemon[i];
|
|
if (PokemonExists(mon) && PokemonIsOnTeam(mon))
|
|
mon->heldItem.id = ITEM_NOTHING;
|
|
}
|
|
|
|
gTeamInventoryRef->teamMoney = 0;
|
|
}
|
|
|
|
// arm9.bin::0200CB14
|
|
static void NDS_LoadOverlay_GroundMain()
|
|
{
|
|
|
|
}
|
|
|
|
// arm9.bin::0200CADC
|
|
static void nullsub_2(DungeonSetupStruct *r0)
|
|
{
|
|
// (not a nullsub in the NDS)
|
|
// Probably loads the dungeon overlay?
|
|
}
|
|
|
|
// arm9.bin::0200CAD0
|
|
// startMode: See enum "StartModeVal"
|
|
static u32 xxx_script_related_8001334(u32 startMode)
|
|
{
|
|
return xxx_script_related_8098468(startMode);
|
|
}
|
|
|
|
// arm9.bin::0200CA1C
|
|
static void LoadAndRunDungeon_Async(DungeonSetupStruct *setupPtr)
|
|
{
|
|
nullsub_2(setupPtr);
|
|
RunDungeon_Async(setupPtr);
|
|
NDS_LoadOverlay_GroundMain();
|
|
}
|
|
|
|
// TODO: NDS has another func here (arm9.bin::0200C970)
|
|
|
|
// arm9.bin::0200C96C
|
|
void nullsub_3(s32 yPos, s32 a1)
|
|
{
|
|
|
|
}
|