Files
mm/src/code/z_schedule.c
T
Anghelo Carvajal ec86f10b0f 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
2023-10-22 16:52:40 +11:00

300 lines
9.4 KiB
C

#include "global.h"
#define SCHEDULE_CALC_TIME(hour, minute, dest, temp) \
(temp) = (hour)*60.0f; \
(temp) += (minute); \
(dest) = (temp) * (0x10000 / 60 / 24.0f); \
(dest) = SCHEDULE_CONVERT_TIME(dest)
s32 Schedule_CheckFlagS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckFlagS* cmd = (ScheduleCmdCheckFlagS*)*script;
u16 flag = PACK_WEEKEVENTREG_FLAG(cmd->flagByte, cmd->flagMask);
if (CHECK_WEEKEVENTREG(flag)) {
*script += cmd->offset;
}
return false;
}
s32 Schedule_CheckFlagL(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckFlagL* cmd = (ScheduleCmdCheckFlagL*)*script;
u16 flag = PACK_WEEKEVENTREG_FLAG(cmd->flagByte, cmd->flagMask);
if (CHECK_WEEKEVENTREG(flag)) {
*script += (s16)((cmd->offsetH << 8) | cmd->offsetL);
}
return false;
}
s32 Schedule_CheckTimeRangeS(PlayState* play, u8** script, ScheduleOutput* output) {
s32 inRange = false;
ScheduleCmdCheckTimeRangeS* cmd = (ScheduleCmdCheckTimeRangeS*)*script;
f32 f;
u16 start;
u16 end;
u16 now;
SCHEDULE_CALC_TIME(cmd->startHr, cmd->startMin, start, f);
SCHEDULE_CALC_TIME(cmd->endHr, cmd->endMin, end, f);
end--;
now = SCHEDULE_TIME_NOW;
if ((start <= now) && (now <= end)) {
inRange = true;
}
if (inRange == true) {
*script += cmd->offset;
}
return false;
}
s32 Schedule_CheckTimeRangeL(PlayState* play, u8** script, ScheduleOutput* output) {
s32 inRange = false;
ScheduleCmdCheckTimeRangeL* cmd = (ScheduleCmdCheckTimeRangeL*)*script;
f32 f;
u16 start;
u16 end;
u16 now;
SCHEDULE_CALC_TIME(cmd->startHr, cmd->startMin, start, f);
SCHEDULE_CALC_TIME(cmd->endHr, cmd->endMin, end, f);
end--;
now = SCHEDULE_TIME_NOW;
if ((start <= now) && (now <= end)) {
inRange = true;
}
if (inRange == true) {
*script += (s16)((cmd->offsetH << 8) | cmd->offsetL);
}
return false;
}
s32 Schedule_ReturnValueL(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdReturnValueL* cmd = (ScheduleCmdReturnValueL*)*script;
//! @bug result is a u8, value is truncated
output->result = (cmd->retH << 8) | cmd->retL;
output->hasResult = true;
return true;
}
s32 Schedule_ReturnNone(PlayState* play, u8** script, ScheduleOutput* output) {
output->hasResult = false;
return true;
}
s32 Schedule_ReturnEmpty(PlayState* play, u8** script, ScheduleOutput* output) {
output->hasResult = true;
return true;
}
s32 Schedule_Nop(PlayState* play, u8** script, ScheduleOutput* output) {
return false;
}
s32 Schedule_CheckMiscS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckMiscS* cmd = (ScheduleCmdCheckMiscS*)*script;
if (((cmd->which == SCHEDULE_CHECK_MISC_ROOM_KEY) && (INV_CONTENT(ITEM_ROOM_KEY) == ITEM_ROOM_KEY)) ||
((cmd->which == SCHEDULE_CHECK_MISC_LETTER_TO_KAFEI) &&
(INV_CONTENT(ITEM_LETTER_TO_KAFEI) == ITEM_LETTER_TO_KAFEI)) ||
((cmd->which == SCHEDULE_CHECK_MISC_MASK_ROMANI) && (Player_GetMask(play) == PLAYER_MASK_ROMANI))) {
*script += cmd->offset;
}
return false;
}
s32 Schedule_ReturnValueS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdReturnValueS* cmd = (ScheduleCmdReturnValueS*)*script;
output->result = cmd->result;
output->hasResult = true;
return true;
}
s32 Schedule_CheckNotInSceneS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckNotInSceneS* cmd = (ScheduleCmdCheckNotInSceneS*)*script;
s16 sceneId = (cmd->sceneIdH << 8) | cmd->sceneIdL;
if (sceneId != play->sceneId) {
*script += cmd->offset;
}
return false;
}
s32 Schedule_CheckNotInSceneL(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckNotInSceneL* cmd = (ScheduleCmdCheckNotInSceneL*)*script;
s16 sceneId = (cmd->sceneIdH << 8) | cmd->sceneIdL;
if (sceneId != play->sceneId) {
*script = *script + (s16)((cmd->offsetH << 8) | cmd->offsetL);
}
return false;
}
s32 Schedule_CheckNotInDayS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckNotInDayS* cmd = (ScheduleCmdCheckNotInDayS*)*script;
s16 day = (cmd->dayH << 8) | cmd->dayL;
if (day != (s16)gSaveContext.save.day) {
*script += cmd->offset;
}
return false;
}
s32 Schedule_CheckNotInDayL(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckNotInDayL* cmd = (ScheduleCmdCheckNotInDayL*)*script;
s16 day = (cmd->dayH << 8) | cmd->dayL;
if (day != (s16)gSaveContext.save.day) {
*script += (s16)((cmd->offsetH << 8) | cmd->offsetL);
}
return false;
}
s32 Schedule_ReturnTime(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdReturnTime* cmd = (ScheduleCmdReturnTime*)*script;
f32 f;
u16 time0;
u16 time1;
SCHEDULE_CALC_TIME(cmd->time0Hr, cmd->time0Min, time0, f);
SCHEDULE_CALC_TIME(cmd->time1Hr, cmd->time1Min, time1, f);
time1--;
output->result = cmd->result;
output->time0 = time0;
output->time1 = time1;
output->hasResult = true;
return true;
}
s32 Schedule_CheckBeforeTimeS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckBeforeTimeS* cmd = (ScheduleCmdCheckBeforeTimeS*)*script;
f32 f;
u16 testTime;
u16 now;
SCHEDULE_CALC_TIME(cmd->timeHr, cmd->timeMin, testTime, f);
now = SCHEDULE_TIME_NOW;
if (now < testTime) {
*script += cmd->offset;
}
return false;
}
s32 Schedule_CheckBeforeTimeL(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdCheckBeforeTimeL* cmd = (ScheduleCmdCheckBeforeTimeL*)*script;
f32 f;
u16 testTime;
u16 now;
SCHEDULE_CALC_TIME(cmd->timeHr, cmd->timeMin, testTime, f);
now = SCHEDULE_TIME_NOW;
if (now < testTime) {
*script += (s16)((cmd->offsetH << 8) | cmd->offsetL);
}
return false;
}
s32 Schedule_BranchS(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdBranchS* cmd = (ScheduleCmdBranchS*)*script;
*script += cmd->offset;
return false;
}
s32 Schedule_BranchL(PlayState* play, u8** script, ScheduleOutput* output) {
ScheduleCmdBranchL* cmd = (ScheduleCmdBranchL*)*script;
*script += (s16)((cmd->offsetH << 8) | cmd->offsetL);
return false;
}
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), // 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) {
u8 size;
s32 stop;
do {
size = sScheduleCmdSizes[*script];
stop = sScheduleCmdFuncs[*script](play, &script, output);
script += size;
} while (!stop);
return output->hasResult;
}