mirror of
https://github.com/HarbourMasters/2ship2harkinian.git
synced 2024-11-28 00:30:37 +00:00
SCHEDULE_TIME
(#1438)
* SCHEDULE_CALC_TIME_ALT * add s32 cast to avoid f32 -> u16 direct cast * SCHEDULE_TIME * remove the alts * Update explanation about the script
This commit is contained in:
parent
425238fd5d
commit
ec86f10b0f
@ -28,10 +28,13 @@
|
||||
*/
|
||||
|
||||
// Macro to convert the time format used in the save struct into the format used in Schedule
|
||||
#define SCHEDULE_CONVERT_TIME(time) ((u16)((time) - 0x10000 / 360 * 90))
|
||||
#define SCHEDULE_CONVERT_TIME(time) ((s32)((time) - 0x10000 / 360 * 90))
|
||||
|
||||
#define SCHEDULE_TIME(hour, minute) SCHEDULE_CONVERT_TIME((((hour)*60.0f) + (minute)) * (0x10000 / 60 / 24.0f))
|
||||
|
||||
#define SCHEDULE_TIME_NOW SCHEDULE_CONVERT_TIME(gSaveContext.save.time)
|
||||
|
||||
typedef enum {
|
||||
typedef enum ScheduleCommandId {
|
||||
/* 0x00 */ SCHEDULE_CMD_ID_CHECK_FLAG_S, // Checks if a weekEventReg flag is set and branches if so, short range branch
|
||||
/* 0x01 */ SCHEDULE_CMD_ID_CHECK_FLAG_L, // Checks if a weekEventReg flag is set and branches if so, long range branch
|
||||
/* 0x02 */ SCHEDULE_CMD_ID_CHECK_TIME_RANGE_S, // Checks if the current time is within the range of the two provided times and branches if so, short range branch
|
||||
|
@ -702,9 +702,35 @@ s32 Environment_IsSceneUpsideDown(PlayState* play) {
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdateSun.s")
|
||||
|
||||
void func_800F88C4(u16 weekEventFlag);
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F88C4.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F8970.s")
|
||||
void func_800F8970(void) {
|
||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_27_40) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(9, 31))) {
|
||||
SET_WEEKEVENTREG(WEEKEVENTREG_27_40);
|
||||
func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_SOUTH_UPPER_CLOCKTOWN);
|
||||
}
|
||||
|
||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_27_80) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(10, 3))) {
|
||||
SET_WEEKEVENTREG(WEEKEVENTREG_27_80);
|
||||
func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_NORTH_CLOCKTOWN);
|
||||
}
|
||||
|
||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_28_01) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(10, 35))) {
|
||||
SET_WEEKEVENTREG(WEEKEVENTREG_28_01);
|
||||
func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_EAST_UPPER_CLOCKTOWN);
|
||||
}
|
||||
|
||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_28_02) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(10, 53))) {
|
||||
SET_WEEKEVENTREG(WEEKEVENTREG_28_02);
|
||||
func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_EAST_LOWER_CLOCKTOWN);
|
||||
}
|
||||
|
||||
if (!CHECK_WEEKEVENTREG(WEEKEVENTREG_28_04) && (SCHEDULE_TIME_NOW >= SCHEDULE_TIME(11, 25))) {
|
||||
SET_WEEKEVENTREG(WEEKEVENTREG_28_04);
|
||||
func_800F88C4(WEEKEVENTREG_DEPOSITED_LETTER_TO_KAFEI_SOUTH_LOWER_CLOCKTOWN);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_UpdatePostmanEvents.s")
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
(temp) = (hour)*60.0f; \
|
||||
(temp) += (minute); \
|
||||
(dest) = (temp) * (0x10000 / 60 / 24.0f); \
|
||||
(dest) = SCHEDULE_CONVERT_TIME(dest);
|
||||
(dest) = SCHEDULE_CONVERT_TIME(dest)
|
||||
|
||||
s32 Schedule_CheckFlagS(PlayState* play, u8** script, ScheduleOutput* output) {
|
||||
ScheduleCmdCheckFlagS* cmd = (ScheduleCmdCheckFlagS*)*script;
|
||||
@ -239,34 +239,50 @@ s32 Schedule_BranchL(PlayState* play, u8** script, ScheduleOutput* output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static s32 (*sScheduleCmdFuncs[])(PlayState*, u8**, ScheduleOutput*) = {
|
||||
Schedule_CheckFlagS, Schedule_CheckFlagL, Schedule_CheckTimeRangeS, Schedule_CheckTimeRangeL,
|
||||
Schedule_ReturnValueL, Schedule_ReturnNone, Schedule_ReturnEmpty, Schedule_Nop,
|
||||
Schedule_CheckMiscS, Schedule_ReturnValueS, Schedule_CheckNotInSceneS, Schedule_CheckNotInSceneL,
|
||||
Schedule_CheckNotInDayS, Schedule_CheckNotInDayL, Schedule_ReturnTime, Schedule_CheckBeforeTimeS,
|
||||
Schedule_CheckBeforeTimeL, Schedule_BranchS, Schedule_BranchL,
|
||||
typedef s32 (*ScheduleCmdFunc)(PlayState*, u8**, ScheduleOutput*);
|
||||
|
||||
static ScheduleCmdFunc sScheduleCmdFuncs[] = {
|
||||
Schedule_CheckFlagS, // SCHEDULE_CMD_ID_CHECK_FLAG_S
|
||||
Schedule_CheckFlagL, // SCHEDULE_CMD_ID_CHECK_FLAG_L
|
||||
Schedule_CheckTimeRangeS, // SCHEDULE_CMD_ID_CHECK_TIME_RANGE_S
|
||||
Schedule_CheckTimeRangeL, // SCHEDULE_CMD_ID_CHECK_TIME_RANGE_L
|
||||
Schedule_ReturnValueL, // SCHEDULE_CMD_ID_RET_VAL_L
|
||||
Schedule_ReturnNone, // SCHEDULE_CMD_ID_RET_NONE
|
||||
Schedule_ReturnEmpty, // SCHEDULE_CMD_ID_RET_EMPTY
|
||||
Schedule_Nop, // SCHEDULE_CMD_ID_NOP
|
||||
Schedule_CheckMiscS, // SCHEDULE_CMD_ID_CHECK_MISC_S
|
||||
Schedule_ReturnValueS, // SCHEDULE_CMD_ID_RET_VAL_S
|
||||
Schedule_CheckNotInSceneS, // SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_S
|
||||
Schedule_CheckNotInSceneL, // SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_L
|
||||
Schedule_CheckNotInDayS, // SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_S
|
||||
Schedule_CheckNotInDayL, // SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_L
|
||||
Schedule_ReturnTime, // SCHEDULE_CMD_ID_RET_TIME
|
||||
Schedule_CheckBeforeTimeS, // SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_S
|
||||
Schedule_CheckBeforeTimeL, // SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_L
|
||||
Schedule_BranchS, // SCHEDULE_CMD_ID_BRANCH_S
|
||||
Schedule_BranchL, // SCHEDULE_CMD_ID_BRANCH_L
|
||||
};
|
||||
|
||||
static u8 sScheduleCmdSizes[] = {
|
||||
sizeof(ScheduleCmdCheckFlagS),
|
||||
sizeof(ScheduleCmdCheckFlagL),
|
||||
sizeof(ScheduleCmdCheckTimeRangeS),
|
||||
sizeof(ScheduleCmdCheckTimeRangeL),
|
||||
sizeof(ScheduleCmdReturnValueL),
|
||||
sizeof(ScheduleCmdBase),
|
||||
sizeof(ScheduleCmdBase),
|
||||
sizeof(ScheduleCmdNop),
|
||||
sizeof(ScheduleCmdCheckMiscS),
|
||||
sizeof(ScheduleCmdReturnValueS),
|
||||
sizeof(ScheduleCmdCheckNotInSceneS),
|
||||
sizeof(ScheduleCmdCheckNotInSceneL),
|
||||
sizeof(ScheduleCmdCheckNotInDayS),
|
||||
sizeof(ScheduleCmdCheckNotInDayL),
|
||||
sizeof(ScheduleCmdReturnTime),
|
||||
sizeof(ScheduleCmdCheckBeforeTimeS),
|
||||
sizeof(ScheduleCmdCheckBeforeTimeL),
|
||||
sizeof(ScheduleCmdBranchS),
|
||||
sizeof(ScheduleCmdBranchL),
|
||||
sizeof(ScheduleCmdCheckFlagS), // SCHEDULE_CMD_ID_CHECK_FLAG_S
|
||||
sizeof(ScheduleCmdCheckFlagL), // SCHEDULE_CMD_ID_CHECK_FLAG_L
|
||||
sizeof(ScheduleCmdCheckTimeRangeS), // SCHEDULE_CMD_ID_CHECK_TIME_RANGE_S
|
||||
sizeof(ScheduleCmdCheckTimeRangeL), // SCHEDULE_CMD_ID_CHECK_TIME_RANGE_L
|
||||
sizeof(ScheduleCmdReturnValueL), // SCHEDULE_CMD_ID_RET_VAL_L
|
||||
sizeof(ScheduleCmdBase), // SCHEDULE_CMD_ID_RET_NONE
|
||||
sizeof(ScheduleCmdBase), // SCHEDULE_CMD_ID_RET_EMPTY
|
||||
sizeof(ScheduleCmdNop), // SCHEDULE_CMD_ID_NOP
|
||||
sizeof(ScheduleCmdCheckMiscS), // SCHEDULE_CMD_ID_CHECK_MISC_S
|
||||
sizeof(ScheduleCmdReturnValueS), // SCHEDULE_CMD_ID_RET_VAL_S
|
||||
sizeof(ScheduleCmdCheckNotInSceneS), // SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_S
|
||||
sizeof(ScheduleCmdCheckNotInSceneL), // SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_L
|
||||
sizeof(ScheduleCmdCheckNotInDayS), // SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_S
|
||||
sizeof(ScheduleCmdCheckNotInDayL), // SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_L
|
||||
sizeof(ScheduleCmdReturnTime), // SCHEDULE_CMD_ID_RET_TIME
|
||||
sizeof(ScheduleCmdCheckBeforeTimeS), // SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_S
|
||||
sizeof(ScheduleCmdCheckBeforeTimeL), // SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_L
|
||||
sizeof(ScheduleCmdBranchS), // SCHEDULE_CMD_ID_BRANCH_S
|
||||
sizeof(ScheduleCmdBranchL), // SCHEDULE_CMD_ID_BRANCH_L
|
||||
};
|
||||
|
||||
s32 Schedule_RunScript(PlayState* play, u8* script, ScheduleOutput* output) {
|
||||
@ -275,7 +291,7 @@ s32 Schedule_RunScript(PlayState* play, u8* script, ScheduleOutput* output) {
|
||||
|
||||
do {
|
||||
size = sScheduleCmdSizes[*script];
|
||||
stop = (*sScheduleCmdFuncs[*script])(play, &script, output);
|
||||
stop = sScheduleCmdFuncs[*script](play, &script, output);
|
||||
script += size;
|
||||
} while (!stop);
|
||||
|
||||
|
@ -187,10 +187,12 @@ s32* func_80C22880(DmTag* this, PlayState* play) {
|
||||
|
||||
switch (this->unk_18E) {
|
||||
case 1:
|
||||
time = gSaveContext.save.time - 0x3FFC;
|
||||
if ((time >= 0xA54B) && (time < 0xB54A) && (gSaveContext.save.day == 2)) {
|
||||
this->msgEventCallback = func_80C227E8;
|
||||
return D_80C22BF0;
|
||||
time = SCHEDULE_TIME_NOW;
|
||||
if ((time >= SCHEDULE_TIME(21, 30)) && (time < SCHEDULE_TIME(23, 0))) {
|
||||
if (gSaveContext.save.day == 2) {
|
||||
this->msgEventCallback = func_80C227E8;
|
||||
return D_80C22BF0;
|
||||
}
|
||||
}
|
||||
return D_80C22C30;
|
||||
|
||||
@ -201,6 +203,7 @@ s32* func_80C22880(DmTag* this, PlayState* play) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -581,7 +581,7 @@ s32 func_80AF7BAC(EnPm* this) {
|
||||
|
||||
case 2:
|
||||
if (CHECK_WEEKEVENTREG(WEEKEVENTREG_89_40)) {
|
||||
D_801F4E78 = 0;
|
||||
D_801F4E78 = CLOCK_TIME(0, 0);
|
||||
this->unk_38C++;
|
||||
}
|
||||
break;
|
||||
|
@ -188,7 +188,7 @@ u16 EnSob1_GetTalkOption(EnSob1* this, PlayState* play) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
|
||||
if (this->shopType == BOMB_SHOP) {
|
||||
if ((gSaveContext.save.day == 1) && (gSaveContext.save.time >= CLOCK_TIME(6, 00))) {
|
||||
if ((gSaveContext.save.day == 1) && (gSaveContext.save.time >= CLOCK_TIME(6, 0))) {
|
||||
return 0x648;
|
||||
} else if (CHECK_WEEKEVENTREG(WEEKEVENTREG_RECOVERED_STOLEN_BOMB_BAG)) {
|
||||
return 0x649;
|
||||
|
@ -701,7 +701,7 @@ s32 func_80A3F9A4(EnTest3* this, PlayState* play) {
|
||||
}
|
||||
|
||||
s32 func_80A3F9E4(EnTest3* this, PlayState* play, struct_80A41828* arg2, ScheduleOutput* scheduleOutput) {
|
||||
scheduleOutput->time0 = SCHEDULE_TIME_NOW;
|
||||
scheduleOutput->time0 = (u16)SCHEDULE_TIME_NOW;
|
||||
scheduleOutput->time1 = (u16)(scheduleOutput->time0 + 70);
|
||||
func_80A40098(this, play, arg2, scheduleOutput);
|
||||
if (this->player.actor.xzDistToPlayer < 300.0f) {
|
||||
@ -729,7 +729,7 @@ s32 func_80A3FA58(EnTest3* this, PlayState* play) {
|
||||
if (cond || this->unk_D8A <= 0) {
|
||||
func_80A3F114(this, play);
|
||||
sp40.unk_1_0 = 5;
|
||||
scheduleOutput.time0 = SCHEDULE_TIME_NOW;
|
||||
scheduleOutput.time0 = (u16)SCHEDULE_TIME_NOW;
|
||||
scheduleOutput.time1 = (u16)(scheduleOutput.time0 + (cond ? 80 : 140));
|
||||
|
||||
func_80A40098(this, play, &sp40, &scheduleOutput);
|
||||
@ -805,7 +805,7 @@ s32 func_80A3FE20(EnTest3* this, PlayState* play) {
|
||||
if (D_80A41D64 == 0) {
|
||||
if (func_80A3E9DC(this, play)) {
|
||||
sp2C.unk_1_0 = 2;
|
||||
scheduleOutput.time0 = SCHEDULE_TIME_NOW;
|
||||
scheduleOutput.time0 = (u16)SCHEDULE_TIME_NOW;
|
||||
scheduleOutput.time1 = (u16)(scheduleOutput.time0 + 1000);
|
||||
func_80A40098(this, play, &sp2C, &scheduleOutput);
|
||||
D_80A41D64 = 1;
|
||||
|
@ -2484,7 +2484,7 @@ void FileSelect_InitContext(GameState* thisx) {
|
||||
ShrinkWindow_Letterbox_SetSizeTarget(0);
|
||||
|
||||
gSaveContext.skyboxTime = 0;
|
||||
gSaveContext.save.time = 0;
|
||||
gSaveContext.save.time = CLOCK_TIME(0, 0);
|
||||
|
||||
Skybox_Init(&this->state, &this->skyboxCtx, 1);
|
||||
R_TIME_SPEED = 10;
|
||||
|
36
tools/schedule_timeconv.py
Executable file
36
tools/schedule_timeconv.py
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-FileCopyrightText: © 2023 ZeldaRET
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Convert time values such as 0x1AA9 to their schedule clock time, i.e. 8,30
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
def u16(x: int|float) -> int:
|
||||
return int(x) & 0xFFFF
|
||||
|
||||
def SCHEDULE_CONVERT_TIME(time: int|float) -> int:
|
||||
return u16(time - 0x10000 // 360 * 90)
|
||||
|
||||
def SCHEDULE_UNCONVERT_TIME(time: int) -> int:
|
||||
return time + 0x10000 // 360 * 90
|
||||
|
||||
time = sys.argv[1]
|
||||
time = int(time, 0)
|
||||
|
||||
minutes = round(((24 * 60) / 0x10000) * SCHEDULE_UNCONVERT_TIME(time))
|
||||
|
||||
hours = int(minutes // 60)
|
||||
minutes = round(minutes - 60 * hours)
|
||||
|
||||
# Since multiple values are mapped to the same clock time, check that it
|
||||
# still matches once converted. If it doesn't match as it is, print a warning.
|
||||
macro_val = SCHEDULE_CONVERT_TIME((hours * 60.0 + minutes) * ((0x10000 // 60) / 24.0))
|
||||
|
||||
print(f"{hours},{minutes:02} -> 0x{macro_val:04X}")
|
||||
print(f"SCHEDULE_TIME({hours}, {minutes})")
|
||||
if time != macro_val:
|
||||
print("Warning: Result does not match as-is")
|
Loading…
Reference in New Issue
Block a user