diff options
Diffstat (limited to 'src/script.c')
-rw-r--r-- | src/script.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/src/script.c b/src/script.c new file mode 100644 index 00000000..e354ec9c --- /dev/null +++ b/src/script.c @@ -0,0 +1,229 @@ +#include "nitro.h"
+#include "script.h"
+
+void InitScriptContext(struct ScriptContext *ctx, void *cmdTable, void *cmdTableEnd)
+{
+ u32 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;
+
+ ctx->unk74 = 0;
+}
+
+u8 SetupBytecodeScript(struct ScriptContext *ctx, const u8 *ptr)
+{
+ ctx->scriptPtr = ptr;
+ ctx->mode = 1;
+ return 1;
+}
+
+void SetupNativeScript(struct ScriptContext *ctx, u8 (*ptr)(void))
+{
+ ctx->mode = 2;
+ ctx->nativePtr = ptr;
+}
+
+void StopScript(struct ScriptContext *ctx)
+{
+ ctx->mode = 0;
+ ctx->scriptPtr = 0;
+}
+
+void FUN_02038B6C(struct ScriptContext *ctx, int r1)
+{
+ ctx->unk74 = r1;
+}
+
+extern void ErrorHandling(void);
+
+#ifdef NONMATCHING
+u8 RunScriptCommand(struct ScriptContext *ctx)
+{
+ struct ScriptContext *localCtx = ctx;
+
+ if (localCtx->mode == 0)
+ return FALSE;
+
+ switch (localCtx->mode)
+ {
+ case 0:
+ return FALSE;
+ case 2:
+ if (localCtx->nativePtr)
+ {
+ if (localCtx->nativePtr() == TRUE)
+ localCtx->mode = 1;
+ return TRUE;
+ }
+ localCtx->mode = 1;
+ case 1:
+ while (1)
+ {
+ u16 cmdCode;
+ ScrCmdFunc *func;
+
+ if (!localCtx->scriptPtr)
+ {
+ localCtx->mode = 0;
+ return FALSE;
+ }
+
+ cmdCode = ScriptReadHalfword(localCtx);
+ if ((u32)localCtx->cmdTableEnd >= cmdCode)
+ {
+ ErrorHandling();
+ localCtx->mode = 0;
+ return FALSE;
+ }
+
+ func = &localCtx->cmdTable[cmdCode];
+
+ if ((*func)(localCtx) == 1)
+ break;
+ }
+ }
+
+ return TRUE;
+}
+#else
+u8 RunScriptCommand(struct ScriptContext *ctx)
+{
+ __asm {
+ add r4, r0, #0x0
+ ldrb r1, [r4, #0x1]
+ cmp r1, #0x0
+ bne _02038B7E
+ mov r0, #0x0
+ pop {r4, pc}
+ _02038B7E:
+ beq _02038B8A
+ cmp r1, #0x1
+ beq _02038BA6
+ cmp r1, #0x2
+ beq _02038B8E
+ b _02038BD8
+ _02038B8A:
+ mov r0, #0x0
+ pop {r4, pc}
+ _02038B8E:
+ ldr r1, [r4, #0x4]
+ cmp r1, #0x0
+ beq _02038BA2
+ blx r1
+ cmp r0, #0x1
+ bne _02038B9E
+ mov r0, #0x1
+ strb r0, [r4, #0x1]
+ _02038B9E:
+ mov r0, #0x1
+ pop {r4, pc}
+ _02038BA2:
+ mov r0, #0x1
+ strb r0, [r4, #0x1]
+ // for some reason it adds a b _02038BA6 here
+ _02038BA6:
+ ldr r0, [r4, #0x8]
+ cmp r0, #0x0
+ bne _02038BB2
+ mov r0, #0x0
+ strb r0, [r4, #0x1]
+ pop {r4, pc}
+ _02038BB2:
+ add r0, r4, #0x0
+ bl ScriptReadHalfword
+ add r1, r0, #0x0
+ ldr r0, [r4, #0x60]
+ cmp r1, r0
+ blo _02038BCA
+ bl ErrorHandling
+ mov r0, #0x0
+ strb r0, [r4, #0x1]
+ pop {r4, pc}
+ _02038BCA:
+ ldr r2, [r4, #0x5c]
+ lsl r1, r1, #0x2
+ ldr r1, [r2, r1]
+ add r0, r4, #0x0
+ blx r1
+ cmp r0, #0x1
+ bne _02038BA6
+ _02038BD8:
+ mov r0, #0x1
+ }
+}
+#endif
+
+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, const u8 *ptr)
+{
+ ctx->scriptPtr = ptr;
+}
+
+void ScriptCall(struct ScriptContext *ctx, const 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++);
+ u32 retVal = 0;
+
+ retVal += value3;
+ retVal <<= 8;
+ retVal += value2;
+ retVal <<= 8;
+ retVal += value1;
+ retVal <<= 8;
+ retVal += value0;
+ return retVal;
+}
|