diff --git a/asm/non_matchings/weather/render_rain_overlay.s b/asm/non_matchings/weather/render_rain_overlay.s index 75857f2f..ec10a921 100644 --- a/asm/non_matchings/weather/render_rain_overlay.s +++ b/asm/non_matchings/weather/render_rain_overlay.s @@ -57,8 +57,8 @@ glabel render_rain_overlay /* 0AE998 800ADD98 03196824 */ and $t5, $t8, $t9 /* 0AE99C 800ADD9C 86180006 */ lh $t8, 6($s0) /* 0AE9A0 800ADDA0 A60D0002 */ sh $t5, 2($s0) -/* 0AE9A4 800ADDA4 3C0D800E */ lui $t5, %hi(D_800E2C6C) # $t5, 0x800e -/* 0AE9A8 800ADDA8 8DAD2C6C */ lw $t5, %lo(D_800E2C6C)($t5) +/* 0AE9A4 800ADDA4 3C0D800E */ lui $t5, %hi(gRainOpacity) # $t5, 0x800e +/* 0AE9A8 800ADDA8 8DAD2C6C */ lw $t5, %lo(gRainOpacity)($t5) /* 0AE9AC 800ADDAC 3C028012 */ lui $v0, %hi(gWeatherCamera) # $v0, 0x8012 /* 0AE9B0 800ADDB0 000D7083 */ sra $t6, $t5, 2 /* 0AE9B4 800ADDB4 00008812 */ mflo $s1 @@ -125,18 +125,18 @@ glabel render_rain_overlay /* 0AEAA8 800ADEA8 35C10003 */ ori $at, $t6, 3 /* 0AEAAC 800ADEAC 38210002 */ xori $at, $at, 2 /* 0AEAB0 800ADEB0 44C1F800 */ ctc1 $at, $31 -/* 0AEAB4 800ADEB4 3C09800E */ lui $t1, %hi(D_800E2C90) # $t1, 0x800e +/* 0AEAB4 800ADEB4 3C09800E */ lui $t1, %hi(gRainVertexFlip) # $t1, 0x800e /* 0AEAB8 800ADEB8 460042A4 */ cvt.w.s $f10, $f8 -/* 0AEABC 800ADEBC 25292C90 */ addiu $t1, %lo(D_800E2C90) # addiu $t1, $t1, 0x2c90 +/* 0AEABC 800ADEBC 25292C90 */ addiu $t1, %lo(gRainVertexFlip) # addiu $t1, $t1, 0x2c90 /* 0AEAC0 800ADEC0 44CEF800 */ ctc1 $t6, $31 /* 0AEAC4 800ADEC4 440F5000 */ mfc1 $t7, $f10 /* 0AEAC8 800ADEC8 46026102 */ mul.s $f4, $f12, $f2 /* 0AEACC 800ADECC 8D2D0000 */ lw $t5, ($t1) -/* 0AEAD0 800ADED0 3C0B800E */ lui $t3, %hi(D_800E2AAC) # $t3, 0x800e +/* 0AEAD0 800ADED0 3C0B800E */ lui $t3, %hi(gRainVertices) # $t3, 0x800e /* 0AEAD4 800ADED4 000DC880 */ sll $t9, $t5, 2 /* 0AEAD8 800ADED8 46007182 */ mul.s $f6, $f14, $f0 /* 0AEADC 800ADEDC 032DC821 */ addu $t9, $t9, $t5 -/* 0AEAE0 800ADEE0 256B2AAC */ addiu $t3, %lo(D_800E2AAC) # addiu $t3, $t3, 0x2aac +/* 0AEAE0 800ADEE0 256B2AAC */ addiu $t3, %lo(gRainVertices) # addiu $t3, $t3, 0x2aac /* 0AEAE4 800ADEE4 0019C840 */ sll $t9, $t9, 1 /* 0AEAE8 800ADEE8 46062200 */ add.s $f8, $f4, $f6 /* 0AEAEC 800ADEEC 01791021 */ addu $v0, $t3, $t9 @@ -291,16 +291,16 @@ glabel render_rain_overlay /* 0AED40 800AE140 AC780000 */ sw $t8, ($v1) /* 0AED44 800AE144 8E6E000C */ lw $t6, 0xc($s3) /* 0AED48 800AE148 3C088000 */ lui $t0, 0x8000 -/* 0AED4C 800AE14C 3C09800E */ lui $t1, %hi(D_800E2C90) # $t1, 0x800e +/* 0AED4C 800AE14C 3C09800E */ lui $t1, %hi(gRainVertexFlip) # $t1, 0x800e /* 0AED50 800AE150 01C8C821 */ addu $t9, $t6, $t0 -/* 0AED54 800AE154 25292C90 */ addiu $t1, %lo(D_800E2C90) # addiu $t1, $t1, 0x2c90 +/* 0AED54 800AE154 25292C90 */ addiu $t1, %lo(gRainVertexFlip) # addiu $t1, $t1, 0x2c90 /* 0AED58 800AE158 AC790004 */ sw $t9, 4($v1) /* 0AED5C 800AE15C 8D380000 */ lw $t8, ($t1) /* 0AED60 800AE160 240A000A */ li $t2, 10 /* 0AED64 800AE164 030A0019 */ multu $t8, $t2 /* 0AED68 800AE168 8FA50068 */ lw $a1, 0x68($sp) -/* 0AED6C 800AE16C 3C0B800E */ lui $t3, %hi(D_800E2AAC) # $t3, 0x800e -/* 0AED70 800AE170 256B2AAC */ addiu $t3, %lo(D_800E2AAC) # addiu $t3, $t3, 0x2aac +/* 0AED6C 800AE16C 3C0B800E */ lui $t3, %hi(gRainVertices) # $t3, 0x800e +/* 0AED70 800AE170 256B2AAC */ addiu $t3, %lo(gRainVertices) # addiu $t3, $t3, 0x2aac /* 0AED74 800AE174 24AF0008 */ addiu $t7, $a1, 8 /* 0AED78 800AE178 AFAF0068 */ sw $t7, 0x68($sp) /* 0AED7C 800AE17C 3C010400 */ lui $at, 0x400 diff --git a/include/structs.h b/include/structs.h index 86344109..88a66623 100644 --- a/include/structs.h +++ b/include/structs.h @@ -452,7 +452,7 @@ typedef struct LevelHeader { /* 0x74 */ LevelHeader_70 *unk74[7]; // Weather related? - /* 0x90 */ s16 weatherEnable; + /* 0x90 */ s16 weatherEnable; // This affects snow density, but for rain, it simply needs to be nonzero. /* 0x92 */ s16 weatherType; /* 0x94 */ u8 weatherIntensity; /* 0x95 */ u8 weatherOpacity; diff --git a/src/game.c b/src/game.c index 9466a07f..88d80578 100644 --- a/src/game.c +++ b/src/game.c @@ -591,11 +591,11 @@ void load_level(s32 levelId, s32 numberOfPlayers, s32 entranceId, Vehicle vehicl } settings->courseId = levelId; if (gCurrentLevelHeader->weatherEnable > 0) { - func_800AB4A8(gCurrentLevelHeader->weatherType, gCurrentLevelHeader->weatherEnable, + weather_reset(gCurrentLevelHeader->weatherType, gCurrentLevelHeader->weatherEnable, gCurrentLevelHeader->weatherVelX << 8, gCurrentLevelHeader->weatherVelY << 8, gCurrentLevelHeader->weatherVelZ << 8, gCurrentLevelHeader->weatherIntensity * 257, gCurrentLevelHeader->weatherOpacity * 257); - set_weather_limits(-1, -512); + weather_clip_planes(-1, -512); } if (gCurrentLevelHeader->skyDome == -1) { gCurrentLevelHeader->unkA4 = load_texture((s32) gCurrentLevelHeader->unkA4); @@ -709,7 +709,7 @@ void clear_audio_and_track(void) { func_80008174(); sound_volume_change(VOLUME_NORMAL); if (gCurrentLevelHeader->weatherEnable > 0) { - free_weather_memory(); + weather_free(); } //! @bug this will never be true because skyDome is signed. if (gCurrentLevelHeader->skyDome == 0xFF) { diff --git a/src/menu.c b/src/menu.c index b81def69..9d2d712a 100644 --- a/src/menu.c +++ b/src/menu.c @@ -190,13 +190,13 @@ s32 gSelectedTrackX; s32 gSelectedTrackY; SoundMask *gSoundOptionMask; s32 gSaveMenuOptionCountLower; -SaveFileData *gSavemenuFilesDest; +SaveFileData *gSaveMenuFilesDest; s32 gSaveMenuOptionCountUpper; -SaveFileData *gSavemenuFilesSource; -s32 gSavemenuRumbleNag; -s32 gSavemenuRumbleConnected; -s32 D_80126A18; -s32 D_80126A1C; +SaveFileData *gSaveMenuFilesSource; +s32 gSaveMenuRumbleNag; +s32 gSaveMenuRumbleConnected; +s32 gSaveMenuSourceState; +s32 gSaveMenuDestState; s32 sControllerPakNotesFree[MAXCONTROLLERS]; // Looks to be an array for number notes free in each controller memory pak u8 sControllerPakIssueNotFound[MAXCONTROLLERS]; // Flag to see if there's no known issues for the given controller pak u8 sControllerPakFatalErrorFound[MAXCONTROLLERS]; // Flag to see if there's a fatal error for the given controller pak @@ -206,12 +206,12 @@ char *gMenuOptionText[8]; // Menu Text u8 sControllerPakDataPresent[MAXCONTROLLERS]; // Flag to see if there's data present for the given controller pak? char *D_80126A64; s32 gMenuOption; -s32 gSavemenuRumbleNagSet; +s32 gSaveMenuRumbleNagSet; char **gDeviceStatusStrings; -s32 D_80126A74; -s32 D_80126A78; +s32 gSaveMenuMessageLines; +s32 gSaveMenuMessageOption; UNUSED s32 D_80126A7C; -unk80126A80 *D_80126A80[4]; +unk80126A80 *gSaveMenuText[4]; s32 gPostRace1Player; s32 gPostRaceTimer; s32 gTracksSaveGhost; @@ -232,11 +232,11 @@ s32 D_80126BCC; UNUSED s32 D_80126BD0; // Set to zero, never read. s32 gSaveMenuOptionSource; s32 D_80126BD8; -f32 gSavemenuScrollSource; +f32 gSaveMenuScrollSource; s32 D_80126BE0; s32 gSaveMenuOptionDest; s32 D_80126BE8; -f32 gSavemenuScrollDest; +f32 gSaveMenuScrollDest; char *gResultOptionText[8]; s32 gCpakWriteTimer; s32 gResultOptionCount; @@ -466,7 +466,7 @@ u32 gContPakSaveBgColours[MAXCONTROLLERS] = { COLOUR_RGBA32(64, 255, 64, 255) // Green for controller 4 }; -SIDeviceStatus D_800DFADC = CONTROLLER_PAK_GOOD; +SIDeviceStatus gDeviceStatus = CONTROLLER_PAK_GOOD; s32 gControllerIndex = 0; // Strings related to the controller pak. @@ -3359,24 +3359,24 @@ void soundoptions_free(void) { * the other variables related to the save options. */ void menu_save_options_init(void) { - gSavemenuRumbleNagSet = TRUE; - gSavemenuRumbleNag = FALSE; - D_80126A18 = 1; - D_80126A1C = 1; + gSaveMenuRumbleNagSet = TRUE; + gSaveMenuRumbleNag = FALSE; + gSaveMenuSourceState = 1; + gSaveMenuDestState = 1; gOptionsMenuItemIndex = 0; gOptionBlinkTimer = 0; gMenuDelay = 0; gMenuStage = SAVEMENU_WAIT; gOpacityDecayTimer = 0; D_80126A64 = (char *) allocate_from_main_pool_safe(0x800, COLOUR_TAG_WHITE); - gSavemenuFilesSource = (SaveFileData *) allocate_from_main_pool_safe(0xA00, COLOUR_TAG_WHITE); - gSavemenuFilesDest = &gSavemenuFilesSource[80]; + gSaveMenuFilesSource = (SaveFileData *) allocate_from_main_pool_safe(0xA00, COLOUR_TAG_WHITE); + gSaveMenuFilesDest = &gSaveMenuFilesSource[80]; gSaveMenuOptionCountUpper = 0; gSaveMenuOptionSource = 0; - gSavemenuScrollSource = 0.0f; + gSaveMenuScrollSource = 0.0f; gSaveMenuOptionCountLower = 0; gSaveMenuOptionDest = 0; - gSavemenuScrollDest = 0.0f; + gSaveMenuScrollDest = 0.0f; menu_assetgroup_load(gSaveMenuObjectIndices); menu_imagegroup_load(gSaveMenuImageIndices); func_8007FFEC(10); @@ -3628,12 +3628,12 @@ void savemenu_render(UNUSED s32 updateRate) { } if (drawUpperElements) { - scroll = (s32) gSavemenuScrollSource; + scroll = (s32) gSaveMenuScrollSource; temp = scroll; - offsetX = 80 - (s32) ((gSavemenuScrollSource - scroll) * 164.0f); + offsetX = 80 - (s32) ((gSaveMenuScrollSource - scroll) * 164.0f); x = offsetX; while (x < videoWidth && temp < gSaveMenuOptionCountUpper) { - savemenu_render_element(&gSavemenuFilesSource[temp], x, 64); + savemenu_render_element(&gSaveMenuFilesSource[temp], x, 64); x += 164; temp++; } @@ -3642,17 +3642,17 @@ void savemenu_render(UNUSED s32 updateRate) { while ((x > 0) && (temp > 0)) { temp--; x -= 164; - savemenu_render_element(&gSavemenuFilesSource[temp], x, 64); + savemenu_render_element(&gSaveMenuFilesSource[temp], x, 64); } } if (drawLowerElements) { - scroll = (s32) gSavemenuScrollDest; + scroll = (s32) gSaveMenuScrollDest; temp = scroll; - offsetX = 80 - (s32) ((gSavemenuScrollDest - (f32) scroll) * 164.0f); + offsetX = 80 - (s32) ((gSaveMenuScrollDest - (f32) scroll) * 164.0f); x = offsetX; while (x < videoWidth && temp < gSaveMenuOptionCountLower) { - savemenu_render_element(&gSavemenuFilesDest[temp], x, 144); + savemenu_render_element(&gSaveMenuFilesDest[temp], x, 144); x += 164; temp++; } @@ -3661,7 +3661,7 @@ void savemenu_render(UNUSED s32 updateRate) { while (x > 0 && temp > 0) { temp--; x -= 164; - savemenu_render_element(&gSavemenuFilesDest[temp], x, 144); + savemenu_render_element(&gSaveMenuFilesDest[temp], x, 144); } } @@ -3748,27 +3748,27 @@ SIDeviceStatus savemenu_load_sources(void) { settings = gSavefileData[3]; gSaveMenuOptionCountUpper = 0; gSaveMenuOptionSource = 0; - gSavemenuScrollSource = 0.0f; + gSaveMenuScrollSource = 0.0f; for (i = 0; i < NUMBER_OF_SAVE_FILES; i++) { if (!gSavefileData[i]->newGame) { - gSavemenuFilesSource[gSaveMenuOptionCountUpper].saveFileType = SAVE_FILE_TYPE_CART_SAVE; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].unk1 = 1; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].balloonCount = gSavefileData[i]->balloonsPtr[0]; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].controllerIndex = i; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].fileSize = get_game_data_file_size(); + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].saveFileType = SAVE_FILE_TYPE_CART_SAVE; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].unk1 = 1; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].balloonCount = gSavefileData[i]->balloonsPtr[0]; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].controllerIndex = i; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].fileSize = get_game_data_file_size(); gSaveMenuOptionCountUpper++; } } - gSavemenuFilesSource[gSaveMenuOptionCountUpper].saveFileType = SAVE_FILE_TYPE_CART_TIMES; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].unk1 = 1; - gSavemenuFilesSource[gSaveMenuOptionCountUpper++].fileSize = get_time_data_file_size(); - gSavemenuFilesSource[gSaveMenuOptionCountUpper++].saveFileType = SAVE_FILE_TYPE_CART_BONUSES; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].saveFileType = SAVE_FILE_TYPE_CART_TIMES; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].unk1 = 1; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper++].fileSize = get_time_data_file_size(); + gSaveMenuFilesSource[gSaveMenuOptionCountUpper++].saveFileType = SAVE_FILE_TYPE_CART_BONUSES; temp_D_80126A64 = D_80126A64; do { numAttempts = 1; - if (D_80126A18 != 0) { - gSavemenuRumbleConnected = FALSE; + if (gSaveMenuSourceState != 0) { + gSaveMenuRumbleConnected = FALSE; do { result = get_controller_pak_file_list(0, 16, fileNames, fileExts, fileSizes, fileTypes); @@ -3781,21 +3781,21 @@ SIDeviceStatus savemenu_load_sources(void) { if ((fileTypes[fileIndex] >= SAVE_FILE_TYPE_CPAK_SAVE) && (fileTypes[fileIndex] <= SAVE_FILE_TYPE_CPAK_OTHER)) { (*sControllerPakNotesFree)--; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].saveFileType = fileTypes[fileIndex]; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].controllerIndex = 0; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].saveFileNumber = fileIndex; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].fileSize = fileSizes[fileIndex]; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].saveFileType = fileTypes[fileIndex]; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].controllerIndex = 0; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].saveFileNumber = fileIndex; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].fileSize = fileSizes[fileIndex]; if (fileTypes[fileIndex] == SAVE_FILE_TYPE_CPAK_SAVE) { if (read_game_data_from_controller_pak(0, fileExts[fileIndex], settings) == CONTROLLER_PAK_GOOD) { - gSavemenuFilesSource[gSaveMenuOptionCountUpper].saveFileExt = temp_D_80126A64; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].saveFileExt = temp_D_80126A64; temp_D_80126A64[0] = *fileExts[fileIndex]; temp_D_80126A64[1] = NULL; temp_D_80126A64 += 2; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].balloonCount = *settings->balloonsPtr; - gSavemenuFilesSource[gSaveMenuOptionCountUpper].adventureTwo = + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].balloonCount = *settings->balloonsPtr; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].adventureTwo = (settings->cutsceneFlags & 4) != 0; // Is in Adventure Two? - gSavemenuFilesSource[gSaveMenuOptionCountUpper].compressedFilename = settings->filename; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].compressedFilename = settings->filename; } else { gSaveMenuOptionCountUpper--; } @@ -3806,7 +3806,7 @@ SIDeviceStatus savemenu_load_sources(void) { if (fileTypes[fileIndex] == SAVE_FILE_TYPE_CPAK_TIMES) { temp = CONTROLLER_PAK_BAD_DATA; } - gSavemenuFilesSource[gSaveMenuOptionCountUpper].saveFileExt = temp_D_80126A64; + gSaveMenuFilesSource[gSaveMenuOptionCountUpper].saveFileExt = temp_D_80126A64; while (fileNames[fileIndex][temp] != '\0') { *temp_D_80126A64 = fileNames[fileIndex][temp]; temp++; @@ -3832,17 +3832,17 @@ SIDeviceStatus savemenu_load_sources(void) { } packDirectoryFree(); } else if (temp == CONTROLLER_PAK_RUMBLE_PAK_FOUND) { - gSavemenuRumbleConnected = TRUE; - if (D_80126A18 < 0) { + gSaveMenuRumbleConnected = TRUE; + if (gSaveMenuSourceState < 0) { result = CONTROLLER_PAK_GOOD; } - if (gSavemenuRumbleNagSet) { - gSavemenuRumbleNag = TRUE; - gSavemenuRumbleNagSet = FALSE; + if (gSaveMenuRumbleNagSet) { + gSaveMenuRumbleNag = TRUE; + gSaveMenuRumbleNagSet = FALSE; } } else if (temp == CONTROLLER_PAK_NOT_FOUND) { result = CONTROLLER_PAK_GOOD; - } else if (D_80126A18 < 0 && temp == CONTROLLER_PAK_CHANGED) { + } else if (gSaveMenuSourceState < 0 && temp == CONTROLLER_PAK_CHANGED) { numAttempts = 0; } } @@ -3861,38 +3861,38 @@ SIDeviceStatus savemenu_load_destinations(void) { gSaveMenuOptionCountLower = 0; - switch (gSavemenuFilesSource[gSaveMenuOptionSource].saveFileType) { + switch (gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileType) { case SAVE_FILE_TYPE_CART_SAVE: - mark_read_save_file(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex); - savemenu_blank_save_destination(gSavemenuFilesDest, &gSaveMenuOptionCountLower); - ret = savemenu_check_space(0, &D_80126A18, gSavemenuFilesDest, &gSaveMenuOptionCountLower, + mark_read_save_file(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex); + savemenu_blank_save_destination(gSaveMenuFilesDest, &gSaveMenuOptionCountLower); + ret = savemenu_check_space(0, &gSaveMenuSourceState, gSaveMenuFilesDest, &gSaveMenuOptionCountLower, get_game_data_file_size(), -1); break; case SAVE_FILE_TYPE_CART_TIMES: - ret = savemenu_check_space(0, &D_80126A18, gSavemenuFilesDest, &gSaveMenuOptionCountLower, + ret = savemenu_check_space(0, &gSaveMenuSourceState, gSaveMenuFilesDest, &gSaveMenuOptionCountLower, get_time_data_file_size(), -1); break; case SAVE_FILE_TYPE_CPAK_SAVE: - savemenu_blank_save_destination(gSavemenuFilesDest, &gSaveMenuOptionCountLower); - ret = savemenu_check_space(1, &D_80126A1C, gSavemenuFilesDest, &gSaveMenuOptionCountLower, + savemenu_blank_save_destination(gSaveMenuFilesDest, &gSaveMenuOptionCountLower); + ret = savemenu_check_space(1, &gSaveMenuDestState, gSaveMenuFilesDest, &gSaveMenuOptionCountLower, get_game_data_file_size(), - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex); break; case SAVE_FILE_TYPE_CPAK_TIMES: - gSavemenuFilesDest[gSaveMenuOptionCountLower++].saveFileType = SAVE_FILE_TYPE_CART_TIMES; - ret = savemenu_check_space(1, &D_80126A1C, gSavemenuFilesDest, &gSaveMenuOptionCountLower, + gSaveMenuFilesDest[gSaveMenuOptionCountLower++].saveFileType = SAVE_FILE_TYPE_CART_TIMES; + ret = savemenu_check_space(1, &gSaveMenuDestState, gSaveMenuFilesDest, &gSaveMenuOptionCountLower, get_time_data_file_size(), - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex); break; case SAVE_FILE_TYPE_CPAK_GHOST: - gSavemenuFilesDest[gSaveMenuOptionCountLower++].saveFileType = SAVE_FILE_TYPE_UNK9; - ret = savemenu_check_space(1, &D_80126A1C, gSavemenuFilesDest, &gSaveMenuOptionCountLower, + gSaveMenuFilesDest[gSaveMenuOptionCountLower++].saveFileType = SAVE_FILE_TYPE_UNK9; + ret = savemenu_check_space(1, &gSaveMenuDestState, gSaveMenuFilesDest, &gSaveMenuOptionCountLower, get_ghost_data_file_size(), - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex); break; } - gSavemenuFilesDest[gSaveMenuOptionCountLower++].saveFileType = SAVE_FILE_TYPE_ERASE; + gSaveMenuFilesDest[gSaveMenuOptionCountLower++].saveFileType = SAVE_FILE_TYPE_ERASE; return ret; } @@ -3908,12 +3908,12 @@ void savemenu_move(s32 updateRate) { optLower = gSaveMenuOptionDest; while (updateRate > 0) { if (gSaveMenuOptionCountUpper > 0) { - lerpUpper = optUpper - gSavemenuScrollSource; - gSavemenuScrollSource += 0.1f * lerpUpper; //!@Delta + lerpUpper = optUpper - gSaveMenuScrollSource; + gSaveMenuScrollSource += 0.1f * lerpUpper; //!@Delta } if (gMenuStage > SAVEMENU_ENTER && gSaveMenuOptionCountLower > 0) { - lerpLower = optLower - gSavemenuScrollDest; - gSavemenuScrollDest += 0.1f * lerpLower; //!@Delta + lerpLower = optLower - gSaveMenuScrollDest; + gSaveMenuScrollDest += 0.1f * lerpLower; //!@Delta } updateRate--; } @@ -3933,33 +3933,33 @@ SIDeviceStatus savemenu_write(void) { Settings *settings; settings = get_settings(); - switch (gSavemenuFilesSource[gSaveMenuOptionSource].saveFileType) { + switch (gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileType) { case SAVE_FILE_TYPE_CART_SAVE: - switch (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType) { + switch (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType) { case SAVE_FILE_TYPE_CART_SAVE: - force_mark_write_save_file(gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex); - gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->cutsceneFlags = + force_mark_write_save_file(gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex); + gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->cutsceneFlags = settings->cutsceneFlags; - gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->newGame = FALSE; - *gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->balloonsPtr = + gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->newGame = FALSE; + *gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->balloonsPtr = *settings->balloonsPtr; - gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->filename = + gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->filename = settings->filename; break; case SAVE_FILE_TYPE_CPAK_EMPTY: - ret = write_game_data_to_controller_pak(gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex, + ret = write_game_data_to_controller_pak(gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex, settings); break; case SAVE_FILE_TYPE_ERASE: - mark_save_file_to_erase(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex); - gSavefileData[gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex]->newGame = TRUE; + mark_save_file_to_erase(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex); + gSavefileData[gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex]->newGame = TRUE; break; } break; case SAVE_FILE_TYPE_CART_TIMES: - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType != SAVE_FILE_TYPE_ERASE) { - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_CPAK_EMPTY) { - ret = write_time_data_to_controller_pak(gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex, + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType != SAVE_FILE_TYPE_ERASE) { + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_CPAK_EMPTY) { + ret = write_time_data_to_controller_pak(gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex, settings); } } else { @@ -3970,93 +3970,93 @@ SIDeviceStatus savemenu_write(void) { } break; case SAVE_FILE_TYPE_CPAK_SAVE: - switch (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType) { + switch (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType) { case SAVE_FILE_TYPE_CART_SAVE: ret = read_game_data_from_controller_pak( - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileExt, settings); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileExt, settings); if (settings->cutsceneFlags & 4 && !is_adventure_two_unlocked()) { ret = CONTROLLER_PAK_NEED_SECOND_ADVENTURE; } if (ret == CONTROLLER_PAK_GOOD) { - force_mark_write_save_file(gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex); - gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->cutsceneFlags = + force_mark_write_save_file(gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex); + gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->cutsceneFlags = settings->cutsceneFlags; - gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->newGame = 0; - *gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->balloonsPtr = + gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->newGame = 0; + *gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->balloonsPtr = *settings->balloonsPtr; - gSavefileData[gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex]->filename = + gSavefileData[gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex]->filename = settings->filename; } break; case SAVE_FILE_TYPE_CPAK_EMPTY: ret = read_game_data_from_controller_pak( - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileExt, gSavefileData[3]); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileExt, gSavefileData[3]); if (ret == CONTROLLER_PAK_GOOD) { - ret = write_game_data_to_controller_pak(gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex, + ret = write_game_data_to_controller_pak(gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex, gSavefileData[3]); } break; case SAVE_FILE_TYPE_ERASE: - ret = delete_file(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileNumber); + ret = delete_file(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileNumber); break; } break; case SAVE_FILE_TYPE_CPAK_TIMES: - for (i = 0; gSavemenuFilesSource[gSaveMenuOptionSource].saveFileExt[i] != '\0'; i++) {} + for (i = 0; gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileExt[i] != '\0'; i++) {} if (i > 0) { - fileExt[0] = gSavemenuFilesSource[gSaveMenuOptionSource].saveFileExt[i - 1]; + fileExt[0] = gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileExt[i - 1]; } else { fileExt[0] = 'A'; } fileExt[1] = '\0'; - switch (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType) { + switch (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType) { case SAVE_FILE_TYPE_CART_TIMES: ret = read_time_data_from_controller_pak( - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, fileExt, settings); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, fileExt, settings); break; case SAVE_FILE_TYPE_CPAK_EMPTY: ret = read_time_data_from_controller_pak( - gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, fileExt, settings); + gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, fileExt, settings); if (ret == CONTROLLER_PAK_GOOD) { - ret = write_time_data_to_controller_pak(gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex, + ret = write_time_data_to_controller_pak(gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex, settings); } mark_to_read_flap_and_course_times(); break; case SAVE_FILE_TYPE_ERASE: - ret = delete_file(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileNumber); + ret = delete_file(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileNumber); break; } break; case SAVE_FILE_TYPE_CPAK_GHOST: - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType != SAVE_FILE_TYPE_ERASE) { - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType != SAVE_FILE_TYPE_CPAK_EMPTY) { - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_UNK9) { + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType != SAVE_FILE_TYPE_ERASE) { + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType != SAVE_FILE_TYPE_CPAK_EMPTY) { + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_UNK9) { gMenuDelay = 1; - gCpakGhostData = gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex; + gCpakGhostData = gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex; } } else { - ret = copy_controller_pak_data(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileNumber, - gSavemenuFilesDest[gSaveMenuOptionDest].controllerIndex); + ret = copy_controller_pak_data(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileNumber, + gSaveMenuFilesDest[gSaveMenuOptionDest].controllerIndex); } } else { - ret = delete_file(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileNumber); + ret = delete_file(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileNumber); } break; case SAVE_FILE_TYPE_CPAK_OTHER: - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_ERASE) { - ret = delete_file(gSavemenuFilesSource[gSaveMenuOptionSource].controllerIndex, - gSavemenuFilesSource[gSaveMenuOptionSource].saveFileNumber); + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_ERASE) { + ret = delete_file(gSaveMenuFilesSource[gSaveMenuOptionSource].controllerIndex, + gSaveMenuFilesSource[gSaveMenuOptionSource].saveFileNumber); } break; case SAVE_FILE_TYPE_CART_BONUSES: - if (gSavemenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_ERASE) { + if (gSaveMenuFilesDest[gSaveMenuOptionDest].saveFileType == SAVE_FILE_TYPE_ERASE) { unset_eeprom_settings_value( 0xFFFFF3); // Reset most eeprom save data including Adventure Two unlock and Drumstick unlock. gActiveMagicCodes &= ~(CHEAT_CONTROL_TT | CHEAT_CONTROL_DRUMSTICK); @@ -4084,14 +4084,14 @@ void savemenu_render_error(SIDeviceStatus deviceStatus) { gControllerIndex = (deviceStatus >> 30) & 3; // Gets the controller index from the device status. deviceStatus &= 0x3FFFFFFF; // Removes the controller index from the device status value. gDeviceStatusStrings = gContPakStrings[deviceStatus]; - D_800DFADC = deviceStatus; - D_80126A74 = 0; + gDeviceStatus = deviceStatus; + gSaveMenuMessageLines = 0; for (k = 0; gDeviceStatusStrings[k] != NULL; k++) {} k++; - for (; gDeviceStatusStrings[k] != NULL; D_80126A74++, k++) {} + for (; gDeviceStatusStrings[k] != NULL; gSaveMenuMessageLines++, k++) {} - D_80126A78 = D_80126A74 - 1; + gSaveMenuMessageOption = gSaveMenuMessageLines - 1; dialogue_clear(7); set_current_dialogue_box_coords(7, 40, SCREEN_HEIGHT_HALF - (((k * 16) + 44) >> 1), 280, @@ -4117,7 +4117,7 @@ void savemenu_render_error(SIDeviceStatus deviceStatus) { i++; y += 16; for (j = 0; gDeviceStatusStrings[i] != NULL; i++, j++, y += 16) { - D_80126A80[j] = render_dialogue_text(7, POS_CENTRED, y, gDeviceStatusStrings[i], 1, ALIGN_MIDDLE_CENTER); + gSaveMenuText[j] = render_dialogue_text(7, POS_CENTRED, y, gDeviceStatusStrings[i], 1, ALIGN_MIDDLE_CENTER); } gMenuStage |= 8; } @@ -4133,7 +4133,7 @@ s32 savemenu_input_source(s32 buttonsPressed, s32 direction) { ret = 0; if (buttonsPressed & B_BUTTON) { gMenuStage = SAVEMENU_ENTER; - if (gSavemenuRumbleNag != gSavemenuRumbleConnected) { + if (gSaveMenuRumbleNag != gSaveMenuRumbleConnected) { savemenu_render_error(CONTROLLER_PAK_SWITCH_TO_RUMBLE); } else { sound_play(SOUND_MENU_BACK3, NULL); @@ -4191,37 +4191,41 @@ s32 savemenu_input_confirm(s32 buttonsPressed, UNUSED s32 arg1) { return 0; } -s32 func_80087734(s32 buttonsPressed, s32 yAxis) { +/** + * Takes input if a message is shown onscreen when first coming into the save menu. + * This resolves having a rumble pak connected, or a damaged controller pak. + */ +s32 savemenu_input_message(s32 buttonsPressed, s32 yAxis) { UNUSED s32 pad[2]; - s32 sp1C; + s32 stage; s32 i; - s32 temp; + s32 highlight; - temp = gOptionBlinkTimer * 8; - if (temp > 255) { - temp = 511 - temp; + highlight = gOptionBlinkTimer * 8; + if (highlight > 255) { + highlight = 511 - highlight; } - sp1C = (gMenuStage & 7); - for (i = 0; i < D_80126A74; i++) { - if (i == D_80126A78) { - D_80126A80[i]->unk13 = temp; + stage = (gMenuStage & 7); + for (i = 0; i < gSaveMenuMessageLines; i++) { + if (i == gSaveMenuMessageOption) { + gSaveMenuText[i]->highlight = highlight; } else { - D_80126A80[i]->unk13 = 0; + gSaveMenuText[i]->highlight = 0; } } - if (buttonsPressed & B_BUTTON || - (buttonsPressed & (START_BUTTON | A_BUTTON) && (u32) D_80126A74 == (u32) (D_80126A78 + 1))) { + if (buttonsPressed & B_BUTTON || (buttonsPressed & (START_BUTTON | A_BUTTON) && + (u32) gSaveMenuMessageLines == (u32) (gSaveMenuMessageOption + 1))) { sound_play(SOUND_MENU_BACK3, NULL); gMenuStage &= ~8; - switch (sp1C) { - case 0: + switch (stage) { + case SAVEMENU_ENTER: if (!(buttonsPressed & (START_BUTTON | A_BUTTON))) { gOpacityDecayTimer = 6; gMenuStage = SAVEMENU_WAIT; } break; - case 2: - switch (D_800DFADC) { + case SAVEMENU_INIT_SOURCE: + switch (gDeviceStatus) { case CONTROLLER_PAK_CHANGED: gOpacityDecayTimer = 5; gMenuStage = SAVEMENU_WAIT; @@ -4230,18 +4234,18 @@ s32 func_80087734(s32 buttonsPressed, s32 yAxis) { case CONTROLLER_PAK_INCONSISTENT: case CONTROLLER_PAK_WITH_BAD_ID: case CONTROLLER_PAK_BAD_DATA: - D_80126A18 = 0; + gSaveMenuSourceState = 0; break; case CONTROLLER_PAK_RUMBLE_PAK_FOUND: - D_80126A18 = -1; + gSaveMenuSourceState = -1; break; default: - D_80126A18 = 1; + gSaveMenuSourceState = 1; break; } break; - case 4: - switch (D_800DFADC) { + case SAVEMENU_INIT_DEST: + switch (gDeviceStatus) { case CONTROLLER_PAK_NOT_FOUND: case CONTROLLER_PAK_CHANGED: gOpacityDecayTimer = 5; @@ -4250,18 +4254,18 @@ s32 func_80087734(s32 buttonsPressed, s32 yAxis) { case CONTROLLER_PAK_INCONSISTENT: case CONTROLLER_PAK_WITH_BAD_ID: case CONTROLLER_PAK_BAD_DATA: - D_80126A1C = 0; + gSaveMenuDestState = 0; break; case CONTROLLER_PAK_RUMBLE_PAK_FOUND: - D_80126A1C = -1; + gSaveMenuDestState = -1; break; default: - D_80126A1C = 1; + gSaveMenuDestState = 1; break; } break; - case 7: - switch (D_800DFADC) { + case SAVEMENU_WRITE: + switch (gDeviceStatus) { case CONTROLLER_PAK_NOT_FOUND: case CONTROLLER_PAK_INCONSISTENT: case CONTROLLER_PAK_WITH_BAD_ID: @@ -4280,38 +4284,38 @@ s32 func_80087734(s32 buttonsPressed, s32 yAxis) { } else if (buttonsPressed & (START_BUTTON | A_BUTTON)) { sound_play(SOUND_SELECT2, NULL); gMenuStage &= ~8; - switch (D_800DFADC) { + switch (gDeviceStatus) { case CONTROLLER_PAK_WITH_BAD_ID: reformat_controller_pak(gControllerIndex); - if (sp1C == 4) { - D_80126A1C = 0; - } else if (sp1C == 7) { - D_80126A18 = 0; + if (stage == SAVEMENU_INIT_DEST) { + gSaveMenuDestState = 0; + } else if (stage == SAVEMENU_WRITE) { + gSaveMenuSourceState = 0; } break; case CONTROLLER_PAK_INCONSISTENT: case CONTROLLER_PAK_BAD_DATA: repair_controller_pak(gControllerIndex); - if (sp1C == 4) { - D_80126A1C = 1; - } else if (sp1C == 2) { - D_80126A18 = 1; + if (stage == SAVEMENU_INIT_DEST) { + gSaveMenuDestState = 1; + } else if (stage == SAVEMENU_INIT_SOURCE) { + gSaveMenuSourceState = 1; } break; case CONTROLLER_PAK_RUMBLE_PAK_FOUND: - if (sp1C == 4) { - D_80126A1C = -1; + if (stage == SAVEMENU_INIT_DEST) { + gSaveMenuDestState = -1; } else { - D_80126A18 = -1; + gSaveMenuSourceState = -1; } break; } - } else if (yAxis < 0 && D_80126A78 < (D_80126A74 - 1)) { + } else if (yAxis < 0 && gSaveMenuMessageOption < (gSaveMenuMessageLines - 1)) { sound_play(SOUND_MENU_PICK2, NULL); - D_80126A78++; - } else if (yAxis > 0 && D_80126A78 > 0) { + gSaveMenuMessageOption++; + } else if (yAxis > 0 && gSaveMenuMessageOption > 0) { sound_play(SOUND_MENU_PICK2, NULL); - D_80126A78--; + gSaveMenuMessageOption--; } return 0; } @@ -4365,7 +4369,7 @@ s32 menu_save_options_loop(s32 updateRate) { } } if (gMenuStage & 8) { - gMenuDelay = func_80087734(buttonsPressed, yAxis); + gMenuDelay = savemenu_input_message(buttonsPressed, yAxis); } else { switch (gMenuStage) { case SAVEMENU_ENTER: @@ -4379,7 +4383,7 @@ s32 menu_save_options_loop(s32 updateRate) { break; case SAVEMENU_INIT_SOURCE: gSaveMenuOptionSource = 0; - gSavemenuScrollSource = 0.0f; + gSaveMenuScrollSource = 0.0f; result = savemenu_load_sources(); if (result != CONTROLLER_PAK_GOOD) { savemenu_render_error(result); @@ -4392,7 +4396,7 @@ s32 menu_save_options_loop(s32 updateRate) { break; case SAVEMENU_INIT_DEST: gSaveMenuOptionDest = 0; - gSavemenuScrollDest = 0.0f; + gSaveMenuScrollDest = 0.0f; result = savemenu_load_destinations(); if (result != CONTROLLER_PAK_GOOD) { savemenu_render_error(result); @@ -4436,7 +4440,7 @@ void savemenu_free(void) { menu_button_free(); menu_assetgroup_free(gSaveMenuObjectIndices); dialogue_clear(7); - free_from_memory_pool((void *) gSavemenuFilesSource); + free_from_memory_pool((void *) gSaveMenuFilesSource); free_from_memory_pool((void *) D_80126A64); } @@ -5658,8 +5662,8 @@ s32 menu_magic_codes_list_loop(s32 updateRate) { if ((xAxis < 0 || xAxis > 0) && numUnlockedCodes != gOptionsMenuItemIndex) { sound_play(SOUND_SELECT2, NULL); code = 1 << gUnlockedCheatIDs[gOptionsMenuItemIndex]; - gActiveMagicCodes ^= code; - cheatlist_exclusive(code, CHEAT_BIG_CHARACTERS, CHEAT_SMALL_CHARACTERS); + gActiveMagicCodes ^= code; // Toggle active cheats? + cheatlist_exclusive(code, CHEAT_BIG_CHARACTERS, CHEAT_SMALL_CHARACTERS); // cheatlist_exclusive() = Clear flags? cheatlist_exclusive(code, CHEAT_SMALL_CHARACTERS, CHEAT_BIG_CHARACTERS); cheatlist_exclusive(code, CHEAT_DISABLE_BANANAS, CHEAT_NO_LIMIT_TO_BANANAS | CHEAT_BANANAS_REDUCE_SPEED | CHEAT_START_WITH_10_BANANAS); @@ -6126,7 +6130,7 @@ void charselect_assign_ai(s32 charSlot) { if (charSlot < 8) { foundIt = FALSE; for (i = 0; i < charSlot && !foundIt; i++) { - if (gCharacterIdSlots[i] == CHARACTER_DIDDY) { + if (gCharacterIdSlots[i] == CHARACTER_DIDDY) { // I think 9 is the character id for Diddy Kong? foundIt = TRUE; } } @@ -6176,7 +6180,7 @@ s32 menu_character_select_loop(s32 updateRate) { // clang-format on charselect_new_player(); if (gNumberOfReadyPlayers == gNumberOfActivePlayers) { - charselect_pick(); // Cancel/Confirm selected character + charselect_pick(); // Cancel/Confirm selected character? } else { charselect_input(activePlayers); // Move and select characters? } diff --git a/src/menu.h b/src/menu.h index 56898c6a..92c74b84 100644 --- a/src/menu.h +++ b/src/menu.h @@ -390,7 +390,7 @@ typedef struct MenuColour { // Unknown Size typedef struct unk80126A80 { u8 pad0[0x13]; - s8 unk13; + s8 highlight; } unk80126A80; /* Size: 0x10 bytes */ @@ -635,7 +635,7 @@ void menu_element_render(s32 elementID); void menu_input(void); SIDeviceStatus savemenu_load_sources(void); void menu_asset_load(s32 arg0); -s32 func_80087734(s32 buttonsPressed, s32 yAxis); +s32 savemenu_input_message(s32 buttonsPressed, s32 yAxis); void savemenu_render_element(SaveFileData *arg0, s32 x, s32 y); void trackmenu_render_2D(s32 x, s32 y, char *hubName, char *trackName, s32 rectOpacity, s32 imageId, s32 copyViewPort, DrawTexture *arg7, s32 arg8); void pausemenu_render(UNUSED s32 updateRate); diff --git a/src/object_functions.c b/src/object_functions.c index 0cd76a99..81d2dbde 100644 --- a/src/object_functions.c +++ b/src/object_functions.c @@ -5621,8 +5621,8 @@ void obj_loop_weather(Object *obj, UNUSED s32 updateRate) { if ((diffX * diffX) + (diffZ * diffZ) <= dist) { if (((!obj->segment.level_entry) && (!obj->segment.level_entry)) && (!obj->segment.level_entry)) { } // Fakematch - changeWeather(entry->unkA * 256, entry->unkC * 256, entry->unkE * 256, entry->unk10 * 257, - entry->unk11 * 257, entry->unk12); + weather_set(entry->unkA * 256, entry->unkC * 256, entry->unkE * 256, entry->unk10 * 257, entry->unk11 * 257, + entry->unk12); } } } diff --git a/src/thread3_main.c b/src/thread3_main.c index 5dd03080..1dc89c0c 100644 --- a/src/thread3_main.c +++ b/src/thread3_main.c @@ -210,7 +210,7 @@ void init_game(void) { debug_text_init(); allocate_ghost_data(); init_particle_assets(); - init_weather(); + weather_init(); calc_and_alloc_heap_for_settings(); default_alloc_displaylist_heap(); load_fonts(); diff --git a/src/tracks.c b/src/tracks.c index eb85222e..bff86224 100644 --- a/src/tracks.c +++ b/src/tracks.c @@ -344,7 +344,7 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, gDPSetBlendColor(gSceneCurrDisplayList++, 0, 0, 0, 0x64); gDPSetPrimColor(gSceneCurrDisplayList++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(gSceneCurrDisplayList++, 255, 255, 255, 0); - func_800AD40C(); + rain_fog(); update_fog(numViewports, tempUpdateRate); func_800AF404(tempUpdateRate); if (gCurrentLevelModel->numberOfAnimatedTextures > 0) { @@ -381,11 +381,11 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, } gDPPipeSync(gSceneCurrDisplayList++); initialise_player_viewport_vars(updateRate); - set_weather_limits(-1, -512); + weather_clip_planes(-1, -512); // Show weather effects in single player. if (gCurrentLevelHeader2->weatherEnable > 0 && numViewports < 2) { - process_weather(&gSceneCurrDisplayList, &gSceneCurrMatrix, &gSceneCurrVertexList, &gSceneCurrTriList, - tempUpdateRate); + weather_update(&gSceneCurrDisplayList, &gSceneCurrMatrix, &gSceneCurrVertexList, &gSceneCurrTriList, + tempUpdateRate); } lensflare_override(get_active_camera_segment()); lensflare_render(&gSceneCurrDisplayList, &gSceneCurrMatrix, &gSceneCurrVertexList, get_active_camera_segment()); @@ -413,7 +413,7 @@ void render_scene(Gfx **dList, MatrixS **mtx, Vertex **vtx, TriangleList **tris, matrix_world_origin(&gSceneCurrDisplayList, &gSceneCurrMatrix); gDPPipeSync(gSceneCurrDisplayList++); initialise_player_viewport_vars(updateRate); - set_weather_limits(-1, -512); + weather_clip_planes(-1, -512); lensflare_override(get_active_camera_segment()); lensflare_render(&gSceneCurrDisplayList, &gSceneCurrMatrix, &gSceneCurrVertexList, get_active_camera_segment()); diff --git a/src/weather.c b/src/weather.c index af096f92..e713750e 100644 --- a/src/weather.c +++ b/src/weather.c @@ -18,24 +18,23 @@ /************ .data ************/ -unk800E2850 D_800E2850[3] = { +SnowGfxData gWeatherPresets[3] = { { 0, 0x40, (TextureHeader *) 0, 0xFE000000, 0xFE000000, 0xFE000000, 0x03FFFFFF, 0x03FFFFFF, 0x03FFFFFF, 4, 4, 8, - 8 }, + 8 }, // Snow { 0, 0x100, (TextureHeader *) 1, 0xFE000000, 0xFE000000, 0xFE000000, 0x03FFFFFF, 0x03FFFFFF, 0x03FFFFFF, 4, 4, 8, - 8 }, + 8 }, // Rain { 0, 0x08, (TextureHeader *) 2, 0xFE000000, 0xFE000000, 0xFE000000, 0x03FFFFFF, 0x03FFFFFF, 0x03FFFFFF, 4, 4, 8, - 8 }, + 8 }, // Unused, game crashes with this. }; -unk800E28D4 *D_800E28D4 = NULL; -unk800E2850 D_800E28D8 = { NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +SnowPosData *gSnowPhysics = NULL; +SnowGfxData gSnowGfx = { NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -// Not sure about typing for the following. -Vertex *D_800E2904 = 0; -s32 D_800E2908 = 0; -Triangle *D_800E290C = NULL; -s16 *D_800E2910 = NULL; -Vertex *D_800E2914[2] = { NULL, NULL }; +Vertex *gSnowVerts = NULL; +s32 gSnowVertCount = 0; +Triangle *gSnowTriangles = NULL; +s16 *gSnowTriIndices = NULL; +Vertex *gSnowVertexData[2] = { NULL, NULL }; s32 *gWeatherAssetTable = NULL; // List of Ids s32 gWeatherAssetTableLength = 0; // Set, but never read. @@ -84,7 +83,7 @@ f32 D_800E2AA0 = -200.0f; f32 D_800E2AA4 = -200.0f; f32 D_800E2AA8 = -200.0f; -Vertex D_800E2AAC[16] = { +Vertex gRainVertices[16] = { { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, { 0, 0, 0, 255, 255, 255, 255 }, @@ -93,32 +92,32 @@ Vertex D_800E2AAC[16] = { { 0, 0, 0, 255, 255, 255, 255 }, }; -ObjectSegment2 D_800E2B4C[8] = { +RainPosData gRainSplashSegments[8] = { { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, { { 0, 0, 0, 0, 1.0f, 0.0f, 0.0f, 0.0f }, 0, 0 }, }; -unk800E2C2C gRainGfx[2] = { - { 0, 0, 0x400, 0x400, 0x000A, 0xFFC4, NULL, 128, 255, 255, 128, 128, 255, 128, 0 }, - { 0, 0, 0x600, 0x600, 0x0020, 0xFF40, NULL, 255, 255, 255, 0, 128, 255, 255, 0 }, +RainGfxData gRainGfx[2] = { + { 0, 0, 0x400, 0x400, 0x000A, 0xFFC4, NULL, 128, 255, 255, 128, 128, 255, 128 }, + { 0, 0, 0x600, 0x600, 0x0020, 0xFF40, NULL, 255, 255, 255, 0, 128, 255, 255 }, }; s32 gWeatherType = WEATHER_SNOW; s32 gLightningFrequency = 0x10000; -s32 D_800E2C64 = 0; -s32 D_800E2C68 = 0x10000; -s32 D_800E2C6C = 0x10000; -s32 D_800E2C70 = 0; -s32 D_800E2C74 = 0x10000; -s32 D_800E2C78 = 0; +s32 gLightningFrequencyStep = 0; +s32 gLightningFrequencyTarget = 0x10000; +s32 gRainOpacity = 0x10000; +s32 gRainOpacityStep = 0; +s32 gRainOpacityTarget = 0x10000; +s32 gRainHiddenTimer = 0; s32 gLightningTimer = 0; s32 gThunderTimer = 0; -s32 D_800E2C84 = 0; +s32 gRainSplashDelay = 0; TextureHeader *gRainOverlayUnusedValue = NULL; // Set, but never read. -Sprite *gRainSplashGfx = 0; -s32 D_800E2C90 = 0; +Sprite *gRainSplashGfx = NULL; +s32 gRainVertexFlip = 0; SoundMask *gWeatherSoundMask = NULL; FadeTransition gThunderTransition = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_INVERT, FADE_COLOR_WHITE, 5, 2); @@ -127,13 +126,13 @@ FadeTransition gThunderTransition = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_I /************ .bss ************/ -s32 D_80127BB0; -s32 D_80127BB4; -RainData D_80127BB8; -unk80127BF8 D_80127BF8; -s32 D_80127C00; -s32 D_80127C04; -s32 D_80127C08; +s32 gSnowDensity; +s32 gSnowParticleCount; +WeatherData gWeather; +SnowLimits gSnowPlane; // Uses negative values, so all distances will be checked in reverse. +s32 gSnowVertOffset; +s32 gSnowTriCount; +s32 gSnowVertexFlip; Gfx *gCurrWeatherDisplayList; MatrixS *gCurrWeatherMatrix; Vertex *gCurrWeatherVertexList; @@ -149,21 +148,23 @@ Object *gLensFlareSwitches[WEATHER_OVERRIDE_COUNT]; /******************************/ /** + * Zero out all the weather data. + * Load the weather table into memory. * Official Name: initWeather */ -void init_weather(void) { - D_800E28D8.unk0 = 0; - D_800E28D8.unk4 = 0; - D_800E28D4 = NULL; - D_80127BB0 = 0; - D_80127C00 = 6; - D_80127C00 <<= 2; - D_80127C04 = D_80127C00 >> 1; - D_800E2914[0] = 0; - D_800E2914[1] = 0; - D_800E290C = 0; - D_80127BF8.unk0 = -1; - D_80127BF8.unk2 = -512; +void weather_init(void) { + gSnowGfx.pos = NULL; + gSnowGfx.size = 0; + gSnowPhysics = NULL; + gSnowDensity = 0; + gSnowVertOffset = 6; + gSnowVertOffset <<= 2; + gSnowTriCount = gSnowVertOffset >> 1; // One triangle per two verts + gSnowVertexData[0] = 0; + gSnowVertexData[1] = 0; + gSnowTriangles = 0; + gSnowPlane.near = -1; + gSnowPlane.far = -512; gLensFlare = NULL; gLensFlareOff = TRUE; gLensFlareOverrideObjs = 0; @@ -174,19 +175,20 @@ void init_weather(void) { gWeatherAssetTableLength++; } } - D_80127C08 = 0; + gSnowVertexFlip = 0; } /** + * Set the near and far culling distances for the weather effects. * Official Name: setWeatherLimits */ -void set_weather_limits(s16 arg0, s16 arg1) { - if (D_80127BF8.unk2 < D_80127BF8.unk0) { - D_80127BF8.unk0 = arg0; - D_80127BF8.unk2 = arg1; +void weather_clip_planes(s16 near, s16 far) { + if (gSnowPlane.far < gSnowPlane.near) { + gSnowPlane.near = near; + gSnowPlane.far = far; } else { - D_80127BF8.unk0 = arg1; - D_80127BF8.unk2 = arg0; + gSnowPlane.near = far; + gSnowPlane.far = near; } } @@ -208,17 +210,17 @@ void set_weather_limits(s16 arg0, s16 arg1) { * If it's raining, then free those too. * Official Name: freeWeather */ -void free_weather_memory(void) { +void weather_free(void) { TextureHeader *tempTex; s32 *tempMem; - FREE_MEM(D_800E290C); - FREE_MEM(D_800E2914[0]); - FREE_MEM(D_800E2914[1]); - FREE_MEM(D_800E28D4); - FREE_MEM(D_800E28D8.unk0); - FREE_TEX(D_800E28D8.unk8); - FREE_MEM(D_800E2910); + FREE_MEM(gSnowTriangles); + FREE_MEM(gSnowVertexData[0]); + FREE_MEM(gSnowVertexData[1]); + FREE_MEM(gSnowPhysics); + FREE_MEM(gSnowGfx.pos); + FREE_TEX(gSnowGfx.texture); + FREE_MEM(gSnowTriIndices); gLensFlareOverrideObjs = 0; gLensFlare = NULL; @@ -228,154 +230,168 @@ void free_weather_memory(void) { } } -// proccess_rain? -void func_800AB4A8(s32 weatherType, s32 weatherEnable, s32 velX, s32 velY, s32 velZ, s32 intensity, s32 opacity) { +/** + * Free all existing weather data. + * If the weather type allows rain, then allocate and initialise rain. + * Afterwards, allocate and set the defaults for snow model data. + */ +void weather_reset(s32 weatherType, s32 density, s32 velX, s32 velY, s32 velZ, s32 intensity, s32 opacity) { s16 width; s16 height; s32 numOfElements; s32 allocSize; s32 i; s32 j; - unk800E2850_unk0 *temp_v0; + Vec3i *pos; - free_weather_memory(); - D_80127BB8.unkC = velX; - D_80127BB8.unk10 = 0; - D_80127BB8.unk14 = velX; - D_80127BB8.unk18 = velY; - D_80127BB8.unk1C = 0; - D_80127BB8.unk20 = velY; - D_80127BB8.unk28 = 0; - D_80127BB8.unk4 = 0; - D_80127BB8.unk34 = 0; - D_80127BB8.unk3C = 0; - D_80127BB8.unk24 = velZ; - D_80127BB8.unk2C = velZ; - D_80127BB8.unk0 = intensity; - D_80127BB8.unk8 = intensity; - D_80127BB8.unk30 = opacity; - D_80127BB8.unk38 = opacity; - if (weatherType >= WEATHER_UNK2) { + weather_free(); + gWeather.velX = velX; + gWeather.velXStep = 0; + gWeather.velXTarget = velX; + gWeather.velY = velY; + gWeather.velYStep = 0; + gWeather.velYTarget = velY; + gWeather.velZStep = 0; + gWeather.intensityStep = 0; + gWeather.opacityStep = 0; + gWeather.shiftTime = 0; + gWeather.velZ = velZ; + gWeather.velZTarget = velZ; + gWeather.intensity = intensity; + gWeather.intensityTarget = intensity; + gWeather.opacity = opacity; + gWeather.opacityTarget = opacity; + if (weatherType > WEATHER_RAIN) { weatherType = WEATHER_RAIN; } - if (D_800E2850[weatherType].unk8 == ((TextureHeader *) 1)) { - func_800AD144(intensity + 1, opacity + 1); + if (gWeatherPresets[weatherType].texture == ((TextureHeader *) 1)) { + rain_init(intensity + 1, opacity + 1); return; } - temp_v0 = (unk800E2850_unk0 *) allocate_from_main_pool_safe( - D_800E2850[weatherType].unk4 * (sizeof(unk800E2850_unk0)), COLOUR_TAG_LIGHT_ORANGE); - D_800E28D8.unk0 = temp_v0; - D_800E28D8.unk4 = D_800E2850[weatherType].unk4; - D_800E28D8.unkC = D_800E2850[weatherType].unkC; - D_800E28D8.unk10 = D_800E2850[weatherType].unk10; - D_800E28D8.unk14 = D_800E2850[weatherType].unk14; - D_800E28D8.unk18 = D_800E2850[weatherType].unk18; - D_800E28D8.unk1C = D_800E2850[weatherType].unk1C; - D_800E28D8.unk20 = D_800E2850[weatherType].unk20; - D_800E28D8.unk24 = D_800E2850[weatherType].unk24; - D_800E28D8.unk26 = D_800E2850[weatherType].unk26; - D_800E28D8.unk28 = D_800E28D8.unk24 * 2; - D_800E28D8.unk2A = D_800E28D8.unk26 * 2; - if (D_800E2850[weatherType].unk8 == NULL) { - func_800ABB34(); + pos = (Vec3i *) allocate_from_main_pool_safe(gWeatherPresets[weatherType].size * (sizeof(Vec3i)), + COLOUR_TAG_LIGHT_ORANGE); + gSnowGfx.pos = pos; + gSnowGfx.size = gWeatherPresets[weatherType].size; + gSnowGfx.offsetX = gWeatherPresets[weatherType].offsetX; + gSnowGfx.offsetY = gWeatherPresets[weatherType].offsetY; + gSnowGfx.offsetZ = gWeatherPresets[weatherType].offsetZ; + gSnowGfx.radiusX = gWeatherPresets[weatherType].radiusX; + gSnowGfx.radiusY = gWeatherPresets[weatherType].radiusY; + gSnowGfx.radiusZ = gWeatherPresets[weatherType].radiusZ; + gSnowGfx.vertOffsetW = gWeatherPresets[weatherType].vertOffsetW; + gSnowGfx.vertOffsetH = gWeatherPresets[weatherType].vertOffsetH; + gSnowGfx.vertWidth = gSnowGfx.vertOffsetW * 2; + gSnowGfx.vertHeight = gSnowGfx.vertOffsetH * 2; + if (gWeatherPresets[weatherType].texture == NULL) { + snow_init(); } - numOfElements = weatherEnable; - D_80127BB0 = numOfElements; - D_800E2910 = (s16 *) allocate_from_main_pool_safe(numOfElements * (sizeof(s16)), COLOUR_TAG_LIGHT_ORANGE); - D_800E28D4 = - (unk800E28D4 *) allocate_from_main_pool_safe(numOfElements * (sizeof(unk800E28D4)), COLOUR_TAG_LIGHT_ORANGE); - for (i = 0; i < D_80127BB0; i++) { - D_800E28D4[i].unk0 = get_random_number_from_range(0, D_800E28D8.unk18); - D_800E28D4[i].unk4 = get_random_number_from_range(0, D_800E28D8.unk1C); - D_800E28D4[i].unk8 = get_random_number_from_range(0, D_800E28D8.unk20); - D_800E28D4[i].unkC = 1 << (get_random_number_from_range(0, 32) + 5); - D_800E28D4[i].unkD = 1 << (get_random_number_from_range(0, 32) + 5); - D_800E28D4[i].unkE = 1 << (get_random_number_from_range(0, 32) + 5); - D_800E28D4[i].unkF = get_random_number_from_range(0, D_800E28D8.unk4 - 1); + numOfElements = density; + gSnowDensity = numOfElements; + gSnowTriIndices = (s16 *) allocate_from_main_pool_safe(numOfElements * (sizeof(s16)), COLOUR_TAG_LIGHT_ORANGE); + gSnowPhysics = + (SnowPosData *) allocate_from_main_pool_safe(numOfElements * (sizeof(SnowPosData)), COLOUR_TAG_LIGHT_ORANGE); + for (i = 0; i < gSnowDensity; i++) { + gSnowPhysics[i].x_position = get_random_number_from_range(0, gSnowGfx.radiusX); + gSnowPhysics[i].y_position = get_random_number_from_range(0, gSnowGfx.radiusY); + gSnowPhysics[i].z_position = get_random_number_from_range(0, gSnowGfx.radiusZ); + gSnowPhysics[i].unused_C = 1 << (get_random_number_from_range(0, 32) + 5); + gSnowPhysics[i].unused_D = 1 << (get_random_number_from_range(0, 32) + 5); + gSnowPhysics[i].unused_E = 1 << (get_random_number_from_range(0, 32) + 5); + gSnowPhysics[i].index = get_random_number_from_range(0, gSnowGfx.size - 1); } numOfElements = numOfElements * 4; allocSize = sizeof(Vertex); allocSize *= numOfElements; - D_800E2914[0] = allocate_from_main_pool_safe(allocSize, COLOUR_TAG_LIGHT_ORANGE); - D_800E2914[1] = allocate_from_main_pool_safe(allocSize, COLOUR_TAG_LIGHT_ORANGE); + gSnowVertexData[0] = allocate_from_main_pool_safe(allocSize, COLOUR_TAG_LIGHT_ORANGE); + gSnowVertexData[1] = allocate_from_main_pool_safe(allocSize, COLOUR_TAG_LIGHT_ORANGE); for (j = 0; j < 2; j++) { - D_800E2904 = D_800E2914[j]; + gSnowVerts = gSnowVertexData[j]; for (i = 0; i < numOfElements; i++) { - D_800E2904[i].r = 0xFF; - D_800E2904[i].g = 0xFF; - D_800E2904[i].b = 0xFF; - D_800E2904[i].a = 0xFF; + gSnowVerts[i].r = 255; + gSnowVerts[i].g = 255; + gSnowVerts[i].b = 255; + gSnowVerts[i].a = 255; } } - width = (D_800E28D8.unk8->width << 5) - 1; - height = (D_800E28D8.unk8->height << 5) - 1; - D_800E290C = (Triangle *) allocate_from_main_pool_safe(D_80127C04 * (sizeof(Triangle)), COLOUR_TAG_LIGHT_ORANGE); - for (i = 0; i < D_80127C04; i += 2) { - D_800E290C[i].flags = 0; - D_800E290C[i].vi0 = (i << 1) + 3; - D_800E290C[i].uv0.u = 0; - D_800E290C[i].uv0.v = height; - D_800E290C[i].vi1 = (i << 1) + 1; - D_800E290C[i].uv1.u = width; - D_800E290C[i].uv1.v = 0; - D_800E290C[i].vi2 = (i << 1) + 0; - D_800E290C[i].uv2.u = 0; - D_800E290C[i].uv2.v = 0; - D_800E290C[i + 1].flags = 0; - D_800E290C[i + 1].vi0 = (i << 1) + 3; - D_800E290C[i + 1].uv0.u = 0; - D_800E290C[i + 1].uv0.v = height; - D_800E290C[i + 1].vi1 = (i << 1) + 2; - D_800E290C[i + 1].uv1.u = width; - D_800E290C[i + 1].uv1.v = height; - D_800E290C[i + 1].vi2 = (i << 1) + 1; - D_800E290C[i + 1].uv2.u = width; - D_800E290C[i + 1].uv2.v = 0; + width = (gSnowGfx.texture->width << 5) - 1; + height = (gSnowGfx.texture->height << 5) - 1; + gSnowTriangles = + (Triangle *) allocate_from_main_pool_safe(gSnowTriCount * (sizeof(Triangle)), COLOUR_TAG_LIGHT_ORANGE); + for (i = 0; i < gSnowTriCount; i += 2) { + gSnowTriangles[i].flags = 0; + gSnowTriangles[i].vi0 = (i << 1) + 3; + gSnowTriangles[i].uv0.u = 0; + gSnowTriangles[i].uv0.v = height; + gSnowTriangles[i].vi1 = (i << 1) + 1; + gSnowTriangles[i].uv1.u = width; + gSnowTriangles[i].uv1.v = 0; + gSnowTriangles[i].vi2 = (i << 1) + 0; + gSnowTriangles[i].uv2.u = 0; + gSnowTriangles[i].uv2.v = 0; + gSnowTriangles[i + 1].flags = 0; + gSnowTriangles[i + 1].vi0 = (i << 1) + 3; + gSnowTriangles[i + 1].uv0.u = 0; + gSnowTriangles[i + 1].uv0.v = height; + gSnowTriangles[i + 1].vi1 = (i << 1) + 2; + gSnowTriangles[i + 1].uv1.u = width; + gSnowTriangles[i + 1].uv1.v = height; + gSnowTriangles[i + 1].vi2 = (i << 1) + 1; + gSnowTriangles[i + 1].uv2.u = width; + gSnowTriangles[i + 1].uv2.v = 0; } - D_80127C08 = 0; + gSnowVertexFlip = 0; } -void func_800ABB34(void) { - s32 temp_v0; - s32 phi_s1; +/** + * Set the initial positions of all the snow particles by making a circle. + * Load the snow texture into memory. + */ +void snow_init(void) { + s32 step; + s32 offset; s32 i; - temp_v0 = 0x10000 / D_800E28D8.unk4; - phi_s1 = 0; + step = 0x10000 / gSnowGfx.size; + offset = 0; - for (i = 0; i < D_800E28D8.unk4; i++) { - D_800E28D8.unk0[i].unk0 = coss(phi_s1 & 0xFFFF) << 3; - D_800E28D8.unk0[i].unk4 = 0xFFFC0000; - D_800E28D8.unk0[i].unk8 = sins(phi_s1 & 0xFFFF) << 1; - phi_s1 += temp_v0; + for (i = 0; i < gSnowGfx.size; i++) { + gSnowGfx.pos[i].x = coss(offset & 0xFFFF) << 3; + gSnowGfx.pos[i].y = 0xFFFC0000; + gSnowGfx.pos[i].z = sins(offset & 0xFFFF) << 1; + offset += step; } - D_800E28D8.unk8 = load_texture(*gWeatherAssetTable); + gSnowGfx.texture = load_texture(*gWeatherAssetTable); } -void changeWeather(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5) { - if ((arg5 > 0) && ((arg0 != D_80127BB8.unk14) || (arg1 != D_80127BB8.unk20) || (arg2 != D_80127BB8.unk2C) || - (arg3 != D_80127BB8.unk0) || (arg4 != D_80127BB8.unk30))) { - D_80127BB8.unk14 = arg0; - D_80127BB8.unk20 = arg1; - D_80127BB8.unk2C = arg2; - D_80127BB8.unk10 = (s32) ((s32) (arg0 - D_80127BB8.unkC) / arg5); - D_80127BB8.unk1C = (s32) ((s32) (arg1 - D_80127BB8.unk18) / arg5); - D_80127BB8.unk28 = (s32) ((s32) (arg2 - D_80127BB8.unk24) / arg5); +/** + * Change the current properties of the weather. + * Will start a timer that means it will gradually shift from the current to the new. + * Official name: changeWeather + */ +void weather_set(s32 velX, s32 velY, s32 velZ, s32 intensity, s32 opacity, s32 time) { + if (time > 0 && (velX != gWeather.velXTarget || velY != gWeather.velYTarget || velZ != gWeather.velZTarget || + intensity != gWeather.intensity || opacity != gWeather.opacity)) { + gWeather.velXTarget = velX; + gWeather.velYTarget = velY; + gWeather.velZTarget = velZ; + gWeather.velXStep = (velX - gWeather.velX) / time; + gWeather.velYStep = (velY - gWeather.velY) / time; + gWeather.velZStep = (velZ - gWeather.velZ) / time; if (gWeatherType == WEATHER_SNOW) { - D_80127BB8.unk4 = (s32) ((s32) (arg3 - D_80127BB8.unk0) / arg5); - D_80127BB8.unk34 = (s32) ((s32) (arg4 - D_80127BB8.unk30) / arg5); - D_80127BB8.unk8 = arg3; - D_80127BB8.unk38 = arg4; - D_80127BB8.unk3C = arg5; + gWeather.intensityStep = (intensity - gWeather.intensity) / time; + gWeather.opacityStep = (opacity - gWeather.opacity) / time; + gWeather.intensityTarget = intensity; + gWeather.opacityTarget = opacity; + gWeather.shiftTime = time; } else { - D_80127BB8.unk0 = arg3; - D_80127BB8.unk30 = arg4; - D_80127BB8.unk3C = 0; - func_800AD2C4(arg3 + 1, arg4 + 1, (f32) arg5 / 60.0f); + gWeather.intensity = intensity; + gWeather.opacity = opacity; + gWeather.shiftTime = 0; + rain_set(intensity + 1, opacity + 1, time / 60.0f); } } } @@ -384,8 +400,8 @@ void changeWeather(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5) { * The root function for handling all weather. * Decide whether to perform rain or snow logic, execute it, then set it to render right after. */ -void process_weather(Gfx **currDisplayList, MatrixS **currHudMat, Vertex **currHudVerts, TriangleList **currHudTris, - s32 updateRate) { +void weather_update(Gfx **currDisplayList, MatrixS **currHudMat, Vertex **currHudVerts, TriangleList **currHudTris, + s32 updateRate) { UNUSED s32 unused; gCurrWeatherDisplayList = *currDisplayList; gCurrWeatherMatrix = *currHudMat; @@ -394,34 +410,35 @@ void process_weather(Gfx **currDisplayList, MatrixS **currHudMat, Vertex **currH gWeatherCamera = get_active_camera_segment(); gWeatherCameraMatrix = get_camera_matrix(); if (gWeatherType != WEATHER_SNOW) { - handle_weather_rain(updateRate); + rain_update(updateRate); } else { - if (D_80127BB8.unk3C > 0) { - if (updateRate < D_80127BB8.unk3C) { - D_80127BB8.unk0 += D_80127BB8.unk4 * updateRate; - D_80127BB8.unkC += D_80127BB8.unk10 * updateRate; - D_80127BB8.unk18 += D_80127BB8.unk1C * updateRate; - D_80127BB8.unk24 += D_80127BB8.unk28 * updateRate; - D_80127BB8.unk30 += D_80127BB8.unk34 * updateRate; - D_80127BB8.unk3C -= updateRate; + if (gWeather.shiftTime > 0) { + if (updateRate < gWeather.shiftTime) { + gWeather.intensity += gWeather.intensityStep * updateRate; + gWeather.velX += gWeather.velXStep * updateRate; + gWeather.velY += gWeather.velYStep * updateRate; + gWeather.velZ += gWeather.velZStep * updateRate; + gWeather.opacity += gWeather.opacityStep * updateRate; + gWeather.shiftTime -= updateRate; } else { - D_80127BB8.unk0 = D_80127BB8.unk8; - D_80127BB8.unkC = D_80127BB8.unk14; - D_80127BB8.unk18 = D_80127BB8.unk20; - D_80127BB8.unk24 = D_80127BB8.unk2C; - D_80127BB8.unk30 = D_80127BB8.unk38; - D_80127BB8.unk3C = 0; + gWeather.intensity = gWeather.intensityTarget; + gWeather.velX = gWeather.velXTarget; + gWeather.velY = gWeather.velYTarget; + gWeather.velZ = gWeather.velZTarget; + gWeather.opacity = gWeather.opacityTarget; + gWeather.shiftTime = 0; } } - D_80127BB4 = (D_80127BB0 * D_80127BB8.unk0) >> (unused = 16); - D_80127BF8.unk4 = (D_80127BF8.unk0 + ((D_80127BF8.unk2 - D_80127BF8.unk0) * D_80127BB8.unk30)) >> (unused = 16); + gSnowParticleCount = (gSnowDensity * gWeather.intensity) >> (unused = 16); + gSnowPlane.current = + (gSnowPlane.near + ((gSnowPlane.far - gSnowPlane.near) * gWeather.opacity)) >> (unused = 16); - func_800AC0C8(updateRate); - if ((D_80127BB4 > 0) && (D_80127BF8.unk4 < D_80127BF8.unk0)) { - D_800E2904 = D_800E2914[D_80127C08]; - func_800AC21C(); // Both of these funcs are needed to render. - render_falling_snow(); - D_80127C08 = 1 - D_80127C08; + snow_update(updateRate); + if (gSnowParticleCount > 0 && gSnowPlane.current < gSnowPlane.near) { + gSnowVerts = gSnowVertexData[gSnowVertexFlip]; + snow_vertices(); + snow_render(); + gSnowVertexFlip = 1 - gSnowVertexFlip; } } *currDisplayList = gCurrWeatherDisplayList; @@ -430,64 +447,71 @@ void process_weather(Gfx **currDisplayList, MatrixS **currHudMat, Vertex **currH *currHudTris = gCurrWeatherTriList; } -// This is the snow physics that makes it move -void func_800AC0C8(s32 updateRate) { - unk800E2850_unk0 *temp_v1; +/** + * Update the positions of all the snow particles. + * Make any far particles wrap around the boundaries. + */ +void snow_update(s32 updateRate) { + Vec3i *snowPos; s32 i; - for (i = 0; i < D_80127BB0; i++) { - temp_v1 = &D_800E28D8.unk0[D_800E28D4[i].unkF]; - D_800E28D4[i].unk0 = - ((((temp_v1->unk0 + (D_80127BB8.unkC * 2)) * updateRate) >> 1) + D_800E28D4[i].unk0) & D_800E28D8.unk18; - D_800E28D4[i].unk4 = - ((((temp_v1->unk4 + (D_80127BB8.unk18 * 2)) * updateRate) >> 1) + D_800E28D4[i].unk4) & D_800E28D8.unk1C; - D_800E28D4[i].unk8 = - ((((temp_v1->unk8 + (D_80127BB8.unk24 * 2)) * updateRate) >> 1) + D_800E28D4[i].unk8) & D_800E28D8.unk20; - D_800E28D4[i].unkF++; - if (D_800E28D4[i].unkF >= D_800E28D8.unk4) { - D_800E28D4[i].unkF -= D_800E28D8.unk4; + for (i = 0; i < gSnowDensity; i++) { + snowPos = &gSnowGfx.pos[gSnowPhysics[i].index]; + gSnowPhysics[i].x_position = + ((((snowPos->x + (gWeather.velX * 2)) * updateRate) >> 1) + gSnowPhysics[i].x_position) & gSnowGfx.radiusX; + gSnowPhysics[i].y_position = + ((((snowPos->y + (gWeather.velY * 2)) * updateRate) >> 1) + gSnowPhysics[i].y_position) & gSnowGfx.radiusY; + gSnowPhysics[i].z_position = + ((((snowPos->z + (gWeather.velZ * 2)) * updateRate) >> 1) + gSnowPhysics[i].z_position) & gSnowGfx.radiusZ; + gSnowPhysics[i].index++; + if (gSnowPhysics[i].index >= gSnowGfx.size) { + gSnowPhysics[i].index -= gSnowGfx.size; } } } -void func_800AC21C(void) { +/** + * Update the position of each vertex for snow. + * This starts from the camera position then + */ +void snow_vertices(void) { s16 pos[3]; - f32 sp64[3]; + f32 posF[3]; s32 i; Vertex *verts; - s32 sp58; - s32 sp54; - s32 sp50; + s32 camX; + s32 camy; + s32 camz; - sp58 = (s32) (gWeatherCamera->trans.x_position * 65536.0f); - sp54 = (s32) (gWeatherCamera->trans.y_position * 65536.0f); - sp50 = (s32) (gWeatherCamera->trans.z_position * 65536.0f); - D_800E2908 = 0; - verts = D_800E2904; - for (i = 0; i < D_80127BB4; i++) { - sp64[0] = (f32) (((D_800E28D4[i].unk0 - sp58) & D_800E28D8.unk18) + D_800E28D8.unkC) * (1.0f / 65536.0f); - sp64[1] = (f32) (((D_800E28D4[i].unk4 - sp54) & D_800E28D8.unk1C) + D_800E28D8.unk10) * (1.0f / 65536.0f); - sp64[2] = (f32) (((D_800E28D4[i].unk8 - sp50) & D_800E28D8.unk20) + D_800E28D8.unk14) * (1.0f / 65536.0f); - f32_matrix_dot(gWeatherCameraMatrix, (Matrix *) &sp64, (Matrix *) &sp64); - pos[2] = sp64[2]; - if ((pos[2] < D_80127BF8.unk0) && (D_80127BF8.unk4 < pos[2])) { - pos[0] = sp64[0]; - pos[1] = sp64[1]; - verts[0].x = pos[0] - D_800E28D8.unk24; - verts[0].y = pos[1] + D_800E28D8.unk26; + camX = gWeatherCamera->trans.x_position * 65536.0f; + camy = gWeatherCamera->trans.y_position * 65536.0f; + camz = gWeatherCamera->trans.z_position * 65536.0f; + gSnowVertCount = 0; + verts = gSnowVerts; + for (i = 0; i < gSnowParticleCount; i++) { + posF[0] = (((gSnowPhysics[i].x_position - camX) & gSnowGfx.radiusX) + gSnowGfx.offsetX) * (1.0f / 65536.0f); + posF[1] = (((gSnowPhysics[i].y_position - camy) & gSnowGfx.radiusY) + gSnowGfx.offsetY) * (1.0f / 65536.0f); + posF[2] = (((gSnowPhysics[i].z_position - camz) & gSnowGfx.radiusZ) + gSnowGfx.offsetZ) * (1.0f / 65536.0f); + f32_matrix_dot(gWeatherCameraMatrix, (Matrix *) &posF, (Matrix *) &posF); + pos[2] = posF[2]; + if (pos[2] < gSnowPlane.near && gSnowPlane.current < pos[2]) { + pos[0] = posF[0]; + pos[1] = posF[1]; + verts[0].x = pos[0] - gSnowGfx.vertOffsetW; + verts[0].y = pos[1] + gSnowGfx.vertOffsetH; verts[0].z = pos[2]; - verts[1].x = pos[0] + D_800E28D8.unk24; - verts[1].y = pos[1] + D_800E28D8.unk26; + verts[1].x = pos[0] + gSnowGfx.vertOffsetW; + verts[1].y = pos[1] + gSnowGfx.vertOffsetH; verts[1].z = pos[2]; - verts[2].x = pos[0] + D_800E28D8.unk24; - verts[2].y = pos[1] - D_800E28D8.unk26; + verts[2].x = pos[0] + gSnowGfx.vertOffsetW; + verts[2].y = pos[1] - gSnowGfx.vertOffsetH; verts[2].z = pos[2]; - verts[3].x = pos[0] - D_800E28D8.unk24; - verts[3].y = pos[1] - D_800E28D8.unk26; + verts[3].x = pos[0] - gSnowGfx.vertOffsetW; + verts[3].y = pos[1] - gSnowGfx.vertOffsetH; verts[3].z = pos[2]; verts += 4; - D_800E2908 += 4; - D_800E2910[D_800E2908 >> 2] = i; + gSnowVertCount += 4; + gSnowTriIndices[gSnowVertCount >> 2] = i; } } } @@ -495,29 +519,30 @@ void func_800AC21C(void) { /** * Load and execute the draw commands for the falling snowflakes, seen with snowy weather enabled. */ -void render_falling_snow(void) { +void snow_render(void) { s32 i; u32 mtx; u32 vtx; - if (D_800E28D8.unk8 != NULL) { - D_80127C00 = 4; - D_80127C04 = 2; - if (D_800E2908 >= 4) { + if (gSnowGfx.texture != NULL) { + gSnowVertOffset = 4; + gSnowTriCount = 2; + if (gSnowVertCount >= 4) { i = 0; mtx = (u32) get_projection_matrix_s16(); gSPMatrix(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(mtx ^ 0), G_MTX_DKR_INDEX_0); gDkrInsertMatrix(gCurrWeatherDisplayList++, G_MTX_DKR_INDEX_0, 0); - load_and_set_texture_no_offset(&gCurrWeatherDisplayList, D_800E28D8.unk8, RENDER_Z_COMPARE); - while (i + D_80127C00 < D_800E2908) { - vtx = (u32) &D_800E2904[i]; - gSPVertexDKR(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(vtx), D_80127C00, 0); - gSPPolygon(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(D_800E290C), D_80127C04, 1); - i += D_80127C00; + load_and_set_texture_no_offset(&gCurrWeatherDisplayList, gSnowGfx.texture, RENDER_Z_COMPARE); + while (i + gSnowVertOffset < gSnowVertCount) { + vtx = (u32) &gSnowVerts[i]; + gSPVertexDKR(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(vtx), gSnowVertOffset, 0); + gSPPolygon(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(gSnowTriangles), gSnowTriCount, 1); + i += gSnowVertOffset; } - vtx = (u32) &D_800E2904[i]; - gSPVertexDKR(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(vtx), (D_800E2908 - i), 0); - gSPPolygon(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(D_800E290C), ((s32) (D_800E2908 - i) >> 1), 1); + vtx = (u32) &gSnowVerts[i]; + gSPVertexDKR(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(vtx), (gSnowVertCount - i), 0); + gSPPolygon(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(gSnowTriangles), ((s32) (gSnowVertCount - i) >> 1), + 1); } } } @@ -610,9 +635,13 @@ void lensflare_init(Object *obj) { gLensFlarePos.z = -gLensFlarePos.z; } +/** + * Based on face direction, start rendering lens flare effects on screen. + * Each element is shifted based on the preset to create the effect of the sun shining in your face. +*/ void lensflare_render(Gfx **dList, MatrixS **mats, Vertex **verts, ObjectSegment *segment) { u16 height; - f32 pep; + f32 mag2; UNUSED s32 pad; Vec3f pos[2]; f32 magnitude; @@ -656,7 +685,7 @@ void lensflare_render(Gfx **dList, MatrixS **mats, Vertex **verts, ObjectSegment lensFlareData = gLensFlareSet2; } if (lensFlareData != NULL) { - while ((lensFlareData->count > 0)) { + while (lensFlareData->count > 0) { trans.x_position = pos[0].x; trans.y_position = pos[0].y; trans.z_position = pos[0].z; @@ -676,12 +705,12 @@ void lensflare_render(Gfx **dList, MatrixS **mats, Vertex **verts, ObjectSegment } } if (i == 1) { - pep = (((pos[1].x * gLensFlarePos.x) + (pos[1].y * gLensFlarePos.y)) + - (pos[1].z * ((0, gLensFlarePos.z)))) * - 2; - pos[1].x = (pep * gLensFlarePos.x) - pos[1].x; - pos[1].y = (pep * gLensFlarePos.y) - pos[1].y; - pos[1].z = (pep * gLensFlarePos.z) - pos[1].z; + mag2 = (((pos[1].x * gLensFlarePos.x) + (pos[1].y * gLensFlarePos.y)) + + (pos[1].z * ((0, gLensFlarePos.z)))) * + 2; + pos[1].x = (mag2 * gLensFlarePos.x) - pos[1].x; + pos[1].y = (mag2 * gLensFlarePos.y) - pos[1].y; + pos[1].z = (mag2 * gLensFlarePos.z) - pos[1].z; } } width = get_video_width_and_height_as_s32(); @@ -764,18 +793,22 @@ void lensflare_override(ObjectSegment *cameraSegment) { } } -void func_800AD144(s32 arg0, s32 arg1) { - gLightningFrequency = arg0; - D_800E2C64 = 0; - D_800E2C68 = gLightningFrequency; - D_800E2C6C = arg1; - D_800E2C70 = 0; - D_800E2C74 = D_800E2C6C; - D_800E2C78 = 0; +/** + * Set all rain related values to the default. + * Load the overlay and splash textures then set the initial opacity and lightning frequency. + */ +void rain_init(s32 intensity, s32 opacity) { + gLightningFrequency = intensity; + gLightningFrequencyStep = 0; + gLightningFrequencyTarget = gLightningFrequency; + gRainOpacity = opacity; + gRainOpacityStep = 0; + gRainOpacityTarget = gRainOpacity; + gRainHiddenTimer = 0; gLightningTimer = 0; gThunderTimer = 0; - D_800E2C84 = 0; - D_800E2C90 = 0; + gRainSplashDelay = 0; + gRainVertexFlip = 0; gRainGfx[0].tex = load_texture(gWeatherAssetTable[1]); gRainGfx[1].tex = load_texture(gWeatherAssetTable[1]); gRainSplashGfx = (Sprite *) func_8007C12C(gWeatherAssetTable[3], 0); @@ -810,15 +843,22 @@ void free_rain_memory(void) { gWeatherType = WEATHER_SNOW; } -void func_800AD2C4(s32 arg0, s32 arg1, f32 arg2) { - D_800E2C78 = osTvType == TV_TYPE_PAL ? 50.0 * arg2 : 60.0 * arg2; - D_800E2C68 = arg0; - D_800E2C64 = (D_800E2C68 - gLightningFrequency) / D_800E2C78; - D_800E2C74 = arg1; - D_800E2C70 = (D_800E2C74 - D_800E2C6C) / D_800E2C78; +/** + * Sets the fade times for the rain visuals and how long to take to fade in. + * The game will slowly ease into the intended values. + */ +void rain_set(s32 lightningFrequency, s32 opacity, f32 time) { + gRainHiddenTimer = osTvType == TV_TYPE_PAL ? 50.0 * time : 60.0 * time; + gLightningFrequencyTarget = lightningFrequency; + gLightningFrequencyStep = (gLightningFrequencyTarget - gLightningFrequency) / gRainHiddenTimer; + gRainOpacityTarget = opacity; + gRainOpacityStep = (gRainOpacityTarget - gRainOpacity) / gRainHiddenTimer; } -void func_800AD40C(void) { +/** + * If it's currently raining, update the fog levels to match the intensity of the storm. + */ +void rain_fog(void) { s32 a, b; if (gWeatherType != WEATHER_SNOW && get_viewport_count() == VIEWPORTS_COUNT_1_PLAYER) { a = ((gLightningFrequency * -38) >> 16) + 1018; @@ -827,47 +867,54 @@ void func_800AD40C(void) { } } -// Unused. -void func_800AD4AC(s32 arg0) { - D_800E2C6C = arg0; +/** + * Set the current opacity of the rain overlay. Ranges from 0 - 0xFFFF. + */ +UNUSED void rain_opacity_set(s32 opacity) { + gRainOpacity = opacity; } /** * When active, (Single player only) Call all the functions related to the behaviour and rendering of * rain, and if necessary, thunder. */ -void handle_weather_rain(s32 updateRate) { +void rain_update(s32 updateRate) { s32 i; - if ((get_viewport_count() == VIEWPORTS_COUNT_1_PLAYER) && (gWeatherType != WEATHER_SNOW)) { - if (D_800E2C78 > 0) { - if (updateRate < D_800E2C78) { - D_800E2C78 -= updateRate; - gLightningFrequency += D_800E2C64 * updateRate; - D_800E2C6C += D_800E2C70 * updateRate; + if (get_viewport_count() == VIEWPORTS_COUNT_1_PLAYER && gWeatherType != WEATHER_SNOW) { + if (gRainHiddenTimer > 0) { + if (updateRate < gRainHiddenTimer) { + gRainHiddenTimer -= updateRate; + gLightningFrequency += gLightningFrequencyStep * updateRate; + gRainOpacity += gRainOpacityStep * updateRate; } else { - D_800E2C78 = 0; - gLightningFrequency = D_800E2C68; - D_800E2C6C = D_800E2C74; + gRainHiddenTimer = 0; + gLightningFrequency = gLightningFrequencyTarget; + gRainOpacity = gRainOpacityTarget; } } - handle_rain_sound(updateRate); - render_rain_splashes(updateRate); - handle_rain_lightning(updateRate); - if (gLightningFrequency >= 256) { + rain_sound(updateRate); + rain_render_splashes(updateRate); + rain_lightning(updateRate); + if (gLightningFrequency > 255) { set_ortho_matrix_view(&gCurrWeatherDisplayList, &gCurrWeatherMatrix); for (i = 0; i < 2; i++) { render_rain_overlay(&gRainGfx[i], updateRate); } gDPSetPrimColor(gCurrWeatherDisplayList++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(gCurrWeatherDisplayList++, 255, 255, 255, 0); - reset_render_settings(&gCurrWeatherDisplayList); // Pipesync and some stuff idk yet - viewport_reset(&gCurrWeatherDisplayList); // Looks to create a viewport scissor. + reset_render_settings(&gCurrWeatherDisplayList); + viewport_reset(&gCurrWeatherDisplayList); } } } -void render_rain_splashes(s32 updateRate) { +/** + * If it's raining hard enough, then start generating rain splash particles. + * Set position to be a random spot near the camera and account for wave height. + * Every existing splash particle gets rendered as a billboard. +*/ +void rain_render_splashes(s32 updateRate) { s32 temp_t0; s32 i; f32 var_f2; @@ -884,16 +931,16 @@ void render_rain_splashes(s32 updateRate) { setEnvColor = TRUE; if (gRainSplashGfx != NULL) { - temp_t0 = (((D_800E2C6C >> 2) * gLightningFrequency) >> 14); + temp_t0 = ((gRainOpacity >> 2) * gLightningFrequency) >> 14; if (temp_t0 > 0x4000) { racer = get_racer_object_by_port(0); - D_800E2C84 -= updateRate; - if (D_800E2C84 <= 0) { + gRainSplashDelay -= updateRate; + if (gRainSplashDelay <= 0) { i = 0; if (racer != NULL) { firstIndexWithoutFlags = -1; - for (; i < ARRAY_COUNT(D_800E2B4C) && firstIndexWithoutFlags < 0; i++) { - if (D_800E2B4C[i].trans.flags == OBJ_FLAGS_NONE) { + for (; i < ARRAY_COUNT(gRainSplashSegments) && firstIndexWithoutFlags < 0; i++) { + if (gRainSplashSegments[i].trans.flags == OBJ_FLAGS_NONE) { firstIndexWithoutFlags = i; } } @@ -937,16 +984,17 @@ void render_rain_splashes(s32 updateRate) { } } if (firstIndexWithoutFlags >= 0) { - D_800E2B4C[firstIndexWithoutFlags].trans.x_position = xPos; - D_800E2B4C[firstIndexWithoutFlags].trans.y_position = waterProps[waveIndex]->waveHeight; - D_800E2B4C[firstIndexWithoutFlags].trans.z_position = zPos; - D_800E2B4C[firstIndexWithoutFlags].animFrame = 0; - D_800E2B4C[firstIndexWithoutFlags].trans.flags = OBJ_FLAGS_UNK_0001; - D_800E2B4C[firstIndexWithoutFlags].unk1A = + gRainSplashSegments[firstIndexWithoutFlags].trans.x_position = xPos; + gRainSplashSegments[firstIndexWithoutFlags].trans.y_position = + waterProps[waveIndex]->waveHeight; + gRainSplashSegments[firstIndexWithoutFlags].trans.z_position = zPos; + gRainSplashSegments[firstIndexWithoutFlags].animFrame = 0; + gRainSplashSegments[firstIndexWithoutFlags].trans.flags = OBJ_FLAGS_UNK_0001; + gRainSplashSegments[firstIndexWithoutFlags].opacity = get_random_number_from_range(128, (temp_t0 >> 10) + 191); - D_800E2C84 = (D_800E2C84 - (temp_t0 >> 10)) + 64; - if (D_800E2C84 < 0) { - D_800E2C84 = 0; + gRainSplashDelay = (gRainSplashDelay - (temp_t0 >> 10)) + 64; + if (gRainSplashDelay < 0) { + gRainSplashDelay = 0; } } } @@ -954,20 +1002,22 @@ void render_rain_splashes(s32 updateRate) { } } } - for (i = 0; i < ARRAY_COUNT(D_800E2B4C); i++) { - if (D_800E2B4C[i].trans.flags != 0) { - D_800E2B4C[i].animFrame += updateRate * 16; - if (D_800E2B4C[i].animFrame > 255) { - D_800E2B4C[i].trans.flags = 0; + for (i = 0; i < ARRAY_COUNT(gRainSplashSegments); i++) { + if (gRainSplashSegments[i].trans.flags != 0) { + gRainSplashSegments[i].animFrame += updateRate * 16; + if (gRainSplashSegments[i].animFrame > 255) { + gRainSplashSegments[i].trans.flags = 0; } else { if (setEnvColor) { setEnvColor = FALSE; gDPSetEnvColor(gCurrWeatherDisplayList++, 255, 255, 255, 0); } - gDPSetPrimColor(gCurrWeatherDisplayList++, 0, 0, 192, 192, 255, (D_800E2B4C[i].unk1A)); + gDPSetPrimColor(gCurrWeatherDisplayList++, 0, 0, 192, 192, 255, gRainSplashSegments[i].opacity); render_sprite_billboard(&gCurrWeatherDisplayList, &gCurrWeatherMatrix, &gCurrWeatherVertexList, - (Object *) &D_800E2B4C[i], (unk80068514_arg4 *) gRainSplashGfx, 0x10E); + (Object *) &gRainSplashSegments[i], (unk80068514_arg4 *) gRainSplashGfx, + RENDER_Z_COMPARE | RENDER_SEMI_TRANSPARENT | RENDER_FOG_ACTIVE | + RENDER_Z_UPDATE); } } } @@ -981,11 +1031,11 @@ void render_rain_splashes(s32 updateRate) { * Set a second timer, that then counts down to zero and creates a flash of lightning in the form of a screen * transition. Afterwards, set the thunder timer back. */ -void handle_rain_lightning(s32 updateRate) { +void rain_lightning(s32 updateRate) { if (gThunderTimer > 0) { gThunderTimer -= updateRate; if (gThunderTimer <= 0) { - if (D_800E2C6C > 0x8000 && check_fadeout_transition() == 0) { + if (gRainOpacity > 0x8000 && check_fadeout_transition() == 0) { transition_begin(&gThunderTransition); } sound_play(SOUND_LIGHTNING, NULL); @@ -994,18 +1044,18 @@ void handle_rain_lightning(s32 updateRate) { } else if (gLightningFrequency >= 48000) { if (gLightningTimer > 0) { gLightningTimer -= updateRate; - return; + } else { + sound_play(SOUND_THUNDER, NULL); + gThunderTimer = 600 - ((gLightningFrequency + -48000) >> 5); + gLightningTimer = get_random_number_from_range(900, 1140) - ((gLightningFrequency + -48000) >> 5); } - sound_play(SOUND_THUNDER, NULL); - gThunderTimer = 600 - ((s32) (gLightningFrequency + -48000) >> 5); - gLightningTimer = get_random_number_from_range(900, 1140) - ((s32) (gLightningFrequency + -48000) >> 5); } } /** * Emit looping rain sound, using the camera position and direction as reference. */ -void handle_rain_sound(UNUSED s32 updateRate) { +void rain_sound(UNUSED s32 updateRate) { f32 xPos; f32 yPos; f32 zPos; @@ -1027,7 +1077,7 @@ void handle_rain_sound(UNUSED s32 updateRate) { } #ifdef NON_EQUIVALENT -void render_rain_overlay(unk800E2C2C *arg0, s32 arg1) { +void render_rain_overlay(RainGfxData *arg0, s32 arg1) { f32 zSins; Triangle *sp64; f32 zCoss; @@ -1051,7 +1101,7 @@ void render_rain_overlay(unk800E2C2C *arg0, s32 arg1) { arg0->unk0 = (normalise_time(arg0->unk8 * arg1) + arg0->unk0) & temp_v1; arg0->unk2 = (normalise_time(arg0->unkA * arg1) + arg0->unk2) & temp_t9; horizontal = (arg0->unk4 * horizontal) >> 8; - opacity = (arg0->unk16 * (((D_800E2C6C >> 2) * gLightningFrequency) >> 14)) >> 16; + opacity = (arg0->opacity * (((gRainOpacity >> 2) * gLightningFrequency) >> 14)) >> 16; if (opacity > 0) { altVertical = arg0->unk2; vertical = ((arg0->unk6 * vertical) >> 8) + arg0->unk2; @@ -1059,7 +1109,7 @@ void render_rain_overlay(unk800E2C2C *arg0, s32 arg1) { horizontal += altHorizontal; zSins = sins_f(gWeatherCamera->trans.z_rotation); zCoss = coss_f(gWeatherCamera->trans.z_rotation); - verts = &D_800E2AAC[D_800E2C90]; + verts = &gRainVertices[gRainVertexFlip]; verts[0].x = ((D_800E2A8C * zCoss) - (D_800E2A9C * zSins)); verts[0].y = ((D_800E2A8C * zSins) + (D_800E2A9C * zCoss)); verts[1].x = ((D_800E2A9C * zCoss) - (D_800E2A9C * zSins)); @@ -1088,10 +1138,10 @@ void render_rain_overlay(unk800E2C2C *arg0, s32 arg1) { COLOUR_RGBA32(arg0->primitiveRed, arg0->primitiveGreen, arg0->primitiveBlue, opacity), COLOUR_RGBA32(arg0->environmentRed, arg0->environmentGreen, arg0->environmentBlue, 0)); gDkrDmaDisplayList(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(tex->cmd), tex->numberOfCommands); - gSPVertexDKR(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(&D_800E2AAC[D_800E2C90]), 4, 0); + gSPVertexDKR(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(&gRainVertices[gRainVertexFlip]), 4, 0); gSPPolygon(gCurrWeatherDisplayList++, OS_PHYSICAL_TO_K0(gCurrWeatherTriList), 2, 1); gDPPipeSync(gCurrWeatherDisplayList++); - D_800E2C90 = (D_800E2C90 + 4) & 0xF; + gRainVertexFlip = (gRainVertexFlip + 4) & 0xF; gCurrWeatherTriList = sp64; } } diff --git a/src/weather.h b/src/weather.h index c713872c..2bac675f 100644 --- a/src/weather.h +++ b/src/weather.h @@ -7,32 +7,25 @@ typedef enum WeatherType { WEATHER_SNOW, - WEATHER_RAIN, - WEATHER_UNK2 + WEATHER_RAIN } WeatherType; -typedef struct unk800E2850_unk0 { - s32 unk0; - s32 unk4; - s32 unk8; -} unk800E2850_unk0; - /* Size: 0x2C Bytes */ -typedef struct unk800E2850 { - unk800E2850_unk0 *unk0; - s32 unk4; - TextureHeader *unk8; - s32 unkC; - s32 unk10; - s32 unk14; - s32 unk18; - s32 unk1C; - s32 unk20; - s16 unk24; - s16 unk26; - s16 unk28; - s16 unk2A; -} unk800E2850; +typedef struct SnowGfxData { + Vec3i *pos; + s32 size; + TextureHeader *texture; + s32 offsetX; + s32 offsetY; + s32 offsetZ; + s32 radiusX; + s32 radiusY; + s32 radiusZ; + s16 vertOffsetW; + s16 vertOffsetH; + s16 vertWidth; + s16 vertHeight; +} SnowGfxData; /* Size: 0x10 Bytes */ typedef struct LensFlareData { @@ -43,14 +36,14 @@ typedef struct LensFlareData { } LensFlareData; /* Size: 0x1C Bytes */ -typedef struct ObjectSegment2 { +typedef struct RainPosData { ObjectTransform trans; s16 animFrame; - s16 unk1A; -} ObjectSegment2; + s16 opacity; +} RainPosData; /* Size: 0x18 Bytes */ -typedef struct unk800E2C2C { +typedef struct RainGfxData { s16 unk0; //tri - u? s16 unk2; //tri - v? s16 unk4; @@ -64,73 +57,68 @@ typedef struct unk800E2C2C { u8 environmentRed; u8 environmentGreen; u8 environmentBlue; - u8 unk16; - u8 unk17; -} unk800E2C2C; + u8 opacity; + // pad +} RainGfxData; typedef struct { - s16 unk0; - s16 unk2; - //s16 unk4; - s32 unk4; -} unk80127BF8; + s16 near; + s16 far; + s32 current; +} SnowLimits; -typedef struct unk800E28D4 { - s32 unk0; - s32 unk4; - s32 unk8; - u8 unkC; - u8 unkD; - u8 unkE; - u8 unkF; -} unk800E28D4; +typedef struct SnowPosData { + s32 x_position; + s32 y_position; + s32 z_position; + u8 unused_C; + u8 unused_D; + u8 unused_E; + u8 index; +} SnowPosData; -typedef struct RainData { - s32 unk0; - s32 unk4; - s32 unk8; - s32 unkC; - s32 unk10; - s32 unk14; - s32 unk18; - s32 unk1C; - s32 unk20; - s32 unk24; - s32 unk28; - s32 unk2C; - s32 unk30; - s32 unk34; - s32 unk38; - s32 unk3C; -} RainData; +typedef struct WeatherData { + s32 intensity; + s32 intensityStep; + s32 intensityTarget; + s32 velX; + s32 velXStep; + s32 velXTarget; + s32 velY; + s32 velYStep; + s32 velYTarget; + s32 velZ; + s32 velZStep; + s32 velZTarget; + s32 opacity; + s32 opacityStep; + s32 opacityTarget; + s32 shiftTime; +} WeatherData; -void set_weather_limits(s16 arg0, s16 arg1); +void weather_clip_planes(s16 arg0, s16 arg1); void lensflare_remove(Object *obj); void lensflare_override_add(Object *obj); void free_rain_memory(void); -void func_800AD2C4(s32 arg0, s32 arg1, f32 arg2); -void func_800AD40C(void); -void handle_weather_rain(s32 updateRate); -void handle_rain_sound(s32 updateRate); -void render_rain_splashes(s32 updateRate); -void handle_rain_lightning(s32 updateRate); -void render_rain_overlay(unk800E2C2C*, s32); -void process_weather(Gfx **currDisplayList, MatrixS **currHudMat, Vertex **currHudVerts, TriangleList **currHudTris, s32 updateRate); -void render_falling_snow(void); -void free_weather_memory(void); -void changeWeather(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5); +void rain_set(s32 arg0, s32 arg1, f32 arg2); +void rain_fog(void); +void rain_update(s32 updateRate); +void rain_sound(s32 updateRate); +void rain_render_splashes(s32 updateRate); +void rain_lightning(s32 updateRate); +void render_rain_overlay(RainGfxData*, s32); +void weather_update(Gfx **currDisplayList, MatrixS **currHudMat, Vertex **currHudVerts, TriangleList **currHudTris, s32 updateRate); +void snow_render(void); +void weather_free(void); +void weather_set(s32 arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5); void lensflare_override(ObjectSegment *cameraSegment); -void func_800AC0C8(s32 updateRate); -void func_800ABB34(void); -void func_800AD144(s32 arg0, s32 arg1); - -s32 coss(s16); -s32 sins(s16); -void init_weather(void); -void f32_matrix_dot(Matrix *arg0, Matrix *arg1, Matrix *arg2); -void func_800AC21C(void); +void snow_update(s32 updateRate); +void snow_init(void); +void rain_init(s32 arg0, s32 arg1); +void weather_init(void); +void snow_vertices(void); void lensflare_init(Object *); void lensflare_render(Gfx**, MatrixS**, Vertex**, ObjectSegment*); -void func_800AB4A8(s32 weatherType, s32 weatherEnable, s32 velX, s32 velY, s32 velZ, s32 intensity, s32 opacity); +void weather_reset(s32 weatherType, s32 weatherEnable, s32 velX, s32 velY, s32 velZ, s32 intensity, s32 opacity); #endif diff --git a/tools/ido-static-recomp b/tools/ido-static-recomp index d6dd7fde..461f6b5f 160000 --- a/tools/ido-static-recomp +++ b/tools/ido-static-recomp @@ -1 +1 @@ -Subproject commit d6dd7fdea26cfe89dd01d7545618d4a9ae4f690a +Subproject commit 461f6b5f14606655bc0abd1c92f2508f60b1417c