diff options
author | Diegoisawesome <diego@domoreaweso.me> | 2017-09-16 03:21:42 -0500 |
---|---|---|
committer | Diegoisawesome <diego@domoreaweso.me> | 2017-09-16 03:21:42 -0500 |
commit | 6ba1dc8169f148adc9f7f68fec0490dc017c892a (patch) | |
tree | 7dfe1cc18efed9adff4c24f279586b369554b434 /src | |
parent | 448497dfbbc1157c640bc09745454b3c97dc947e (diff) | |
parent | 78009a835f840864b3d30af00c65a745f75b80fa (diff) |
Merge remote-tracking branch 'pret/master'
Diffstat (limited to 'src')
-rw-r--r-- | src/safari_zone.c | 4 | ||||
-rw-r--r-- | src/script.c | 434 | ||||
-rw-r--r-- | src/util.c | 503 |
3 files changed, 939 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); +} diff --git a/src/util.c b/src/util.c new file mode 100644 index 000000000..27b7c5ee5 --- /dev/null +++ b/src/util.c @@ -0,0 +1,503 @@ +#include "global.h" +#include "util.h" +#include "sprite.h" + +const u32 gBitTable[] = +{ + 1 << 0, + 1 << 1, + 1 << 2, + 1 << 3, + 1 << 4, + 1 << 5, + 1 << 6, + 1 << 7, + 1 << 8, + 1 << 9, + 1 << 10, + 1 << 11, + 1 << 12, + 1 << 13, + 1 << 14, + 1 << 15, + 1 << 16, + 1 << 17, + 1 << 18, + 1 << 19, + 1 << 20, + 1 << 21, + 1 << 22, + 1 << 23, + 1 << 24, + 1 << 25, + 1 << 26, + 1 << 27, + 1 << 28, + 1 << 29, + 1 << 30, + 1 << 31, +}; + +static const struct SpriteTemplate sInvisibleSpriteTemplate = +{ + .tileTag = 0, + .paletteTag = 0, + .oam = &gDummyOamData, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const u8 sSpriteDimensions[3][4][2] = +{ + // square + { + {1, 1}, + {2, 2}, + {4, 4}, + {8, 8}, + }, + + // horizontal rectangle + { + {2, 1}, + {4, 1}, + {4, 2}, + {8, 4}, + }, + + // vertical rectangle + { + {1, 2}, + {1, 4}, + {2, 4}, + {4, 8}, + }, +}; + +static const u16 sCrc16Table[] = +{ + 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, + 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, + 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, + 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, + 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, + 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, + 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, + 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, + 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, + 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, + 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, + 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, + 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, + 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, + 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, + 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, + 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, + 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, + 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, + 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, + 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, + 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, + 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, + 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, + 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, + 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, + 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, + 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, + 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, + 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, + 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, + 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78, +}; + +const u8 gMiscBlank_Gfx[] = INCBIN_U8("graphics/interface/blank.4bpp"); // unused in Emerald + +u8 CreateInvisibleSpriteWithCallback(void (*callback)(struct Sprite *)) +{ + u8 sprite = CreateSprite(&sInvisibleSpriteTemplate, 248, 168, 14); + gSprites[sprite].invisible = TRUE; + gSprites[sprite].callback = callback; + return sprite; +} + +void StoreWordInTwoHalfwords(u16 *h, u32 w) +{ + h[0] = (u16)(w); + h[1] = (u16)(w >> 16); +} + +void LoadWordFromTwoHalfwords(u16 *h, u32 *w) +{ + *w = h[0] | (s16)h[1] << 16; +} + +void SetBgAffineStruct(struct BgAffineSrcData *src, u32 texX, u32 texY, s16 scrX, s16 scrY, s16 sx, s16 sy, u16 alpha) +{ + src->texX = texX; + src->texY = texY; + src->scrX = scrX; + src->scrY = scrY; + src->sx = sx; + src->sy = sy; + src->alpha = alpha; +} + +void DoBgAffineSet(struct BgAffineDstData *dest, u32 texX, u32 texY, s16 scrX, s16 scrY, s16 sx, s16 sy, u16 alpha) +{ + struct BgAffineSrcData src; + + SetBgAffineStruct(&src, texX, texY, scrX, scrY, sx, sy, alpha); + BgAffineSet(&src, dest, 1); +} + +#ifdef NONMATCHING + +// Functionally equivalent. +// Only the two yflip loops don't match. +void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output) +{ + u8 x, y; + s8 i, j; + u8 xflip[32]; + u8 h = sSpriteDimensions[shape][size][1]; + u8 w = sSpriteDimensions[shape][size][0]; + + for (y = 0; y < h; y++) + { + int filler = 32 - w; + + for (x = 0; x < w; x++) + { + int tile = (*tilemap & 0x3ff) * 32; + int attr = *tilemap & 0xc00; + + if (attr == 0) + { + void *src = tiles + tile; + void *dest = output; + int length = 32; + DmaCopy32(3, src, dest, length); + } + else if (attr == 0x800) // yflip + { + for (i = 0; i < 8; i++) + { + void *src = tiles; + void *dest = output; + int length = 4; + // this is likely wrong, but makes it closer to matching + src += tile + (7 - i) * 4; + dest += i * 4; + DmaCopy32(3, src, dest, length); + } + } + else // xflip + { + for (i = 0; i < 8; i++) + { + for (j = 0; j < 4; j++) + { + u8 i2 = i * 4; + xflip[i2 + (3-j)] = (tiles[tile + i2 + j] & 0xf) << 4; + xflip[i2 + (3-j)] |= tiles[tile + i2 + j] >> 4; + } + } + if (*tilemap & 0x800) // yflip + { + for (i = 0; i < 8; i++) + { + void *src = xflip + (7-i) * 4; + void *dest = output + i*4; + int length = 4; + DmaCopy32(3, src, dest, length); + } + } + else + { + void *src = xflip; + void *dest = output; + int length = 32; + DmaCopy32(3, src, dest, length); + } + } + tilemap++; + output += 32; + } + tilemap += filler; + } +} + +#else +__attribute__((naked)) void CopySpriteTiles(u8 shape, u8 size, u8 *tiles, u16 *tilemap, u8 *output) +{ + asm("\n\ + .syntax unified\n\ + push {r4-r7,lr}\n\ + mov r7, r10\n\ + mov r6, r9\n\ + mov r5, r8\n\ + push {r5-r7}\n\ + sub sp, 0x38\n\ + str r2, [sp, 0x20]\n\ + adds r4, r3, 0\n\ + ldr r7, [sp, 0x58]\n\ + lsls r0, 24\n\ + lsls r1, 24\n\ + ldr r2, =sSpriteDimensions\n\ + lsrs r1, 23\n\ + lsrs r0, 21\n\ + adds r1, r0\n\ + adds r0, r2, 0x1\n\ + adds r0, r1, r0\n\ + ldrb r0, [r0]\n\ + str r0, [sp, 0x24]\n\ + adds r1, r2\n\ + ldrb r1, [r1]\n\ + str r1, [sp, 0x28]\n\ + movs r0, 0\n\ + b _0806F88C\n\ + .pool\n\ + _0806F740:\n\ + movs r5, 0\n\ + adds r0, 0x1\n\ + str r0, [sp, 0x30]\n\ + b _0806F874\n\ + _0806F748:\n\ + ldrh r0, [r4]\n\ + ldr r2, =0x000003ff\n\ + adds r1, r2, 0\n\ + ands r1, r0\n\ + lsls r1, 5\n\ + mov r8, r1\n\ + movs r2, 0xC0\n\ + lsls r2, 4\n\ + adds r1, r2, 0\n\ + ands r1, r0\n\ + mov r2, sp\n\ + strh r0, [r2, 0x34]\n\ + cmp r1, 0\n\ + bne _0806F788\n\ + ldr r0, [sp, 0x20]\n\ + add r0, r8\n\ + adds r1, r7, 0\n\ + ldr r2, =0x04000008\n\ + bl CpuSet\n\ + adds r4, 0x2\n\ + str r4, [sp, 0x2C]\n\ + adds r7, 0x20\n\ + mov r10, r7\n\ + adds r5, 0x1\n\ + mov r9, r5\n\ + b _0806F86A\n\ + .pool\n\ + _0806F788:\n\ + movs r0, 0x80\n\ + lsls r0, 4\n\ + cmp r1, r0\n\ + bne _0806F7CC\n\ + movs r1, 0\n\ + adds r4, 0x2\n\ + str r4, [sp, 0x2C]\n\ + movs r2, 0x20\n\ + adds r2, r7\n\ + mov r10, r2\n\ + adds r5, 0x1\n\ + mov r9, r5\n\ + _0806F7A0:\n\ + lsls r4, r1, 24\n\ + asrs r4, 24\n\ + movs r0, 0x7\n\ + subs r0, r4\n\ + lsls r0, 2\n\ + add r0, r8\n\ + ldr r1, [sp, 0x20]\n\ + adds r0, r1, r0\n\ + lsls r1, r4, 2\n\ + adds r1, r7, r1\n\ + ldr r2, =0x04000001\n\ + bl CpuSet\n\ + adds r4, 0x1\n\ + lsls r4, 24\n\ + lsrs r1, r4, 24\n\ + asrs r4, 24\n\ + cmp r4, 0x7\n\ + ble _0806F7A0\n\ + b _0806F86A\n\ + .pool\n\ + _0806F7CC:\n\ + movs r1, 0\n\ + adds r4, 0x2\n\ + str r4, [sp, 0x2C]\n\ + movs r2, 0x20\n\ + adds r2, r7\n\ + mov r10, r2\n\ + adds r5, 0x1\n\ + mov r9, r5\n\ + movs r0, 0xF\n\ + mov r12, r0\n\ + _0806F7E0:\n\ + movs r2, 0\n\ + lsls r4, r1, 24\n\ + lsls r0, r4, 2\n\ + lsrs r0, 24\n\ + adds r6, r0, 0x3\n\ + mov r1, r8\n\ + adds r5, r1, r0\n\ + _0806F7EE:\n\ + lsls r1, r2, 24\n\ + asrs r1, 24\n\ + subs r0, r6, r1\n\ + mov r2, sp\n\ + adds r3, r2, r0\n\ + adds r0, r5, r1\n\ + ldr r2, [sp, 0x20]\n\ + adds r0, r2, r0\n\ + ldrb r2, [r0]\n\ + mov r0, r12\n\ + ands r0, r2\n\ + lsls r0, 4\n\ + lsrs r2, 4\n\ + orrs r0, r2\n\ + strb r0, [r3]\n\ + adds r1, 0x1\n\ + lsls r1, 24\n\ + lsrs r2, r1, 24\n\ + asrs r1, 24\n\ + cmp r1, 0x3\n\ + ble _0806F7EE\n\ + movs r1, 0x80\n\ + lsls r1, 17\n\ + adds r0, r4, r1\n\ + lsrs r1, r0, 24\n\ + asrs r0, 24\n\ + cmp r0, 0x7\n\ + ble _0806F7E0\n\ + mov r2, sp\n\ + ldrh r0, [r2, 0x34]\n\ + movs r2, 0x80\n\ + lsls r2, 4\n\ + ands r0, r2\n\ + cmp r0, 0\n\ + beq _0806F860\n\ + movs r1, 0\n\ + _0806F836:\n\ + lsls r4, r1, 24\n\ + asrs r4, 24\n\ + movs r0, 0x7\n\ + subs r0, r4\n\ + lsls r0, 2\n\ + add r0, sp\n\ + lsls r1, r4, 2\n\ + adds r1, r7, r1\n\ + ldr r2, =0x04000001\n\ + bl CpuSet\n\ + adds r4, 0x1\n\ + lsls r4, 24\n\ + lsrs r1, r4, 24\n\ + asrs r4, 24\n\ + cmp r4, 0x7\n\ + ble _0806F836\n\ + b _0806F86A\n\ + .pool\n\ + _0806F860:\n\ + mov r0, sp\n\ + adds r1, r7, 0\n\ + ldr r2, =0x04000008\n\ + bl CpuSet\n\ + _0806F86A:\n\ + ldr r4, [sp, 0x2C]\n\ + mov r7, r10\n\ + mov r1, r9\n\ + lsls r0, r1, 24\n\ + lsrs r5, r0, 24\n\ + _0806F874:\n\ + ldr r2, [sp, 0x28]\n\ + cmp r5, r2\n\ + bcs _0806F87C\n\ + b _0806F748\n\ + _0806F87C:\n\ + movs r0, 0x20\n\ + ldr r1, [sp, 0x28]\n\ + subs r0, r1\n\ + lsls r0, 1\n\ + adds r4, r0\n\ + ldr r2, [sp, 0x30]\n\ + lsls r0, r2, 24\n\ + lsrs r0, 24\n\ + _0806F88C:\n\ + ldr r1, [sp, 0x24]\n\ + cmp r0, r1\n\ + bcs _0806F894\n\ + b _0806F740\n\ + _0806F894:\n\ + add sp, 0x38\n\ + pop {r3-r5}\n\ + mov r8, r3\n\ + mov r9, r4\n\ + mov r10, r5\n\ + pop {r4-r7}\n\ + pop {r0}\n\ + bx r0\n\ + .pool\n\ + .syntax divided"); +} + +#endif // NONMATCHING + +int CountTrailingZeroBits(u32 value) +{ + u8 i; + + for (i = 0; i < 32; i++) + { + if ((value & 1) == 0) + value >>= 1; + else + return i; + } + return 0; +} + +u16 CalcCRC16(u8 *data, s32 length) +{ + u16 i, j; + u16 crc = 0x1121; + + for (i = 0; i < length; i++) + { + crc ^= data[i]; + for (j = 0; j < 8; j++) + { + if (crc & 1) + crc = (crc >> 1) ^ 0x8408; + else + crc >>= 1; + } + } + return ~crc; +} + +u16 CalcCRC16WithTable(u8 *data, u32 length) +{ + u16 i; + u16 crc = 0x1121; + u8 byte; + + for (i = 0; i < length; i++) + { + byte = crc >> 8; + crc ^= data[i]; + crc = byte ^ sCrc16Table[(u8)crc]; + } + return ~crc; +} + +u32 CalcByteArraySum(const u8* data, u32 length) +{ + u32 sum, i; + for (sum = 0, i = 0; i < length; i++) + sum += data[i]; + return sum; +} |