Merge remote-tracking branch 'pret/master'

This commit is contained in:
Diegoisawesome
2017-09-16 03:21:42 -05:00
58 changed files with 1542 additions and 1925 deletions

View File

@@ -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);
}
}

434
src/script.c Normal file
View File

@@ -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);
}

503
src/util.c Normal file
View File

@@ -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;
}