mirror of
https://github.com/pret/pokeplatinum.git
synced 2026-07-17 17:22:07 -05:00
163 lines
3.6 KiB
C
163 lines
3.6 KiB
C
#include <nitro.h>
|
|
#include <string.h>
|
|
|
|
#include "field_script_context.h"
|
|
|
|
enum {
|
|
SCRIPT_STATE_STOPPED,
|
|
SCRIPT_STATE_RUNNING,
|
|
SCRIPT_STATE_WAITING,
|
|
};
|
|
|
|
void ScriptContext_Init (ScriptContext * ctx, const ScrCmdFunc * cmdTable, u32 cmdTableSize)
|
|
{
|
|
ctx->state = SCRIPT_STATE_STOPPED;
|
|
ctx->scriptPtr = NULL;
|
|
ctx->stackPointer = 0;
|
|
ctx->shouldResume = NULL;
|
|
ctx->cmdTable = cmdTable;
|
|
ctx->cmdTableSize = cmdTableSize;
|
|
|
|
u32 i;
|
|
for (i = 0; i < NELEMS(ctx->data); i++) {
|
|
ctx->data[i] = 0;
|
|
}
|
|
|
|
for (i = 0; i < NELEMS(ctx->stack); i++) {
|
|
ctx->stack[i] = NULL;
|
|
}
|
|
|
|
ctx->taskManager = NULL;
|
|
}
|
|
|
|
BOOL ScriptContext_Start (ScriptContext * ctx, const u8 * ptr)
|
|
{
|
|
ctx->scriptPtr = ptr;
|
|
ctx->state = SCRIPT_STATE_RUNNING;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void ScriptContext_Pause (ScriptContext * ctx, ShouldResumeScriptFunc shouldResume)
|
|
{
|
|
ctx->state = SCRIPT_STATE_WAITING;
|
|
ctx->shouldResume = shouldResume;
|
|
}
|
|
|
|
void ScriptContext_Stop (ScriptContext * ctx)
|
|
{
|
|
ctx->state = SCRIPT_STATE_STOPPED;
|
|
ctx->scriptPtr = NULL;
|
|
}
|
|
|
|
void ScriptContext_SetTaskManager (ScriptContext * ctx, TaskManager * taskManager)
|
|
{
|
|
ctx->taskManager = taskManager;
|
|
}
|
|
|
|
BOOL ScriptContext_Run (ScriptContext * ctx)
|
|
{
|
|
if (ctx->state == SCRIPT_STATE_STOPPED) {
|
|
return FALSE;
|
|
}
|
|
|
|
switch (ctx->state) {
|
|
case SCRIPT_STATE_STOPPED:
|
|
// this branch is never taken due to the above check
|
|
return FALSE;
|
|
|
|
case SCRIPT_STATE_WAITING:
|
|
if (ctx->shouldResume != NULL) {
|
|
if (ctx->shouldResume(ctx) == TRUE) {
|
|
ctx->state = SCRIPT_STATE_RUNNING;
|
|
}
|
|
return TRUE;
|
|
}
|
|
ctx->state = SCRIPT_STATE_RUNNING;
|
|
// fallthrough
|
|
|
|
case SCRIPT_STATE_RUNNING:
|
|
while (TRUE) {
|
|
if (ctx->scriptPtr == NULL) {
|
|
ctx->state = SCRIPT_STATE_STOPPED;
|
|
return FALSE;
|
|
}
|
|
u16 cmdCode = ScriptContext_ReadHalfWord(ctx);
|
|
if (cmdCode >= ctx->cmdTableSize) {
|
|
GF_ASSERT(FALSE);
|
|
ctx->state = SCRIPT_STATE_STOPPED;
|
|
return FALSE;
|
|
}
|
|
if (ctx->cmdTable[cmdCode](ctx) == TRUE) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL ScriptContext_Push (ScriptContext * ctx, const u8 * ptr)
|
|
{
|
|
if (ctx->stackPointer + 1 >= (int)NELEMS(ctx->stack)) {
|
|
return TRUE;
|
|
}
|
|
|
|
ctx->stack[ctx->stackPointer] = ptr;
|
|
ctx->stackPointer++;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static const u8 * ScriptContext_Pop (ScriptContext * ctx)
|
|
{
|
|
if (ctx->stackPointer == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
return ctx->stack[--ctx->stackPointer];
|
|
}
|
|
|
|
void ScriptContext_Jump (ScriptContext * ctx, const u8 * ptr)
|
|
{
|
|
ctx->scriptPtr = ptr;
|
|
}
|
|
|
|
void ScriptContext_Call (ScriptContext * ctx, const u8 * ptr)
|
|
{
|
|
ScriptContext_Push(ctx, ctx->scriptPtr);
|
|
ctx->scriptPtr = ptr;
|
|
}
|
|
|
|
void ScriptContext_Return (ScriptContext * ctx)
|
|
{
|
|
ctx->scriptPtr = ScriptContext_Pop(ctx);
|
|
}
|
|
|
|
u16 ScriptContext_ReadHalfWord (ScriptContext * ctx)
|
|
{
|
|
u16 value = ScriptContext_ReadByte(ctx);
|
|
value += ScriptContext_ReadByte(ctx) << 8;
|
|
|
|
return value;
|
|
}
|
|
|
|
u32 ScriptContext_ReadWord (ScriptContext * ctx)
|
|
{
|
|
u8 byte0 = ScriptContext_ReadByte(ctx);
|
|
u8 byte1 = ScriptContext_ReadByte(ctx);
|
|
u8 byte2 = ScriptContext_ReadByte(ctx);
|
|
u8 byte3 = ScriptContext_ReadByte(ctx);
|
|
u32 value = 0;
|
|
|
|
value += byte3;
|
|
value <<= 8;
|
|
value += byte2;
|
|
value <<= 8;
|
|
value += byte1;
|
|
value <<= 8;
|
|
value += byte0;
|
|
|
|
return value;
|
|
}
|