fix battle transition conflicts

This commit is contained in:
DizzyEggg
2018-01-14 22:19:26 +01:00
806 changed files with 26595 additions and 2758 deletions

View File

@@ -1,13 +1,24 @@
#include "global.h"
#include "dma3.h"
IWRAM_DATA struct {
/* 0x00 */ const u8 *src;
/* 0x04 */ u8 *dest;
/* 0x08 */ u16 size;
/* 0x0A */ u16 mode;
/* 0x0C */ u32 value;
} gDma3Requests[128];
// Maximum amount of data we will transfer in one operation
#define MAX_DMA_BLOCK_SIZE 0x1000
#define MAX_DMA_REQUESTS 128
#define DMA_REQUEST_COPY32 1
#define DMA_REQUEST_FILL32 2
#define DMA_REQUEST_COPY16 3
#define DMA_REQUEST_FILL16 4
IWRAM_DATA struct
{
const u8 *src;
u8 *dest;
u16 size;
u16 mode;
u32 value;
} gDma3Requests[MAX_DMA_REQUESTS];
static bool8 gDma3ManagerLocked;
static u8 gDma3RequestCursor;
@@ -19,88 +30,103 @@ void ClearDma3Requests(void)
gDma3ManagerLocked = TRUE;
gDma3RequestCursor = 0;
for(i = 0; i < (u8)ARRAY_COUNT(gDma3Requests); i++)
for (i = 0; i < MAX_DMA_REQUESTS; i++)
{
gDma3Requests[i].size = 0;
gDma3Requests[i].src = 0;
gDma3Requests[i].dest = 0;
gDma3Requests[i].src = NULL;
gDma3Requests[i].dest = NULL;
}
gDma3ManagerLocked = FALSE;
}
#ifdef NONMATCHING
#define Dma3CopyLarge_(src, dest, size, bit) \
{ \
const void *_src = src; \
void *_dest = dest; \
u32 _size = size; \
while (1) \
{ \
if (_size <= MAX_DMA_BLOCK_SIZE) \
{ \
DmaCopy##bit(3, _src, _dest, _size); \
break; \
} \
DmaCopy##bit(3, _src, _dest, MAX_DMA_BLOCK_SIZE); \
_src += MAX_DMA_BLOCK_SIZE; \
_dest += MAX_DMA_BLOCK_SIZE; \
_size -= MAX_DMA_BLOCK_SIZE; \
} \
}
#define Dma3CopyLarge16_(src, dest, size) Dma3CopyLarge_(src, dest, size, 16)
#define Dma3CopyLarge32_(src, dest, size) Dma3CopyLarge_(src, dest, size, 32)
#define Dma3FillLarge_(value, dest, size, bit) \
{ \
void *_dest = dest; \
u32 _size = size; \
while (1) \
{ \
if (_size <= MAX_DMA_BLOCK_SIZE) \
{ \
DmaFill##bit(3, value, _dest, _size); \
break; \
} \
DmaFill##bit(3, value, _dest, MAX_DMA_BLOCK_SIZE); \
_dest += MAX_DMA_BLOCK_SIZE; \
_size -= MAX_DMA_BLOCK_SIZE; \
} \
}
#define Dma3FillLarge16_(value, dest, size) Dma3FillLarge_(value, dest, size, 16)
#define Dma3FillLarge32_(value, dest, size) Dma3FillLarge_(value, dest, size, 32)
void ProcessDma3Requests(void)
{
// NOTE: the fillerA member of the DMA struct is actually u32 value;
u16 total_size;
u16 bytesTransferred;
if (gDma3ManagerLocked)
return;
total_size = 0;
bytesTransferred = 0;
// as long as there are DMA requests to process (unless size or vblank is an issue), do not exit
while (gDma3Requests[gDma3RequestCursor].size)
while (gDma3Requests[gDma3RequestCursor].size != 0)
{
total_size += gDma3Requests[gDma3RequestCursor].size;
bytesTransferred += gDma3Requests[gDma3RequestCursor].size;
if (total_size > 0xA000)
return; // don't do too much at once
if (REG_VCOUNT > 224)
return;// we're about to leave vblank, stop
if (bytesTransferred > 40 * 1024)
return; // don't transfer more than 40 KiB
if (*(u8 *)REG_ADDR_VCOUNT > 224)
return; // we're about to leave vblank, stop
switch (gDma3Requests[gDma3RequestCursor].mode)
{
case 1: // regular 32-bit copy
// _08000C8C
if(gDma3Requests[gDma3RequestCursor].size <= 0x1000)
{
DmaCopy32(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
break;
}
while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
{
DmaCopy32(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
gDma3Requests[gDma3RequestCursor].src += 0x1000;
gDma3Requests[gDma3RequestCursor].dest += 0x1000;
gDma3Requests[gDma3RequestCursor].size -= 0x1000;
}
DmaCopy32(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
case DMA_REQUEST_COPY32: // regular 32-bit copy
Dma3CopyLarge32_(gDma3Requests[gDma3RequestCursor].src,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
break;
case 2: // repeat a single 32-bit value across RAM
// _08000CD0
while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
{
DmaFill32(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
gDma3Requests[gDma3RequestCursor].dest += 0x1000;
gDma3Requests[gDma3RequestCursor].size -= 0x1000;
}
DmaFill32(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
case DMA_REQUEST_FILL32: // repeat a single 32-bit value across RAM
Dma3FillLarge32_(gDma3Requests[gDma3RequestCursor].value,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
break;
case 3: // regular 16-bit copy
// _08000D3C
while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
{
DmaCopy16(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
gDma3Requests[gDma3RequestCursor].src += 0x1000;
gDma3Requests[gDma3RequestCursor].dest += 0x1000;
gDma3Requests[gDma3RequestCursor].size -= 0x1000;
}
DmaCopy16(3, gDma3Requests[gDma3RequestCursor].src, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
case DMA_REQUEST_COPY16: // regular 16-bit copy
Dma3CopyLarge16_(gDma3Requests[gDma3RequestCursor].src,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
break;
case 4: // repeat a single 16-bit value across RAM
// _08000D88
while (gDma3Requests[gDma3RequestCursor].size > 0x1000)
{
DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, 0x1000);
gDma3Requests[gDma3RequestCursor].dest += 0x1000;
gDma3Requests[gDma3RequestCursor].size -= 0x1000;
}
DmaFill16(3, gDma3Requests[gDma3RequestCursor].value, gDma3Requests[gDma3RequestCursor].dest, gDma3Requests[gDma3RequestCursor].size);
case DMA_REQUEST_FILL16: // repeat a single 16-bit value across RAM
Dma3FillLarge16_(gDma3Requests[gDma3RequestCursor].value,
gDma3Requests[gDma3RequestCursor].dest,
gDma3Requests[gDma3RequestCursor].size);
break;
}
// Free the request
gDma3Requests[gDma3RequestCursor].src = NULL;
gDma3Requests[gDma3RequestCursor].dest = NULL;
gDma3Requests[gDma3RequestCursor].size = 0;
@@ -108,375 +134,54 @@ void ProcessDma3Requests(void)
gDma3Requests[gDma3RequestCursor].value = 0;
gDma3RequestCursor++;
if (gDma3RequestCursor >= 128) // loop back to the first DMA request
if (gDma3RequestCursor >= MAX_DMA_REQUESTS) // loop back to the first DMA request
gDma3RequestCursor = 0;
}
}
#else
__attribute__((naked))
void ProcessDma3Requests(void)
{
asm(".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, 0xC\n\
ldr r0, =gDma3ManagerLocked\n\
ldrb r0, [r0]\n\
cmp r0, 0\n\
beq _08000C06\n\
b _08000E46\n\
_08000C06:\n\
movs r0, 0\n\
str r0, [sp, 0x8]\n\
ldr r1, =gDma3Requests\n\
ldr r2, =gDma3RequestCursor\n\
ldrb r0, [r2]\n\
lsls r0, 4\n\
adds r0, r1\n\
ldrh r0, [r0, 0x8]\n\
mov r12, r2\n\
cmp r0, 0\n\
bne _08000C1E\n\
b _08000E46\n\
_08000C1E:\n\
mov r8, r1\n\
adds r1, 0x4\n\
mov r10, r1\n\
movs r6, 0x80\n\
lsls r6, 5\n\
ldr r7, =0x040000D4 @REG_DMA3\n\
movs r2, 0\n\
mov r9, r2\n\
_08000C2E:\n\
mov r3, r12 @ gDma3RequestCursor\n\
ldrb r0, [r3]\n\
lsls r5, r0, 4\n\
mov r0, r8 @ gDma3Requests\n\
adds r1, r5, r0 @ gDma3Requests[gDma3RequestCursor]\n\
ldrh r0, [r1, 0x8] @ gDma3Requests[gDma3RequestCursor].size\n\
ldr r2, [sp, 0x8]\n\
adds r0, r2, r0\n\
lsls r0, 16\n\
lsrs r0, 16\n\
str r0, [sp, 0x8]\n\
movs r0, 0xA0\n\
lsls r0, 8\n\
ldr r3, [sp, 0x8]\n\
cmp r3, r0\n\
bls _08000C50\n\
b _08000E46\n\
_08000C50:\n\
ldr r0, =0x04000006 @REG_VCOUNT\n\
ldrb r0, [r0]\n\
cmp r0, 0xE0\n\
bls _08000C5A\n\
b _08000E46\n\
_08000C5A:\n\
ldrh r0, [r1, 0xA]\n\
cmp r0, 0x2\n\
beq _08000CD0\n\
cmp r0, 0x2\n\
bgt _08000C80\n\
cmp r0, 0x1\n\
beq _08000C8C\n\
b _08000DF0\n\
.pool\n\
_08000C80:\n\
cmp r0, 0x3\n\
beq _08000D3C\n\
cmp r0, 0x4\n\
bne _08000C8A\n\
b _08000D88\n\
_08000C8A:\n\
b _08000DF0\n\
_08000C8C:\n\
ldr r3, [r1]\n\
mov r2, r10\n\
adds r0, r5, r2\n\
ldr r2, [r0]\n\
ldrh r1, [r1, 0x8]\n\
cmp r1, r6\n\
bhi _08000CA6\n\
str r3, [r7]\n\
str r2, [r7, 0x4]\n\
lsrs r0, r1, 2\n\
movs r1, 0x84\n\
lsls r1, 24\n\
b _08000DAA\n\
_08000CA6:\n\
ldr r4, =0x040000D4 @REG_DMA3\n\
str r3, [r4]\n\
str r2, [r4, 0x4]\n\
ldr r0, =0x84000400\n\
str r0, [r4, 0x8]\n\
ldr r0, [r4, 0x8]\n\
adds r3, r6\n\
adds r2, r6\n\
subs r1, r6\n\
cmp r1, r6\n\
bhi _08000CA6\n\
str r3, [r4]\n\
str r2, [r4, 0x4]\n\
lsrs r0, r1, 2\n\
movs r1, 0x84\n\
lsls r1, 24\n\
b _08000D76\n\
.pool\n\
_08000CD0:\n\
mov r3, r10\n\
adds r0, r5, r3\n\
ldr r4, [r0]\n\
ldrh r1, [r1, 0x8]\n\
cmp r1, r6\n\
bhi _08000CF4\n\
mov r0, r8\n\
adds r0, 0xC\n\
adds r0, r5, r0\n\
ldr r0, [r0]\n\
str r0, [sp]\n\
mov r5, sp\n\
str r5, [r7]\n\
str r4, [r7, 0x4]\n\
lsrs r0, r1, 2\n\
movs r1, 0x85\n\
lsls r1, 24\n\
b _08000DAA\n\
_08000CF4:\n\
mov r2, r12\n\
ldrb r0, [r2]\n\
lsls r0, 4\n\
mov r5, r8\n\
adds r5, 0xC\n\
adds r0, r5\n\
ldr r0, [r0]\n\
str r0, [sp]\n\
ldr r3, =0x040000D4 @REG_DMA3\n\
mov r0, sp\n\
str r0, [r3]\n\
str r4, [r3, 0x4]\n\
ldr r0, =0x85000400\n\
str r0, [r3, 0x8]\n\
ldr r0, [r3, 0x8]\n\
adds r4, r6\n\
subs r1, r6\n\
cmp r1, r6\n\
bhi _08000CF4\n\
ldrb r0, [r2]\n\
lsls r0, 4\n\
adds r0, r5\n\
ldr r0, [r0]\n\
str r0, [sp]\n\
mov r2, sp\n\
str r2, [r3]\n\
str r4, [r3, 0x4]\n\
lsrs r0, r1, 2\n\
movs r1, 0x85\n\
lsls r1, 24\n\
b _08000DEA\n\
.pool\n\
_08000D3C:\n\
ldr r3, [r1]\n\
mov r2, r10\n\
adds r0, r5, r2\n\
ldr r2, [r0]\n\
ldrh r1, [r1, 0x8]\n\
cmp r1, r6\n\
bhi _08000D56\n\
str r3, [r7]\n\
str r2, [r7, 0x4]\n\
lsrs r0, r1, 1\n\
movs r1, 0x80\n\
lsls r1, 24\n\
b _08000DAA\n\
_08000D56:\n\
ldr r4, =0x040000D4 @REG_DMA3\n\
str r3, [r4]\n\
str r2, [r4, 0x4]\n\
ldr r0, =0x80000800\n\
str r0, [r4, 0x8]\n\
ldr r0, [r4, 0x8]\n\
adds r3, r6\n\
adds r2, r6\n\
subs r1, r6\n\
cmp r1, r6\n\
bhi _08000D56\n\
str r3, [r4]\n\
str r2, [r4, 0x4]\n\
lsrs r0, r1, 1\n\
movs r1, 0x80\n\
lsls r1, 24\n\
_08000D76:\n\
orrs r0, r1\n\
str r0, [r4, 0x8]\n\
ldr r0, [r4, 0x8]\n\
b _08000DF0\n\
.pool\n\
_08000D88:\n\
mov r3, r10\n\
adds r0, r5, r3\n\
ldr r2, [r0]\n\
ldrh r4, [r1, 0x8]\n\
add r1, sp, 0x4\n\
cmp r4, r6\n\
bhi _08000DB2\n\
mov r0, r8\n\
adds r0, 0xC\n\
adds r0, r5, r0\n\
ldr r0, [r0]\n\
strh r0, [r1]\n\
str r1, [r7]\n\
str r2, [r7, 0x4]\n\
lsrs r0, r4, 1\n\
movs r1, 0x81\n\
lsls r1, 24\n\
_08000DAA:\n\
orrs r0, r1\n\
str r0, [r7, 0x8]\n\
ldr r0, [r7, 0x8]\n\
b _08000DF0\n\
_08000DB2:\n\
mov r5, r12\n\
ldrb r0, [r5]\n\
lsls r0, 4\n\
ldr r3, =gDma3Requests + 0x0C\n\
adds r0, r3\n\
ldr r0, [r0]\n\
strh r0, [r1]\n\
ldr r3, =0x040000D4 @REG_DMA3\n\
str r1, [r3]\n\
str r2, [r3, 0x4]\n\
ldr r0, =0x81000800\n\
str r0, [r3, 0x8]\n\
ldr r0, [r3, 0x8]\n\
adds r2, r6\n\
subs r4, r6\n\
cmp r4, r6\n\
bhi _08000DB2\n\
ldrb r0, [r5]\n\
lsls r0, 4\n\
ldr r5, =gDma3Requests + 0x0C\n\
adds r0, r5\n\
ldr r0, [r0]\n\
strh r0, [r1]\n\
str r1, [r3]\n\
str r2, [r3, 0x4]\n\
lsrs r0, r4, 1\n\
movs r1, 0x81\n\
lsls r1, 24\n\
_08000DEA:\n\
orrs r0, r1\n\
str r0, [r3, 0x8]\n\
ldr r0, [r3, 0x8]\n\
_08000DF0:\n\
ldr r1, =gDma3Requests\n\
mov r3, r12\n\
ldrb r0, [r3]\n\
lsls r0, 4\n\
adds r0, r1\n\
mov r2, r9\n\
str r2, [r0]\n\
ldrb r0, [r3]\n\
lsls r0, 4\n\
add r0, r10\n\
str r2, [r0]\n\
ldrb r0, [r3]\n\
lsls r0, 4\n\
adds r0, r1\n\
movs r4, 0\n\
strh r2, [r0, 0x8]\n\
ldrb r0, [r3]\n\
lsls r0, 4\n\
adds r0, r1\n\
mov r5, r9\n\
strh r5, [r0, 0xA]\n\
ldrb r0, [r3]\n\
lsls r0, 4\n\
adds r1, 0xC\n\
adds r0, r1\n\
mov r1, r9\n\
str r1, [r0]\n\
ldrb r0, [r3]\n\
adds r0, 0x1\n\
strb r0, [r3]\n\
lsls r0, 24\n\
cmp r0, 0\n\
bge _08000E34\n\
strb r4, [r3]\n\
_08000E34:\n\
mov r2, r12\n\
ldrb r0, [r2]\n\
lsls r0, 4\n\
ldr r3, =gDma3Requests\n\
adds r0, r3\n\
ldrh r0, [r0, 0x8]\n\
cmp r0, 0\n\
beq _08000E46\n\
b _08000C2E\n\
_08000E46:\n\
add sp, 0xC\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
int RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
s16 RequestDma3Copy(const void *src, void *dest, u16 size, u8 mode)
{
int cursor;
int var = 0;
gDma3ManagerLocked = 1;
int i = 0;
gDma3ManagerLocked = TRUE;
cursor = gDma3RequestCursor;
while(1)
while (i < MAX_DMA_REQUESTS)
{
if(!gDma3Requests[cursor].size) // an empty copy was found and the current cursor will be returned.
if (gDma3Requests[cursor].size == 0) // an empty request was found.
{
gDma3Requests[cursor].src = src;
gDma3Requests[cursor].dest = dest;
gDma3Requests[cursor].size = size;
if(mode == 1)
gDma3Requests[cursor].mode = mode;
if (mode == 1)
gDma3Requests[cursor].mode = DMA_REQUEST_COPY32;
else
gDma3Requests[cursor].mode = 3;
gDma3Requests[cursor].mode = DMA_REQUEST_COPY16;
gDma3ManagerLocked = FALSE;
return (s16)cursor;
return cursor;
}
if(++cursor >= 0x80) // loop back to start.
{
if (++cursor >= MAX_DMA_REQUESTS) // loop back to start.
cursor = 0;
}
if(++var >= 0x80) // max checks were made. all resulted in failure.
{
break;
}
i++;
}
gDma3ManagerLocked = FALSE;
return -1;
return -1; // no free DMA request was found
}
int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
s16 RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
{
int cursor;
int var = 0;
int i = 0;
cursor = gDma3RequestCursor;
gDma3ManagerLocked = 1;
gDma3ManagerLocked = TRUE;
while(1)
while (i < MAX_DMA_REQUESTS)
{
if(!gDma3Requests[cursor].size)
if (gDma3Requests[cursor].size == 0) // an empty request was found.
{
gDma3Requests[cursor].dest = dest;
gDma3Requests[cursor].size = size;
@@ -484,41 +189,39 @@ int RequestDma3Fill(s32 value, void *dest, u16 size, u8 mode)
gDma3Requests[cursor].value = value;
if(mode == 1)
gDma3Requests[cursor].mode = 2;
gDma3Requests[cursor].mode = DMA_REQUEST_FILL32;
else
gDma3Requests[cursor].mode = 4;
gDma3Requests[cursor].mode = DMA_REQUEST_FILL16;
gDma3ManagerLocked = FALSE;
return (s16)cursor;
return cursor;
}
if(++cursor >= 0x80) // loop back to start.
{
if (++cursor >= MAX_DMA_REQUESTS) // loop back to start.
cursor = 0;
}
if(++var >= 0x80) // max checks were made. all resulted in failure.
{
break;
}
i++;
}
gDma3ManagerLocked = FALSE;
return -1;
return -1; // no free DMA request was found
}
int CheckForSpaceForDma3Request(s16 index)
{
int current = 0;
int i = 0;
if (index == -1)
if (index == -1) // check if all requests are free
{
for (; current < 0x80; current ++)
if (gDma3Requests[current].size)
while (i < MAX_DMA_REQUESTS)
{
if (gDma3Requests[i].size != 0)
return -1;
i++;
}
return 0;
}
else // check the specified request
{
if (gDma3Requests[index].size != 0)
return -1;
return 0;
}
if (gDma3Requests[index].size)
return -1;
return 0;
}

898
src/field_door.c Normal file
View File

@@ -0,0 +1,898 @@
#include "global.h"
#include "field_door.h"
#include "field_camera.h"
#include "fieldmap.h"
#include "metatile_behavior.h"
#include "event_data.h"
#include "constants/songs.h"
#include "constants/flags.h"
#include "constants/maps.h"
#include "task.h"
bool8 sub_808A964(void);
const u8 DoorAnimTiles_04[][0x100] =
{
INCBIN_U8("graphics/door_anims/04/0.4bpp"),
INCBIN_U8("graphics/door_anims/04/1.4bpp"),
INCBIN_U8("graphics/door_anims/04/2.4bpp"),
};
// TODO: Make these blank palette includes?
asm(".space 32");
const u8 DoorAnimTiles_05[][0x100] =
{
INCBIN_U8("graphics/door_anims/05/0.4bpp"),
INCBIN_U8("graphics/door_anims/05/1.4bpp"),
INCBIN_U8("graphics/door_anims/05/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_08[][0x100] =
{
INCBIN_U8("graphics/door_anims/08/0.4bpp"),
INCBIN_U8("graphics/door_anims/08/1.4bpp"),
INCBIN_U8("graphics/door_anims/08/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_15[][0x100] =
{
INCBIN_U8("graphics/door_anims/15/0.4bpp"),
INCBIN_U8("graphics/door_anims/15/1.4bpp"),
INCBIN_U8("graphics/door_anims/15/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_16[][0x100] =
{
INCBIN_U8("graphics/door_anims/16/0.4bpp"),
INCBIN_U8("graphics/door_anims/16/1.4bpp"),
INCBIN_U8("graphics/door_anims/16/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_00[][0x100] =
{
INCBIN_U8("graphics/door_anims/00/0.4bpp"),
INCBIN_U8("graphics/door_anims/00/1.4bpp"),
INCBIN_U8("graphics/door_anims/00/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_01[][0x100] =
{
INCBIN_U8("graphics/door_anims/01/0.4bpp"),
INCBIN_U8("graphics/door_anims/01/1.4bpp"),
INCBIN_U8("graphics/door_anims/01/2.4bpp"),
};
const u8 DoorAnimTiles_02[][0x100] =
{
INCBIN_U8("graphics/door_anims/02/0.4bpp"),
INCBIN_U8("graphics/door_anims/02/1.4bpp"),
INCBIN_U8("graphics/door_anims/02/2.4bpp"),
};
const u8 DoorAnimTiles_03[][0x100] =
{
INCBIN_U8("graphics/door_anims/03/0.4bpp"),
INCBIN_U8("graphics/door_anims/03/1.4bpp"),
INCBIN_U8("graphics/door_anims/03/2.4bpp"),
};
const u8 DoorAnimTiles_06[][0x100] =
{
INCBIN_U8("graphics/door_anims/06/0.4bpp"),
INCBIN_U8("graphics/door_anims/06/1.4bpp"),
INCBIN_U8("graphics/door_anims/06/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_07[][0x100] =
{
INCBIN_U8("graphics/door_anims/07/0.4bpp"),
INCBIN_U8("graphics/door_anims/07/1.4bpp"),
INCBIN_U8("graphics/door_anims/07/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_09[][0x100] =
{
INCBIN_U8("graphics/door_anims/09/0.4bpp"),
INCBIN_U8("graphics/door_anims/09/1.4bpp"),
INCBIN_U8("graphics/door_anims/09/2.4bpp"),
};
asm(".space 0x5900");
const u8 DoorAnimTiles_UnusedTops[][0x40] =
{
INCBIN_U8("graphics/door_anims/unused_848EDEC/0_top.4bpp"),
INCBIN_U8("graphics/door_anims/unused_848EDEC/1_top.4bpp"),
INCBIN_U8("graphics/door_anims/unused_848EDEC/2_top.4bpp"),
};
asm(".space 0x140");
const u8 DoorAnimTiles_UnusedBottoms[][0x40] =
{
INCBIN_U8("graphics/door_anims/unused_848EDEC/0_bottom.4bpp"),
INCBIN_U8("graphics/door_anims/unused_848EDEC/1_bottom.4bpp"),
INCBIN_U8("graphics/door_anims/unused_848EDEC/2_bottom.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_10[][0x100] =
{
INCBIN_U8("graphics/door_anims/10/0.4bpp"),
INCBIN_U8("graphics/door_anims/10/1.4bpp"),
INCBIN_U8("graphics/door_anims/10/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_11[][0x100] =
{
INCBIN_U8("graphics/door_anims/11/0.4bpp"),
INCBIN_U8("graphics/door_anims/11/1.4bpp"),
INCBIN_U8("graphics/door_anims/11/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_12[][0x100] =
{
INCBIN_U8("graphics/door_anims/12/0.4bpp"),
INCBIN_U8("graphics/door_anims/12/1.4bpp"),
INCBIN_U8("graphics/door_anims/12/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_13[][0x100] =
{
INCBIN_U8("graphics/door_anims/13/0.4bpp"),
INCBIN_U8("graphics/door_anims/13/1.4bpp"),
INCBIN_U8("graphics/door_anims/13/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_14[][0x100] =
{
INCBIN_U8("graphics/door_anims/14/0.4bpp"),
INCBIN_U8("graphics/door_anims/14/1.4bpp"),
INCBIN_U8("graphics/door_anims/14/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_17[][0x100] =
{
INCBIN_U8("graphics/door_anims/17/0.4bpp"),
INCBIN_U8("graphics/door_anims/17/1.4bpp"),
INCBIN_U8("graphics/door_anims/17/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_18[][0x100] =
{
INCBIN_U8("graphics/door_anims/18/0.4bpp"),
INCBIN_U8("graphics/door_anims/18/1.4bpp"),
INCBIN_U8("graphics/door_anims/18/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_19[][0x100] =
{
INCBIN_U8("graphics/door_anims/19/0.4bpp"),
INCBIN_U8("graphics/door_anims/19/1.4bpp"),
INCBIN_U8("graphics/door_anims/19/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_20[][0x100] =
{
INCBIN_U8("graphics/door_anims/20/0.4bpp"),
INCBIN_U8("graphics/door_anims/20/1.4bpp"),
INCBIN_U8("graphics/door_anims/20/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_21[][0x100] =
{
INCBIN_U8("graphics/door_anims/21/0.4bpp"),
INCBIN_U8("graphics/door_anims/21/1.4bpp"),
INCBIN_U8("graphics/door_anims/21/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_22[][0x100] =
{
INCBIN_U8("graphics/door_anims/22/0.4bpp"),
INCBIN_U8("graphics/door_anims/22/1.4bpp"),
INCBIN_U8("graphics/door_anims/22/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_23[][0x100] =
{
INCBIN_U8("graphics/door_anims/23/0.4bpp"),
INCBIN_U8("graphics/door_anims/23/1.4bpp"),
INCBIN_U8("graphics/door_anims/23/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_24[][0x100] =
{
INCBIN_U8("graphics/door_anims/24/0.4bpp"),
INCBIN_U8("graphics/door_anims/24/1.4bpp"),
INCBIN_U8("graphics/door_anims/24/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_25[][0x100] =
{
INCBIN_U8("graphics/door_anims/25/0.4bpp"),
INCBIN_U8("graphics/door_anims/25/1.4bpp"),
INCBIN_U8("graphics/door_anims/25/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_26[][0x100] =
{
INCBIN_U8("graphics/door_anims/26/0.4bpp"),
INCBIN_U8("graphics/door_anims/26/1.4bpp"),
INCBIN_U8("graphics/door_anims/26/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_27[][0x100] =
{
INCBIN_U8("graphics/door_anims/27/0.4bpp"),
INCBIN_U8("graphics/door_anims/27/1.4bpp"),
INCBIN_U8("graphics/door_anims/27/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_28[][0x100] =
{
INCBIN_U8("graphics/door_anims/28/0.4bpp"),
INCBIN_U8("graphics/door_anims/28/1.4bpp"),
INCBIN_U8("graphics/door_anims/28/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_29[][0x100] =
{
INCBIN_U8("graphics/door_anims/29/0.4bpp"),
INCBIN_U8("graphics/door_anims/29/1.4bpp"),
INCBIN_U8("graphics/door_anims/29/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_30[][0x100] =
{
INCBIN_U8("graphics/door_anims/30/0.4bpp"),
INCBIN_U8("graphics/door_anims/30/1.4bpp"),
INCBIN_U8("graphics/door_anims/30/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_31[][0x100] =
{
INCBIN_U8("graphics/door_anims/31/0.4bpp"),
INCBIN_U8("graphics/door_anims/31/1.4bpp"),
INCBIN_U8("graphics/door_anims/31/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_32[][0x100] =
{
INCBIN_U8("graphics/door_anims/32/0.4bpp"),
INCBIN_U8("graphics/door_anims/32/1.4bpp"),
INCBIN_U8("graphics/door_anims/32/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_33[][0x100] =
{
INCBIN_U8("graphics/door_anims/33/0.4bpp"),
INCBIN_U8("graphics/door_anims/33/1.4bpp"),
INCBIN_U8("graphics/door_anims/33/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_34[][0x100] =
{
INCBIN_U8("graphics/door_anims/34/0.4bpp"),
INCBIN_U8("graphics/door_anims/34/1.4bpp"),
INCBIN_U8("graphics/door_anims/34/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_35[][0x100] =
{
INCBIN_U8("graphics/door_anims/35/0.4bpp"),
INCBIN_U8("graphics/door_anims/35/1.4bpp"),
INCBIN_U8("graphics/door_anims/35/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_36[][0x100] =
{
INCBIN_U8("graphics/door_anims/36/0.4bpp"),
INCBIN_U8("graphics/door_anims/36/1.4bpp"),
INCBIN_U8("graphics/door_anims/36/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_37[][0x100] =
{
INCBIN_U8("graphics/door_anims/37/0.4bpp"),
INCBIN_U8("graphics/door_anims/37/1.4bpp"),
INCBIN_U8("graphics/door_anims/37/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_38[][0x100] =
{
INCBIN_U8("graphics/door_anims/38/0.4bpp"),
INCBIN_U8("graphics/door_anims/38/1.4bpp"),
INCBIN_U8("graphics/door_anims/38/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_39[][0x100] =
{
INCBIN_U8("graphics/door_anims/39/0.4bpp"),
INCBIN_U8("graphics/door_anims/39/1.4bpp"),
INCBIN_U8("graphics/door_anims/39/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_40[][0x100] =
{
INCBIN_U8("graphics/door_anims/40/0.4bpp"),
INCBIN_U8("graphics/door_anims/40/1.4bpp"),
INCBIN_U8("graphics/door_anims/40/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_41[][0x100] =
{
INCBIN_U8("graphics/door_anims/41/0.4bpp"),
INCBIN_U8("graphics/door_anims/41/1.4bpp"),
INCBIN_U8("graphics/door_anims/41/2.4bpp"),
};
const u8 DoorAnimTiles_42[][0x100] =
{
INCBIN_U8("graphics/door_anims/42/0.4bpp"),
INCBIN_U8("graphics/door_anims/42/1.4bpp"),
INCBIN_U8("graphics/door_anims/42/2.4bpp"),
INCBIN_U8("graphics/door_anims/42/3.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_43[][0x100] =
{
INCBIN_U8("graphics/door_anims/43/0.4bpp"),
INCBIN_U8("graphics/door_anims/43/1.4bpp"),
INCBIN_U8("graphics/door_anims/43/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_44[][0x100] =
{
INCBIN_U8("graphics/door_anims/44/0_left.4bpp"),
INCBIN_U8("graphics/door_anims/44/0_right.4bpp"),
INCBIN_U8("graphics/door_anims/44/1_left.4bpp"),
INCBIN_U8("graphics/door_anims/44/1_right.4bpp"),
INCBIN_U8("graphics/door_anims/44/2_left.4bpp"),
INCBIN_U8("graphics/door_anims/44/2_right.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_45[][0x100] =
{
INCBIN_U8("graphics/door_anims/45/0.4bpp"),
INCBIN_U8("graphics/door_anims/45/1.4bpp"),
INCBIN_U8("graphics/door_anims/45/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_46[][0x100] =
{
INCBIN_U8("graphics/door_anims/46/0.4bpp"),
INCBIN_U8("graphics/door_anims/46/1.4bpp"),
INCBIN_U8("graphics/door_anims/46/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_47[][0x100] =
{
INCBIN_U8("graphics/door_anims/47/0.4bpp"),
INCBIN_U8("graphics/door_anims/47/1.4bpp"),
INCBIN_U8("graphics/door_anims/47/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_48[][0x100] =
{
INCBIN_U8("graphics/door_anims/48/0.4bpp"),
INCBIN_U8("graphics/door_anims/48/1.4bpp"),
INCBIN_U8("graphics/door_anims/48/2.4bpp"),
INCBIN_U8("graphics/door_anims/48/3.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_49[][0x100] =
{
INCBIN_U8("graphics/door_anims/49/0.4bpp"),
INCBIN_U8("graphics/door_anims/49/1.4bpp"),
INCBIN_U8("graphics/door_anims/49/2.4bpp"),
};
asm(".space 32");
const u8 DoorAnimTiles_50[][0x100] =
{
INCBIN_U8("graphics/door_anims/50/0.4bpp"),
INCBIN_U8("graphics/door_anims/50/1.4bpp"),
INCBIN_U8("graphics/door_anims/50/2.4bpp"),
};
asm(".space 32");
static const struct DoorAnimFrame gDoorOpenAnimFrames[] =
{
{4, -1},
{4, 0},
{4, 0x100},
{4, 0x200},
{0, 0},
};
static const struct DoorAnimFrame gDoorCloseAnimFrames[] =
{
{4, 0x200},
{4, 0x100},
{4, 0},
{4, -1},
{0, 0},
};
static const struct DoorAnimFrame gBigDoorOpenAnimFrames[] =
{
{4, -1},
{4, 0},
{4, 0x200},
{4, 0x400},
{0, 0},
};
static const struct DoorAnimFrame gBigDoorCloseAnimFrames[] =
{
{4, 0x400},
{4, 0x200},
{4, 0},
{4, -1},
{0, 0},
};
const u8 DoorAnimPalettes_8496FDC[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 00
const u8 DoorAnimPalettes_8496FE4[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 01
const u8 DoorAnimPalettes_8496FEC[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 02
const u8 DoorAnimPalettes_8496FF4[] = {0, 0, 1, 1, 1, 1, 1, 1}; // door 03
const u8 DoorAnimPalettes_8496FFC[] = {10, 10, 6, 6, 6, 6, 6, 6}; // door 04
const u8 DoorAnimPalettes_8497004[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 05
const u8 DoorAnimPalettes_849700C[] = {11, 11, 11, 11, 11, 11, 11, 11}; // door 06
const u8 DoorAnimPalettes_8497014[] = {10, 10, 10, 10, 10, 10, 10, 10}; // door 07
const u8 DoorAnimPalettes_849701C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 08
const u8 DoorAnimPalettes_8497024[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 09
const u8 DoorAnimPalettes_849702C[] = {10, 10, 9, 9, 9, 9, 9, 9}; // door 10
const u8 DoorAnimPalettes_8497034[] = {9, 9, 1, 1, 1, 1, 1, 1}; // door 11
const u8 DoorAnimPalettes_849703C[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 12
const u8 DoorAnimPalettes_8497044[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 13
const u8 DoorAnimPalettes_849704C[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 14
const u8 DoorAnimPalettes_8497054[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 15
const u8 DoorAnimPalettes_849705C[] = {0, 0, 5, 5, 5, 5, 5, 5}; // door 16
const u8 DoorAnimPalettes_8497064[] = {6, 6, 1, 1, 1, 1, 1, 1}; // door 17
const u8 DoorAnimPalettes_849706C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 18
const u8 DoorAnimPalettes_8497074[] = {6, 6, 5, 5, 5, 5, 5, 5}; // door 19
const u8 DoorAnimPalettes_849707C[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 20
const u8 DoorAnimPalettes_8497084[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 21
const u8 DoorAnimPalettes_849708C[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 22
const u8 DoorAnimPalettes_8497094[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 23
const u8 DoorAnimPalettes_849709C[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 24
const u8 DoorAnimPalettes_84970A4[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 25
const u8 DoorAnimPalettes_84970AC[] = {8, 8, 8, 8, 8, 8, 8, 8}; // door 26
const u8 DoorAnimPalettes_84970B4[] = {6, 6, 6, 6, 6, 6, 6, 6}; // door 27
const u8 DoorAnimPalettes_84970BC[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 28
const u8 DoorAnimPalettes_84970C4[] = {11, 11, 7, 7, 7, 7, 7, 7}; // door 29
const u8 DoorAnimPalettes_84970CC[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 30
const u8 DoorAnimPalettes_84970D4[] = {6, 6, 7, 7, 7, 7, 7, 7}; // door 31
const u8 DoorAnimPalettes_84970DC[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 32
const u8 DoorAnimPalettes_84970E4[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 33
const u8 DoorAnimPalettes_84970EC[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 34
const u8 DoorAnimPalettes_84970F4[] = {1, 1, 1, 1, 1, 1, 1, 1}; // door 35
const u8 DoorAnimPalettes_84970FC[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 36
const u8 DoorAnimPalettes_8497104[] = {0, 0, 0, 0, 0, 0, 0, 0}; // door 37
const u8 DoorAnimPalettes_849710C[] = {5, 5, 5, 5, 5, 5, 5, 5}; // door 38
const u8 DoorAnimPalettes_8497114[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 39
const u8 DoorAnimPalettes_849711C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 40
const u8 DoorAnimPalettes_8497124[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 41
const u8 DoorAnimPalettes_849712C[] = {1, 1, 1, 1, 1, 1, 1, 1}; // doors 42, 43, and 44
const u8 DoorAnimPalettes_8497134[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 45
const u8 DoorAnimPalettes_849713C[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 46
const u8 DoorAnimPalettes_8497144[] = {1, 1, 1, 1, 1, 1, 1, 1}; // unused
const u8 DoorAnimPalettes_849714C[] = {1, 1, 1, 1, 1, 1, 1, 1}; // doors 47 and 48
const u8 DoorAnimPalettes_8497154[] = {9, 9, 7, 7, 7, 7, 7, 7}; // door 49
const u8 DoorAnimPalettes_849715C[] = {9, 9, 9, 9, 9, 9, 9, 9}; // door 50
const u8 DoorAnimPalettes_8497164[] = {7, 7, 7, 7, 7, 7, 7, 7}; // door 51
const u8 DoorAnimPalettes_849716C[] = {9, 9, 7, 7, 7, 7, 7, 7}; // door 52
static const struct DoorGraphics gDoorAnimGraphicsTable[] =
{
{0x021, 0, 1, DoorAnimTiles_00, DoorAnimPalettes_8496FDC}, // door 00
{0x061, 1, 1, DoorAnimTiles_01, DoorAnimPalettes_8496FE4}, // door 01
{0x1CD, 1, 1, DoorAnimTiles_02, DoorAnimPalettes_8496FEC}, // door 02
{0x041, 1, 1, DoorAnimTiles_03, DoorAnimPalettes_8496FF4}, // door 03
{0x248, 0, 1, DoorAnimTiles_04, DoorAnimPalettes_8496FFC}, // door 04
{0x249, 0, 1, DoorAnimTiles_05, DoorAnimPalettes_8497004}, // door 05
{0x22F, 0, 1, DoorAnimTiles_06, DoorAnimPalettes_849700C}, // door 06
{0x21F, 0, 1, DoorAnimTiles_07, DoorAnimPalettes_8497014}, // door 07
{0x2A5, 0, 1, DoorAnimTiles_08, DoorAnimPalettes_849701C}, // door 08
{0x287, 0, 1, DoorAnimTiles_09, DoorAnimPalettes_849702C}, // door 09
{0x2AC, 0, 1, DoorAnimTiles_10, DoorAnimPalettes_849706C}, // door 10
{0x3A1, 0, 1, DoorAnimTiles_11, DoorAnimPalettes_8497074}, // door 11
{0x2DC, 0, 1, DoorAnimTiles_12, DoorAnimPalettes_8497064}, // door 12
{0x225, 0, 1, DoorAnimTiles_13, DoorAnimPalettes_849705C}, // door 13
{0x1DB, 1, 1, DoorAnimTiles_14, DoorAnimPalettes_8497084}, // door 14
{0x246, 0, 1, DoorAnimTiles_15, DoorAnimPalettes_8497024}, // door 15
{0x28E, 0, 1, DoorAnimTiles_16, DoorAnimPalettes_849707C}, // door 16
{0x2A1, 0, 1, DoorAnimTiles_17, DoorAnimPalettes_8497034}, // door 17
{0x21C, 0, 1, DoorAnimTiles_18, DoorAnimPalettes_849704C}, // door 18
{0x21E, 0, 1, DoorAnimTiles_19, DoorAnimPalettes_8497054}, // door 19
{0x21D, 1, 1, DoorAnimTiles_20, DoorAnimPalettes_849703C}, // door 20
{0x21A, 0, 1, DoorAnimTiles_21, DoorAnimPalettes_8497044}, // door 21
{0x224, 0, 1, DoorAnimTiles_22, DoorAnimPalettes_849708C}, // door 22
{0x289, 0, 1, DoorAnimTiles_23, DoorAnimPalettes_8497094}, // door 23
{0x30C, 1, 1, DoorAnimTiles_24, DoorAnimPalettes_849709C}, // door 24
{0x32D, 1, 1, DoorAnimTiles_25, DoorAnimPalettes_84970A4}, // door 25
{0x2ED, 1, 1, DoorAnimTiles_26, DoorAnimPalettes_84970AC}, // door 26
{0x264, 1, 1, DoorAnimTiles_27, DoorAnimPalettes_84970B4}, // door 27
{0x22B, 0, 1, DoorAnimTiles_28, DoorAnimPalettes_84970BC}, // door 28
{0x2F7, 0, 1, DoorAnimTiles_29, DoorAnimPalettes_84970C4}, // door 29
{0x297, 0, 1, DoorAnimTiles_30, DoorAnimPalettes_84970CC}, // door 30
{0x285, 1, 1, DoorAnimTiles_31, DoorAnimPalettes_84970D4}, // door 31
{0x25D, 1, 1, DoorAnimTiles_32, DoorAnimPalettes_84970DC}, // door 32
{0x20E, 1, 1, DoorAnimTiles_33, DoorAnimPalettes_84970E4}, // door 33
{0x3B0, 1, 1, DoorAnimTiles_34, DoorAnimPalettes_84970EC}, // door 34
{0x28A, 1, 1, DoorAnimTiles_35, DoorAnimPalettes_84970F4}, // door 35
{0x263, 1, 1, DoorAnimTiles_36, DoorAnimPalettes_84970FC}, // door 36
{0x329, 1, 1, DoorAnimTiles_37, DoorAnimPalettes_8497104}, // door 37
{0x291, 0, 1, DoorAnimTiles_38, DoorAnimPalettes_849710C}, // door 38
{0x21B, 2, 1, DoorAnimTiles_39, DoorAnimPalettes_8497114}, // door 39
{0x209, 1, 1, DoorAnimTiles_40, DoorAnimPalettes_849711C}, // door 40
{0x219, 0, 1, DoorAnimTiles_41, DoorAnimPalettes_8497124}, // door 41
{0x393, 1, 1, DoorAnimTiles_42, DoorAnimPalettes_849712C}, // door 42
{0x3D4, 1, 1, DoorAnimTiles_42, DoorAnimPalettes_849712C}, // door 43
{0x36C, 1, 1, DoorAnimTiles_42, DoorAnimPalettes_849712C}, // door 44
{0x25E, 1, 1, DoorAnimTiles_43, DoorAnimPalettes_8497134}, // door 45
{0x2AD, 1, 2, DoorAnimTiles_44, DoorAnimPalettes_849713C}, // door 46
{0x3FC, 0, 1, DoorAnimTiles_45, DoorAnimPalettes_849714C}, // door 47
{0x396, 1, 1, DoorAnimTiles_46, DoorAnimPalettes_849714C}, // door 48
{0x20A, 1, 1, DoorAnimTiles_47, DoorAnimPalettes_8497154}, // door 49
{0x26B, 1, 1, DoorAnimTiles_48, DoorAnimPalettes_849715C}, // door 50
{0x32C, 1, 1, DoorAnimTiles_49, DoorAnimPalettes_8497164}, // door 51
{0x383, 1, 1, DoorAnimTiles_50, DoorAnimPalettes_849716C}, // door 52
{0, 0, 0, NULL, NULL},
};
static void CopyDoorTilesToVram(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frame)
{
if (gfx->size == 2)
CpuFastSet(gfx->tiles + frame->offset, (void *)(VRAM + 0x7E00), 0x80);
else
CpuFastSet(gfx->tiles + frame->offset, (void *)(VRAM + 0x7F00), 0x40);
}
static void door_build_blockdef(u16 *a, u16 b, const u8 *c)
{
int i;
u16 unk;
for (i = 0; i < 4; i++)
{
unk = *(c++) << 12;
a[i] = unk | (b + i);
}
for (; i < 8; i++)
{
unk = *(c++) << 12;
a[i] = unk;
}
}
static void DrawCurrentDoorAnimFrame(const struct DoorGraphics *gfx, u32 x, u32 y, const u8 *pal)
{
u16 arr[24];
if (gfx->size == 2)
{
door_build_blockdef(&arr[8], 0x3F0, pal);
DrawDoorMetatileAt(x, y - 1, &arr[8]);
door_build_blockdef(&arr[8], 0x3F4, pal + 4);
DrawDoorMetatileAt(x, y, &arr[8]);
door_build_blockdef(&arr[8], 0x3F8, pal);
DrawDoorMetatileAt(x + 1, y - 1, &arr[8]);
door_build_blockdef(&arr[8], 0x3FC, pal + 4);
DrawDoorMetatileAt(x + 1, y, &arr[8]);
}
else
{
door_build_blockdef(&arr[0], 0x3F8, pal);
DrawDoorMetatileAt(x, y - 1, &arr[0]);
door_build_blockdef(&arr[0], 0x3FC, pal + 4);
DrawDoorMetatileAt(x, y, &arr[0]);
}
}
static void DrawClosedDoorTiles(const struct DoorGraphics *gfx, u32 x, u32 y)
{
CurrentMapDrawMetatileAt(x, y - 1);
CurrentMapDrawMetatileAt(x, y);
if (gfx->size == 2)
{
CurrentMapDrawMetatileAt(x + 1, y - 1);
CurrentMapDrawMetatileAt(x + 1, y);
}
}
static void DrawDoor(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frame, u32 x, u32 y)
{
if (frame->offset == 0xFFFF)
{
DrawClosedDoorTiles(gfx, x, y);
if (sub_808A964())
DrawClosedDoorTiles(gfx, gSpecialVar_0x8004 + 7, gSpecialVar_0x8005 + 7);
}
else
{
CopyDoorTilesToVram(gfx, frame);
DrawCurrentDoorAnimFrame(gfx, x, y, gfx->palette);
if (sub_808A964())
DrawCurrentDoorAnimFrame(gfx, gSpecialVar_0x8004 + 7, gSpecialVar_0x8005 + 7, gfx->palette);
}
}
enum
{
TD_FRAMELIST = 0,
TD_GFX = 2,
TD_FRAME = 4,
TD_COUNTER,
TD_X,
TD_Y
};
static bool32 sub_808A5F0(struct DoorGraphics *gfx, struct DoorAnimFrame *frames, s16 *taskData)
{
if (taskData[TD_COUNTER] == 0)
DrawDoor(gfx, &frames[taskData[TD_FRAME]], taskData[TD_X], taskData[TD_Y]);
if (taskData[TD_COUNTER] == frames[taskData[TD_FRAME]].time)
{
taskData[TD_COUNTER] = 0;
taskData[TD_FRAME]++;
if (frames[taskData[TD_FRAME]].time == 0)
return FALSE;
else
return TRUE;
}
taskData[TD_COUNTER]++;
return TRUE;
}
static void Task_AnimateDoor(u8 taskId)
{
u16 *taskData = gTasks[taskId].data;
struct DoorAnimFrame *frames = (struct DoorAnimFrame *)(taskData[TD_FRAMELIST] << 16 | taskData[TD_FRAMELIST + 1]);
struct DoorGraphics *gfx = (struct DoorGraphics *)(taskData[TD_GFX] << 16 | taskData[TD_GFX + 1]);
if (sub_808A5F0(gfx, frames, taskData) == FALSE)
DestroyTask(taskId);
}
static const struct DoorAnimFrame *GetLastDoorFrame(const struct DoorAnimFrame *frame, const void *unused)
{
while (frame->time != 0)
frame++;
return frame - 1;
}
static const struct DoorGraphics *GetDoorGraphics(const struct DoorGraphics *gfx, u16 metatileNum)
{
while (gfx->tiles != NULL)
{
if (gfx->metatileNum == metatileNum)
return gfx;
gfx++;
}
return NULL;
}
static s8 StartDoorAnimationTask(const struct DoorGraphics *gfx, const struct DoorAnimFrame *frames, u32 x, u32 y)
{
if (FuncIsActiveTask(Task_AnimateDoor) == TRUE)
return -1;
else
{
u8 taskId = CreateTask(Task_AnimateDoor, 0x50);
s16 *taskData = gTasks[taskId].data;
taskData[TD_X] = x;
taskData[TD_Y] = y;
taskData[TD_FRAMELIST + 1] = (u32)frames;
taskData[TD_FRAMELIST] = (u32)frames >> 16;
taskData[TD_GFX + 1] = (u32)gfx;
taskData[TD_GFX] = (u32)gfx >> 16;
return taskId;
}
}
static void DrawClosedDoor(const struct DoorGraphics *gfx, u32 x, u32 y)
{
DrawClosedDoorTiles(gfx, x, y);
}
static void DrawOpenedDoor(const struct DoorGraphics *gfx, u32 x, u32 y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx != NULL)
DrawDoor(gfx, GetLastDoorFrame(gDoorOpenAnimFrames, gDoorOpenAnimFrames), x, y);
}
static s8 StartDoorOpenAnimation(const struct DoorGraphics *gfx, u32 x, u32 y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx == NULL)
{
return -1;
}
else
{
if (gfx->size == 2)
return StartDoorAnimationTask(gfx, gBigDoorOpenAnimFrames, x, y);
else
return StartDoorAnimationTask(gfx, gDoorOpenAnimFrames, x, y);
}
}
static s8 StartDoorCloseAnimation(const struct DoorGraphics *gfx, u32 x, u32 y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx == NULL)
return -1;
else
return StartDoorAnimationTask(gfx, gDoorCloseAnimFrames, x, y);
}
static s8 cur_mapdata_get_door_x2_at(const struct DoorGraphics *gfx, u32 x, u32 y)
{
gfx = GetDoorGraphics(gfx, MapGridGetMetatileIdAt(x, y));
if (gfx == NULL)
return -1;
else
return gfx->sound;
}
void unref_sub_808A83C(u32 x, u32 y)
{
StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
}
void FieldSetDoorOpened(u32 x, u32 y)
{
if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
DrawOpenedDoor(gDoorAnimGraphicsTable, x, y);
}
void FieldSetDoorClosed(u32 x, u32 y)
{
if (MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
DrawClosedDoor(gDoorAnimGraphicsTable, x, y);
}
s8 FieldAnimateDoorClose(u32 x, u32 y)
{
if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
return -1;
else
return StartDoorCloseAnimation(gDoorAnimGraphicsTable, x, y);
}
s8 FieldAnimateDoorOpen(u32 x, u32 y)
{
if (!MetatileBehavior_IsDoor(MapGridGetMetatileBehaviorAt(x, y)))
return -1;
else
return StartDoorOpenAnimation(gDoorAnimGraphicsTable, x, y);
}
bool8 FieldIsDoorAnimationRunning(void)
{
return FuncIsActiveTask(Task_AnimateDoor);
}
u32 GetDoorSoundEffect(u32 x, u32 y)
{
int sound = cur_mapdata_get_door_x2_at(gDoorAnimGraphicsTable, x, y);
if (sound == 0)
return SE_DOOR;
else if (sound == 1)
return SE_JIDO_DOA;
else if (sound == 2)
return SE_TU_SAA;
else
return SE_DOOR;
}
bool8 sub_808A964(void)
{
if (FlagGet(FLAG_SPECIAL_FLAG_0x4002))
{
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR_2) && gSaveBlock1Ptr->location.mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_CORRIDOR_2))
{
return TRUE;
}
}
return FALSE;
}

46
src/fldeff_teleport.c Normal file
View File

@@ -0,0 +1,46 @@
#include "global.h"
#include "fldeff_teleport.h"
#include "field_effect.h"
#include "field_player_avatar.h"
#include "party_menu.h"
#include "overworld.h"
#include "rom6.h"
#include "task.h"
extern bool8 (*gUnknown_03005DB0)(void);
extern void (*gUnknown_0203CEEC)(void);
bool8 SetUpFieldMove_Teleport(void)
{
if (Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType) == TRUE)
{
gUnknown_03005DB0 = FieldCallback_Teleport;
gUnknown_0203CEEC = hm_teleport_run_dp02scr;
return TRUE;
}
return FALSE;
}
void hm_teleport_run_dp02scr(void)
{
Overworld_ResetStateAfterTeleport();
FieldEffectStart(FLDEFF_USE_TELEPORT);
gFieldEffectArguments[0] = (u32)GetCursorSelectionMonId();
}
bool8 FldEff_UseTeleport(void)
{
u8 taskId = oei_task_add();
gTasks[taskId].data[8] = (u32)sub_817C94C >> 16;
gTasks[taskId].data[9] = (u32)sub_817C94C;
SetPlayerAvatarTransitionFlags(1);
return FALSE;
}
void sub_817C94C(void)
{
FieldEffectActiveListRemove(FLDEFF_USE_TELEPORT);
sub_80B7FC8();
}

View File

@@ -1,173 +0,0 @@
#include "global.h"
#include <stddef.h>
#define LBLOCKSIZE (sizeof(long))
// Nonzero if (long)X contains a NULL byte.
#define CONTAINSNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
// Nonzero if X is not aligned on a "long" boundary.
#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
void *memcpy(void *dst0, const void *src0, size_t len0)
{
char *dst = dst0;
const char *src = src0;
long *aligned_dst;
const long *aligned_src;
unsigned int len = len0;
// If the size is small, or either src or dst is unaligned,
// then go to the byte copy loop. This should be rare.
if(len >= 16 && !(UNALIGNED(src) | UNALIGNED(dst)))
{
aligned_dst = (long *)dst;
aligned_src = (long *)src;
// Copy 4X long words at a time if possible.
while(len >= 16)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= 16;
}
// Copy one long word at a time if possible
while(len >= 4)
{
*aligned_dst++ = *aligned_src++;
len -= 4;
}
dst = (char *)aligned_dst;
src = (char *)aligned_src;
}
// Pick up any remaining bytes with a byte copier.
while(len--)
*dst++ = *src++;
return dst0;
}
void *memset(void *m, int c, size_t n)
{
char *s = (char *)m;
int count, i;
unsigned long buffer;
unsigned long *aligned_addr;
unsigned char *unaligned_addr;
// If the size is small or m is unaligned,
// then go to the byte copy loop. This should be rare.
if(n >= LBLOCKSIZE && !UNALIGNED(m))
{
// We know that n is large and m is word-aligned.
aligned_addr = (unsigned long *)m;
// Store C into each char sized location in buffer so that
// we can set large blocks quickly.
c &= 0xFF;
if(LBLOCKSIZE == 4)
{
buffer = (c << 8) | c;
buffer |= (buffer << 16);
}
else
{
buffer = 0;
for(i = 0; i < LBLOCKSIZE; i++)
buffer = (buffer << 8) | c;
}
while(n >= LBLOCKSIZE * 4)
{
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
*aligned_addr++ = buffer;
n -= LBLOCKSIZE * 4;
}
while(n >= LBLOCKSIZE)
{
*aligned_addr++ = buffer;
n -= LBLOCKSIZE;
}
s = (char *)aligned_addr;
}
// Pick up the remainder with a bytewise loop.
while(n--)
*s++ = (char)c;
return m;
}
int strcmp(const char *s1, const char *s2)
{
unsigned long *a1;
unsigned long *a2;
// If s1 or s2 are unaligned, then skip this and compare bytes.
if(!(UNALIGNED(s1) | UNALIGNED(s2)))
{
// Compare them a word at a time.
a1 = (unsigned long *)s1;
a2 = (unsigned long *)s2;
while(*a1 == *a2)
{
// If *a1 == *a2, and we find a null in *a1,
// then the strings must be equal, so return zero.
if(CONTAINSNULL(*a1))
return 0;
a1++;
a2++;
}
s1 = (char *)a1;
s2 = (char *)a2;
}
// Check the remaining few bytes.
while(*s1 != '\0' && *s1 == *s2)
{
s1++;
s2++;
}
return (*(unsigned char *) s1) - (*(unsigned char *) s2);
}
char* strcpy(char *dst0, const char *src0)
{
char *dst = dst0;
const char *src = src0;
unsigned long *a1;
const unsigned long *a2;
// If SRC or DEST is unaligned, then copy bytes.
if(!(UNALIGNED(src) | UNALIGNED(dst)))
{
// SRC and DEST are both "long int" aligned, try to do "long int"
// sized copies.
a1 = (unsigned long *)dst;
a2 = (unsigned long *)src;
while(!CONTAINSNULL(*a2))
{
*a1++ = *a2++;
}
dst = (char *)a1;
src = (char *)a2;
}
// Copy the remaining few bytes.
while(*dst++ = *src++);
return dst0;
}

177
src/libisagbprn.c Executable file
View File

@@ -0,0 +1,177 @@
#include <stdarg.h>
#include <stdio.h>
#include "gba/gba.h"
#include "config.h"
#define AGB_PRINT_FLUSH_ADDR 0x9FE209D
#define AGB_PRINT_STRUCT_ADDR 0x9FE20F8
#define AGB_PRINT_PROTECT_ADDR 0x9FE2FFE
#define WSCNT_DATA (WAITCNT_PHI_OUT_16MHZ | WAITCNT_WS0_S_2 | WAITCNT_WS0_N_4)
// originally for auto no$gba support, the string "no$gba" should be at this address,
// the user needs to read this string out as the memory viewer won't show it.
#define NOCASHGBAIDADDR 0x4FFFA00
#define NOCASHGBAPRINTADDR1 0x4FFFA10 // automatically adds a newline after the string has finished
#define NOCASHGBAPRINTADDR2 0x4FFFA14 // does not automatically add the newline. by default, NOCASHGBAPRINTADDR2 is used. this is used to keep strings consistent between no$gba and VBA-RR, but a user can choose to forgo this.
struct AGBPrintStruct
{
u16 m_nRequest;
u16 m_nBank;
u16 m_nGet;
u16 m_nPut;
};
typedef void (*LPFN_PRINT_FLUSH)(void);
#ifndef NDEBUG
void AGBPrintFlush1Block(void);
void AGBPrintInit(void)
{
volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
u16 nOldWSCNT = *pWSCNT;
*pWSCNT = WSCNT_DATA;
*pProtect = 0x20;
pPrint->m_nRequest = pPrint->m_nGet = pPrint->m_nPut = 0;
pPrint->m_nBank = 0xFD;
*pProtect = 0;
*pWSCNT = nOldWSCNT;
}
static void AGBPutcInternal(const char cChr)
{
volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
u16 *pPrintBuf = (u16 *)(0x8000000 + (pPrint->m_nBank << 16));
u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
u16 nData = pPrintBuf[pPrint->m_nPut / 2];
*pProtect = 0x20;
nData = (pPrint->m_nPut & 1) ? (nData & 0xFF) | (cChr << 8) : (nData & 0xFF00) | cChr;
pPrintBuf[pPrint->m_nPut / 2] = nData;
pPrint->m_nPut++;
*pProtect = 0;
}
void AGBPutc(const char cChr)
{
u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
u16 nOldWSCNT = *pWSCNT;
volatile struct AGBPrintStruct *pPrint;
*pWSCNT = WSCNT_DATA;
AGBPutcInternal(cChr);
*pWSCNT = nOldWSCNT;
pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
if (pPrint->m_nPut == ((pPrint->m_nGet - 1) & 0xFFFF))
AGBPrintFlush1Block();
}
void AGBPrint(const char *pBuf)
{
volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
u16 nOldWSCNT = *pWSCNT;
*pWSCNT = WSCNT_DATA;
while (*pBuf)
{
AGBPutc(*pBuf);
pBuf++;
}
*pWSCNT = nOldWSCNT;
}
void AGBPrintf(const char *pBuf, ...)
{
char bufPrint[0x100];
va_list vArgv;
va_start(vArgv, pBuf);
vsprintf(bufPrint, pBuf, vArgv);
va_end(vArgv);
AGBPrint(bufPrint);
}
static void AGBPrintTransferDataInternal(u32 bAllData)
{
LPFN_PRINT_FLUSH lpfnFuncFlush;
u16 *pIME;
u16 nIME;
u16 *pWSCNT;
u16 nOldWSCNT;
u16 *pProtect;
volatile struct AGBPrintStruct *pPrint;
pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
lpfnFuncFlush = (LPFN_PRINT_FLUSH)AGB_PRINT_FLUSH_ADDR;
pIME = (u16 *)REG_ADDR_IME;
nIME = *pIME;
pWSCNT = (u16 *)REG_ADDR_WAITCNT;
nOldWSCNT = *pWSCNT;
*pIME = nIME & ~1;
*pWSCNT = WSCNT_DATA;
if (bAllData)
{
while (pPrint->m_nPut != pPrint->m_nGet)
{
*pProtect = 0x20;
lpfnFuncFlush();
*pProtect = 0;
}
}
else if (pPrint->m_nPut != pPrint->m_nGet)
{
*pProtect = 0x20;
lpfnFuncFlush();
*pProtect = 0;
}
*pWSCNT = nOldWSCNT;
*pIME = nIME;
}
void AGBPrintFlush1Block(void)
{
AGBPrintTransferDataInternal(FALSE);
}
void AGBPrintFlush(void)
{
AGBPrintTransferDataInternal(TRUE);
}
void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram)
{
if (nStopProgram)
{
AGBPrintf("ASSERTION FAILED FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
AGBPrintFlush();
asm(".hword 0xEFFF");
}
else
{
AGBPrintf("WARING FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
}
}
// no$gba print functions, uncomment to use
/*
void NoCashGBAPrint(const char *pBuf)
{
*(volatile u32*)NOCASHGBAPRINTADDR2 = (u32)pBuf;
}
void NoCashGBAPrintf(const char *pBuf, ...)
{
char bufPrint[0x100];
va_list vArgv;
va_start(vArgv, pBuf);
vsprintf(bufPrint, pBuf, vArgv);
va_end(vArgv);
NoCashGBAPrint(bufPrint);
}
*/
#endif

View File

@@ -80,45 +80,15 @@ void SetSaveBlocksPointers(u16 offset)
SetDecorationInventoriesPointers();
}
// stuff i used to try and match MoveSaveBlocks_ResetHeap
struct SaveBlocksInOne
{
struct SaveBlock2 sav2;
struct SaveBlock1 sav1;
struct PokemonStorage sav3;
};
extern u8 gHeap[];
extern struct SaveBlocksInOne gHeap;
#define ewram_addr 0x02000000 // oh no...
#define ewram_addr2 0x02000f2c
#define ewram_addr3 0x02004cb4
#define eSaveBlockCopy (*(struct SaveBlocksInOne *)(ewram_addr + 0x0))
#define eSaveBlock2Copy (*(struct SaveBlock2 *)((void*)(ewram_addr + 0x0)))
#define eSaveBlock1Copy (*(struct SaveBlock1 *)((void*)(ewram_addr + sizeof(struct SaveBlock2))))
#define eSaveBlock3Copy (*(struct PokemonStorage *)((void*)(ewram_addr + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1))))
#ifdef NONMATCHING // this is one devil of a motherfucker
/*
The reason MoveSaveBlocks_ResetHeap mismatches is due to incorrect memcpys. Various
things have been tried, such as: direct struct copys, ewram casts, use of defining
the addresses manually, using memcpy anyway, delayed allocation of pointers at
the start of function, as seen above and below. Scope declaration has been used to try and
reproduce the correct macro thought to be used, but nothing has worked. It is worth
noting that at this point that the compiler will delay the allocation of the save block
pointers at the beginningto be allocated later: which might matter for matching this.
Due to loading shared ewram heap areas directly, it is very likely emerald used ewram
defines for this function, but there is no known example of a matching define.
In addition, dead code might be present in the form of a runtime variable used
to fix the address of the save blocks. This has been tested and is shown to affect
the registers as well.
*/
void MoveSaveBlocks_ResetHeap(void)
{
void *vblankCB, *hblankCB;
u32 encryptionKey;
struct SaveBlock1 **sav1Copy = &gSaveBlock1Ptr; // r10;
struct SaveBlock2 *saveBlock2Copy;
struct SaveBlock1 *saveBlock1Copy;
struct PokemonStorage *pokemonStorageCopy;
// save interrupt functions and turn them off
vblankCB = gMain.vblankCallback;
@@ -127,22 +97,30 @@ void MoveSaveBlocks_ResetHeap(void)
gMain.hblankCallback = NULL;
gUnknown_0203CF5C = NULL;
saveBlock2Copy = (struct SaveBlock2 *)(gHeap);
saveBlock1Copy = (struct SaveBlock1 *)(gHeap + sizeof(struct SaveBlock2));
pokemonStorageCopy = (struct PokemonStorage *)(gHeap + sizeof(struct SaveBlock2) + sizeof(struct SaveBlock1));
// backup the saves.
eSaveBlock1Copy = **sav1Copy;
eSaveBlock2Copy = *gSaveBlock2Ptr;
eSaveBlock3Copy = *gPokemonStoragePtr;
*saveBlock2Copy = *gSaveBlock2Ptr;
*saveBlock1Copy = *gSaveBlock1Ptr;
*pokemonStorageCopy = *gPokemonStoragePtr;
// change saveblocks' pointers
// argument is a sum of the individual trainerId bytes
SetSaveBlocksPointers(eSaveBlock2Copy.playerTrainerId[0] + eSaveBlock2Copy.playerTrainerId[1] + eSaveBlock2Copy.playerTrainerId[2] + eSaveBlock2Copy.playerTrainerId[3]);
SetSaveBlocksPointers(
saveBlock2Copy->playerTrainerId[0] +
saveBlock2Copy->playerTrainerId[1] +
saveBlock2Copy->playerTrainerId[2] +
saveBlock2Copy->playerTrainerId[3]);
// restore saveblock data since the pointers changed
**sav1Copy = eSaveBlock1Copy;
*gSaveBlock2Ptr = eSaveBlock2Copy;
*gPokemonStoragePtr = eSaveBlock3Copy;
*gSaveBlock2Ptr = *saveBlock2Copy;
*gSaveBlock1Ptr = *saveBlock1Copy;
*gPokemonStoragePtr = *pokemonStorageCopy;
// heap was destroyed in the copying process, so reset it
InitHeap((void*)(0x02000000), 0x1C000);
InitHeap(gHeap, HEAP_SIZE);
// restore interrupt functions
gMain.hblankCallback = hblankCB;
@@ -153,105 +131,7 @@ void MoveSaveBlocks_ResetHeap(void)
ApplyNewEncryptionKeyToAllEncryptedData(encryptionKey);
gSaveBlock2Ptr->encryptionKey = encryptionKey;
}
#else
__attribute__((naked))
void MoveSaveBlocks_ResetHeap(void)
{
asm(".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, 0x8\n\
ldr r5, =gMain\n\
ldr r0, [r5, 0xC]\n\
str r0, [sp]\n\
ldr r1, [r5, 0x10]\n\
str r1, [sp, 0x4]\n\
movs r0, 0\n\
str r0, [r5, 0xC]\n\
str r0, [r5, 0x10]\n\
ldr r1, =gUnknown_0203CF5C\n\
str r0, [r1]\n\
ldr r4, =0x02000000\n\
ldr r0, =gSaveBlock2Ptr\n\
ldr r1, [r0]\n\
ldr r6, =0x00000f2c\n\
adds r0, r4, 0\n\
adds r2, r6, 0\n\
bl memcpy\n\
ldr r1, =gSaveBlock1Ptr\n\
mov r10, r1\n\
ldr r1, [r1]\n\
ldr r7, =0x00003d88\n\
ldr r0, =0x02000f2c\n\
adds r2, r7, 0\n\
bl memcpy\n\
ldr r0, =gPokemonStoragePtr\n\
mov r8, r0\n\
ldr r1, [r0]\n\
ldr r0, =0x000083d0\n\
mov r9, r0\n\
ldr r0, =0x02004cb4\n\
mov r2, r9\n\
bl memcpy\n\
ldrb r1, [r4, 0xA]\n\
ldrb r0, [r4, 0xB]\n\
adds r1, r0\n\
ldrb r0, [r4, 0xC]\n\
adds r1, r0\n\
ldrb r0, [r4, 0xD]\n\
adds r0, r1\n\
bl SetSaveBlocksPointers\n\
ldr r1, =gSaveBlock2Ptr\n\
ldr r0, [r1]\n\
adds r1, r4, 0\n\
adds r2, r6, 0\n\
bl memcpy\n\
mov r1, r10\n\
ldr r0, [r1]\n\
ldr r1, =0x02000f2c\n\
adds r2, r7, 0\n\
bl memcpy\n\
mov r1, r8\n\
ldr r0, [r1]\n\
ldr r1, =0x02004cb4\n\
mov r2, r9\n\
bl memcpy\n\
movs r1, 0xE0\n\
lsls r1, 9\n\
adds r0, r4, 0\n\
bl InitHeap\n\
ldr r0, [sp, 0x4]\n\
str r0, [r5, 0x10]\n\
ldr r1, [sp]\n\
str r1, [r5, 0xC]\n\
bl Random\n\
adds r4, r0, 0\n\
bl Random\n\
lsls r4, 16\n\
lsls r0, 16\n\
lsrs r0, 16\n\
adds r4, r0\n\
adds r0, r4, 0\n\
bl ApplyNewEncryptionKeyToAllEncryptedData\n\
ldr r1, =gSaveBlock2Ptr\n\
ldr r0, [r1]\n\
adds r0, 0xAC\n\
str r4, [r0]\n\
add sp, 0x8\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\n");
}
#endif
u8 sav2_x1_query_bit1(void)
{

View File

@@ -122,7 +122,7 @@ void AgbMain()
ClearDma3Requests();
ResetBgs();
SetDefaultFontsPointer();
InitHeap(gHeap, 0x1C000);
InitHeap(gHeap, HEAP_SIZE);
gSoftResetDisabled = FALSE;
@@ -332,7 +332,6 @@ void SetSerialCallback(IntrCallback callback)
}
extern void CopyBufferedValuesToGpuRegs(void);
extern void ProcessDma3Requests(void);
static void VBlankIntr(void)
{

View File

@@ -23,10 +23,8 @@ void sub_81700F8(void)
ResetSaveCounters();
sub_81534D0(0);
if (gSaveFileStatus == 0 || gSaveFileStatus == 2)
{
Sav2_ClearSetDefault();
}
SetPokemonCryStereo(gSaveBlock2Ptr->optionsSound);
InitHeap(gHeap, 0x1c000);
InitHeap(gHeap, HEAP_SIZE);
SetMainCallback2(sub_8086230);
}

View File

@@ -465,696 +465,74 @@ void FillWindowPixelBuffer(u8 windowId, u8 fillValue)
CpuFastFill8(fillValue, gWindows[windowId].tileData, 0x20 * fillSize);
}
// functionally equivalent, its fucking hard to match
#ifdef NONMATCHING
#define MOVE_TILES_DOWN(a) \
{ \
destOffset = i + (a); \
srcOffset = i + (((width * (distanceLoop & ~7)) | (distanceLoop & 7)) * 4); \
if (srcOffset < size) \
*(u32*)(tileData + destOffset) = *(u32*)(tileData + srcOffset); \
else \
*(u32*)(tileData + destOffset) = fillValue32; \
distanceLoop++; \
}
#define MOVE_TILES_UP(a) \
{ \
destOffset = i + (a); \
srcOffset = i + (((width * (distanceLoop & ~7)) | (distanceLoop & 7)) * 4); \
if (srcOffset < size) \
*(u32*)(tileData - destOffset) = *(u32*)(tileData - srcOffset); \
else \
*(u32*)(tileData - destOffset) = fillValue32; \
distanceLoop++; \
}
void ScrollWindow(u8 windowId, u8 direction, u8 distance, u8 fillValue)
{
s32 i, id1, id2, size;
u32 distanceLoop, toFill, width;
u8 *tileData;
struct WindowTemplate window;
struct WindowTemplate window = gWindows[windowId].window;
u8 *tileData = gWindows[windowId].tileData;
u32 fillValue32 = (fillValue << 24) | (fillValue << 16) | (fillValue << 8) | fillValue;
s32 size = window.height * window.width * 32;
u32 width = window.width;
s32 i;
s32 srcOffset, destOffset;
u32 distanceLoop;
tileData = gWindows[windowId].tileData;
toFill = (fillValue << 0x18) | (fillValue << 0x10) | (fillValue << 8) | fillValue;
window = gWindows[windowId].window;
size = 0x20 * (window.height * window.width);
width = window.width;
if (direction != 1)
switch (direction)
{
s32 signedDirection = direction;
if (signedDirection <= 1)
{
if (signedDirection == 0)
{
for (i = 0; i < size; i += 0x20)
{
distanceLoop = distance;
id1 = i + 0;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 4;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 8;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 12;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 16;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 20;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 24;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
distanceLoop++;
id1 = i + 28;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData + id1) = *(u32*)(tileData + id2);
else
*(u32*)(tileData + id1) = toFill;
}
}
}
}
else
{
tileData += size - 4;
for (i = 0; i < size; i += 0x20)
case 0:
for (i = 0; i < size; i += 32)
{
distanceLoop = distance;
id1 = i + 0;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 4;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 8;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 12;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 16;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 20;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 24;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
distanceLoop++;
id1 = i + 28;
id2 = i + (((width * ((distanceLoop) & ~(7))) | ((distanceLoop) & 7)) * 4);
if (id2 < size)
*(u32*)(tileData - id1) = *(u32*)(tileData - id2);
else
*(u32*)(tileData - id1) = toFill;
MOVE_TILES_DOWN(0)
MOVE_TILES_DOWN(4)
MOVE_TILES_DOWN(8)
MOVE_TILES_DOWN(12)
MOVE_TILES_DOWN(16)
MOVE_TILES_DOWN(20)
MOVE_TILES_DOWN(24)
MOVE_TILES_DOWN(28)
}
break;
case 1:
tileData += size - 4;
for (i = 0; i < size; i += 32)
{
distanceLoop = distance;
MOVE_TILES_UP(0)
MOVE_TILES_UP(4)
MOVE_TILES_UP(8)
MOVE_TILES_UP(12)
MOVE_TILES_UP(16)
MOVE_TILES_UP(20)
MOVE_TILES_UP(24)
MOVE_TILES_UP(28)
}
break;
case 2:
break;
}
}
#else
__attribute__((naked))
void ScrollWindow(u8 windowId, u8 direction, u8 distance, u8 fillValue)
{
asm(".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, 0x8\n\
lsls r0, 24\n\
lsrs r0, 24\n\
lsls r1, 24\n\
lsrs r1, 24\n\
mov r8, r1\n\
lsls r2, 24\n\
lsrs r2, 24\n\
str r2, [sp]\n\
lsls r3, 24\n\
lsrs r3, 24\n\
ldr r2, =gWindows\n\
lsls r1, r0, 1\n\
adds r1, r0\n\
lsls r1, 2\n\
adds r4, r1, r2\n\
adds r2, 0x8\n\
adds r1, r2\n\
ldr r5, [r1]\n\
lsls r7, r3, 24\n\
lsls r0, r3, 16\n\
orrs r7, r0\n\
lsls r0, r3, 8\n\
orrs r7, r0\n\
orrs r7, r3\n\
ldr r1, [r4]\n\
ldr r2, [r4, 0x4]\n\
ldrb r3, [r4, 0x4]\n\
lsrs r0, r1, 24\n\
muls r0, r3\n\
lsls r6, r0, 5\n\
lsrs r1, 24\n\
mov r12, r1\n\
mov r0, r8\n\
cmp r0, 0x1\n\
bne _08003CE8\n\
b _08003E9E\n\
_08003CE8:\n\
cmp r0, 0x1\n\
ble _08003CEE\n\
b _08004046\n\
_08003CEE:\n\
cmp r0, 0\n\
beq _08003CF4\n\
b _08004046\n\
_08003CF4:\n\
movs r4, 0\n\
cmp r4, r6\n\
blt _08003CFC\n\
b _08004046\n\
_08003CFC:\n\
movs r1, 0x8\n\
negs r1, r1\n\
mov r9, r1\n\
movs r2, 0x7\n\
mov r8, r2\n\
mov r10, r5\n\
_08003D08:\n\
ldr r3, [sp]\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
adds r0, r3, 0\n\
mov r2, r8\n\
ands r0, r2\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003D34\n\
adds r0, r5, r1\n\
ldr r0, [r0]\n\
mov r1, r10\n\
str r0, [r1]\n\
b _08003D38\n\
.pool\n\
_08003D34:\n\
mov r2, r10\n\
str r7, [r2]\n\
_08003D38:\n\
adds r3, 0x1\n\
adds r2, r4, 0x4\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003D64\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003D68\n\
_08003D64:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003D68:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x8\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003D96\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003D9A\n\
_08003D96:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003D9A:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0xC\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003DC8\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003DCC\n\
_08003DC8:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003DCC:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x10\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003DFA\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003DFE\n\
_08003DFA:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003DFE:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x14\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003E2C\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003E30\n\
_08003E2C:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003E30:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x18\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003E5E\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003E62\n\
_08003E5E:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003E62:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x1C\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
adds r0, r1, 0\n\
mov r1, r8\n\
ands r3, r1\n\
orrs r0, r3\n\
lsls r0, 2\n\
adds r1, r4, r0\n\
cmp r1, r6\n\
bge _08003E8C\n\
adds r0, r5, r2\n\
adds r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003E90\n\
_08003E8C:\n\
adds r0, r5, r2\n\
str r7, [r0]\n\
_08003E90:\n\
movs r2, 0x20\n\
add r10, r2\n\
adds r4, 0x20\n\
cmp r4, r6\n\
bge _08003E9C\n\
b _08003D08\n\
_08003E9C:\n\
b _08004046\n\
_08003E9E:\n\
subs r0, r6, 0x4\n\
adds r5, r0\n\
movs r4, 0\n\
cmp r4, r6\n\
blt _08003EAA\n\
b _08004046\n\
_08003EAA:\n\
movs r0, 0x8\n\
negs r0, r0\n\
mov r9, r0\n\
movs r1, 0x7\n\
mov r8, r1\n\
mov r10, r5\n\
_08003EB6:\n\
ldr r3, [sp]\n\
adds r0, r3, 0\n\
mov r2, r9\n\
ands r0, r2\n\
mov r1, r12\n\
muls r1, r0\n\
adds r0, r3, 0\n\
mov r2, r8\n\
ands r0, r2\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003EDC\n\
subs r0, r5, r1\n\
ldr r0, [r0]\n\
mov r1, r10\n\
str r0, [r1]\n\
b _08003EE0\n\
_08003EDC:\n\
mov r2, r10\n\
str r7, [r2]\n\
_08003EE0:\n\
adds r3, 0x1\n\
adds r2, r4, 0x4\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003F0C\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003F10\n\
_08003F0C:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_08003F10:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x8\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003F3E\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003F42\n\
_08003F3E:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_08003F42:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0xC\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003F70\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003F74\n\
_08003F70:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_08003F74:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x10\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003FA2\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003FA6\n\
_08003FA2:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_08003FA6:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x14\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08003FD4\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08003FD8\n\
_08003FD4:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_08003FD8:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x18\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
str r1, [sp, 0x4]\n\
adds r0, r3, 0\n\
mov r1, r8\n\
ands r0, r1\n\
ldr r1, [sp, 0x4]\n\
orrs r1, r0\n\
lsls r1, 2\n\
adds r1, r4, r1\n\
cmp r1, r6\n\
bge _08004006\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _0800400A\n\
_08004006:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_0800400A:\n\
adds r3, 0x1\n\
adds r2, r4, 0\n\
adds r2, 0x1C\n\
adds r0, r3, 0\n\
mov r1, r9\n\
ands r0, r1\n\
mov r1, r12\n\
muls r1, r0\n\
adds r0, r1, 0\n\
mov r1, r8\n\
ands r3, r1\n\
orrs r0, r3\n\
lsls r0, 2\n\
adds r1, r4, r0\n\
cmp r1, r6\n\
bge _08004034\n\
subs r0, r5, r2\n\
subs r1, r5, r1\n\
ldr r1, [r1]\n\
str r1, [r0]\n\
b _08004038\n\
_08004034:\n\
subs r0, r5, r2\n\
str r7, [r0]\n\
_08004038:\n\
movs r2, 0x20\n\
negs r2, r2\n\
add r10, r2\n\
adds r4, 0x20\n\
cmp r4, r6\n\
bge _08004046\n\
b _08003EB6\n\
_08004046:\n\
add sp, 0x8\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\
.syntax divided");
}
#endif // NONMATCHING
void CallWindowFunction(u8 windowId, void ( *func)(u8, u8, u8, u8, u8, u8))
{