summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/safari_zone.c4
-rw-r--r--src/script.c434
2 files changed, 436 insertions, 2 deletions
diff --git a/src/safari_zone.c b/src/safari_zone.c
index 37ee664cd..fdfdd961a 100644
--- a/src/safari_zone.c
+++ b/src/safari_zone.c
@@ -34,7 +34,7 @@ extern void c2_exit_to_overworld_2_switch(void);
extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void);
extern void c2_load_new_map(void);
extern void sub_80AF6F0(void);
-extern void script_env_2_set_ctx_paused(void);
+extern void ScriptContext1_Stop(void);
extern void warp_in(void);
extern void GetXYCoordsOneStepInFrontOfPlayer(s16* x, s16* y);
extern void PlayerGetDestCoords(s16* x, s16* y);
@@ -124,7 +124,7 @@ void sub_80FC190(void)
else if (gBattleOutcome == BATTLE_CAUGHT)
{
ScriptContext1_SetupScript(gUnknown_082A4B9B);
- script_env_2_set_ctx_paused();
+ ScriptContext1_Stop();
SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
}
}
diff --git a/src/script.c b/src/script.c
new file mode 100644
index 000000000..b2809a137
--- /dev/null
+++ b/src/script.c
@@ -0,0 +1,434 @@
+#include "global.h"
+#include "script.h"
+#include "event_data.h"
+#include "util.h"
+
+#define RAM_SCRIPT_MAGIC 51
+
+extern u8* gUnknown_020375C0;
+
+extern bool32 sub_801B27C(void);
+
+// ewram bss
+IWRAM_DATA static u8 sScriptContext1Status;
+IWRAM_DATA static u32 sUnusedVariable1;
+IWRAM_DATA static struct ScriptContext sScriptContext1;
+IWRAM_DATA static u32 sUnusedVariable2;
+IWRAM_DATA static struct ScriptContext sScriptContext2;
+IWRAM_DATA static bool8 sScriptContext2Enabled;
+
+extern ScrCmdFunc gScriptCmdTable[];
+extern ScrCmdFunc gScriptCmdTableEnd[];
+extern void *gNullScriptPtr;
+
+void InitScriptContext(struct ScriptContext *ctx, void *cmdTable, void *cmdTableEnd)
+{
+ s32 i;
+
+ ctx->mode = 0;
+ ctx->scriptPtr = 0;
+ ctx->stackDepth = 0;
+ ctx->nativePtr = 0;
+ ctx->cmdTable = cmdTable;
+ ctx->cmdTableEnd = cmdTableEnd;
+
+ for (i = 0; i < 4; i++)
+ ctx->data[i] = 0;
+
+ for (i = 0; i < 20; i++)
+ ctx->stack[i] = 0;
+}
+
+u8 SetupBytecodeScript(struct ScriptContext *ctx, const u8 *ptr)
+{
+ ctx->scriptPtr = ptr;
+ ctx->mode = 1;
+ return 1;
+}
+
+void SetupNativeScript(struct ScriptContext *ctx, bool8 (*ptr)(void))
+{
+ ctx->mode = 2;
+ ctx->nativePtr = ptr;
+}
+
+void StopScript(struct ScriptContext *ctx)
+{
+ ctx->mode = 0;
+ ctx->scriptPtr = 0;
+}
+
+bool8 RunScriptCommand(struct ScriptContext *ctx)
+{
+ if (ctx->mode == 0)
+ return FALSE;
+
+ switch (ctx->mode)
+ {
+ case 0:
+ return FALSE;
+ case 2:
+ if (ctx->nativePtr)
+ {
+ if (ctx->nativePtr() == TRUE)
+ ctx->mode = 1;
+ return TRUE;
+ }
+ ctx->mode = 1;
+ case 1:
+ while (1)
+ {
+ u8 cmdCode;
+ ScrCmdFunc *func;
+
+ if (!ctx->scriptPtr)
+ {
+ ctx->mode = 0;
+ return FALSE;
+ }
+
+ if (ctx->scriptPtr == gNullScriptPtr)
+ {
+ while (1)
+ asm("svc 2"); // HALT
+ }
+
+ cmdCode = *(ctx->scriptPtr);
+ ctx->scriptPtr++;
+ func = &ctx->cmdTable[cmdCode];
+
+ if (func >= ctx->cmdTableEnd)
+ {
+ ctx->mode = 0;
+ return FALSE;
+ }
+
+ if ((*func)(ctx) == 1)
+ return TRUE;
+ }
+ }
+
+ return TRUE;
+}
+
+u8 ScriptPush(struct ScriptContext *ctx, const u8 *ptr)
+{
+ if (ctx->stackDepth + 1 >= 20)
+ {
+ return 1;
+ }
+ else
+ {
+ ctx->stack[ctx->stackDepth] = ptr;
+ ctx->stackDepth++;
+ return 0;
+ }
+}
+
+const u8 *ScriptPop(struct ScriptContext *ctx)
+{
+ if (ctx->stackDepth == 0)
+ return NULL;
+
+ ctx->stackDepth--;
+ return ctx->stack[ctx->stackDepth];
+}
+
+void ScriptJump(struct ScriptContext *ctx, u8 *ptr)
+{
+ ctx->scriptPtr = ptr;
+}
+
+void ScriptCall(struct ScriptContext *ctx, u8 *ptr)
+{
+ ScriptPush(ctx, ctx->scriptPtr);
+ ctx->scriptPtr = ptr;
+}
+
+void ScriptReturn(struct ScriptContext *ctx)
+{
+ ctx->scriptPtr = ScriptPop(ctx);
+}
+
+u16 ScriptReadHalfword(struct ScriptContext *ctx)
+{
+ u16 value = *(ctx->scriptPtr++);
+ value |= *(ctx->scriptPtr++) << 8;
+ return value;
+}
+
+u32 ScriptReadWord(struct ScriptContext *ctx)
+{
+ u32 value0 = *(ctx->scriptPtr++);
+ u32 value1 = *(ctx->scriptPtr++);
+ u32 value2 = *(ctx->scriptPtr++);
+ u32 value3 = *(ctx->scriptPtr++);
+ return (((((value3 << 8) + value2) << 8) + value1) << 8) + value0;
+}
+
+void ScriptContext2_Enable(void)
+{
+ sScriptContext2Enabled = TRUE;
+}
+
+void ScriptContext2_Disable(void)
+{
+ sScriptContext2Enabled = FALSE;
+}
+
+bool8 ScriptContext2_IsEnabled(void)
+{
+ return sScriptContext2Enabled;
+}
+
+bool8 ScriptContext1_IsScriptSetUp(void)
+{
+ if (sScriptContext1Status == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void ScriptContext1_Init(void)
+{
+ InitScriptContext(&sScriptContext1, gScriptCmdTable, gScriptCmdTableEnd);
+ sScriptContext1Status = 2;
+}
+
+bool8 ScriptContext2_RunScript(void)
+{
+ if (sScriptContext1Status == 2)
+ return 0;
+
+ if (sScriptContext1Status == 1)
+ return 0;
+
+ ScriptContext2_Enable();
+
+ if (!RunScriptCommand(&sScriptContext1))
+ {
+ sScriptContext1Status = 2;
+ ScriptContext2_Disable();
+ return 0;
+ }
+
+ return 1;
+}
+
+void ScriptContext1_SetupScript(const u8 *ptr)
+{
+ InitScriptContext(&sScriptContext1, gScriptCmdTable, gScriptCmdTableEnd);
+ SetupBytecodeScript(&sScriptContext1, ptr);
+ ScriptContext2_Enable();
+ sScriptContext1Status = 0;
+}
+
+void ScriptContext1_Stop(void)
+{
+ sScriptContext1Status = 1;
+}
+
+void EnableBothScriptContexts(void)
+{
+ sScriptContext1Status = 0;
+ ScriptContext2_Enable();
+}
+
+void ScriptContext2_RunNewScript(const u8 *ptr)
+{
+ InitScriptContext(&sScriptContext2, &gScriptCmdTable, &gScriptCmdTableEnd);
+ SetupBytecodeScript(&sScriptContext2, ptr);
+ while (RunScriptCommand(&sScriptContext2) == TRUE);
+}
+
+u8 *mapheader_get_tagged_pointer(u8 tag)
+{
+ u8 *mapScripts = gMapHeader.mapScripts;
+
+ if (!mapScripts)
+ return NULL;
+
+ while (1)
+ {
+ if (!*mapScripts)
+ return NULL;
+ if (*mapScripts == tag)
+ {
+ mapScripts++;
+ return (u8 *)(mapScripts[0] + (mapScripts[1] << 8) + (mapScripts[2] << 16) + (mapScripts[3] << 24));
+ }
+ mapScripts += 5;
+ }
+}
+
+void mapheader_run_script_by_tag(u8 tag)
+{
+ u8 *ptr = mapheader_get_tagged_pointer(tag);
+ if (ptr)
+ ScriptContext2_RunNewScript(ptr);
+}
+
+u8 *mapheader_get_first_match_from_tagged_ptr_list(u8 tag)
+{
+ u8 *ptr = mapheader_get_tagged_pointer(tag);
+
+ if (!ptr)
+ return NULL;
+
+ while (1)
+ {
+ u16 varIndex1;
+ u16 varIndex2;
+ varIndex1 = ptr[0] | (ptr[1] << 8);
+ if (!varIndex1)
+ return NULL;
+ ptr += 2;
+ varIndex2 = ptr[0] | (ptr[1] << 8);
+ ptr += 2;
+ if (VarGet(varIndex1) == VarGet(varIndex2))
+ return (u8 *)(ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24));
+ ptr += 4;
+ }
+}
+
+void mapheader_run_script_with_tag_x1(void)
+{
+ mapheader_run_script_by_tag(1);
+}
+
+void mapheader_run_script_with_tag_x3(void)
+{
+ mapheader_run_script_by_tag(3);
+}
+
+void mapheader_run_script_with_tag_x5(void)
+{
+ mapheader_run_script_by_tag(5);
+}
+
+void mapheader_run_script_with_tag_x7(void)
+{
+ mapheader_run_script_by_tag(7);
+}
+
+void mapheader_run_script_with_tag_x6(void)
+{
+ mapheader_run_script_by_tag(6);
+}
+
+bool8 mapheader_run_first_tag2_script_list_match(void)
+{
+ u8 *ptr = mapheader_get_first_match_from_tagged_ptr_list(2);
+
+ if (!ptr)
+ return 0;
+
+ ScriptContext1_SetupScript(ptr);
+ return 1;
+}
+
+void mapheader_run_first_tag4_script_list_match(void)
+{
+ u8 *ptr = mapheader_get_first_match_from_tagged_ptr_list(4);
+ if (ptr)
+ ScriptContext2_RunNewScript(ptr);
+}
+
+u32 CalculateRamScriptChecksum(void)
+{
+ return CalcCRC16WithTable((u8*)(&gSaveBlock1Ptr->ramScript.data), sizeof(gSaveBlock1Ptr->ramScript.data));
+}
+
+void ClearRamScript(void)
+{
+ CpuFill32(0, &gSaveBlock1Ptr->ramScript, sizeof(struct RamScript));
+}
+
+bool8 InitRamScript(u8 *script, u16 scriptSize, u8 mapGroup, u8 mapNum, u8 objectId)
+{
+ struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
+
+ ClearRamScript();
+
+ if (scriptSize > sizeof(scriptData->script))
+ return FALSE;
+
+ scriptData->magic = RAM_SCRIPT_MAGIC;
+ scriptData->mapGroup = mapGroup;
+ scriptData->mapNum = mapNum;
+ scriptData->objectId = objectId;
+ memcpy(scriptData->script, script, scriptSize);
+ gSaveBlock1Ptr->ramScript.checksum = CalculateRamScriptChecksum();
+ return TRUE;
+}
+
+u8 *GetRamScript(u8 objectId, u8 *script)
+{
+ struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
+ gUnknown_020375C0 = NULL;
+ if (scriptData->magic != RAM_SCRIPT_MAGIC)
+ return script;
+ if (scriptData->mapGroup != gSaveBlock1Ptr->location.mapGroup)
+ return script;
+ if (scriptData->mapNum != gSaveBlock1Ptr->location.mapNum)
+ return script;
+ if (scriptData->objectId != objectId)
+ return script;
+ if (CalculateRamScriptChecksum() != gSaveBlock1Ptr->ramScript.checksum)
+ {
+ ClearRamScript();
+ return script;
+ }
+ else
+ {
+ gUnknown_020375C0 = script;
+ return scriptData->script;
+ }
+}
+
+bool32 sub_80991F8(void)
+{
+ struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
+ if (scriptData->magic != RAM_SCRIPT_MAGIC)
+ return FALSE;
+ if (scriptData->mapGroup != 0xFF)
+ return FALSE;
+ if (scriptData->mapNum != 0xFF)
+ return FALSE;
+ if (scriptData->objectId != 0xFF)
+ return FALSE;
+ if (CalculateRamScriptChecksum() != gSaveBlock1Ptr->ramScript.checksum)
+ return FALSE;
+ return TRUE;
+}
+
+u8 *sub_8099244(void)
+{
+ struct RamScriptData *scriptData = &gSaveBlock1Ptr->ramScript.data;
+ if (!sub_801B27C())
+ return NULL;
+ if (scriptData->magic != RAM_SCRIPT_MAGIC)
+ return NULL;
+ if (scriptData->mapGroup != 0xFF)
+ return NULL;
+ if (scriptData->mapNum != 0xFF)
+ return NULL;
+ if (scriptData->objectId != 0xFF)
+ return NULL;
+ if (CalculateRamScriptChecksum() != gSaveBlock1Ptr->ramScript.checksum)
+ {
+ ClearRamScript();
+ return NULL;
+ }
+ else
+ {
+ return scriptData->script;
+ }
+}
+
+void sub_80992A0(u8 *script, u16 scriptSize)
+{
+ if (scriptSize > sizeof(gSaveBlock1Ptr->ramScript.data.script))
+ scriptSize = sizeof(gSaveBlock1Ptr->ramScript.data.script);
+ InitRamScript(script, scriptSize, 0xFF, 0xFF, 0xFF);
+}