From 754f5b7e8532c516a459749ee93796f04e8cbd49 Mon Sep 17 00:00:00 2001 From: Seth Barberee Date: Fri, 3 Jan 2025 21:35:19 -0800 Subject: [PATCH] more status sprite func decomp --- asm/code_800ED38.s | 496 ------------------------------ include/dungeon_pokemon_sprites.h | 2 +- src/code_800F958.c | 203 +++++++++++- 3 files changed, 198 insertions(+), 503 deletions(-) diff --git a/asm/code_800ED38.s b/asm/code_800ED38.s index 5a089b655..a7d7e6908 100644 --- a/asm/code_800ED38.s +++ b/asm/code_800ED38.s @@ -429,500 +429,4 @@ _0800F240: bx r1 thumb_func_end GetDungeonPokemonSprite - thumb_func_start NewDungeonPokemonSprite - @ DungeonPokemonSprite *NewDungeonPokemonSprite(void) -NewDungeonPokemonSprite: - push {lr} - movs r2, 0 - ldr r0, _0800F25C - ldr r0, [r0] - adds r1, r0, 0x4 -_0800F252: - ldrb r0, [r1] - cmp r0, 0 - bne _0800F260 - adds r0, r1, 0 - b _0800F26A - .align 2, 0 -_0800F25C: .4byte gDungeonPokemonSprites -_0800F260: - adds r1, 0x40 - adds r2, 0x1 - cmp r2, 0x15 - ble _0800F252 - movs r0, 0 -_0800F26A: - pop {r1} - bx r1 - thumb_func_end NewDungeonPokemonSprite - - thumb_func_start GetNextStatusSymbol - @ u32 GetNextStatusSymbol(?, int select) - @ The "select" parameter exists to differentiate between the two kinds of - @ status symbols that can appear at the same time. - @ Only frozen falls under select = 1, every other symbol falls under select = 0 -GetNextStatusSymbol: - push {r4-r6,lr} - adds r2, r0, 0 - lsls r0, r1, 3 - adds r0, 0x28 - adds r3, r2, r0 - movs r5, 0x80 - lsls r5, 21 - cmp r1, 0 - bne _0800F284 - movs r5, 0x1 -_0800F284: - movs r6, 0x80 - lsls r6, 21 - cmp r1, 0 - bne _0800F290 - movs r6, 0x80 - lsls r6, 20 -_0800F290: - movs r4, 0x1 - cmp r1, 0 - bne _0800F298 - movs r4, 0x1C -_0800F298: - ldr r0, [r2, 0xC] - cmp r0, 0 - bne _0800F2A4 - b _0800F2CC -_0800F2A0: - adds r0, r1, 0 - b _0800F2CE -_0800F2A4: - ldr r2, [r3] - adds r1, r5, 0 - cmp r2, 0 - beq _0800F2AE - adds r1, r2, 0 -_0800F2AE: - movs r2, 0 - cmp r2, r4 - bge _0800F2CC - adds r3, r0, 0 -_0800F2B6: - lsls r1, 1 - cmp r1, r6 - bls _0800F2BE - adds r1, r5, 0 -_0800F2BE: - adds r0, r3, 0 - ands r0, r1 - cmp r0, 0 - bne _0800F2A0 - adds r2, 0x1 - cmp r2, r4 - blt _0800F2B6 -_0800F2CC: - movs r0, 0 -_0800F2CE: - pop {r4-r6} - pop {r1} - bx r1 - thumb_func_end GetNextStatusSymbol - - thumb_func_start StatusSymbolBitToIndex -StatusSymbolBitToIndex: - push {lr} - movs r1, 0 - cmp r0, 0 - beq _0800F2E4 -_0800F2DC: - lsrs r0, 1 - adds r1, 0x1 - cmp r0, 0 - bne _0800F2DC -_0800F2E4: - adds r0, r1, 0 - pop {r1} - bx r1 - thumb_func_end StatusSymbolBitToIndex - - thumb_func_start sub_800F2EC -sub_800F2EC: - push {r4-r7,lr} - sub sp, 0xC - adds r5, r0, 0 - adds r6, r1, 0 - adds r7, r2, 0 - lsls r0, r6, 3 - adds r0, 0x28 - adds r4, r5, r0 - ldr r0, [r5, 0xC] - cmp r0, 0 - bne _0800F306 - str r0, [r4] - b _0800F35C -_0800F306: - ldr r0, [r4] - cmp r0, 0 - bne _0800F30E - str r0, [r4, 0x4] -_0800F30E: - ldr r0, [r4, 0x4] - cmp r0, 0 - bgt _0800F32A - adds r0, r5, 0 - adds r1, r6, 0 - bl GetNextStatusSymbol - adds r1, r0, 0 - ldr r0, [r4] - cmp r0, r1 - beq _0800F326 - str r1, [r4] -_0800F326: - movs r0, 0x3C - b _0800F32C -_0800F32A: - subs r0, 0x1 -_0800F32C: - str r0, [r4, 0x4] - ldrb r0, [r5, 0x10] - cmp r0, 0 - beq _0800F35C - ldr r0, [r4] - cmp r0, 0 - beq _0800F35C - bl StatusSymbolBitToIndex - adds r1, r0, 0 - movs r2, 0x8 - ldrsh r0, [r5, r2] - adds r2, r5, 0 - adds r2, 0x14 - lsls r3, r6, 2 - adds r3, 0x18 - adds r3, r5, r3 - str r7, [sp] - ldrb r4, [r5, 0x11] - str r4, [sp, 0x4] - ldr r4, [r5, 0x4] - str r4, [sp, 0x8] - bl DrawStatusSprite -_0800F35C: - add sp, 0xC - pop {r4-r7} - pop {r0} - bx r0 - thumb_func_end sub_800F2EC - - thumb_func_start DrawStatusSprite - @ void DrawStatusSprite(?, int status, Position *pos, Position *pos_offset, Position *pos_screen, ?) -DrawStatusSprite: - push {r4-r7,lr} - mov r7, r8 - push {r7} - sub sp, 0x8 - mov r12, r2 - ldr r0, [sp, 0x20] - mov r8, r0 - ldr r4, [sp, 0x24] - ldr r0, _0800F410 - lsls r1, 3 - adds r2, r1, r0 - ldr r0, [r2] - ldr r1, [r2, 0x4] - str r0, [sp] - str r1, [sp, 0x4] - lsls r2, r0, 1 - ldr r1, [sp] - adds r2, r1 - lsls r2, 3 - ldr r0, _0800F414 - adds r2, r0 - ldr r0, [r2, 0x8] - ldr r6, _0800F418 - adds r7, r0, r6 - movs r0, 0x3 - ands r4, r0 - lsls r4, 10 - ldr r5, _0800F41C - ldrh r1, [r5, 0x4] - ldr r0, _0800F420 - ands r0, r1 - orrs r0, r4 - strh r0, [r5, 0x4] - mov r0, r12 - movs r4, 0 - ldrsh r1, [r0, r4] - ldr r0, [r2] - lsls r0, 2 - subs r1, r0 - mov r6, r8 - movs r4, 0 - ldrsh r0, [r6, r4] - subs r1, r0 - movs r6, 0 - ldrsh r0, [r3, r6] - adds r4, r1, r0 - mov r0, r12 - movs r6, 0x2 - ldrsh r1, [r0, r6] - ldr r0, [r2, 0x4] - lsls r0, 2 - subs r1, r0 - mov r2, r8 - movs r6, 0x2 - ldrsh r0, [r2, r6] - subs r1, r0 - movs r2, 0x2 - ldrsh r0, [r3, r2] - adds r3, r1, r0 - adds r6, r3, 0 - subs r6, 0x10 - movs r0, 0x20 - negs r0, r0 - cmp r4, r0 - bge _0800F3E8 - b _0800F5E4 -_0800F3E8: - cmp r3, r0 - bge _0800F3EE - b _0800F5E4 -_0800F3EE: - cmp r4, 0xEF - ble _0800F3F4 - b _0800F5E4 -_0800F3F4: - cmp r3, 0x9F - ble _0800F3FA - b _0800F5E4 -_0800F3FA: - ldr r0, [sp] - subs r0, 0x1 - cmp r0, 0xF - bls _0800F404 - b _0800F5A6 -_0800F404: - lsls r0, 2 - ldr r1, _0800F424 - adds r0, r1 - ldr r0, [r0] - mov pc, r0 - .align 2, 0 -_0800F410: .4byte gStatusSprites -_0800F414: .4byte gStatusGraphics -_0800F418: .4byte 0x0000032b -_0800F41C: .4byte gUnknown_203B0DC -_0800F420: .4byte 0x0000f3ff -_0800F424: .4byte _0800F428 - .align 2, 0 -_0800F428: - .4byte _0800F468 - .4byte _0800F4CC - .4byte _0800F4CC - .4byte _0800F574 - .4byte _0800F538 - .4byte _0800F4CC - .4byte _0800F4CC - .4byte _0800F498 - .4byte _0800F4CC - .4byte _0800F4CC - .4byte _0800F4CC - .4byte _0800F468 - .4byte _0800F4CC - .4byte _0800F468 - .4byte _0800F4CC - .4byte _0800F500 -_0800F468: - ldrh r2, [r5] - ldr r1, _0800F48C - adds r0, r1, 0 - ands r0, r2 - strh r0, [r5] - ldrh r0, [r5, 0x2] - ands r1, r0 - ldr r0, _0800F490 - ands r4, r0 - movs r0, 0xFE - lsls r0, 8 - ands r1, r0 - orrs r1, r4 - strh r1, [r5, 0x2] - ldr r1, _0800F494 - ands r1, r6 - b _0800F59A - .align 2, 0 -_0800F48C: .4byte 0x00003fff -_0800F490: .4byte 0x000001ff -_0800F494: .4byte 0x00000fff -_0800F498: - movs r3, 0x80 - lsls r3, 8 - ldrh r2, [r5] - ldr r1, _0800F4C0 - adds r0, r1, 0 - ands r0, r2 - orrs r0, r3 - strh r0, [r5] - ldrh r0, [r5, 0x2] - ands r1, r0 - ldr r0, _0800F4C4 - ands r4, r0 - movs r0, 0xFE - lsls r0, 8 - ands r1, r0 - orrs r1, r4 - strh r1, [r5, 0x2] - ldr r1, _0800F4C8 - ands r1, r6 - b _0800F59A - .align 2, 0 -_0800F4C0: .4byte 0x00003fff -_0800F4C4: .4byte 0x000001ff -_0800F4C8: .4byte 0x00000fff -_0800F4CC: - ldrh r2, [r5] - ldr r1, _0800F4F4 - adds r0, r1, 0 - ands r0, r2 - strh r0, [r5] - movs r2, 0x80 - lsls r2, 7 - ldrh r0, [r5, 0x2] - ands r1, r0 - orrs r1, r2 - ldr r0, _0800F4F8 - ands r4, r0 - movs r0, 0xFE - lsls r0, 8 - ands r1, r0 - orrs r1, r4 - strh r1, [r5, 0x2] - ldr r1, _0800F4FC - ands r1, r6 - b _0800F59A - .align 2, 0 -_0800F4F4: .4byte 0x00003fff -_0800F4F8: .4byte 0x000001ff -_0800F4FC: .4byte 0x00000fff -_0800F500: - ldrh r2, [r5] - ldr r1, _0800F52C - adds r0, r1, 0 - ands r0, r2 - strh r0, [r5] - movs r2, 0x80 - lsls r2, 7 - ldrh r0, [r5, 0x2] - ands r1, r0 - orrs r1, r2 - adds r2, r4, 0 - adds r2, 0x8 - ldr r0, _0800F530 - ands r2, r0 - movs r0, 0xFE - lsls r0, 8 - ands r1, r0 - orrs r1, r2 - strh r1, [r5, 0x2] - ldr r1, _0800F534 - ands r1, r6 - b _0800F59A - .align 2, 0 -_0800F52C: .4byte 0x00003fff -_0800F530: .4byte 0x000001ff -_0800F534: .4byte 0x00000fff -_0800F538: - movs r3, 0x80 - lsls r3, 7 - ldrh r2, [r5] - ldr r1, _0800F568 - adds r0, r1, 0 - ands r0, r2 - orrs r0, r3 - strh r0, [r5] - movs r2, 0x80 - lsls r2, 8 - ldrh r0, [r5, 0x2] - ands r1, r0 - orrs r1, r2 - ldr r0, _0800F56C - ands r4, r0 - movs r0, 0xFE - lsls r0, 8 - ands r1, r0 - orrs r1, r4 - strh r1, [r5, 0x2] - ldr r1, _0800F570 - ands r1, r6 - b _0800F59A - .align 2, 0 -_0800F568: .4byte 0x00003fff -_0800F56C: .4byte 0x000001ff -_0800F570: .4byte 0x00000fff -_0800F574: - ldrh r2, [r5] - ldr r1, _0800F5F0 - adds r0, r1, 0 - ands r0, r2 - strh r0, [r5] - movs r2, 0x80 - lsls r2, 8 - ldrh r0, [r5, 0x2] - ands r1, r0 - orrs r1, r2 - ldr r0, _0800F5F4 - ands r4, r0 - movs r0, 0xFE - lsls r0, 8 - ands r1, r0 - orrs r1, r4 - strh r1, [r5, 0x2] - ldr r1, _0800F5F8 - ands r1, r3 -_0800F59A: - lsls r1, 4 - ldrh r2, [r5, 0x6] - movs r0, 0xF - ands r0, r2 - orrs r0, r1 - strh r0, [r5, 0x6] -_0800F5A6: - ldr r0, _0800F5FC - ands r7, r0 - ldrh r1, [r5, 0x4] - movs r0, 0xFC - lsls r0, 8 - ands r0, r1 - orrs r0, r7 - movs r1, 0xF - ldr r3, [sp, 0x4] - ands r1, r3 - lsls r1, 12 - ldr r2, _0800F5F8 - ands r0, r2 - orrs r0, r1 - strh r0, [r5, 0x4] - mov r4, r12 - movs r6, 0x2 - ldrsh r1, [r4, r6] - mov r2, r8 - movs r3, 0x2 - ldrsh r0, [r2, r3] - subs r1, r0 - lsrs r0, r1, 31 - adds r1, r0 - asrs r1, 1 - adds r1, 0x1 - adds r0, r5, 0 - movs r2, 0 - movs r3, 0 - bl AddSprite -_0800F5E4: - add sp, 0x8 - pop {r3} - mov r8, r3 - pop {r4-r7} - pop {r0} - bx r0 - .align 2, 0 -_0800F5F0: .4byte 0x00003fff -_0800F5F4: .4byte 0x000001ff -_0800F5F8: .4byte 0x00000fff -_0800F5FC: .4byte 0x000003ff - thumb_func_end DrawStatusSprite - .align 2,0 diff --git a/include/dungeon_pokemon_sprites.h b/include/dungeon_pokemon_sprites.h index 2508b8f62..5b718dd34 100644 --- a/include/dungeon_pokemon_sprites.h +++ b/include/dungeon_pokemon_sprites.h @@ -7,7 +7,7 @@ typedef struct DungeonPokemonStatusSprite { /* 0x0 */ u32 status; - /* 0x4 */ u32 frame; + /* 0x4 */ s32 frame; } DungeonPokemonStatusSprite; // size: 0x40 diff --git a/src/code_800F958.c b/src/code_800F958.c index ffdb727ad..4b74960e1 100644 --- a/src/code_800F958.c +++ b/src/code_800F958.c @@ -4,6 +4,8 @@ #include "cpu.h" #include "dungeon_pokemon_sprites.h" #include "memory.h" +#include "sprite.h" +#include "structs/sprite_oam.h" struct StatusGraphicsInfo { @@ -14,16 +16,205 @@ struct StatusGraphicsInfo /* 0x10 */ s32 graphicsCount; /* 0x14 */ s32 offsetIntoGraphic; }; - extern struct StatusGraphicsInfo gStatusGraphics[]; // 0x80CE79C -extern u8 *gStatusGraphics4bpp[]; // TODO use INCBIN_U8 -extern DungeonPokemonSprite *NewDungeonPokemonSprite(void); +struct StatusSprite +{ + u32 image; + u32 palette; +}; +extern struct StatusSprite gStatusSprites[8]; + +extern u8 *gStatusGraphics4bpp[]; // TODO use INCBIN_U8 +extern DungeonPos gUnknown_80D3564; +extern SpriteOAM gUnknown_203B0DC; + extern DungeonPokemonSprite* GetDungeonPokemonSprite(s32 id); -extern DungeonPos gUnknown_80D3564; +void DrawStatusSprite(s16 param_1,s32 status,DungeonPos *pos,DungeonPos *posOffset, + DungeonPos *posScreen,u32 param_6, u32 unused); -void sub_800F2EC(DungeonPokemonSprite *, s32, s16 *); +DungeonPokemonSprite *NewDungeonPokemonSprite(void){ + s32 index; + DungeonPokemonSprite *sprite; + + for(index = 0; index < 22; index++) + { + sprite = &gDungeonPokemonSprites->sprites[index]; + + if(!sprite->exists) + { + return sprite; + } + } + return NULL; +} + +u32 GetNextStatusSymbol(DungeonPokemonSprite *sprite, s32 statusIndex) +{ + u32 uVar1; + u32 status; + s32 counter; + s32 max; + u32 uVar5; + u32 uVar6; + DungeonPokemonStatusSprite *statusSprite; + + statusSprite = &sprite->statusSprites[statusIndex]; + uVar5 = 0x10000000; + if (statusIndex == 0) { + uVar5 = 1; + } + uVar6 = 0x10000000; + if (statusIndex == 0) { + uVar6 = 0x8000000; + } + max = 1; + if (statusIndex == 0) { + max = 0x1c; + } + if (sprite->status == 0) { + return 0; + } + + status = statusSprite->status; + uVar1 = uVar5; + if (status != 0) { + uVar1 = status; + } + + for(counter = 0; counter < max; counter++) + { + uVar1 *= 2; + if (uVar1 > uVar6) { + uVar1 = uVar5; + } + if ((sprite->status & uVar1) != 0) { + return uVar1; + } + } + return 0; +} + +u32 StatusSymbolBitToIndex(u32 statusBit) +{ + u32 index; + + index = 0; + if (statusBit != 0) { + do { + statusBit = statusBit >> 1; + index++; + } while (statusBit != 0); + } + return index; +} + +void sub_800F2EC(DungeonPokemonSprite *sprite, s32 index, DungeonPos *screenPos) +{ + u32 newFrame; + DungeonPokemonStatusSprite *statusSprite; + u32 statusSymbol; + + statusSprite = sprite->statusSprites + index; + if (sprite->status == 0) { + statusSprite->status = 0; + } + else { + if (statusSprite->status == 0) { + statusSprite->frame = 0; + } + if (statusSprite->frame < 1) { + statusSymbol = GetNextStatusSymbol(sprite,index); + if (statusSprite->status != statusSymbol) { + statusSprite->status = statusSymbol; + } + newFrame = 0x3c; + } + else { + newFrame = statusSprite->frame - 1; + } + statusSprite->frame = newFrame; + if ((sprite->visible != '\0') && (statusSprite->status != 0)) { + DrawStatusSprite(sprite->species,StatusSymbolBitToIndex(statusSprite->status),&(sprite->pos), + &sprite->statusOffsets[index],screenPos,sprite->unk11, sprite->id); + } + } +} + +void DrawStatusSprite(s16 param_1, s32 status, DungeonPos *pos, DungeonPos *posOffset, + DungeonPos *posScreen, u32 param_6, u32 unused) +{ + struct StatusSprite sprite; + s32 posY; + s32 posX; + u32 uVar7; + s32 vramIndex; + struct StatusGraphicsInfo *ptr; + + sprite = gStatusSprites[status]; + + ptr = &gStatusGraphics[sprite.image]; + vramIndex = (ptr->vramIndex + 0x32b); + SpriteSetPriority(&gUnknown_203B0DC, param_6); + + posX = (pos->x - ptr->width * 4 - posScreen->x) + posOffset->x; + posY = (pos->y - ptr->height * 4 - posScreen->y) + posOffset->y; + uVar7 = posY - 0x10; + if ((((-0x20 <= posX) && (-0x20 <= posY)) && (posX < 0xf0)) && (posY < 0xa0)) { + switch(sprite.image) { + case 1: + case 0xc: + case 0xe: + SpriteSetShape(&gUnknown_203B0DC, 0); + SpriteSetSize(&gUnknown_203B0DC, 0); + SpriteSetX(&gUnknown_203B0DC, posX); + SpriteSetY(&gUnknown_203B0DC, uVar7); + break; + case 8: + SpriteSetShape(&gUnknown_203B0DC, 2); + SpriteSetSize(&gUnknown_203B0DC, 0); + SpriteSetX(&gUnknown_203B0DC, posX); + SpriteSetY(&gUnknown_203B0DC, uVar7); + break; + case 2: + case 3: + case 6: + case 7: + case 9: + case 10: + case 11: + case 13: + case 15: + SpriteSetShape(&gUnknown_203B0DC, 0); + SpriteSetSize(&gUnknown_203B0DC, 1); + SpriteSetX(&gUnknown_203B0DC, posX); + SpriteSetY(&gUnknown_203B0DC, uVar7); + break; + case 0x10: + SpriteSetShape(&gUnknown_203B0DC, 0); + SpriteSetSize(&gUnknown_203B0DC, 1); + SpriteSetX(&gUnknown_203B0DC, posX + 8); + SpriteSetY(&gUnknown_203B0DC, uVar7); + break; + case 5: + SpriteSetShape(&gUnknown_203B0DC, 1); + SpriteSetSize(&gUnknown_203B0DC, 2); + SpriteSetX(&gUnknown_203B0DC, posX); + SpriteSetY(&gUnknown_203B0DC, uVar7); + break; + case 4: + SpriteSetShape(&gUnknown_203B0DC, 0); + SpriteSetSize(&gUnknown_203B0DC, 2); + SpriteSetX(&gUnknown_203B0DC, posX); + SpriteSetY(&gUnknown_203B0DC, posY); + break; + } + SpriteSetTileNum(&gUnknown_203B0DC, vramIndex); + SpriteSetPalNum(&gUnknown_203B0DC, sprite.palette); + AddSprite(&gUnknown_203B0DC,(pos->y - posScreen->y) / 2 + 1,NULL,NULL); + } +} void LoadStatusGraphics(s32 graphicIndex, bool8 param_2) { @@ -122,7 +313,7 @@ void sub_800F794(s32 id, s32 r1, s32 r2, s32 r3, s32 *r4) } } -void sub_800F7D0(s16 *r0) +void sub_800F7D0(DungeonPos *r0) { s32 index;