From d3652cf59b1fb899a6415e97e609cd83afd0afc5 Mon Sep 17 00:00:00 2001 From: Kermalis <29823718+Kermalis@users.noreply.github.com> Date: Wed, 4 Dec 2024 02:47:10 -0500 Subject: [PATCH] SpriteOAM memes --- asm/code_80130A8.s | 2 + include/code_800DAC0.h | 2 +- include/ground_sprite.h | 11 -- include/other_menus1.h | 6 +- include/sprite.h | 3 +- include/structs/menu.h | 2 +- include/{ => structs}/sprite_oam.h | 26 ++- include/structs/sprite_oam_temp.h | 293 +++++++++++++++++++++++++++++ src/code_8012A18_1.c | 2 +- src/code_803E724.c | 6 +- src/code_805D8C8_1.c | 4 +- src/code_8069E0C.c | 2 +- src/code_808333C.c | 2 +- src/dungeon_message.c | 8 +- src/menu_input.c | 7 +- src/other_menus1.c | 2 +- src/save_menu.c | 2 +- src/sprite.c | 4 +- src/string_format.c | 12 +- src/unk_menu_203B360.c | 2 +- 20 files changed, 352 insertions(+), 46 deletions(-) rename include/{ => structs}/sprite_oam.h (77%) create mode 100644 include/structs/sprite_oam_temp.h diff --git a/asm/code_80130A8.s b/asm/code_80130A8.s index afa6f039d..b5ff8020e 100644 --- a/asm/code_80130A8.s +++ b/asm/code_80130A8.s @@ -5,6 +5,7 @@ .text +@ SpriteOAM memes. Same as sub_8013F84 except instead of a 0x60 it's a 0x80 thumb_func_start sub_8013E54 sub_8013E54: push {r4-r6,lr} @@ -152,6 +153,7 @@ _08013F7C: .4byte 0x00003fff _08013F80: .4byte 0x00000fff thumb_func_end sub_8013E54 +@ SpriteOAM memes https://decomp.me/scratch/GROyH thumb_func_start sub_8013F84 sub_8013F84: push {r4-r6,lr} diff --git a/include/code_800DAC0.h b/include/code_800DAC0.h index efe6a6844..1f7f2288e 100644 --- a/include/code_800DAC0.h +++ b/include/code_800DAC0.h @@ -1,7 +1,7 @@ #ifndef GUARD_CODE_800DAC0_H #define GUARD_CODE_800DAC0_H -#include "ground_sprite.h" +#include "structs/sprite_oam.h" #include "structs/str_position.h" typedef struct unkStruct_80416E0 diff --git a/include/ground_sprite.h b/include/ground_sprite.h index 56ed89169..fdaf41da7 100644 --- a/include/ground_sprite.h +++ b/include/ground_sprite.h @@ -1,17 +1,6 @@ #ifndef GUARD_GROUND_SPRITE_H #define GUARD_GROUND_SPRITE_H -// size: 0xC -typedef struct unkStruct_2039DB0 -{ - u16 unk0; - s16 unk2; - u16 unk4; - u16 unk6; - u16 unk8; - u16 unkA; -} unkStruct_2039DB0; - // size: 0xC typedef struct unkStruct_3001B7C_sub0 { diff --git a/include/other_menus1.h b/include/other_menus1.h index 871a46715..9155b4c1e 100644 --- a/include/other_menus1.h +++ b/include/other_menus1.h @@ -1,12 +1,12 @@ #ifndef GUARD_OTHER_MENUS1_H #define GUARD_OTHER_MENUS1_H +#include "structs/menu.h" +#include "structs/sprite_oam.h" +#include "structs/str_text.h" #include "code_8094F88.h" #include "main_menu1.h" -#include "structs/menu.h" #include "pokemon.h" -#include "sprite_oam.h" -#include "structs/str_text.h" // size: 0x504 typedef struct unkStruct_203B35C diff --git a/include/sprite.h b/include/sprite.h index c5369d187..931d07408 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -2,9 +2,8 @@ #define GUARD_SPRITE_H #include "structs/axdata.h" -#include "ground_sprite.h" +#include "structs/sprite_oam.h" #include "structs/str_position.h" -#include "sprite_oam.h" // size: 0x8 typedef struct UnkSpriteLink diff --git a/include/structs/menu.h b/include/structs/menu.h index 90034c950..6a2ae4bcd 100644 --- a/include/structs/menu.h +++ b/include/structs/menu.h @@ -1,7 +1,7 @@ #ifndef GUARD_MENU_H #define GUARD_MENU_H -#include "sprite_oam.h" +#include "structs/sprite_oam.h" #include "structs/str_text.h" #include "structs/str_position.h" diff --git a/include/sprite_oam.h b/include/structs/sprite_oam.h similarity index 77% rename from include/sprite_oam.h rename to include/structs/sprite_oam.h index 06e2c20fb..7867e3a0e 100644 --- a/include/sprite_oam.h +++ b/include/structs/sprite_oam.h @@ -1,6 +1,18 @@ #ifndef GUARD_SPRITE_OAM_H #define GUARD_SPRITE_OAM_H +// size: 0xC +// This is probably used for blue/gold rescue team to convert from GBA OAM to their platform's OAM in AddSprite() +typedef struct unkStruct_2039DB0 +{ + u16 unk0; // SpriteOAM attrib1 mask + s16 unk2; // SpriteOAM attrib2 mask + u16 unk4; // SpriteOAM attrib3 mask + u16 unk6; // SpriteOAM attrib1 value + u16 unk8; // SpriteOAM attrib2 value + u16 unkA; // SpriteOAM attrib3 value +} unkStruct_2039DB0; + // size: 0x8. Similar to struct OamData but unk6 is not copied to OAM typedef struct SpriteOAM { @@ -10,7 +22,7 @@ typedef struct SpriteOAM /* 0x2 */ u16 attrib2; // tileNum:10 priority:2 paletteNum:4 /* 0x4 */ u16 attrib3; - // unk6_0:1 unk6_1:1 unk6_2:2? unk6_4:12 + // unk6_0:1 unk6_1:1 unk6_2:1 unk6_3:1 unk6_4:12 u16 unk6; } SpriteOAM; @@ -86,6 +98,18 @@ typedef struct SpriteOAM #define SPRITEOAM_SHIFT_UNK6_1 1 #define SPRITEOAM_MASK_UNK6_1 (SPRITEOAM_MAX_UNK6_1 << SPRITEOAM_SHIFT_UNK6_1) // ~ 0xFFFD +#define SPRITEOAM_MAX_UNK6_2 1 +#define SPRITEOAM_SHIFT_UNK6_2 2 +#define SPRITEOAM_MASK_UNK6_2 (SPRITEOAM_MAX_UNK6_2 << SPRITEOAM_SHIFT_UNK6_2) // ~ 0xFFFB + +/* Not seen yet +#define SPRITEOAM_MAX_UNK6_3 1 +#define SPRITEOAM_SHIFT_UNK6_3 3 +#define SPRITEOAM_MASK_UNK6_3 (SPRITEOAM_MAX_UNK6_3 << SPRITEOAM_SHIFT_UNK6_3) // ~ 0xFFF7 +*/ + +// Seems to be the "working" Y coord. Gets copied to attrib1's Y coord in `AddSprite()`. +// kermalis is too lazy to rename it atm since we're still figuring things out #define SPRITEOAM_MAX_UNK6_4 0xFFF #define SPRITEOAM_SHIFT_UNK6_4 4 #define SPRITEOAM_MASK_UNK6_4 (SPRITEOAM_MAX_UNK6_4 << SPRITEOAM_SHIFT_UNK6_4) // ~ 0xF diff --git a/include/structs/sprite_oam_temp.h b/include/structs/sprite_oam_temp.h new file mode 100644 index 000000000..7f014c53a --- /dev/null +++ b/include/structs/sprite_oam_temp.h @@ -0,0 +1,293 @@ +#ifndef GUARD_SPRITE_OAM_TEMP_H +#define GUARD_SPRITE_OAM_TEMP_H + +#include "sprite_oam.h" + +// This file is here for temporary decomp notes about SpriteOAM. It can be deleted later when we figure it out. +// SpriteOAM initialization is handled by inlines. Potentially has inlines for other scenarios [for example: AddSprite()] + +// There is lots of testing done and evidence that it most likely is not handled by macros. +// Some funcs (such as sub_8039174) can be fakematched with "{} while(0);" contexts and a temp var. Note that it's not a "do {} while(0)" but just a "{} while(0)". +// However, that does not work for most funcs, and does not produce some of the register preloading we get with inlines. +// Also, the inlines I (kermalis) have tested with DO produce the behavior we see in all of the funcs. It just doesn't match 100% yet. + +// Most of the special work seems to be done on the first two u16 of SpriteOAM. +// They are usually loaded/stored separately from the second half of the struct. +// There doesn't seem to be a logical reason for SpriteOAM to be split into two substructs, but the evidence points to it. +// AddSprite() still hasn't been matched (I'm writing this Dec 4 2024), because it suggests SpriteOAM is actually two separate substructs. +// "volatile u32/u16" was the first thing we tried, but it produces horrible asm and doesn't make sense for Chunsoft to have used it in this context. +// The main breakthrough came from producing 99% similar asm through attrib1/attrib2 being a substruct. + +// Proposed struct definition: +typedef struct SpriteOAM2_Sub1 +{ + u16 attrib1; + u16 attrib2; +} SpriteOAM2_Sub1; + +typedef struct SpriteOAM2_Sub2 +{ + u16 attrib3; + u16 unk6; +} SpriteOAM2_Sub2; + +typedef struct SpriteOAM2 +{ + SpriteOAM2_Sub1 unk0; + SpriteOAM2_Sub2 unk2; +} SpriteOAM2; +// (It's called SpriteOAM2 temporarily to avoid conflicts with the current one) + +// There seem to be 3 ways of handling SpriteOAM that I have found so far. +// #1 - When a SpriteOAM is initialized on the stack, certain inlines set its fields. This produces heavily inefficient asm but that's what they did. +// #2 - When a SpriteOAM is initialized from ram, it uses different inlines that produce way better asm. They're still known to be inlines because of the register preloading. +// #3 - Sometimes neither of the above 2's inlines are used for attrib1. It appears to be a third set of inlines (didn't attempt yet, feel free to). + +// For type #3, way more testing needs to be done. +// The thing is, in all 3 scenarios, an identical order of operations is usually applied. +// The asm being nearly identical each time also makes it unlikely to be done manually without some macros or inlines. +// And this is why we haven't "real" matched many (any?) SpriteOAM funcs in the years this decomp has existed. + +// Here are some helpful decomp.me links with examples. +// Type #1 - Main func (sub_8013F84) - Initializes a SpriteOAM on the stack [https://decomp.me/scratch/KYLmA] +// Type #2 - Complex fast init func (sub_8052FB8) - Loop func that initializes many SpriteOAM from ram [https://decomp.me/scratch/RX3cp] +// Type #3 - Fast init func (sub_8039174) - Initializes a SpriteOAM from ram [https://decomp.me/scratch/4qs37] + + + +// Type #1 attrib1 inlines: + +static inline void SetAttrib1(SpriteOAM2_Sub1 *sub, u32 attrib1) +{ + SpriteOAM2_Sub1 nSub = *sub; + nSub.attrib1 = attrib1; + *sub = nSub; + // The only issue with this is the fact that the "ldr" happens before the "0xFFFF0000" mask is loaded. + // The only way we have gotten the mask to load before the "ldr" is with something like this: + // *sub = (SpriteOAM2_Sub){ value, sub->attrib2 }; + // However, that produces bad asm. So the solution is to somehow make it a one liner like the above, while still loading from the entire "*sub" somehow. + // This func can also be changed to simply return a SpriteOAM2_Sub1 instead of replacing the value. + + // BTW, making a "{} while(0)" macro for this actually folds the constants together unlike this... which is more efficient asm. Not what we want for matching lol. + // Matching this will be a huge deal! +} + +static inline void SetAffineMode1(SpriteOAM2 *s, u32 mode1) +{ + u32 valueM = mode1 & SPRITEOAM_MAX_AFFINEMODE1; + u32 value = valueM << SPRITEOAM_SHIFT_AFFINEMODE1; + + SetAttrib1(&s->unk0, s->unk0.attrib1 & (u16)~SPRITEOAM_MASK_AFFINEMODE1); + SetAttrib1(&s->unk0, s->unk0.attrib1 | value); +} +static inline void SetAffineMode2(SpriteOAM2 *s, u32 mode2) +{ + u32 valueM = mode2 & SPRITEOAM_MAX_AFFINEMODE2; + u32 value = valueM << SPRITEOAM_SHIFT_AFFINEMODE2; + + SetAttrib1(&s->unk0, s->unk0.attrib1 & (u16)~SPRITEOAM_MASK_AFFINEMODE2); + SetAttrib1(&s->unk0, s->unk0.attrib1 | value); +} +static inline void SetObjMode(SpriteOAM2 *s, u32 mode) +{ + u32 valueM = mode & SPRITEOAM_MAX_OBJMODE; + u32 value = valueM << SPRITEOAM_SHIFT_OBJMODE; + + SetAttrib1(&s->unk0, s->unk0.attrib1 & (u16)~SPRITEOAM_MASK_OBJMODE); + SetAttrib1(&s->unk0, s->unk0.attrib1 | value); +} +static inline void SetMosaic(SpriteOAM2 *s, u32 mosaic) +{ + u32 valueM = mosaic & SPRITEOAM_MAX_MOSAIC; + u32 value = valueM << SPRITEOAM_SHIFT_MOSAIC; + + SetAttrib1(&s->unk0, s->unk0.attrib1 & (u16)~SPRITEOAM_MASK_MOSAIC); + SetAttrib1(&s->unk0, s->unk0.attrib1 | value); +} +static inline void SetBPP(SpriteOAM2 *s, u32 bpp) +{ + u32 valueM = bpp & SPRITEOAM_MAX_BPP; + u32 value = valueM << SPRITEOAM_SHIFT_BPP; + + SetAttrib1(&s->unk0, s->unk0.attrib1 & (u16)~SPRITEOAM_MASK_BPP); + SetAttrib1(&s->unk0, s->unk0.attrib1 | value); +} +static inline void SetShape(SpriteOAM2 *s, u32 shape) +{ + u32 valueM = shape & SPRITEOAM_MAX_SHAPE; + u32 value = valueM << SPRITEOAM_SHIFT_SHAPE; + + SetAttrib1(&s->unk0, s->unk0.attrib1 & (u16)~SPRITEOAM_MASK_SHAPE); + SetAttrib1(&s->unk0, s->unk0.attrib1 | value); +} + +// Type #2 attrib1 inlines: + +static inline void FastSetAffineMode1(SpriteOAM2 *s, u32 mode1) +{ + u32 value; + + value = mode1 & SPRITEOAM_MAX_AFFINEMODE1; + s->unk0.attrib1 &= ~SPRITEOAM_MASK_AFFINEMODE1; + s->unk0.attrib1 |= value << SPRITEOAM_SHIFT_AFFINEMODE1; +} +static inline void FastSetAffineMode2(SpriteOAM2 *s, u32 mode2) +{ + u32 value; + + value = mode2 & SPRITEOAM_MAX_AFFINEMODE2; + s->unk0.attrib1 &= ~SPRITEOAM_MASK_AFFINEMODE2; + s->unk0.attrib1 |= value << SPRITEOAM_SHIFT_AFFINEMODE2; +} +static inline void FastSetObjMode(SpriteOAM2 *s, u32 mode) +{ + u32 value; + + value = mode & SPRITEOAM_MAX_OBJMODE; + s->unk0.attrib1 &= ~SPRITEOAM_MASK_OBJMODE; + s->unk0.attrib1 |= value << SPRITEOAM_SHIFT_OBJMODE; +} +static inline void FastSetMosaic(SpriteOAM2 *s, u32 mosaic) +{ + u32 value; + + value = mosaic & SPRITEOAM_MAX_MOSAIC; + s->unk0.attrib1 &= ~SPRITEOAM_MASK_MOSAIC; + s->unk0.attrib1 |= value << SPRITEOAM_SHIFT_MOSAIC; +} +static inline void FastSetBPP(SpriteOAM2 *s, u32 bpp) +{ + u32 value; + + value = bpp & SPRITEOAM_MAX_BPP; + s->unk0.attrib1 &= ~SPRITEOAM_MASK_BPP; + s->unk0.attrib1 |= value << SPRITEOAM_SHIFT_BPP; +} +static inline void FastSetShape(SpriteOAM2 *s, u32 shape) +{ + u32 value; + + value = shape & SPRITEOAM_MAX_SHAPE; + s->unk0.attrib1 &= ~SPRITEOAM_MASK_SHAPE; + s->unk0.attrib1 |= value << SPRITEOAM_SHIFT_SHAPE; +} + +// attrib2 inlines: +// These pretty much match in every scenario. +// Trying to macro-ify or make a sub-inline will remove some register preloading we rely on. + +static inline void SetX(SpriteOAM2 *s, u32 x) +{ + u32 value; + u32 valueS; + + value = x & SPRITEOAM_MAX_X; + valueS = value << SPRITEOAM_SHIFT_X; + s->unk0.attrib2 &= ~SPRITEOAM_MASK_X; + s->unk0.attrib2 |= valueS; +} + +static inline void SetMatrixNum(SpriteOAM2 *s, u32 matNum) +{ + u32 value; + u32 valueS; + + value = matNum & SPRITEOAM_MAX_MATRIXNUM; + valueS = value << SPRITEOAM_SHIFT_MATRIXNUM; + s->unk0.attrib2 &= ~SPRITEOAM_MASK_MATRIXNUM; + s->unk0.attrib2 |= valueS; +} + +static inline void SetSize(SpriteOAM2 *s, u32 size) +{ + u32 value; + u32 valueS; + + value = size & SPRITEOAM_MAX_SIZE; + valueS = value << SPRITEOAM_SHIFT_SIZE; + s->unk0.attrib2 &= ~SPRITEOAM_MASK_SIZE; + s->unk0.attrib2 |= valueS; +} + +// attrib3 inline: +// For some reason this one is all combined. Also matches pretty much every time. +// It's possible the attrib1 ones are also combined like this, but not the attrib2 ones since they're called out of order or not at all. +// And just like the attrib2 inlines, attempting to macro or inline further results in removed preloading. + +static inline void SetAttrib3(SpriteOAM2 *s, u32 tileNum, u32 prio, u32 palNum) +{ + u32 value; + u32 valueS; + + value = tileNum & SPRITEOAM_MAX_TILENUM; + valueS = value << SPRITEOAM_SHIFT_TILENUM; + s->unk2.attrib3 &= ~SPRITEOAM_MASK_TILENUM; + s->unk2.attrib3 |= valueS; + + value = prio & SPRITEOAM_MAX_PRIORITY; + valueS = value << SPRITEOAM_SHIFT_PRIORITY; + s->unk2.attrib3 &= ~SPRITEOAM_MASK_PRIORITY; + s->unk2.attrib3 |= valueS; + + value = palNum & SPRITEOAM_MAX_PALETTENUM; + valueS = value << SPRITEOAM_SHIFT_PALETTENUM; + s->unk2.attrib3 &= ~SPRITEOAM_MASK_PALETTENUM; + s->unk2.attrib3 |= valueS; +} + +// unk6 inlines: +// Basically same situation as attrib2 inlines. Can't be altered past this or combined, and matches like this. + +static inline void SetUnk6_0(SpriteOAM2 *s, u32 part0) +{ + u32 value; + u32 valueS; + + value = part0 & SPRITEOAM_MAX_UNK6_0; + valueS = value << SPRITEOAM_SHIFT_UNK6_0; + s->unk2.unk6 &= ~SPRITEOAM_MASK_UNK6_0; + s->unk2.unk6 |= valueS; +} +static inline void SetUnk6_1(SpriteOAM2 *s, u32 part1) +{ + u32 value; + u32 valueS; + + value = part1 & SPRITEOAM_MAX_UNK6_1; + valueS = value << SPRITEOAM_SHIFT_UNK6_1; + s->unk2.unk6 &= ~SPRITEOAM_MASK_UNK6_1; + s->unk2.unk6 |= valueS; +} +static inline void SetUnk6_2(SpriteOAM2 *s, u32 part2) +{ + u32 value; + u32 valueS; + + value = part2 & SPRITEOAM_MAX_UNK6_2; + valueS = value << SPRITEOAM_SHIFT_UNK6_2; + s->unk2.unk6 &= ~SPRITEOAM_MASK_UNK6_2; + s->unk2.unk6 |= valueS; +} +// Not seen yet +/*static inline void SetUnk6_3(SpriteOAM2 *s, u32 part3) +{ + u32 value; + u32 valueS; + + value = part3 & SPRITEOAM_MAX_UNK6_3; + valueS = value << SPRITEOAM_SHIFT_UNK6_3; + s->unk2.unk6 &= ~SPRITEOAM_MASK_UNK6_3; + s->unk2.unk6 |= valueS; +}*/ +static inline void SetUnk6_4(SpriteOAM2 *s, u32 part4) +{ + u32 value; + u32 valueS; + + value = part4 & SPRITEOAM_MAX_UNK6_4; + valueS = value << SPRITEOAM_SHIFT_UNK6_4; + s->unk2.unk6 &= ~SPRITEOAM_MASK_UNK6_4; + s->unk2.unk6 |= valueS; +} + +#endif // GUARD_SPRITE_OAM_TEMP_H \ No newline at end of file diff --git a/src/code_8012A18_1.c b/src/code_8012A18_1.c index cc7070598..b73c00b26 100644 --- a/src/code_8012A18_1.c +++ b/src/code_8012A18_1.c @@ -1,6 +1,6 @@ #include "global.h" #include "code_8012A18_1.h" -#include "sprite_oam.h" +#include "structs/sprite_oam.h" #include "text_util.h" #include "text2.h" diff --git a/src/code_803E724.c b/src/code_803E724.c index 265015a1e..2f80e0cc0 100644 --- a/src/code_803E724.c +++ b/src/code_803E724.c @@ -410,9 +410,9 @@ void sub_803EDF0(void) gUnknown_202EDDC.attrib3 &= ~SPRITEOAM_MASK_PALETTENUM; gUnknown_202EDDC.attrib3 |= palNum; - gUnknown_202EDDC.unk6 &= 0xFFFE; - gUnknown_202EDDC.unk6 &= 0xFFFD; - gUnknown_202EDDC.unk6 &= 0xFFFB; + gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_0; + gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_1; + gUnknown_202EDDC.unk6 &= ~SPRITEOAM_MASK_UNK6_2; AddSprite(&gUnknown_202EDDC, 0x100, NULL, NULL); } diff --git a/src/code_805D8C8_1.c b/src/code_805D8C8_1.c index 1fb12e6c4..706417e83 100644 --- a/src/code_805D8C8_1.c +++ b/src/code_805D8C8_1.c @@ -626,9 +626,9 @@ struct UnkStruct_8106AE8 extern const struct UnkStruct_8106AE8 gUnknown_8106AE8[]; #ifdef NONMATCHING -// Not even close in terms of matching, but functionally equivalent. Sprite OAM memes break the stack here. +// Sprite OAM memes. https://decomp.me/scratch/Jm4oC // Creates arrow sprites which are used when in rotate or diagonal modes. -static void TryCreateModeArrows(Entity *leader) // https://decomp.me/scratch/gFX1S +static void TryCreateModeArrows(Entity *leader) { UnkDungeonGlobal_unk181E8_sub *unkPtr = &gDungeon->unk181e8; diff --git a/src/code_8069E0C.c b/src/code_8069E0C.c index ffe3ae31e..8401382e9 100644 --- a/src/code_8069E0C.c +++ b/src/code_8069E0C.c @@ -2310,7 +2310,7 @@ void sub_806C51C(Entity *entity) finalYSprite = ySprite + spriteStructPtr->y; finalYSprite &= SPRITEOAM_MAX_UNK6_4; finalYSprite <<= SPRITEOAM_SHIFT_UNK6_4; - spriteStructPtr->sprite.unk6 &= 0xF; + spriteStructPtr->sprite.unk6 &= ~SPRITEOAM_MASK_UNK6_4; spriteStructPtr->sprite.unk6 |= finalYSprite; AddSprite(&spriteStructPtr->sprite, 0, NULL, NULL); diff --git a/src/code_808333C.c b/src/code_808333C.c index 068a3e1e1..863723cfe 100644 --- a/src/code_808333C.c +++ b/src/code_808333C.c @@ -19,7 +19,7 @@ bool8 sub_8083568(s32 inX, s32 inY, u8 index) finalYSprite = y + gUnknown_202ED28[0][index].y; finalYSprite &= SPRITEOAM_MAX_UNK6_4; finalYSprite <<= SPRITEOAM_SHIFT_UNK6_4; - gUnknown_202ED28[0][index].sprite.unk6 &= 0xF; + gUnknown_202ED28[0][index].sprite.unk6 &= ~SPRITEOAM_MASK_UNK6_4; gUnknown_202ED28[0][index].sprite.unk6 |= finalYSprite; AddSprite(&gUnknown_202ED28[0][index].sprite, 0, NULL, NULL); diff --git a/src/dungeon_message.c b/src/dungeon_message.c index 610caeb7f..f36fdac1b 100644 --- a/src/dungeon_message.c +++ b/src/dungeon_message.c @@ -796,7 +796,7 @@ void sub_8052FB8(const u8 *str) sUnknown_202F1F0.attrib3 |= palNum; unk6 = 0x78 << SPRITEOAM_SHIFT_UNK6_4; - sUnknown_202F1F0.unk6 &= mask; + sUnknown_202F1F0.unk6 &= mask; // ~SPRITEOAM_MASK_UNK6_4 sUnknown_202F1F0.unk6 |= unk6; sUnknown_202F1F0.attrib2 &= ~SPRITEOAM_MASK_X; @@ -1103,13 +1103,13 @@ static void CreateMessageLogArrow(bool8 upArrow, s32 y) sMessageLogArrowSpriteOAM.attrib2 &= ~SPRITEOAM_MASK_MATRIXNUM; sMessageLogArrowSpriteOAM.attrib2 |= matrixNum; - mask = 0xF; - yMask = 0xFFF; + mask = 0xF; // ~SPRITEOAM_MASK_UNK6_4 + yMask = SPRITEOAM_MAX_UNK6_4; ySprite = (yMask & (unkStr->unk2 * 8 + y)) << 4; sMessageLogArrowSpriteOAM.unk6 &= mask; sMessageLogArrowSpriteOAM.unk6 |= ySprite; - xSprite = 0x1FF & ((unkStr->unk0 * 8) + 92); + xSprite = SPRITEOAM_MAX_X & ((unkStr->unk0 * 8) + 92); sMessageLogArrowSpriteOAM.attrib2 &= ~SPRITEOAM_MASK_X; sMessageLogArrowSpriteOAM.attrib2 |= xSprite; diff --git a/src/menu_input.c b/src/menu_input.c index 76e07ac0e..35fdbf979 100644 --- a/src/menu_input.c +++ b/src/menu_input.c @@ -616,7 +616,7 @@ void AddMenuCursorSprite_(MenuInputStruct *a0, u8 *a1) UpdateMenuCursorSpriteCoords(a0); if (!(a0->unk24 & 8)) { - #ifdef NONMATCHING // SpriteOAM memes https://decomp.me/scratch/T9aXl TODO: Match like sub_8039174 with multiple vars and while(0) + #ifdef NONMATCHING // SpriteOAM memes https://decomp.me/scratch/T9aXl u32 tmp, tmp2; #else register u32 tmp asm("r0"), tmp2 asm("r1"); @@ -688,12 +688,11 @@ void nullsub_34(MenuInputStructSub *a0, s32 a1) { } -// Maybe DungeonPos static void sub_801332C(DungeonPos *a0) { SpriteOAM sp = {}; SpriteOAM* ptr; - #ifdef NONMATCHING // SpriteOAM memes https://decomp.me/scratch/zeLxS TODO: Match like sub_8039174 with multiple vars and while(0) + #ifdef NONMATCHING // SpriteOAM memes https://decomp.me/scratch/zeLxS u32 r0, r1, r2; #else register u32 r0 asm("r0"); @@ -762,7 +761,7 @@ static void sub_801332C(DungeonPos *a0) static void sub_8013470(MenuInputStruct *a0) { SpriteOAM sp = {}; - #ifdef NONMATCHING // SpriteOAM memes https://decomp.me/scratch/70Ieb TODO: Match like sub_8039174 with multiple vars and while(0) + #ifdef NONMATCHING // SpriteOAM memes https://decomp.me/scratch/70Ieb SpriteOAM *ptr; u32 r0, r1, r5; #else diff --git a/src/other_menus1.c b/src/other_menus1.c index e5fa64de4..1285186c7 100644 --- a/src/other_menus1.c +++ b/src/other_menus1.c @@ -333,7 +333,7 @@ static void sub_8037400(void) static void sub_80376CC(void) { -#ifdef NONMATCHING // SpriteOAM memes. TODO: Match like sub_8039174 with multiple vars and while(0) +#ifdef NONMATCHING // SpriteOAM memes u32 r0; u32 r2; #else diff --git a/src/save_menu.c b/src/save_menu.c index 8bf7559fb..bb5e87815 100644 --- a/src/save_menu.c +++ b/src/save_menu.c @@ -266,7 +266,7 @@ s32 UpdateSaveMenu(void) void sub_8038830(void) { -#ifdef NONMATCHING // SpriteOAM memes. TODO: Match like sub_8039174 with multiple vars and while(0) +#ifdef NONMATCHING // SpriteOAM memes u32 r0; u32 r2; #else diff --git a/src/sprite.c b/src/sprite.c index 0b54ca523..32ebc13d5 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -149,7 +149,7 @@ void ResetSprites(bool8 a0) void sub_8004E8C(unkStruct_2039DB0 *a0) { a0->unk0 = 0xFFFF; - a0->unk2 = -1; + a0->unk2 = 0xFFFF; a0->unk4 = 0xFFFF; a0->unk6 = 0; a0->unk8 = 0; @@ -557,7 +557,7 @@ void AddSprite(SpriteOAM *a0, s32 a1, UnkSpriteMem *a2, unkStruct_2039DB0 *a3) spr->unk6 = a0->unk6; } - yPos = spr->unk6 / 16; + yPos = spr->unk6 >> SPRITEOAM_SHIFT_UNK6_4; nullsub_3(yPos, 0); yPos &= SPRITEOAM_MAX_Y; spr->attrib1 &= ~SPRITEOAM_MASK_Y; diff --git a/src/string_format.c b/src/string_format.c index 522ec0052..d28b81e20 100644 --- a/src/string_format.c +++ b/src/string_format.c @@ -517,21 +517,21 @@ void DrawDialogueBoxString(void) sDialogueBoxArrowSprite.attrib3 |= palNum; if (sUnknownTextFlags & 0x10) { - u32 var = 0x780; - sDialogueBoxArrowSprite.unk6 &= 0xF; + u32 var = (0x78 & SPRITEOAM_MAX_UNK6_4) << SPRITEOAM_SHIFT_UNK6_4; + sDialogueBoxArrowSprite.unk6 &= ~SPRITEOAM_MASK_UNK6_4; sDialogueBoxArrowSprite.unk6 |= var; sDialogueBoxArrowSprite.attrib2 &= ~SPRITEOAM_MASK_X; - sDialogueBoxArrowSprite.attrib2 |= 0x70; + sDialogueBoxArrowSprite.attrib2 |= (0x70 & SPRITEOAM_MAX_X) << SPRITEOAM_SHIFT_X; } else { s16 x; - u32 var = ((gUnknown_202E748.unkA + 1) & 0xFFF) << 4; - sDialogueBoxArrowSprite.unk6 &= 0xF; + u32 var = ((gUnknown_202E748.unkA + 1) & SPRITEOAM_MAX_UNK6_4) << SPRITEOAM_SHIFT_UNK6_4; + sDialogueBoxArrowSprite.unk6 &= ~SPRITEOAM_MASK_UNK6_4; sDialogueBoxArrowSprite.unk6 |= var; x = gUnknown_202E748.unk8; sDialogueBoxArrowSprite.attrib2 &= ~SPRITEOAM_MASK_X; - sDialogueBoxArrowSprite.attrib2 |= x & 0x1FF; + sDialogueBoxArrowSprite.attrib2 |= (x & SPRITEOAM_MAX_X) << SPRITEOAM_SHIFT_X; } AddSprite(&sDialogueBoxArrowSprite, 0x100, NULL, NULL); diff --git a/src/unk_menu_203B360.c b/src/unk_menu_203B360.c index 2a14e3a93..833aa84ef 100644 --- a/src/unk_menu_203B360.c +++ b/src/unk_menu_203B360.c @@ -127,7 +127,7 @@ u32 sub_80383D4(void) void sub_8038440(void) { -#ifdef NONMATCHING // SpriteOAM memes. TODO: Match like sub_8039174 with multiple vars and while(0) +#ifdef NONMATCHING // SpriteOAM memes u32 r0; u32 r2; #else