diff options
author | sceptillion <33798691+sceptillion@users.noreply.github.com> | 2017-12-18 14:13:23 -0800 |
---|---|---|
committer | sceptillion <33798691+sceptillion@users.noreply.github.com> | 2017-12-18 14:13:23 -0800 |
commit | 3b992d3ad3376d3a37d9afbf60de91aecac5d32b (patch) | |
tree | 64a42ec270c54533bab8941c7f1e4cb5d52d4543 /src/window.c | |
parent | f70d7efa6638c428885756405800aa022fb339da (diff) |
decompile window
Diffstat (limited to 'src/window.c')
-rw-r--r-- | src/window.c | 1152 |
1 files changed, 1152 insertions, 0 deletions
diff --git a/src/window.c b/src/window.c new file mode 100644 index 000000000..7666fc91f --- /dev/null +++ b/src/window.c @@ -0,0 +1,1152 @@ +#include "global.h" +#include "window.h" +#include "malloc.h" + +extern u8 gWindowClearTile; +extern void* gWindowBgTilemapBuffers[]; +extern u32 gUnneededFireRedVariable; + +#define WINDOWS_MAX 32 + +EWRAM_DATA struct Window gWindows[WINDOWS_MAX] = {0}; + +extern void* GetBgTilemapBuffer(u8 bg); +extern int DummiedOutFireRedLeafGreenTileAllocFunc(int, int, int, int); +extern u16 GetBgAttribute(u8 bg, u8 attributeId); +extern void SetBgTilemapBuffer(u8 bg, void *tilemap); +extern void CopyBgTilemapBufferToVram(u8 bg); +extern u8 LoadBgTiles(u8 bg, void *src, u16 size, u16 destOffset); +extern void WriteSequenceToBgTilemapBuffer(u8 bg, u16 firstTileNum, u8 x, u8 y, u8 width, u8 height, u8 paletteSlot, u16 tileNumDelta); +extern void FillBgTilemapBufferRect(u8 bg, u16 tileNum, u8 x, u8 y, u8 width, u8 height, u8 palette); +extern void BlitBitmapRect4Bit(struct Bitmap *src, struct Bitmap *dest, u16 srcX, u16 srcY, u16 destX, u16 destY, u16 width, u16 height, u8 colorKey); +extern void BlitBitmapRect4BitTo8Bit(struct Bitmap *src, struct Bitmap *dest, u16 srcX, u16 srcY, u16 destX, u16 destY, u16 width, u16 height, u8 colorKey, u8 paletteNum); +extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue); +extern void FillBitmapRect8Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue); + +static u8 GetNumActiveWindowsOnBg(u8 bgId); + +static const struct WindowTemplate sDummyWindowTemplate = {0xFF, 0, 0, 0, 0, 0, 0}; + +static void nullsub_8(void) +{ + +} + +bool16 InitWindows(const struct WindowTemplate *templates) +{ + int i; + void *bgTilemapBuffer; + int j; + u8 bgLayer; + u16 attrib; + u8* allocatedTilemapBuffer; + int allocatedBaseBlock; + + for (i = 0; i < 0x4; ++i) + { + bgTilemapBuffer = GetBgTilemapBuffer(i); + if (bgTilemapBuffer != NULL) + gWindowBgTilemapBuffers[i] = nullsub_8; + else + gWindowBgTilemapBuffers[i] = bgTilemapBuffer; + } + + for (i = 0; i < 0x20; ++i) + { + gWindows[i].window = sDummyWindowTemplate; + gWindows[i].tileData = NULL; + } + + for (i = 0, allocatedBaseBlock = 0, bgLayer = templates[i].priority; bgLayer != 0xFF && i < 0x20; ++i, bgLayer = templates[i].priority) + { + if (gUnneededFireRedVariable == 1) + { + allocatedBaseBlock = DummiedOutFireRedLeafGreenTileAllocFunc(bgLayer, 0, templates[i].width * templates[i].height, 0); + if (allocatedBaseBlock == -1) + return FALSE; + } + + if (gWindowBgTilemapBuffers[bgLayer] == NULL) + { + attrib = GetBgAttribute(bgLayer, 0x8); + + if (attrib != 0xFFFF) + { + allocatedTilemapBuffer = Alloc(attrib); + + if (allocatedTilemapBuffer == NULL) + { + FreeAllWindowBuffers(); + return FALSE; + } + + for (j = 0; j < attrib; ++j) + allocatedTilemapBuffer[j] = 0; + + gWindowBgTilemapBuffers[bgLayer] = allocatedTilemapBuffer; + SetBgTilemapBuffer(bgLayer, allocatedTilemapBuffer); + } + } + + allocatedTilemapBuffer = Alloc((u16)(0x20 * (templates[i].width * templates[i].height))); + + if (allocatedTilemapBuffer == NULL) + { + if ((GetNumActiveWindowsOnBg(bgLayer) == 0) && (gWindowBgTilemapBuffers[bgLayer] != nullsub_8)) + { + Free(gWindowBgTilemapBuffers[bgLayer]); + gWindowBgTilemapBuffers[bgLayer] = allocatedTilemapBuffer; + } + + return FALSE; + } + + gWindows[i].tileData = allocatedTilemapBuffer; + gWindows[i].window = templates[i]; + + if (gUnneededFireRedVariable == 1) + { + gWindows[i].window.baseBlock = allocatedBaseBlock; + DummiedOutFireRedLeafGreenTileAllocFunc(bgLayer, allocatedBaseBlock, templates[i].width * templates[i].height, 1); + } + } + + gWindowClearTile = 0; + return TRUE; +} + +u16 AddWindow(const struct WindowTemplate *template) +{ + u16 win; + u8 bgLayer; + int allocatedBaseBlock; + u16 attrib; + u8 *allocatedTilemapBuffer; + int i; + + for (win = 0; win < 0x20; ++win) + { + if ((bgLayer = gWindows[win].window.priority) == 0xFF) + break; + } + + if (win == 0x20) + return 0xFF; + + bgLayer = template->priority; + allocatedBaseBlock = 0; + + if (gUnneededFireRedVariable == 1) + { + allocatedBaseBlock = DummiedOutFireRedLeafGreenTileAllocFunc(bgLayer, 0, template->width * template->height, 0); + + if (allocatedBaseBlock == -1) + return 0xFF; + } + + if (gWindowBgTilemapBuffers[bgLayer] == NULL) + { + attrib = GetBgAttribute(bgLayer, 0x8); + + if (attrib != 0xFFFF) + { + allocatedTilemapBuffer = Alloc(attrib); + + if (allocatedTilemapBuffer == NULL) + return 0xFF; + + for (i = 0; i < attrib; ++i) + allocatedTilemapBuffer[i] = 0; + + gWindowBgTilemapBuffers[bgLayer] = allocatedTilemapBuffer; + SetBgTilemapBuffer(bgLayer, allocatedTilemapBuffer); + } + } + + allocatedTilemapBuffer = Alloc((u16)(0x20 * (template->width * template->height))); + + if (allocatedTilemapBuffer == NULL) + { + if ((GetNumActiveWindowsOnBg(bgLayer) == 0) && (gWindowBgTilemapBuffers[bgLayer] != nullsub_8)) + { + Free(gWindowBgTilemapBuffers[bgLayer]); + gWindowBgTilemapBuffers[bgLayer] = allocatedTilemapBuffer; + } + return 0xFF; + } + + gWindows[win].tileData = allocatedTilemapBuffer; + gWindows[win].window = *template; + + if (gUnneededFireRedVariable == 1) + { + gWindows[win].window.baseBlock = allocatedBaseBlock; + DummiedOutFireRedLeafGreenTileAllocFunc(bgLayer, allocatedBaseBlock, gWindows[win].window.width * gWindows[win].window.height, 1); + } + + return win; +} + +void RemoveWindow(u8 windowId) +{ + u8 bgLayer = gWindows[windowId].window.priority; + + if (gUnneededFireRedVariable == 1) + { + DummiedOutFireRedLeafGreenTileAllocFunc(bgLayer, gWindows[windowId].window.baseBlock, gWindows[windowId].window.width * gWindows[windowId].window.height, 2); + } + + gWindows[windowId].window = sDummyWindowTemplate; + + if (GetNumActiveWindowsOnBg(bgLayer) == 0) + { + if (gWindowBgTilemapBuffers[bgLayer] != nullsub_8) + { + Free(gWindowBgTilemapBuffers[bgLayer]); + gWindowBgTilemapBuffers[bgLayer] = 0; + } + } + + if (gWindows[windowId].tileData != NULL) + { + Free(gWindows[windowId].tileData); + gWindows[windowId].tileData = NULL; + } +} + +void FreeAllWindowBuffers(void) +{ + int i; + + for (i = 0; i < 4; ++i) + { + if (gWindowBgTilemapBuffers[i] != NULL && gWindowBgTilemapBuffers[i] != nullsub_8) + { + Free(gWindowBgTilemapBuffers[i]); + gWindowBgTilemapBuffers[i] = NULL; + } + } + + for (i = 0; i < 0x20; ++i) + { + if (gWindows[i].tileData != NULL) + { + Free(gWindows[i].tileData); + gWindows[i].tileData = NULL; + } + } +} + +void CopyWindowToVram(u8 windowId, u8 mode) +{ + struct Window windowLocal = gWindows[windowId]; + u16 windowSize = 32 * (windowLocal.window.width * windowLocal.window.height); + + switch (mode) + { + case 1: + CopyBgTilemapBufferToVram(windowLocal.window.priority); + break; + case 2: + LoadBgTiles(windowLocal.window.priority, windowLocal.tileData, windowSize, windowLocal.window.baseBlock); + break; + case 3: + LoadBgTiles(windowLocal.window.priority, windowLocal.tileData, windowSize, windowLocal.window.baseBlock); + CopyBgTilemapBufferToVram(windowLocal.window.priority); + break; + } +} + +void PutWindowTilemap(u8 windowId) +{ + struct Window windowLocal = gWindows[windowId]; + + WriteSequenceToBgTilemapBuffer( + windowLocal.window.priority, + GetBgAttribute(windowLocal.window.priority, 0xA) + windowLocal.window.baseBlock, + windowLocal.window.tilemapLeft, + windowLocal.window.tilemapTop, + windowLocal.window.width, + windowLocal.window.height, + windowLocal.window.paletteNum, + 1); +} + +void PutWindowRectTilemapOverridePalette(u8 windowId, u8 x, u8 y, u8 width, u8 height, u8 palette) +{ + struct Window windowLocal = gWindows[windowId]; + u16 currentRow = windowLocal.window.baseBlock + (y * windowLocal.window.width) + x + GetBgAttribute(windowLocal.window.priority, 0xA); + int i; + + for (i = 0; i < height; ++i) + { + WriteSequenceToBgTilemapBuffer( + windowLocal.window.priority, + currentRow, + windowLocal.window.tilemapLeft + x, + windowLocal.window.tilemapTop + y + i, + width, + 1, + palette, + 1); + + currentRow += windowLocal.window.width; + } +} + +void ClearWindowTilemap(u8 windowId) +{ + struct Window windowLocal = gWindows[windowId]; + + FillBgTilemapBufferRect( + windowLocal.window.priority, + gWindowClearTile, + windowLocal.window.tilemapLeft, + windowLocal.window.tilemapTop, + windowLocal.window.width, + windowLocal.window.height, + windowLocal.window.paletteNum); +} + +void PutWindowRectTilemap(u8 windowId, u8 x, u8 y, u8 width, u8 height) +{ + struct Window windowLocal = gWindows[windowId]; + u16 currentRow = windowLocal.window.baseBlock + (y * windowLocal.window.width) + x + GetBgAttribute(windowLocal.window.priority, 0xA); + int i; + + for (i = 0; i < height; ++i) + { + WriteSequenceToBgTilemapBuffer( + windowLocal.window.priority, + currentRow, + windowLocal.window.tilemapLeft + x, + windowLocal.window.tilemapTop + y + i, + width, + 1, + windowLocal.window.paletteNum, + 1); + + currentRow += windowLocal.window.width; + } +} + +void BlitBitmapToWindow(u8 windowId, u8 *pixels, u16 x, u16 y, u16 width, u16 height) +{ + BlitBitmapRectToWindow(windowId, pixels, 0, 0, width, height, x, y, width, height); +} + +void BlitBitmapRectToWindow(u8 windowId, const u8 *pixels, u16 srcX, u16 srcY, u16 srcWidth, int srcHeight, u16 destX, u16 destY, u16 rectWidth, u16 rectHeight) +{ + struct Bitmap sourceRect; + struct Bitmap destRect; + + sourceRect.pixels = (u8*)pixels; + sourceRect.width = srcWidth; + sourceRect.height = srcHeight; + + destRect.pixels = gWindows[windowId].tileData; + destRect.width = 8 * gWindows[windowId].window.width; + destRect.height = 8 * gWindows[windowId].window.height; + + BlitBitmapRect4Bit(&sourceRect, &destRect, srcX, srcY, destX, destY, rectWidth, rectHeight, 0); +} + +void BlitBitmapRectToWindowWithColorKey(u8 windowId, const u8 *pixels, u16 srcX, u16 srcY, u16 srcWidth, int srcHeight, u16 destX, u16 destY, u16 rectWidth, u16 rectHeight, u8 colorKey) +{ + struct Bitmap sourceRect; + struct Bitmap destRect; + + sourceRect.pixels = (u8*)pixels; + sourceRect.width = srcWidth; + sourceRect.height = srcHeight; + + destRect.pixels = gWindows[windowId].tileData; + destRect.width = 8 * gWindows[windowId].window.width; + destRect.height = 8 * gWindows[windowId].window.height; + + BlitBitmapRect4Bit(&sourceRect, &destRect, srcX, srcY, destX, destY, rectWidth, rectHeight, colorKey); +} + +void FillWindowPixelRect(u8 windowId, u8 fillValue, u16 x, u16 y, u16 width, u16 height) +{ + struct Bitmap pixelRect; + + pixelRect.pixels = gWindows[windowId].tileData; + pixelRect.width = 8 * gWindows[windowId].window.width; + pixelRect.height = 8 * gWindows[windowId].window.height; + + FillBitmapRect4Bit(&pixelRect, x, y, width, height, fillValue); +} + +void CopyToWindowPixelBuffer(u8 windowId, const u8 *src, u16 size, u16 tileOffset) +{ + if (size != 0) + CpuCopy16(src, gWindows[windowId].tileData + (0x20 * tileOffset), size); + else + LZ77UnCompWram(src, gWindows[windowId].tileData + (0x20 * tileOffset)); +} + +void FillWindowPixelBuffer(u8 windowId, u8 fillValue) +{ + int fillSize = gWindows[windowId].window.width * gWindows[windowId].window.height; + CpuFastFill8(fillValue, gWindows[windowId].tileData, 0x20 * fillSize); +} + +// functionally equivalent, its fucking hard to match +#ifdef NONMATCHING +void ScrollWindow(u8 windowId, u8 direction, u8 distance, u8 fillValue) +{ + s32 i, id1, id2, size; + u32 distanceLoop, toFill, width; + u8 *tileData; + struct WindowTemplate window; + + 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) + { + 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) + { + 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 +__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)) +{ + struct WindowTemplate window = gWindows[windowId].window; + func(window.priority, window.tilemapLeft, window.tilemapTop, window.width, window.height, window.paletteNum); +} + +bool8 SetWindowAttribute(u8 windowId, u8 attributeId, u32 value) +{ + switch (attributeId) + { + case WINDOW_TILEMAP_LEFT: + gWindows[windowId].window.tilemapLeft = value; + return FALSE; + case WINDOW_TILEMAP_TOP: + gWindows[windowId].window.tilemapTop = value; + return FALSE; + case WINDOW_PALETTE_NUM: + gWindows[windowId].window.paletteNum = value; + return FALSE; + case WINDOW_BASE_BLOCK: + gWindows[windowId].window.baseBlock = value; + return FALSE; + case WINDOW_TILE_DATA: + case WINDOW_PRIORITY: + case WINDOW_WIDTH: + case WINDOW_HEIGHT: + default: + return TRUE; + } +} + +u32 GetWindowAttribute(u8 windowId, u8 attributeId) +{ + switch (attributeId) + { + case WINDOW_PRIORITY: + return gWindows[windowId].window.priority; + case WINDOW_TILEMAP_LEFT: + return gWindows[windowId].window.tilemapLeft; + case WINDOW_TILEMAP_TOP: + return gWindows[windowId].window.tilemapTop; + case WINDOW_WIDTH: + return gWindows[windowId].window.width; + case WINDOW_HEIGHT: + return gWindows[windowId].window.height; + case WINDOW_PALETTE_NUM: + return gWindows[windowId].window.paletteNum; + case WINDOW_BASE_BLOCK: + return gWindows[windowId].window.baseBlock; + case WINDOW_TILE_DATA: + return (u32)(gWindows[windowId].tileData); + default: + return 0; + } +} + +static u8 GetNumActiveWindowsOnBg(u8 bgId) +{ + u8 windowsNum = 0; + s32 i; + for (i = 0; i < WINDOWS_MAX; i++) + { + if (gWindows[i].window.priority == bgId) + windowsNum++; + } + return windowsNum; +} |