Merge pull request #418 from DizzyEggg/dungeon_status
Some checks failed
GithubCI / build (push) Has been cancelled

Document and clean up dungeon pokemon sprites file
This commit is contained in:
Seth Barberee
2025-06-12 15:05:33 -07:00
committed by GitHub
38 changed files with 614 additions and 658 deletions

View File

@@ -1,64 +0,0 @@
.section .rodata
.align 2,0
@ code_800F958
.global gStatusGraphics4bpp
gStatusGraphics4bpp: @ 80CE934
.incbin "graphics/status/sleepless.4bpp"
.incbin "graphics/status/burned.4bpp"
.incbin "graphics/status/poisoned.4bpp"
.incbin "graphics/status/frozen.4bpp"
.incbin "graphics/status/confused.4bpp"
.incbin "graphics/status/whiffer.4bpp"
.incbin "graphics/status/taunted.4bpp"
.incbin "graphics/status/lowhp.4bpp"
.incbin "graphics/status/shield.4bpp"
.incbin "graphics/status/statdown.4bpp"
.incbin "graphics/status/sword.4bpp"
.incbin "graphics/status/blinker.4bpp"
.incbin "graphics/status/cross_eyed.4bpp"
.incbin "graphics/status/eyedrops.4bpp"
.incbin "graphics/status/muzzled.4bpp"
.incbin "graphics/status/sleep.4bpp"
.global gStatusSprites
gStatusSprites: @ 80D3474
@ Status to status image conversion
@ image, palette
.4byte 0, 0
.4byte 1, 0 @ STATUS_SPRITE_SLEEPLESS
.4byte 2, 0 @ STATUS_SPRITE_BURNED
.4byte 3, 11 @ STATUS_SPRITE_POISONED
.4byte 3, 7 @ STATUS_SPRITE_BADLY_POISONED
.4byte 5, 0 @ STATUS_SPRITE_CONFUSED
.4byte 6, 0 @ STATUS_SPRITE_COWERING
.4byte 7, 0 @ STATUS_SPRITE_TAUNTED
.4byte 8, 0 @ STATUS_SPRITE_ENCORE
.4byte 9, 0 @ STATUS_SPRITE_SHIELD_BLUE
.4byte 9, 4 @ STATUS_SPRITE_SHIELD_RED
.4byte 9, 3 @ STATUS_SPRITE_SHIELD_YELLOW
.4byte 9, 10 @ STATUS_SPRITE_SHIELD_GREEN
.4byte 9, 5 @ STATUS_SPRITE_ENDURE
.4byte 8, 0 @ STATUS_SPRITE_LOWHP
.4byte 3, 6 @ STATUS_SPRITE_CURSED
.4byte 8, 3 @ STATUS_SPRITE_SNATCH
.4byte 11, 0 @ STATUS_SPRITE_SURE_SHOT
.4byte 6, 10 @ STATUS_SPRITE_WHIFFER
.4byte 11, 5 @ STATUS_SPRITE_SET_DAMAGE
.4byte 11, 4 @ STATUS_SPRITE_FOCUS_ENERGY
.4byte 12, 0 @ STATUS_SPRITE_BLINKER
.4byte 13, 0 @ STATUS_SPRITE_CROSS_EYED
.4byte 14, 0 @ STATUS_SPRITE_EYEDROPS
.4byte 15, 0 @ STATUS_SPRITE_MUZZLED
.4byte 9, 7 @ STATUS_SPRITE_GRUDGE
.4byte 14, 4 @ STATUS_SPRITE_EXPOSED
.4byte 16, 4 @ STATUS_SPRITE_SLEEP
.4byte 10, 3 @ STATUS_SPRITE_STAT_DOWN
.4byte 4, 0 @ STATUS_SPRITE_FROZEN
.global gUnknown_80D3564
gUnknown_80D3564: @ 80D3564
.byte 0,0,0,0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 398 B

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 472 B

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 354 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 374 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 380 B

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 397 B

View File

@@ -1,9 +0,0 @@
#ifndef GUARD_CODE_800F958_H
#define GUARD_CODE_800F958_H
#include "structs/str_position.h"
void AddPokemonDungeonSprite(s32 id, s16 species, DungeonPos *pos, u32 priority);
void UpdateDungeonPokemonSprite(s32 id, s32 species, s32 status, u32 visible);
#endif // GUARD_CODE_800F958_H

View File

@@ -92,34 +92,65 @@
#define STATUS_CROSS_EYED 2
#define STATUS_EYEDROPS 3
#define STATUS_SPRITE_SLEEPLESS (1 << 0)
#define STATUS_SPRITE_BURNED (1 << 1)
#define STATUS_SPRITE_POISONED (1 << 2)
#define STATUS_SPRITE_BADLY_POISONED (1 << 3)
#define STATUS_SPRITE_CONFUSED (1 << 4)
#define STATUS_SPRITE_COWERING (1 << 5)
#define STATUS_SPRITE_TAUNTED (1 << 6)
#define STATUS_SPRITE_ENCORE (1 << 7)
#define STATUS_SPRITE_SHIELD_BLUE (1 << 8) // REFLECT, COUNTER, MINI_COUNTER, MIST
#define STATUS_SPRITE_SHIELD_RED (1 << 9) // SAFEGUARD, MIRROR_COAT
#define STATUS_SPRITE_SHIELD_YELLOW (1 << 10) // LIGHT_SCREEN, MAGIC_COAT
#define STATUS_SPRITE_SHIELD_GREEN (1 << 11) // PROTECT, MIRRO_MOVE, VITAL_THROW
#define STATUS_SPRITE_ENDURE (1 << 12)
#define STATUS_SPRITE_LOWHP (1 << 13)
#define STATUS_SPRITE_CURSED (1 << 14)
#define STATUS_SPRITE_SNATCH (1 << 15)
#define STATUS_SPRITE_SURE_SHOT (1 << 16)
#define STATUS_SPRITE_WHIFFER (1 << 17)
#define STATUS_SPRITE_SET_DAMAGE (1 << 18)
#define STATUS_SPRITE_FOCUS_ENERGY (1 << 19)
#define STATUS_SPRITE_BLINKER (1 << 20)
#define STATUS_SPRITE_CROSS_EYED (1 << 21)
#define STATUS_SPRITE_EYEDROPS (1 << 22)
#define STATUS_SPRITE_MUZZLED (1 << 23)
#define STATUS_SPRITE_GRUDGE (1 << 24)
#define STATUS_SPRITE_EXPOSED (1 << 25)
#define STATUS_SPRITE_SLEEP (1 << 26)
#define STATUS_SPRITE_STAT_DOWN (1 << 27)
#define STATUS_SPRITE_FROZEN (1 << 28)
#define STATUS_SPRITE_ID_SLEEPLESS 0
#define STATUS_SPRITE_ID_BURNED 1
#define STATUS_SPRITE_ID_POISONED 2
#define STATUS_SPRITE_ID_BADLY_POISONED 3
#define STATUS_SPRITE_ID_CONFUSED 4
#define STATUS_SPRITE_ID_COWERING 5
#define STATUS_SPRITE_ID_TAUNTED 6
#define STATUS_SPRITE_ID_ENCORE 7
#define STATUS_SPRITE_ID_SHIELD_BLUE 8
#define STATUS_SPRITE_ID_SHIELD_RED 9
#define STATUS_SPRITE_ID_SHIELD_YELLOW 10
#define STATUS_SPRITE_ID_SHIELD_GREEN 11
#define STATUS_SPRITE_ID_ENDURE 12
#define STATUS_SPRITE_ID_LOWHP 13
#define STATUS_SPRITE_ID_CURSED 14
#define STATUS_SPRITE_ID_SNATCH 15
#define STATUS_SPRITE_ID_SURE_SHOT 16
#define STATUS_SPRITE_ID_WHIFFER 17
#define STATUS_SPRITE_ID_SET_DAMAGE 18
#define STATUS_SPRITE_ID_FOCUS_ENERGY 19
#define STATUS_SPRITE_ID_BLINKER 20
#define STATUS_SPRITE_ID_CROSS_EYED 21
#define STATUS_SPRITE_ID_EYEDROPS 22
#define STATUS_SPRITE_ID_MUZZLED 23
#define STATUS_SPRITE_ID_GRUDGE 24
#define STATUS_SPRITE_ID_EXPOSED 25
#define STATUS_SPRITE_ID_SLEEP 26
#define STATUS_SPRITE_ID_STAT_DOWN 27
#define STATUS_SPRITE_ID_FROZEN 28
#define STATUS_SPRITE_ID_LAST 28
#define STATUS_SPRITE_SLEEPLESS (1 << STATUS_SPRITE_ID_SLEEPLESS)
#define STATUS_SPRITE_BURNED (1 << STATUS_SPRITE_ID_BURNED)
#define STATUS_SPRITE_POISONED (1 << STATUS_SPRITE_ID_POISONED)
#define STATUS_SPRITE_BADLY_POISONED (1 << STATUS_SPRITE_ID_BADLY_POISONED)
#define STATUS_SPRITE_CONFUSED (1 << STATUS_SPRITE_ID_CONFUSED)
#define STATUS_SPRITE_COWERING (1 << STATUS_SPRITE_ID_COWERING)
#define STATUS_SPRITE_TAUNTED (1 << STATUS_SPRITE_ID_TAUNTED)
#define STATUS_SPRITE_ENCORE (1 << STATUS_SPRITE_ID_ENCORE)
#define STATUS_SPRITE_SHIELD_BLUE (1 << STATUS_SPRITE_ID_SHIELD_BLUE) // REFLECT, COUNTER, MINI_COUNTER, MIST
#define STATUS_SPRITE_SHIELD_RED (1 << STATUS_SPRITE_ID_SHIELD_RED) // SAFEGUARD, MIRROR_COAT
#define STATUS_SPRITE_SHIELD_YELLOW (1 << STATUS_SPRITE_ID_SHIELD_YELLOW) // LIGHT_SCREEN, MAGIC_COAT
#define STATUS_SPRITE_SHIELD_GREEN (1 << STATUS_SPRITE_ID_SHIELD_GREEN) // PROTECT, MIRRO_MOVE, VITAL_THROW
#define STATUS_SPRITE_ENDURE (1 << STATUS_SPRITE_ID_ENDURE)
#define STATUS_SPRITE_LOWHP (1 << STATUS_SPRITE_ID_LOWHP)
#define STATUS_SPRITE_CURSED (1 << STATUS_SPRITE_ID_CURSED)
#define STATUS_SPRITE_SNATCH (1 << STATUS_SPRITE_ID_SNATCH)
#define STATUS_SPRITE_SURE_SHOT (1 << STATUS_SPRITE_ID_SURE_SHOT)
#define STATUS_SPRITE_WHIFFER (1 << STATUS_SPRITE_ID_WHIFFER)
#define STATUS_SPRITE_SET_DAMAGE (1 << STATUS_SPRITE_ID_SET_DAMAGE)
#define STATUS_SPRITE_FOCUS_ENERGY (1 << STATUS_SPRITE_ID_FOCUS_ENERGY)
#define STATUS_SPRITE_BLINKER (1 << STATUS_SPRITE_ID_BLINKER)
#define STATUS_SPRITE_CROSS_EYED (1 << STATUS_SPRITE_ID_CROSS_EYED)
#define STATUS_SPRITE_EYEDROPS (1 << STATUS_SPRITE_ID_EYEDROPS)
#define STATUS_SPRITE_MUZZLED (1 << STATUS_SPRITE_ID_MUZZLED)
#define STATUS_SPRITE_GRUDGE (1 << STATUS_SPRITE_ID_GRUDGE)
#define STATUS_SPRITE_EXPOSED (1 << STATUS_SPRITE_ID_EXPOSED)
#define STATUS_SPRITE_SLEEP (1 << STATUS_SPRITE_ID_SLEEP)
#define STATUS_SPRITE_STAT_DOWN (1 << STATUS_SPRITE_ID_STAT_DOWN)
#define STATUS_SPRITE_FROZEN (1 << STATUS_SPRITE_ID_FROZEN)
#endif

View File

@@ -3,41 +3,12 @@
#include "structs/str_position.h"
// size: 0x8
typedef struct DungeonPokemonStatusSprite
{
/* 0x0 */ u32 status;
/* 0x4 */ s32 frame;
} DungeonPokemonStatusSprite;
// size: 0x40
typedef struct DungeonPokemonSprite
{
/* 0x0 */ u8 exists;
/* 0x4 */ u32 id;
/* 0x8 */ u16 species; // Or sprite ID?
/* 0xA */ u16 unkA;
/* 0xC */ u32 status;
/* 0x10 */ u8 visible;
/* 0x11 */ u8 priority;
/* 0x14 */ DungeonPos pos;
/* 0x18 */ DungeonPos statusOffsets[2];
/* 0x20 */ u32 unk20;
/* 0x24 */ u32 unk24;
/* 0x28 */ DungeonPokemonStatusSprite statusSprites[2];
/* 0x38 */ u8 unk38;
u16 fill3A;
/* 0x3C */ u16 unk3C;
/* 0x3E */ u16 unk3E;
} DungeonPokemonSprite;
// size: 0x584
typedef struct DungeonPokemonSprites
{
/* 0x0 */ s32 frame;
/* 0x4 */ DungeonPokemonSprite sprites[22];
} DungeonPokemonSprites;
extern DungeonPokemonSprites *gDungeonPokemonSprites;
void InitDungeonPokemonSprites(void);
void FreeDungeonPokemonSprites(void);
void UpdateDungeonPokemonSprite(s32 dungeonSpriteId, s32 species_, s32 status, u32 visible_);
void FrameUpdateDungeonStatusSprites(DungeonPos *screenPos);
void AddPokemonDungeonSprite(s32 dungeonSpriteId, s32 species_, DungeonPos *pos, u32 priority);
void DeletePokemonDungeonSprite(s32 dungeonSpriteId);
void UpdateDungeonPokemonSprite2(s32 dungeonSpriteId, DungeonPos *pos, DungeonPos *statusOffsets, u32 priority);
#endif // GUARD_DUNGEON_POKEMON_SPRITES_H

View File

@@ -238,7 +238,7 @@ typedef struct EntityInfo
/* 0x90 */ IqSkillFlags IQSkillFlags;
/* 0x94 */ u8 tactic;
u8 fill95[0x98 - 0x95];
/* 0x98 */ u32 unk98;
/* 0x98 */ u32 dungeonSpriteId;
/* 0x9C */ u32 unk9C;
/* 0xA0 */ s32 unkA0;
/* 0xA4 */ u8 monsterBehavior;

View File

@@ -87,7 +87,7 @@ SECTIONS {
src/code_800E9E4.o(.text);
src/code_800ED38.o(.text);
src/code_800F034.o(.text);
src/code_800F958.o(.text);
src/dungeon_pokemon_sprites.o(.text);
src/friend_areas_map.o(.text);
src/world_map.o(.text);
src/friend_areas_map_util.o(.text);
@@ -438,8 +438,7 @@ SECTIONS {
src/reg_control.o(.rodata);
data/data_80B9BB8_2.o(.rodata);
src/code_800F034.o(.rodata);
src/code_800F958.o(.rodata);
data/data_80CE77C.o(.rodata);
src/dungeon_pokemon_sprites.o(.rodata);
src/friend_areas_map.o(.rodata);
src/world_map.o(.rodata);
src/friend_areas_map_util.o(.rodata);

View File

@@ -7,7 +7,6 @@
#include "code_800ED38.h"
#include "code_803E724.h"
#include "dungeon_message.h"
#include "dungeon_pokemon_sprites.h"
#include "file_system.h"
#include "main_loops.h"
#include "memory.h"
@@ -36,8 +35,6 @@ struct unkStruct_203B0D0 {
EWRAM_INIT struct unkStruct_203B0D0 *gUnknown_203B0D0 = NULL;
EWRAM_INIT void *gUnknown_203B0D4 = NULL; // TODO: figure out the actual struct
EWRAM_INIT DungeonPokemonSprites *gDungeonPokemonSprites = NULL; // Todo: move to a different file, or merge files in this rom region
EWRAM_INIT SpriteOAM gUnknown_203B0DC = {0};
OpenedFile *sub_800F1C0(s32, s32);
s32 sub_800F0F4(s32, s32);

View File

@@ -1,481 +0,0 @@
#include "global.h"
#include "globaldata.h"
#include "structs/sprite_oam.h"
#include "code_800F958.h"
#include "code_8009804.h"
#include "cpu.h"
#include "dungeon_pokemon_sprites.h"
#include "memory.h"
#include "sprite.h"
struct StatusGraphicsInfo
{
/* 0x0 */ s32 width;
/* 0x4 */ s32 height;
/* 0x8 */ s32 vramIndex;
/* 0xC */ s32 unk;
/* 0x10 */ s32 graphicsCount;
/* 0x14 */ s32 offsetIntoGraphic;
};
#define TILE_SIZE_2BPP 32
const struct StatusGraphicsInfo gStatusGraphics[] = {
{0, 0, 0, 0, 0, 0},
{1, 1, 0, 0, 14, TILE_SIZE_2BPP * 0 }, // sleepless
{2, 2, 1, 0, 7, TILE_SIZE_2BPP * 14 }, // burned
{2, 2, 5, 0, 16, TILE_SIZE_2BPP * 42 }, // poisoned
{4, 4, 9, 0, 6, TILE_SIZE_2BPP * 106}, // frozen
{4, 2, 25, 0, 4, TILE_SIZE_2BPP * 202}, // confused
{2, 2, 33, 0, 9, TILE_SIZE_2BPP * 234}, // whiffer
{2, 2, 37, 0, 8, TILE_SIZE_2BPP * 270}, // taunted
{1, 2, 41, 0, 8, TILE_SIZE_2BPP * 302}, // lowhp
{2, 2, 43, 0, 13, TILE_SIZE_2BPP * 318}, // shield
{2, 2, 47, 10, 10, TILE_SIZE_2BPP * 370}, // statdown
{2, 2, 51, 0, 13, TILE_SIZE_2BPP * 410}, // sword
{1, 1, 55, 0, 14, TILE_SIZE_2BPP * 462}, // blinker
{2, 2, 56, 0, 10, TILE_SIZE_2BPP * 476}, // cross-eyed
{1, 1, 60, 0, 14, TILE_SIZE_2BPP * 516}, // eyedrops
{2, 2, 61, 0, 8, TILE_SIZE_2BPP * 530}, // muzzled
{2, 2, 65, 4, 10, TILE_SIZE_2BPP * 562}, // sleep
};
extern const u8 gStatusGraphics4bpp[16][3072];
// static const u8 *gStatusGraphics4bpp[16][3072] = {
// INCBIN_U8("graphics/status/sleepless.4bpp"),
// INCBIN_U8("graphics/status/burned.4bpp"),
// INCBIN_U8("graphics/status/poisoned.4bpp"),
// INCBIN_U8("graphics/status/frozen.4bpp"),
// INCBIN_U8("graphics/status/confused.4bpp"),
// INCBIN_U8("graphics/status/whiffer.4bpp"),
// INCBIN_U8("graphics/status/taunted.4bpp"),
// INCBIN_U8("graphics/status/lowhp.4bpp"),
// INCBIN_U8("graphics/status/shield.4bpp"),
// INCBIN_U8("graphics/status/statdown.4bpp"),
// INCBIN_U8("graphics/status/sword.4bpp"),
// INCBIN_U8("graphics/status/blinker.4bpp"),
// INCBIN_U8("graphics/status/cross_eyed.4bpp"),
// INCBIN_U8("graphics/status/eyedrops.4bpp"),
// INCBIN_U8("graphics/status/muzzled.4bpp"),
// INCBIN_U8("graphics/status/sleep.4bpp")
// };
struct StatusSprite
{
u32 image;
u32 palette;
};
extern struct StatusSprite gStatusSprites[8];
extern SpriteOAM gUnknown_203B0DC;
extern DungeonPos gUnknown_80D3564;
static void DrawStatusSprite(s16 param_1,s32 status,DungeonPos *pos,DungeonPos *posOffset,
DungeonPos *posScreen,u32 priority, u32 unused);
DungeonPokemonSprite *GetDungeonPokemonSprite(s32 id)
{
s32 index;
for(index = 0; index < 22; index++)
{
if(gDungeonPokemonSprites->sprites[index].exists && gDungeonPokemonSprites->sprites[index].id == id)
{
return &gDungeonPokemonSprites->sprites[index];
}
}
return NULL;
}
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;
while (statusBit != 0) {
statusBit >>= 1;
index++;
}
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->priority, sprite->id);
}
}
}
static void DrawStatusSprite(s16 param_1, s32 status, DungeonPos *pos, DungeonPos *posOffset,
DungeonPos *posScreen, u32 priority, u32 unused)
{
struct StatusSprite sprite;
s32 posY;
s32 posX;
u32 uVar7;
s32 vramIndex;
const struct StatusGraphicsInfo *ptr;
sprite = gStatusSprites[status];
ptr = &gStatusGraphics[sprite.image];
vramIndex = (ptr->vramIndex + 0x32b);
SpriteSetPriority(&gUnknown_203B0DC, priority);
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)
{
s32 frame;
s32 size;
s32 vramIndex;
s32 offset;
u8 *ptr;
s32 graphicsCount;
const struct StatusGraphicsInfo *graphic = &gStatusGraphics[graphicIndex];
offset = graphic->offsetIntoGraphic;
graphicsCount = graphic->graphicsCount;
size = graphic->width * graphic->height * 0x20;
vramIndex = (graphic->vramIndex + 0x32b) * 0x20;
frame = (gDungeonPokemonSprites->frame / 4) % graphicsCount;
frame *= size;
ptr = (u8 *)gStatusGraphics4bpp + (offset) + (frame);
if (param_2) {
sub_80098BC((void *)(VRAM + 0x10000 + vramIndex), (void *)ptr, size);
}
else {
CpuCopy((void *)(VRAM + 0x10000 + vramIndex), ptr, size);
}
return;
}
void InitDungeonPokemonSprites(void)
{
if (gDungeonPokemonSprites == NULL) {
gDungeonPokemonSprites = MemoryAlloc(sizeof(DungeonPokemonSprites),0xc);
MemoryClear8(gDungeonPokemonSprites,sizeof(DungeonPokemonSprites));
}
gDungeonPokemonSprites->frame = 0;
LoadStatusGraphics(1,0);
LoadStatusGraphics(2,0);
LoadStatusGraphics(3,0);
LoadStatusGraphics(4,0);
LoadStatusGraphics(5,0);
LoadStatusGraphics(6,0);
LoadStatusGraphics(7,0);
LoadStatusGraphics(8,0);
LoadStatusGraphics(9,0);
LoadStatusGraphics(10,0);
LoadStatusGraphics(0xb,0);
LoadStatusGraphics(0xc,0);
LoadStatusGraphics(0xd,0);
LoadStatusGraphics(0xe,0);
LoadStatusGraphics(0xf,0);
LoadStatusGraphics(0x10,0);
return;
}
void FreeDungeonPokemonSprites(void)
{
if (gDungeonPokemonSprites != 0) {
MemoryFree(gDungeonPokemonSprites);
gDungeonPokemonSprites = NULL;
}
}
void UpdateDungeonPokemonSprite(s32 id, s32 species, s32 status, u32 visible)
{
DungeonPokemonSprite *sprite;
s32 species_s32 = (s16)species;
u32 visible_u8 = (u8)visible;
if (gDungeonPokemonSprites != 0) {
sprite = GetDungeonPokemonSprite(id);
if (sprite != 0) {
sprite->species = species_s32;
sprite->status = status;
sprite->visible = visible_u8;
sprite->unk38 = 0;
}
}
}
void sub_800F794(s32 id, s32 r1, s32 r2, s32 r3, s32 *r4)
{
if(gDungeonPokemonSprites)
{
DungeonPokemonSprite *sprite = GetDungeonPokemonSprite(id);
if(sprite)
{
sprite->unk38 = 1;
sprite->unk3C = r2;
sprite->unk3E = r3;
sprite->unk20 = r4[0];
sprite->unk24 = r4[3];
}
}
}
void sub_800F7D0(DungeonPos *r0)
{
s32 index;
if (gDungeonPokemonSprites == NULL)
return;
switch(gDungeonPokemonSprites->frame % 4) {
case 0:
LoadStatusGraphics(1, 1);
LoadStatusGraphics(2, 1);
LoadStatusGraphics(3, 1);
LoadStatusGraphics(4, 1);
break;
case 1:
LoadStatusGraphics(5, 1);
LoadStatusGraphics(6, 1);
LoadStatusGraphics(7, 1);
LoadStatusGraphics(8, 1);
break;
case 2:
LoadStatusGraphics(9, 1);
LoadStatusGraphics(0xA, 1);
LoadStatusGraphics(0xB, 1);
LoadStatusGraphics(0xC, 1);
break;
case 3:
LoadStatusGraphics(0xD, 1);
LoadStatusGraphics(0xE, 1);
LoadStatusGraphics(0xF, 1);
LoadStatusGraphics(0x10, 1);
break;
}
for (index = 0; index < 22; index++) {
if (gDungeonPokemonSprites->sprites[index].exists) {
DungeonPokemonSprite *spritePtr = &gDungeonPokemonSprites->sprites[index];
sub_800F2EC(spritePtr, 0, r0);
sub_800F2EC(spritePtr, 1, r0);
}
}
gDungeonPokemonSprites->frame++;
}
void AddPokemonDungeonSprite(s32 id, s16 species, DungeonPos *pos, u32 priority) {
DungeonPokemonSprite *dSprite;
DungeonPokemonSprite *newSprite;
DungeonPos newPos;
s32 species_s32;
species_s32 = species;
if(gDungeonPokemonSprites == NULL)
return;
dSprite = GetDungeonPokemonSprite(id);
if(dSprite != NULL)
return;
newSprite = NewDungeonPokemonSprite();
if(newSprite == NULL)
return;
newSprite->exists = 1;
newSprite->id = id;
newSprite->species = species_s32;
newSprite->status = 0;
newSprite->pos = *pos;
newSprite->priority = priority;
newPos = gUnknown_80D3564;
newSprite->statusOffsets[1] = newPos;
newSprite->statusOffsets[0] = newPos;
newSprite->statusSprites[0].status = 0;
newSprite->statusSprites[0].frame = 0;
newSprite->statusSprites[1].status = 0;
newSprite->statusSprites[1].frame = 0;
}
void DeletePokemonDungeonSprite(s32 id)
{
DungeonPokemonSprite *dSprite;
if (gDungeonPokemonSprites == NULL)
return;
dSprite = GetDungeonPokemonSprite(id);
if (dSprite == NULL)
return;
MemoryClear8(dSprite, sizeof(DungeonPokemonSprite));
}
void sub_800F958(s32 dungeonSpriteID, DungeonPos *pos,
DungeonPos *statusOffsets, u32 priority)
{
DungeonPokemonSprite *dSprite;
if (gDungeonPokemonSprites == NULL)
return;
dSprite = GetDungeonPokemonSprite(dungeonSpriteID);
if (dSprite == NULL)
return;
dSprite->pos = *pos;
dSprite->priority = priority;
dSprite->statusOffsets[0] = statusOffsets[0];
dSprite->statusOffsets[1] = statusOffsets[3];
}

View File

@@ -9,7 +9,6 @@
#include "structs/dungeon_entity.h"
#include "structs/str_806B7F8.h"
#include "structs/str_dungeon.h"
#include "code_800F958.h"
#include "dungeon_vram.h"
#include "code_805D8C8.h"
#include "code_806CD90.h"
@@ -22,6 +21,7 @@
#include "dungeon_logic.h"
#include "dungeon_random.h"
#include "dungeon_message.h"
#include "dungeon_pokemon_sprites.h"
#include "dungeon_util.h"
#include "exclusive_pokemon.h"
#include "file_system.h"
@@ -53,7 +53,6 @@ extern void sub_803F4A0(Entity *a0);
extern bool8 sub_80860A8(u8 id);
extern u8 gUnknown_202F32C;
extern u8 GetRandomFloorItem(s32 a0);
extern void DeletePokemonDungeonSprite(s32 id);
extern void sub_80429E8(Entity *r0);
extern s32 sub_803DA20(s32 param_1);
extern Entity *sub_804550C(s16 a);
@@ -684,7 +683,7 @@ void sub_806BB6C(Entity *entity, s32 _species)
struct unkStruct_806B7F8 spStruct;
EntityInfo *entInfo = GetEntInfo(entity);
DeletePokemonDungeonSprite(entInfo->unk98);
DeletePokemonDungeonSprite(entInfo->dungeonSpriteId);
// s16 memes...
spStruct.species = 0;
speciesMatch = species;
@@ -766,7 +765,7 @@ void sub_806BC68(bool8 a0, Entity *entity, struct unkStruct_806B7F8 *structPtr,
}
}
entInfo->unk98 = gDungeon->unk37F0;
entInfo->dungeonSpriteId = gDungeon->unk37F0;
gDungeon->unk37F0++;
entInfo->unk9C = 0;
if (structPtr->level == 0) {
@@ -850,7 +849,7 @@ void sub_806BC68(bool8 a0, Entity *entity, struct unkStruct_806B7F8 *structPtr,
entityPos.x = entity->pos.x;
entityPos.y = entity->pos.y;
AddPokemonDungeonSprite(entInfo->unk98, entInfo->apparentID, &entityPos, gDungeon->unk181e8.priority);
AddPokemonDungeonSprite(entInfo->dungeonSpriteId, entInfo->apparentID, &entityPos, gDungeon->unk181e8.priority);
LoadIQSkills(entity);
sub_806A898(entity, FALSE, FALSE);
}

View File

@@ -20,6 +20,7 @@
#include "dungeon_random.h"
#include "dungeon_misc.h"
#include "dungeon_util.h"
#include "dungeon_pokemon_sprites.h"
#include "exclusive_pokemon.h"
#include "move_effects_target.h"
#include "pokemon.h"
@@ -30,7 +31,6 @@
#include "text_util.h"
#include "sprite.h"
#include "random.h"
#include "code_800F958.h"
#include "structs/str_202ED28.h"
const u8 gUnknown_8106EC8[][13] = {
@@ -44,7 +44,6 @@ const u8 gUnknown_8106EEF[] = {0x03, 0x04, 0x05, 0x00, 0x00, 0x70, 0x6b, 0x73, 0
extern s32 gDungeonFramesCounter;
extern void sub_8042EC8(Entity *a0, s32 a1);
extern void sub_800F958(s32 dungeonSpriteID, DungeonPos *pos, DungeonPos *statusOffsets, u32 a3);
static inline u16 GetUnkFlag(Entity *entity)
{
@@ -224,10 +223,10 @@ void sub_806C51C(Entity *entity)
pos1.y = ((entity->pixelPos.y - entity->unk1C.raw) - entInfo->unk174.raw) / 256;
sub_8005700(posArray, &entity->axObj);
sub_800F958(entInfo->unk98, &pos1, posArray, gDungeon->unk181e8.priority);
UpdateDungeonPokemonSprite2(entInfo->dungeonSpriteId, &pos1, posArray, gDungeon->unk181e8.priority);
statusSprites = EntityGetStatusSprites(entity);
UpdateDungeonPokemonSprite(entInfo->unk98, entInfo->apparentID, statusSprites, (var_3C && entInfo->unk14C));
UpdateDungeonPokemonSprite(entInfo->dungeonSpriteId, entInfo->apparentID, statusSprites, (var_3C && entInfo->unk14C));
sub_8042EC8(entity, y2);
if (entInfo->unk15C == 0) {

View File

@@ -316,7 +316,7 @@ void sub_8074094(Entity *entity)
}
else {
EntityInfo *targetInfo = GetEntInfo(target);
if (targetInfo->unk98 != entityInfo->leechSeedClassStatus.unk4) {
if (targetInfo->dungeonSpriteId != entityInfo->leechSeedClassStatus.unk4) {
entityInfo->leechSeedClassStatus.status = 0;
}
else {

View File

@@ -255,7 +255,7 @@ void HandleDealingDamage(Entity *attacker, Entity *target, struct DamageStruct *
if (destBondTarget == NULL) {
targetInfo->leechSeedClassStatus.status = 0;
}
else if (GetEntInfo(destBondTarget)->unk98 != targetInfo->leechSeedClassStatus.unk4) {
else if (GetEntInfo(destBondTarget)->dungeonSpriteId != targetInfo->leechSeedClassStatus.unk4) {
targetInfo->leechSeedClassStatus.status = 0;
}
else {

View File

@@ -427,7 +427,7 @@ void TrySpawnMonsterAndActivatePlusMinus(void)
if (AbilityIsActive(entity, ABILITY_LIGHTNINGROD)) {
gDungeon->lightningRodPokemon = entity;
gDungeon->unk17B38 = entityInfo->unk98;
gDungeon->unk17B38 = entityInfo->dungeonSpriteId;
}
if (AbilityIsActive(entity, ABILITY_MINUS)) {
gDungeon->minusIsActive[isNotEnemy] = TRUE;

View File

@@ -48,7 +48,6 @@ static void EnsureDeoxysLoaded(void);
extern bool8 IsLevelResetTo1(u8 dungeon);
extern void xxx_pokemonstruct_index_to_pokemon2_808DE30(void* r0, u32 r1);
extern void DeletePokemonDungeonSprite(s32 id);
extern void sub_806C264(s32 teamIndex, EntityInfo *entInfo);
extern bool8 sub_806A58C(s16 r0);
extern void sub_8084E00(Entity *entity, u8 param_2, u8 param_3);
@@ -80,7 +79,6 @@ extern void DeletePokemonDungeonSprite(s32 id);
extern void sub_80429E8(Entity *r0);
extern s32 sub_803DA20(s32 param_1);
extern s32 gDungeonFramesCounter;
extern void sub_800F958(s32 dungeonSpriteID, DungeonPos *pos, DungeonPos *statusOffsets, u32 a3);
extern void sub_8042EC8(Entity *a0, s32 a1);
extern Entity *sub_804550C(s16 a);
extern Entity *sub_80453AC(s16 id);
@@ -662,7 +660,7 @@ void sub_8068FE0(Entity *entity, s32 param_2, Entity *param_3)
mon2Ptr->unk0 = 0;
}
DeletePokemonDungeonSprite(entInfo->unk98);
DeletePokemonDungeonSprite(entInfo->dungeonSpriteId);
gLeaderPointer = 0;
gDungeon->unkC = 1;
entity->type = ENTITY_NOTHING;
@@ -1325,7 +1323,7 @@ void sub_806A338(void)
Entity *entity = gDungeon->activePokemon[i];
if (EntityIsValid(entity) && (GetEntInfo(entity)->curseClassStatus.status == STATUS_SNATCH)) {
gDungeon->snatchPokemon = entity;
gDungeon->unk17B3C = GetEntInfo(entity)->unk98;
gDungeon->unk17B3C = GetEntInfo(entity)->dungeonSpriteId;
return;
}
}

View File

@@ -127,7 +127,7 @@ void UseMoveAgainstTargets(Entity **targetsArray, Entity *attacker, Move *move,
Entity *snatchMon = gDungeon->snatchPokemon;
if (GetEntityType(snatchMon) == ENTITY_MONSTER
&& snatchMon != attacker
&& GetEntInfo(snatchMon)->unk98 == gDungeon->unk17B3C
&& GetEntInfo(snatchMon)->dungeonSpriteId == gDungeon->unk17B3C
&& targetInfo->unkFF == 0)
{
TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FCD28); // The move was snatched.
@@ -138,7 +138,7 @@ void UseMoveAgainstTargets(Entity **targetsArray, Entity *attacker, Move *move,
Entity *lightRodMon = gDungeon->lightningRodPokemon;
if (GetEntityType(lightRodMon) == ENTITY_MONSTER) {
EntityInfo *lightRodInfo = GetEntInfo(lightRodMon);
if (lightRodInfo->unk98 == gDungeon->unk17B38
if (lightRodInfo->dungeonSpriteId == gDungeon->unk17B38
&& GetTreatmentBetweenMonsters(lightRodMon, attacker, TRUE, FALSE) == 1
&& ((targetInfo->unkFF == 0 && lightRodInfo->unkFF == 0) || currTarget == lightRodMon))
{

View File

@@ -0,0 +1,516 @@
#include "global.h"
#include "globaldata.h"
#include "dungeon_pokemon_sprites.h"
#include "structs/sprite_oam.h"
#include "code_8009804.h"
#include "cpu.h"
#include "memory.h"
#include "sprite.h"
#include "constants/status.h"
// size: 0x8
typedef struct DungeonPokemonStatusSprite
{
/* 0x0 */ u32 status;
/* 0x4 */ s32 frame;
} DungeonPokemonStatusSprite;
// size: 0x40
typedef struct DungeonPokemonSprite
{
/* 0x0 */ bool8 exists;
/* 0x4 */ u32 id;
/* 0x8 */ u16 species; // Or sprite ID?
/* 0xA */ u16 unkA;
/* 0xC */ u32 status;
/* 0x10 */ u8 visible;
/* 0x11 */ u8 priority;
/* 0x14 */ DungeonPos pos;
/* 0x18 */ DungeonPos statusOffsets[2];
/* 0x20 */ DungeonPos unk20[2];
/* 0x28 */ DungeonPokemonStatusSprite statusSprites[2];
/* 0x38 */ u8 unk38;
u16 fill3A;
/* 0x3C */ u16 unk3C;
/* 0x3E */ u16 unk3E;
} DungeonPokemonSprite;
#define MAX_DUNGEON_POKEMON_SPRITES 22
// size: 0x584
typedef struct DungeonPokemonSprites
{
/* 0x0 */ s32 frame;
/* 0x4 */ DungeonPokemonSprite sprites[MAX_DUNGEON_POKEMON_SPRITES];
} DungeonPokemonSprites;
struct StatusGraphicsInfo
{
/* 0x0 */ s32 width;
/* 0x4 */ s32 height;
/* 0x8 */ s32 vramIndex;
/* 0xC */ s32 unk;
/* 0x10 */ s32 graphicsCount;
/* 0x14 */ s32 offsetIntoGraphic;
};
enum {
STATUS_GFX_NONE,
STATUS_GFX_SLEEPLESS,
STATUS_GFX_BURNED,
STATUS_GFX_POISONED,
STATUS_GFX_FROZEN,
STATUS_GFX_CONFUSED,
STATUS_GFX_WHIFFER,
STATUS_GFX_TAUNTED,
STATUS_GFX_LOWHP,
STATUS_GFX_SHIELD,
STATUS_GFX_STATDOWN,
STATUS_GFX_SWORD,
STATUS_GFX_BLINKER,
STATUS_GFX_CROSS_EYED,
STATUS_GFX_EYEDROPS,
STATUS_GFX_MUZZLED,
STATUS_GFX_SLEEP,
};
#define TILE_SIZE_2BPP 32
static const struct StatusGraphicsInfo sStatusGfxInfo[] = {
[STATUS_GFX_NONE] = {0, 0, 0, 0, 0, 0},
[STATUS_GFX_SLEEPLESS] = {1, 1, 0, 0, 14, TILE_SIZE_2BPP * 0 },
[STATUS_GFX_BURNED] = {2, 2, 1, 0, 7, TILE_SIZE_2BPP * 14 },
[STATUS_GFX_POISONED] = {2, 2, 5, 0, 16, TILE_SIZE_2BPP * 42 },
[STATUS_GFX_FROZEN] = {4, 4, 9, 0, 6, TILE_SIZE_2BPP * 106},
[STATUS_GFX_CONFUSED] = {4, 2, 25, 0, 4, TILE_SIZE_2BPP * 202},
[STATUS_GFX_WHIFFER] = {2, 2, 33, 0, 9, TILE_SIZE_2BPP * 234},
[STATUS_GFX_TAUNTED] = {2, 2, 37, 0, 8, TILE_SIZE_2BPP * 270},
[STATUS_GFX_LOWHP] = {1, 2, 41, 0, 8, TILE_SIZE_2BPP * 302},
[STATUS_GFX_SHIELD] = {2, 2, 43, 0, 13, TILE_SIZE_2BPP * 318},
[STATUS_GFX_STATDOWN] = {2, 2, 47, 10, 10, TILE_SIZE_2BPP * 370},
[STATUS_GFX_SWORD] = {2, 2, 51, 0, 13, TILE_SIZE_2BPP * 410},
[STATUS_GFX_BLINKER] = {1, 1, 55, 0, 14, TILE_SIZE_2BPP * 462},
[STATUS_GFX_CROSS_EYED] = {2, 2, 56, 0, 10, TILE_SIZE_2BPP * 476},
[STATUS_GFX_EYEDROPS] = {1, 1, 60, 0, 14, TILE_SIZE_2BPP * 516},
[STATUS_GFX_MUZZLED] = {2, 2, 61, 0, 8, TILE_SIZE_2BPP * 530},
[STATUS_GFX_SLEEP] = {2, 2, 65, 4, 10, TILE_SIZE_2BPP * 562},
};
static const u8 sStatusGfx[] = INCBIN_U8("graphics/status/sleepless.4bpp",
"graphics/status/burned.4bpp",
"graphics/status/poisoned.4bpp",
"graphics/status/frozen.4bpp",
"graphics/status/confused.4bpp",
"graphics/status/whiffer.4bpp",
"graphics/status/taunted.4bpp",
"graphics/status/lowhp.4bpp",
"graphics/status/shield.4bpp",
"graphics/status/statdown.4bpp",
"graphics/status/sword.4bpp",
"graphics/status/blinker.4bpp",
"graphics/status/cross_eyed.4bpp",
"graphics/status/eyedrops.4bpp",
"graphics/status/muzzled.4bpp",
"graphics/status/sleep.4bpp");
struct StatusSprite
{
u32 gfxIndex;
u32 palIndex;
};
// + 1 because of how StatusSymbolBitToIndex operates
static const struct StatusSprite sStatusSpritesInfo[] = {
[0] = {STATUS_GFX_NONE, 0},
[STATUS_SPRITE_ID_SLEEPLESS + 1] = {STATUS_GFX_SLEEPLESS, 0},
[STATUS_SPRITE_ID_BURNED + 1] = {STATUS_GFX_BURNED, 0},
[STATUS_SPRITE_ID_POISONED + 1] = {STATUS_GFX_POISONED, 11},
[STATUS_SPRITE_ID_BADLY_POISONED + 1] = {STATUS_GFX_POISONED, 7},
[STATUS_SPRITE_ID_CONFUSED + 1] = {STATUS_GFX_CONFUSED, 0},
[STATUS_SPRITE_ID_COWERING + 1] = {STATUS_GFX_WHIFFER, 0},
[STATUS_SPRITE_ID_TAUNTED + 1] = {STATUS_GFX_TAUNTED, 0},
[STATUS_SPRITE_ID_ENCORE + 1] = {STATUS_GFX_LOWHP, 0},
[STATUS_SPRITE_ID_SHIELD_BLUE + 1] = {STATUS_GFX_SHIELD, 0},
[STATUS_SPRITE_ID_SHIELD_RED + 1] = {STATUS_GFX_SHIELD, 4},
[STATUS_SPRITE_ID_SHIELD_YELLOW + 1] = {STATUS_GFX_SHIELD, 3},
[STATUS_SPRITE_ID_SHIELD_GREEN + 1] = {STATUS_GFX_SHIELD, 10},
[STATUS_SPRITE_ID_ENDURE + 1] = {STATUS_GFX_SHIELD, 5},
[STATUS_SPRITE_ID_LOWHP + 1] = {STATUS_GFX_LOWHP, 0},
[STATUS_SPRITE_ID_CURSED + 1] = {STATUS_GFX_POISONED, 6},
[STATUS_SPRITE_ID_SNATCH + 1] = {STATUS_GFX_LOWHP, 3},
[STATUS_SPRITE_ID_SURE_SHOT + 1] = {STATUS_GFX_SWORD, 0},
[STATUS_SPRITE_ID_WHIFFER + 1] = {STATUS_GFX_WHIFFER, 10},
[STATUS_SPRITE_ID_SET_DAMAGE + 1] = {STATUS_GFX_SWORD, 5},
[STATUS_SPRITE_ID_FOCUS_ENERGY + 1] = {STATUS_GFX_SWORD, 4},
[STATUS_SPRITE_ID_BLINKER + 1] = {STATUS_GFX_BLINKER, 0},
[STATUS_SPRITE_ID_CROSS_EYED + 1] = {STATUS_GFX_CROSS_EYED, 0},
[STATUS_SPRITE_ID_EYEDROPS + 1] = {STATUS_GFX_EYEDROPS, 0},
[STATUS_SPRITE_ID_MUZZLED + 1] = {STATUS_GFX_MUZZLED, 0},
[STATUS_SPRITE_ID_GRUDGE + 1] = {STATUS_GFX_SHIELD, 7},
[STATUS_SPRITE_ID_EXPOSED + 1] = {STATUS_GFX_EYEDROPS, 4},
[STATUS_SPRITE_ID_SLEEP + 1] = {STATUS_GFX_SLEEP, 4},
[STATUS_SPRITE_ID_STAT_DOWN + 1] = {STATUS_GFX_STATDOWN, 3},
[STATUS_SPRITE_ID_FROZEN + 1] = {STATUS_GFX_FROZEN, 0},
};
static EWRAM_INIT DungeonPokemonSprites *sDungeonPokemonSprites = NULL;
static EWRAM_INIT SpriteOAM sStatusSpriteOAM = {0};
static void DrawStatusSprite(s16 param_1,s32 status,DungeonPos *pos,DungeonPos *posOffset, DungeonPos *posScreen,u32 priority, u32 unused);
static DungeonPokemonSprite *GetSpriteById(s32 id)
{
s32 i;
for (i = 0; i < MAX_DUNGEON_POKEMON_SPRITES; i++) {
if (sDungeonPokemonSprites->sprites[i].exists && sDungeonPokemonSprites->sprites[i].id == id) {
return &sDungeonPokemonSprites->sprites[i];
}
}
return NULL;
}
static DungeonPokemonSprite *GetFirstFreeSlot(void)
{
s32 i;
for (i = 0; i < MAX_DUNGEON_POKEMON_SPRITES; i++) {
if (!sDungeonPokemonSprites->sprites[i].exists) {
return &sDungeonPokemonSprites->sprites[i];
}
}
return NULL;
}
static u32 GetNextStatusSymbol(DungeonPokemonSprite *sprite, s32 statusIndex)
{
u32 bits;
u32 status;
s32 i;
s32 n;
u32 lastBit;
u32 secondLastBit;
DungeonPokemonStatusSprite *statusSprite;
statusSprite = &sprite->statusSprites[statusIndex];
lastBit = (1 << STATUS_SPRITE_ID_LAST);
if (statusIndex == 0) {
lastBit = 1;
}
secondLastBit = (1 << STATUS_SPRITE_ID_LAST);
if (statusIndex == 0) {
secondLastBit = (1 << (STATUS_SPRITE_ID_LAST - 1));
}
n = 1;
if (statusIndex == 0) {
n = STATUS_SPRITE_ID_LAST;
}
if (sprite->status == 0) {
return 0;
}
status = statusSprite->status;
bits = lastBit;
if (status != 0) {
bits = status;
}
for (i = 0; i < n; i++) {
bits <<= 1;
if (bits > secondLastBit) {
bits = lastBit;
}
if (sprite->status & bits) {
return bits;
}
}
return 0;
}
static u32 StatusSymbolBitToIndex(u32 statusBit)
{
u32 index = 0;
while (statusBit != 0) {
statusBit >>= 1;
index++;
}
return index;
}
static void UpdateStatusSprite(DungeonPokemonSprite *sprite, s32 index, DungeonPos *screenPos)
{
DungeonPokemonStatusSprite *statusSprite = &sprite->statusSprites[index];
if (sprite->status == 0) {
statusSprite->status = 0;
}
else {
u32 newFrame;
if (statusSprite->status == 0) {
statusSprite->frame = 0;
}
if (statusSprite->frame < 1) {
u32 statusSymbol = GetNextStatusSymbol(sprite,index);
if (statusSprite->status != statusSymbol) {
statusSprite->status = statusSymbol;
}
newFrame = 60;
}
else {
newFrame = statusSprite->frame - 1;
}
statusSprite->frame = newFrame;
if (sprite->visible && statusSprite->status != 0) {
DrawStatusSprite(sprite->species,StatusSymbolBitToIndex(statusSprite->status),&sprite->pos,
&sprite->statusOffsets[index],screenPos,sprite->priority, sprite->id);
}
}
}
#define STATUS_GFX_VRAM_INDEX 0x32B
static void DrawStatusSprite(s16 species, s32 status, DungeonPos *pos, DungeonPos *posOffset, DungeonPos *posScreen, u32 priority, u32 unused)
{
s32 posX, posY;
s32 ySubbed;
struct StatusSprite spriteInfo = sStatusSpritesInfo[status];
const struct StatusGraphicsInfo *gfxInfo = &sStatusGfxInfo[spriteInfo.gfxIndex];
s32 vramIndex = (gfxInfo->vramIndex + STATUS_GFX_VRAM_INDEX);
SpriteSetPriority(&sStatusSpriteOAM, priority);
posX = (pos->x - gfxInfo->width * 4 - posScreen->x) + posOffset->x;
posY = (pos->y - gfxInfo->height * 4 - posScreen->y) + posOffset->y;
ySubbed = posY - 16;
if (posX >= -32 && posY >= -32 && posX < 240 && posY < 160) {
switch (spriteInfo.gfxIndex) {
case STATUS_GFX_SLEEPLESS:
case STATUS_GFX_BLINKER:
case STATUS_GFX_EYEDROPS:
SpriteSetShape(&sStatusSpriteOAM, 0);
SpriteSetSize(&sStatusSpriteOAM, 0);
SpriteSetX(&sStatusSpriteOAM, posX);
SpriteSetY(&sStatusSpriteOAM, ySubbed);
break;
case STATUS_GFX_LOWHP:
SpriteSetShape(&sStatusSpriteOAM, 2);
SpriteSetSize(&sStatusSpriteOAM, 0);
SpriteSetX(&sStatusSpriteOAM, posX);
SpriteSetY(&sStatusSpriteOAM, ySubbed);
break;
case STATUS_GFX_BURNED:
case STATUS_GFX_POISONED:
case STATUS_GFX_WHIFFER:
case STATUS_GFX_TAUNTED:
case STATUS_GFX_SHIELD:
case STATUS_GFX_STATDOWN:
case STATUS_GFX_SWORD:
case STATUS_GFX_CROSS_EYED:
case STATUS_GFX_MUZZLED:
SpriteSetShape(&sStatusSpriteOAM, 0);
SpriteSetSize(&sStatusSpriteOAM, 1);
SpriteSetX(&sStatusSpriteOAM, posX);
SpriteSetY(&sStatusSpriteOAM, ySubbed);
break;
case STATUS_GFX_SLEEP:
SpriteSetShape(&sStatusSpriteOAM, 0);
SpriteSetSize(&sStatusSpriteOAM, 1);
SpriteSetX(&sStatusSpriteOAM, posX + 8);
SpriteSetY(&sStatusSpriteOAM, ySubbed);
break;
case STATUS_GFX_CONFUSED:
SpriteSetShape(&sStatusSpriteOAM, 1);
SpriteSetSize(&sStatusSpriteOAM, 2);
SpriteSetX(&sStatusSpriteOAM, posX);
SpriteSetY(&sStatusSpriteOAM, ySubbed);
break;
case STATUS_GFX_FROZEN:
SpriteSetShape(&sStatusSpriteOAM, 0);
SpriteSetSize(&sStatusSpriteOAM, 2);
SpriteSetX(&sStatusSpriteOAM, posX);
SpriteSetY(&sStatusSpriteOAM, posY);
break;
}
SpriteSetTileNum(&sStatusSpriteOAM, vramIndex);
SpriteSetPalNum(&sStatusSpriteOAM, spriteInfo.palIndex);
AddSprite(&sStatusSpriteOAM,(pos->y - posScreen->y) / 2 + 1,NULL,NULL);
}
}
static void LoadStatusGraphics(s32 graphicIndex, bool8 queueLoad)
{
const struct StatusGraphicsInfo *gfxInfo = &sStatusGfxInfo[graphicIndex];
s32 offset = gfxInfo->offsetIntoGraphic;
s32 graphicsCount = gfxInfo->graphicsCount;
s32 size = gfxInfo->width * gfxInfo->height * 32;
s32 vramIndex = (gfxInfo->vramIndex + STATUS_GFX_VRAM_INDEX) * 32;
s32 frame = (sDungeonPokemonSprites->frame / 4) % graphicsCount;
const u8 *ptr = sStatusGfx + offset + (frame * size);
if (queueLoad) {
sub_80098BC((void *)(VRAM + 0x10000 + vramIndex), (void *)ptr, size);
}
else {
CpuCopy((void *)(VRAM + 0x10000 + vramIndex), ptr, size);
}
}
void InitDungeonPokemonSprites(void)
{
if (sDungeonPokemonSprites == NULL) {
sDungeonPokemonSprites = MemoryAlloc(sizeof(DungeonPokemonSprites),12);
MemoryClear8(sDungeonPokemonSprites,sizeof(DungeonPokemonSprites));
}
sDungeonPokemonSprites->frame = 0;
LoadStatusGraphics(STATUS_GFX_SLEEPLESS,FALSE);
LoadStatusGraphics(STATUS_GFX_BURNED,FALSE);
LoadStatusGraphics(STATUS_GFX_POISONED,FALSE);
LoadStatusGraphics(STATUS_GFX_FROZEN,FALSE);
LoadStatusGraphics(STATUS_GFX_CONFUSED,FALSE);
LoadStatusGraphics(STATUS_GFX_WHIFFER,FALSE);
LoadStatusGraphics(STATUS_GFX_TAUNTED,FALSE);
LoadStatusGraphics(STATUS_GFX_LOWHP,FALSE);
LoadStatusGraphics(STATUS_GFX_SHIELD,FALSE);
LoadStatusGraphics(STATUS_GFX_STATDOWN,FALSE);
LoadStatusGraphics(STATUS_GFX_SWORD,FALSE);
LoadStatusGraphics(STATUS_GFX_BLINKER,FALSE);
LoadStatusGraphics(STATUS_GFX_CROSS_EYED,FALSE);
LoadStatusGraphics(STATUS_GFX_EYEDROPS,FALSE);
LoadStatusGraphics(STATUS_GFX_MUZZLED,FALSE);
LoadStatusGraphics(STATUS_GFX_SLEEP,FALSE);
}
void FreeDungeonPokemonSprites(void)
{
TRY_FREE_AND_SET_NULL(sDungeonPokemonSprites);
}
void UpdateDungeonPokemonSprite(s32 dungeonSpriteId, s32 species_, s32 status, u32 visible_)
{
s32 species = (s16) species_;
u32 visible = (u8) visible_;
if (sDungeonPokemonSprites != NULL) {
DungeonPokemonSprite *sprite = GetSpriteById(dungeonSpriteId);
if (sprite != NULL) {
sprite->species = species;
sprite->status = status;
sprite->visible = visible;
sprite->unk38 = 0;
}
}
}
UNUSED static void sub_800F794(s32 id, s32 r1, s32 r2, s32 r3, DungeonPos *statusOffsets)
{
if (sDungeonPokemonSprites != NULL) {
DungeonPokemonSprite *sprite = GetSpriteById(id);
if (sprite != NULL) {
sprite->unk38 = 1;
sprite->unk3C = r2;
sprite->unk3E = r3;
sprite->unk20[0] = statusOffsets[0];
sprite->unk20[1] = statusOffsets[3];
}
}
}
void FrameUpdateDungeonStatusSprites(DungeonPos *screenPos)
{
s32 i;
if (sDungeonPokemonSprites == NULL)
return;
switch (sDungeonPokemonSprites->frame % 4) {
case 0:
LoadStatusGraphics(STATUS_GFX_SLEEPLESS, TRUE);
LoadStatusGraphics(STATUS_GFX_BURNED, TRUE);
LoadStatusGraphics(STATUS_GFX_POISONED, TRUE);
LoadStatusGraphics(STATUS_GFX_FROZEN, TRUE);
break;
case 1:
LoadStatusGraphics(STATUS_GFX_CONFUSED, TRUE);
LoadStatusGraphics(STATUS_GFX_WHIFFER, TRUE);
LoadStatusGraphics(STATUS_GFX_TAUNTED, TRUE);
LoadStatusGraphics(STATUS_GFX_LOWHP, TRUE);
break;
case 2:
LoadStatusGraphics(STATUS_GFX_SHIELD, TRUE);
LoadStatusGraphics(STATUS_GFX_STATDOWN, TRUE);
LoadStatusGraphics(STATUS_GFX_SWORD, TRUE);
LoadStatusGraphics(STATUS_GFX_BLINKER, TRUE);
break;
case 3:
LoadStatusGraphics(STATUS_GFX_CROSS_EYED, TRUE);
LoadStatusGraphics(STATUS_GFX_EYEDROPS, TRUE);
LoadStatusGraphics(STATUS_GFX_MUZZLED, TRUE);
LoadStatusGraphics(STATUS_GFX_SLEEP, TRUE);
break;
}
for (i = 0; i < MAX_DUNGEON_POKEMON_SPRITES; i++) {
if (sDungeonPokemonSprites->sprites[i].exists) {
DungeonPokemonSprite *spritePtr = &sDungeonPokemonSprites->sprites[i];
UpdateStatusSprite(spritePtr, 0, screenPos);
UpdateStatusSprite(spritePtr, 1, screenPos);
}
}
sDungeonPokemonSprites->frame++;
}
void AddPokemonDungeonSprite(s32 dungeonSpriteId, s32 species_, DungeonPos *pos, u32 priority)
{
static const DungeonPos posZero = {0, 0};
DungeonPokemonSprite *newSprite;
s32 species = (s16) species_;
if (sDungeonPokemonSprites == NULL)
return;
if (GetSpriteById(dungeonSpriteId) != NULL)
return;
newSprite = GetFirstFreeSlot();
if (newSprite == NULL)
return;
newSprite->exists = TRUE;
newSprite->id = dungeonSpriteId;
newSprite->species = species;
newSprite->status = 0;
newSprite->pos = *pos;
newSprite->priority = priority;
newSprite->statusOffsets[0] = newSprite->statusOffsets[1] = posZero;
newSprite->statusSprites[0].status = 0;
newSprite->statusSprites[0].frame = 0;
newSprite->statusSprites[1].status = 0;
newSprite->statusSprites[1].frame = 0;
}
void DeletePokemonDungeonSprite(s32 dungeonSpriteId)
{
DungeonPokemonSprite *dSprite;
if (sDungeonPokemonSprites == NULL)
return;
dSprite = GetSpriteById(dungeonSpriteId);
if (dSprite == NULL)
return;
MemoryClear8(dSprite, sizeof(*dSprite));
}
void UpdateDungeonPokemonSprite2(s32 dungeonSpriteId, DungeonPos *pos, DungeonPos *statusOffsets, u32 priority)
{
if (sDungeonPokemonSprites != NULL) {
DungeonPokemonSprite *sprite = GetSpriteById(dungeonSpriteId);
if (sprite != NULL) {
sprite->pos = *pos;
sprite->priority = priority;
sprite->statusOffsets[0] = statusOffsets[0];
sprite->statusOffsets[1] = statusOffsets[3];
}
}
}

View File

@@ -1,7 +1,6 @@
#include "global.h"
#include "globaldata.h"
#include "structs/str_dungeon.h"
#include "code_800F958.h"
#include "code_805D8C8.h"
#include "code_806CD90.h"
#include "dungeon_items.h"
@@ -9,6 +8,7 @@
#include "dungeon_logic.h"
#include "dungeon_serializer.h"
#include "dungeon_util.h"
#include "dungeon_pokemon_sprites.h"
#include "pokemon.h"
extern u8 gUnknown_202EE70[MAX_TEAM_BODY_SIZE];
@@ -323,7 +323,7 @@ static void WriteMonster(DataSerializer *seri, Entity *src)
WriteIQSkills(seri, &info->IQSkillFlags);
WriteTactic(seri, info->tactic);
WriteHiddenPower(seri, &info->hiddenPower);
WriteU32(seri, info->unk98);
WriteU32(seri, info->dungeonSpriteId);
WriteU32(seri, info->unk9C);
WriteU32(seri, info->unkA0);
WriteSleepClassStatus(seri, &info->sleepClassStatus);
@@ -1006,7 +1006,7 @@ static void ReadMonster(DataSerializer *seri, bool8 isTeamMember, s32 index)
ReadIQSkills(seri, &entInfo.IQSkillFlags);
entInfo.tactic = ReadTactic(seri);
ReadHiddenPower(seri, &entInfo.hiddenPower);
entInfo.unk98 = ReadU32(seri);
entInfo.dungeonSpriteId = ReadU32(seri);
entInfo.unk9C = ReadU32(seri);
entInfo.unkA0 = ReadU32(seri);
ReadSleepClassStatus(seri, &entInfo.sleepClassStatus);
@@ -1238,7 +1238,7 @@ void sub_8082B40(void)
entity->axObj.spriteFile = GetSpriteData(info->apparentID);
sub_806CCB4(entity, sub_806CEBC(entity));
pos = entity->pos;
AddPokemonDungeonSprite(info->unk98, info->apparentID, &pos, 3);
AddPokemonDungeonSprite(info->dungeonSpriteId, info->apparentID, &pos, 3);
entity->room = GetTileMut(entity->pos.x, entity->pos.y)->room;
}
}

View File

@@ -4,7 +4,6 @@
#include "structs/str_dungeon.h"
#include "structs/str_traps.h"
#include "structs/map.h"
#include "code_800F958.h"
#include "code_8041AD0.h"
#include "code_806CD90.h"
#include "dungeon_items.h"
@@ -20,6 +19,7 @@
#include "dungeon_util.h"
#include "dungeon_leader.h"
#include "dungeon_message.h"
#include "dungeon_pokemon_sprites.h"
#include "dungeon_music.h"
#include "dungeon_map.h"
#include "string_format.h"
@@ -153,7 +153,7 @@ void sub_804522C(void)
{
info = GetEntInfo(entity);
statusSprites = EntityGetStatusSprites(entity);
UpdateDungeonPokemonSprite(info->unk98, info->apparentID, statusSprites, FALSE);
UpdateDungeonPokemonSprite(info->dungeonSpriteId, info->apparentID, statusSprites, FALSE);
}
}
}

View File

@@ -27,6 +27,7 @@
#include "dungeon_logic.h"
#include "dungeon_range.h"
#include "dungeon_util.h"
#include "dungeon_pokemon_sprites.h"
#include "menu_input.h"
#include "code_801602C.h"
@@ -55,7 +56,6 @@ void sub_803ECE0();
void sub_803EDF0();
void sub_800E90C();
void sub_8042E5C();
void sub_800F7D0(DungeonPos *);
static void sub_803E490(u32);
static s32 sub_803EF90(s32 a0, u8 a1);
@@ -193,7 +193,7 @@ static void sub_803E490(u32 unused)
sub_804522C();
sub_803F9CC();
sub_800F7D0(&gDungeon->unk181e8.cameraPixelPos);
FrameUpdateDungeonStatusSprites(&gDungeon->unk181e8.cameraPixelPos);
if(gDungeon->unk12 <= 0x63)
gDungeon->unk12++;

View File

@@ -347,7 +347,7 @@ void HandleLeechSeed(Entity * pokemon, Entity * target, bool8 displayMessage)
if (pokemon == gDungeon->activePokemon[index]) {
entityInfo->leechSeedClassStatus.unk8 = index;
entityInfo2 = GetEntInfo(pokemon);
entityInfo->leechSeedClassStatus.unk4 = entityInfo2->unk98;
entityInfo->leechSeedClassStatus.unk4 = entityInfo2->dungeonSpriteId;
}
}
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80FAE58);
@@ -372,7 +372,7 @@ void sub_8078084(Entity * pokemon)
entityInfo2 = GetEntInfo(target);
if(entityInfo2->leechSeedClassStatus.status == STATUS_LEECH_SEED || entityInfo2->leechSeedClassStatus.status == STATUS_DESTINY_BOND)
{
if(entityInfo2->leechSeedClassStatus.unk4 == entityInfo->unk98)
if(entityInfo2->leechSeedClassStatus.unk4 == entityInfo->dungeonSpriteId)
{
entityInfo2->leechSeedClassStatus.status = STATUS_NONE;
EntityUpdateStatusSprites(target);
@@ -413,7 +413,7 @@ void DestinyBondStatusTarget(Entity * pokemon, Entity * target)
if (target == gDungeon->activePokemon[index]) {
entityInfo->leechSeedClassStatus.unk8 = index;
entityInfo2 = GetEntInfo(target);
entityInfo->leechSeedClassStatus.unk4 = entityInfo2->unk98;
entityInfo->leechSeedClassStatus.unk4 = entityInfo2->dungeonSpriteId;
}
}
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80FBB4C);
@@ -626,7 +626,7 @@ void SnatchStatusTarget(Entity * pokemon, Entity * target)
}
gDungeon->snatchPokemon = target;
gDungeon->unk17B3C = targetEntityInfo->unk98;
gDungeon->unk17B3C = targetEntityInfo->dungeonSpriteId;
SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0],target,0);
TryDisplayDungeonLoggableMessage3(pokemon,target,gUnknown_80FB01C);
EntityUpdateStatusSprites(target);

View File

@@ -35,6 +35,7 @@
#include "dungeon_message_log.h"
#include "dungeon_misc.h"
#include "dungeon_music.h"
#include "dungeon_pokemon_sprites.h"
#include "dungeon_random.h"
#include "dungeon_strings.h"
#include "dungeon_serializer.h"
@@ -69,7 +70,6 @@ extern void IncrementThievingSuccesses(void);
extern void ShowDungeonClearedWindow(void);
extern void sub_8084424(void);
extern void sub_8086130(void);
extern void FreeDungeonPokemonSprites(void);
extern void sub_80847D4(void);
extern void sub_8043D60(void);
extern void sub_806890C(void);
@@ -86,7 +86,6 @@ extern void ShowWholeRevealedDungeonMap(void);
extern void sub_807E5AC(void);
extern void TriggerWeatherAbilities(void);
extern void sub_807E88C(void);
extern void InitDungeonPokemonSprites(void);
extern void nullsub_16(void);
extern void sub_80521D0(void);
extern void sub_803F27C(u8);

View File

@@ -15,6 +15,7 @@
.include "src/cpu.o"
.include "src/code_800DAC0.o"
.include "src/code_800ED38.o"
.include "src/dungeon_pokemon_sprites.o"
.include "src/friend_areas_map.o"
.include "src/world_map.o"
.include "src/debug.o"