sync icon sprite handling

This commit is contained in:
cawtds 2025-06-14 14:25:41 +02:00
parent ed3b380ab8
commit 7013defe00
7 changed files with 147 additions and 76 deletions

View File

@ -41,7 +41,6 @@ enum {
};
#define ITEMMENU_SWAP_LINE_LENGTH 9
// Indexes for gItemMenuIconSpriteIds
enum {
ITEMMENUSPRITE_BAG,
ITEMMENUSPRITE_SWAP_LINE,
@ -65,6 +64,7 @@ struct BagMenu
{
void (*newScreenCallback)(void);
u8 tilemapBuffer[BG_SCREEN_SIZE];
u8 spriteIds[ITEMMENUSPRITE_COUNT];
u8 windowIds[ITEMWIN_COUNT];
u8 toSwapPos;
u8 pocketSwitchMode:4;
@ -82,8 +82,6 @@ struct BagMenu
s16 graphicsLoadState;
};
extern u8 gItemMenuIconSpriteIds[ITEMMENUSPRITE_COUNT];
extern struct BagMenu *gBagMenu;
extern u16 gSpecialVar_ItemId;

View File

@ -16,7 +16,4 @@ void CreateItemMenuSwapLine(void);
void SetItemMenuSwapLineInvisibility(bool8 invisible);
void UpdateItemMenuSwapLinePos(u16 y);
void ResetItemMenuIconState(void);
void CreateBerryPouchItemIcon(u16 itemId, u8 id);
#endif // GUARD_ITEM_MENU_ICONS_H

View File

@ -42,6 +42,7 @@ struct BerryPouchStruct_203F36C
u8 listMenuNumItems;
u8 listMenuMaxShowed;
u8 itemMenuIconId;
u8 itemSpriteIds[2];
u8 ALIGNED(4) bg1TilemapBuffer[BG_SCREEN_SIZE];
s16 data[4];
};
@ -439,6 +440,8 @@ void InitBerryPouch(u8 type, void (*savedCallback)(void), u8 allowSelect)
sStaticCnt.savedCallback = savedCallback;
sResources->exitCallback = NULL;
sResources->itemMenuIconId = 0;
sResources->itemSpriteIds[0] = SPRITE_NONE,
sResources->itemSpriteIds[1] = SPRITE_NONE,
sResources->indicatorTaskId = 0xFF;
for (i = 0; i < 4; i++)
sResources->data[i] = 0;
@ -515,7 +518,6 @@ static bool8 RunBerryPouchInit(void)
gMain.state++;
break;
case 5:
ResetItemMenuIconState();
gMain.state++;
break;
case 6:
@ -721,6 +723,39 @@ static void CopySelectedListMenuItemName(s16 itemIdx, u8 * dest)
StringCopy(dest, &sListMenuStrbuf[itemIdx * 27]);
}
static void CreateBerryPouchItemIcon(u16 item, u8 iconSlot)
{
u8 *spriteIdPtr = &sResources->itemSpriteIds[iconSlot];
if (*spriteIdPtr == SPRITE_NONE)
{
u8 spriteId;
// Either TAG_ITEM_ICON or TAG_ITEM_ICON_ALT
FreeSpriteTilesByTag(TAG_ITEM_ICON + iconSlot);
FreeSpritePaletteByTag(TAG_ITEM_ICON + iconSlot);
spriteId = AddItemIconSprite(TAG_ITEM_ICON + iconSlot, TAG_ITEM_ICON + iconSlot, item);
if (spriteId != MAX_SPRITES)
{
*spriteIdPtr = spriteId;
gSprites[spriteId].x2 = 24;
gSprites[spriteId].y2 = 147;
}
}
}
static void RemoveBerryPouchItemIcon(u8 iconSlot)
{
u8 *spriteIdPtr = &sResources->itemSpriteIds[iconSlot];
if (*spriteIdPtr == SPRITE_NONE)
return;
FreeSpriteTilesByTag(iconSlot + TAG_ITEM_ICON);
FreeSpritePaletteByTag(iconSlot + TAG_ITEM_ICON);
DestroySprite(&gSprites[*spriteIdPtr]);
*spriteIdPtr = SPRITE_NONE;
}
static void BerryPouchMoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list)
{
if (onInit != TRUE)
@ -728,11 +763,11 @@ static void BerryPouchMoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMen
PlaySE(SE_BAG_CURSOR);
StartBerryPouchSpriteWobbleAnim();
}
RemoveBagItemIconSprite(sResources->itemMenuIconId ^ 1);
if (sResources->listMenuNumItems != itemIndex)
CreateBerryPouchItemIcon(BagGetItemIdByPocketPosition(POCKET_BERRIES, itemIndex), sResources->itemMenuIconId);
else
CreateBerryPouchItemIcon(ITEMS_COUNT, sResources->itemMenuIconId);
RemoveBerryPouchItemIcon(sResources->itemMenuIconId ^ 1);
sResources->itemMenuIconId ^= 1;
PrintSelectedBerryDescription(itemIndex);
}

View File

@ -702,6 +702,7 @@ void GoToBagMenu(u8 location, u8 pocket, MainCallback exitCallback)
gBagMenu->toSwapPos = NOT_SWAPPING;
gBagMenu->pocketScrollArrowsTask = TASK_NONE;
gBagMenu->pocketSwitchArrowsTask = TASK_NONE;
memset(gBagMenu->spriteIds, SPRITE_NONE, sizeof(gBagMenu->spriteIds));
memset(gBagMenu->windowIds, WINDOW_NONE, sizeof(gBagMenu->windowIds));
SetMainCallback2(CB2_Bag);
@ -778,7 +779,6 @@ static bool8 SetupBagMenu(void)
gMain.state++;
break;
case 5:
ResetItemMenuIconState();
gMain.state++;
break;
case 6:
@ -1507,7 +1507,7 @@ static void Task_HandleSwappingItemsInput(u8 taskId)
if (JOY_NEW(SELECT_BUTTON))
{
PlaySE(SE_SELECT);
ListMenuGetScrollAndRow(data[0], &gBagPosition.scrollPosition[gBagPosition.pocket], &gBagPosition.cursorPosition[gBagPosition.pocket]);
ListMenuGetScrollAndRow(tListTaskId, &gBagPosition.scrollPosition[gBagPosition.pocket], &gBagPosition.cursorPosition[gBagPosition.pocket]);
DoItemSwap(taskId);
}
else

View File

@ -12,8 +12,6 @@ enum {
AFFINEANIM_BAG_SHAKE,
};
EWRAM_DATA u8 gItemMenuIconSpriteIds[ITEMMENUSPRITE_COUNT] = {0};
static void SpriteCB_BagVisualSwitchingPockets(struct Sprite *sprite);
static void SpriteCB_ShakeBagSprite(struct Sprite *sprite);
@ -121,23 +119,15 @@ const struct SpriteTemplate gItemIconSpriteTemplate = {
.callback = SpriteCallbackDummy
};
void ResetItemMenuIconState(void)
{
u16 i;
for (i = 0; i < ITEMMENUSPRITE_COUNT; i++)
gItemMenuIconSpriteIds[i] = SPRITE_NONE;
}
void AddBagVisualSprite(u8 bagPocketId)
{
gItemMenuIconSpriteIds[ITEMMENUSPRITE_BAG] = CreateSprite(&sSpriteTemplate_Bag, 40, 68, 0);
gBagMenu->spriteIds[ITEMMENUSPRITE_BAG] = CreateSprite(&sSpriteTemplate_Bag, 40, 68, 0);
SetBagVisualPocketId(bagPocketId);
}
void SetBagVisualPocketId(u8 bagPocketId)
{
struct Sprite *sprite = &gSprites[gItemMenuIconSpriteIds[ITEMMENUSPRITE_BAG]];
struct Sprite *sprite = &gSprites[gBagMenu->spriteIds[ITEMMENUSPRITE_BAG]];
sprite->y2 = -5;
sprite->callback = SpriteCB_BagVisualSwitchingPockets;
StartSpriteAnim(sprite, bagPocketId);
@ -153,7 +143,7 @@ static void SpriteCB_BagVisualSwitchingPockets(struct Sprite *sprite)
void ShakeBagSprite(void)
{
struct Sprite *sprite = &gSprites[gItemMenuIconSpriteIds[ITEMMENUSPRITE_BAG]];
struct Sprite *sprite = &gSprites[gBagMenu->spriteIds[ITEMMENUSPRITE_BAG]];
if (sprite->affineAnimEnded)
{
StartSpriteAffineAnim(sprite, AFFINEANIM_BAG_SHAKE);
@ -172,7 +162,7 @@ static void SpriteCB_ShakeBagSprite(struct Sprite *sprite)
void AddBagItemIconSprite(u16 itemId, u8 id)
{
u8 *spriteIds = &gItemMenuIconSpriteIds[ITEMMENUSPRITE_ITEM];
u8 *spriteIds = &gBagMenu->spriteIds[ITEMMENUSPRITE_ITEM];
if (spriteIds[id] == SPRITE_NONE)
{
@ -193,7 +183,7 @@ void AddBagItemIconSprite(u16 itemId, u8 id)
void RemoveBagItemIconSprite(u8 id)
{
u8 *spriteIds = &gItemMenuIconSpriteIds[ITEMMENUSPRITE_ITEM];
u8 *spriteIds = &gBagMenu->spriteIds[ITEMMENUSPRITE_ITEM];
if (spriteIds[id] != SPRITE_NONE)
{
@ -204,37 +194,17 @@ void RemoveBagItemIconSprite(u8 id)
void CreateItemMenuSwapLine(void)
{
CreateSwapLineSprites(&gItemMenuIconSpriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH);
CreateSwapLineSprites(&gBagMenu->spriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH);
}
void SetItemMenuSwapLineInvisibility(bool8 invisible)
{
SetSwapLineSpritesInvisibility(&gItemMenuIconSpriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH, invisible);
SetSwapLineSpritesInvisibility(&gBagMenu->spriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH, invisible);
}
void UpdateItemMenuSwapLinePos(u16 y)
{
UpdateSwapLineSpritesPos(&gItemMenuIconSpriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH, 0, y + 6);
}
void CreateBerryPouchItemIcon(u16 itemId, u8 id)
{
u8 *spriteIds = &gItemMenuIconSpriteIds[ITEMMENUSPRITE_ITEM];
u8 spriteId;
if (spriteIds[id] == SPRITE_NONE)
{
// Either TAG_ITEM_ICON or TAG_ITEM_ICON_ALT
FreeSpriteTilesByTag(TAG_ITEM_ICON + id);
FreeSpritePaletteByTag(TAG_ITEM_ICON + id);
spriteId = AddItemIconSprite(TAG_ITEM_ICON + id, TAG_ITEM_ICON + id, itemId);
if (spriteId != MAX_SPRITES)
{
spriteIds[id] = spriteId;
gSprites[spriteId].x2 = 24;
gSprites[spriteId].y2 = 147; // This value is the only difference from AddBagItemIconSprite
}
}
UpdateSwapLineSpritesPos(&gBagMenu->spriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH, 0, y + 6);
}

View File

@ -34,6 +34,8 @@ struct ItemPcResources
u8 scrollIndicatorArrowPairId;
u16 withdrawQuantitySubmenuCursorPos;
s16 data[3];
u8 swapLineSpriteIds[ITEMMENU_SWAP_LINE_LENGTH];
u8 itemSpriteIds[2];
};
struct ItemPcStaticResources
@ -216,7 +218,7 @@ void ItemPc_Init(u8 kind, MainCallback callback)
SetMainCallback2(callback);
return;
}
if ((sStateDataPtr = Alloc(sizeof(struct ItemPcResources))) == NULL)
if ((sStateDataPtr = AllocZeroed(sizeof(struct ItemPcResources))) == NULL)
{
SetMainCallback2(callback);
return;
@ -230,6 +232,8 @@ void ItemPc_Init(u8 kind, MainCallback callback)
sStateDataPtr->itemMenuIconSlot = 0;
sStateDataPtr->scrollIndicatorArrowPairId = 0xFF;
sStateDataPtr->savedCallback = 0;
sStateDataPtr->itemSpriteIds[0] = SPRITE_NONE;
sStateDataPtr->itemSpriteIds[1] = SPRITE_NONE;
for (i = 0; i < 3; i++)
{
sStateDataPtr->data[i] = 0;
@ -291,7 +295,6 @@ static bool8 ItemPc_DoGfxSetup(void)
gMain.state++;
break;
case 5:
ResetItemMenuIconState();
gMain.state++;
break;
case 6:
@ -342,7 +345,7 @@ static bool8 ItemPc_DoGfxSetup(void)
gMain.state++;
break;
case 14:
CreateSwapLineSprites(&gItemMenuIconSpriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH);
CreateSwapLineSprites(sStateDataPtr->swapLineSpriteIds, ITEMMENU_SWAP_LINE_LENGTH);
gMain.state++;
break;
case 15:
@ -508,6 +511,39 @@ static void ItemPc_BuildListMenuTemplate(void)
gMultiuseListMenuTemplate.cursorKind = 0;
}
static void AddPcItemIconSprite(u16 item, u8 iconSlot)
{
u8 *spriteIdPtr = &sStateDataPtr->itemSpriteIds[iconSlot];
if (*spriteIdPtr == SPRITE_NONE)
{
u8 spriteId;
// Either TAG_ITEM_ICON or TAG_ITEM_ICON_ALT
FreeSpriteTilesByTag(TAG_ITEM_ICON + iconSlot);
FreeSpritePaletteByTag(TAG_ITEM_ICON + iconSlot);
spriteId = AddItemIconSprite(TAG_ITEM_ICON + iconSlot, TAG_ITEM_ICON + iconSlot, item);
if (spriteId != MAX_SPRITES)
{
*spriteIdPtr = spriteId;
gSprites[spriteId].x2 = 24;
gSprites[spriteId].y2 = 140;
}
}
}
static void RemovePcItemIconSprite(u16 item, u8 iconSlot)
{
u8 *spriteIdPtr = &sStateDataPtr->itemSpriteIds[iconSlot];
if (*spriteIdPtr == SPRITE_NONE)
return;
FreeSpriteTilesByTag(iconSlot + TAG_ITEM_ICON);
FreeSpritePaletteByTag(iconSlot + TAG_ITEM_ICON);
DestroySprite(&gSprites[*spriteIdPtr]);
*spriteIdPtr = SPRITE_NONE;
}
static void ItemPc_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu * list)
{
u16 itemId;
@ -517,11 +553,10 @@ static void ItemPc_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *
if (sStateDataPtr->moveModeOrigPos == 0xFF)
{
RemoveBagItemIconSprite(sStateDataPtr->itemMenuIconSlot ^ 1);
if (itemIndex != -2)
{
itemId = ItemPc_GetItemIdBySlotId(itemIndex);
AddBagItemIconSprite(itemId, sStateDataPtr->itemMenuIconSlot);
AddPcItemIconSprite(itemId, sStateDataPtr->itemMenuIconSlot);
if (GetItemPocket(itemId) == POCKET_TM_HM)
desc = gMovesInfo[ItemIdToBattleMoveId(itemId)].name;
else
@ -529,9 +564,10 @@ static void ItemPc_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *
}
else
{
AddBagItemIconSprite(ITEMS_COUNT, sStateDataPtr->itemMenuIconSlot);
AddPcItemIconSprite(ITEMS_COUNT, sStateDataPtr->itemMenuIconSlot);
desc = gText_ReturnToPC;
}
RemovePcItemIconSprite(itemId, sStateDataPtr->itemMenuIconSlot ^ 1);
sStateDataPtr->itemMenuIconSlot ^= 1;
FillWindowPixelBuffer(1, 0);
ItemPc_AddTextPrinterParameterized(1, FONT_NORMAL, desc, 0, 3, 2, 0, 0, 3);
@ -765,7 +801,7 @@ static void ItemPc_ReturnFromSubmenu(u8 taskId)
static void ItemStorage_UpdateSwapLinePos(u8 y)
{
UpdateSwapLineSpritesPos(&gItemMenuIconSpriteIds[ITEMMENUSPRITE_SWAP_LINE], ITEMMENU_SWAP_LINE_LENGTH, -32, y + 6);
UpdateSwapLineSpritesPos(sStateDataPtr->swapLineSpriteIds, ITEMMENU_SWAP_LINE_LENGTH, -32, y + 6);
}
static void ItemStorage_StartItemSwap(u8 taskId, s16 pos)
@ -780,7 +816,7 @@ static void ItemStorage_StartItemSwap(u8 taskId, s16 pos)
FillWindowPixelBuffer(1, 0x00);
ItemPc_AddTextPrinterParameterized(1, FONT_NORMAL, gStringVar4, 0, 3, 2, 3, 0, 0);
ItemStorage_UpdateSwapLinePos(ListMenuGetYCoordForPrintingArrowCursor(data[0]));
SetItemMenuSwapLineInvisibility(FALSE);
SetSwapLineSpritesInvisibility(sStateDataPtr->swapLineSpriteIds, ITEMMENU_SWAP_LINE_LENGTH, FALSE);
ItemPc_PrintOrRemoveCursor(data[0], 2);
gTasks[taskId].func = ItemStorage_ProcessItemSwapInput;
}
@ -819,7 +855,7 @@ static void ItemPc_InsertItemIntoNewSlot(u8 taskId, u32 pos)
sListMenuState.row--;
ItemPc_BuildListMenuTemplate();
data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sListMenuState.scroll, sListMenuState.row);
SetItemMenuSwapLineInvisibility(TRUE);
SetSwapLineSpritesInvisibility(sStateDataPtr->swapLineSpriteIds, ITEMMENU_SWAP_LINE_LENGTH, TRUE);
gTasks[taskId].func = Task_ItemPcMain;
}
}
@ -833,7 +869,7 @@ static void ItemPc_MoveItemModeCancel(u8 taskId, u32 pos)
sListMenuState.row--;
ItemPc_BuildListMenuTemplate();
data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sListMenuState.scroll, sListMenuState.row);
SetItemMenuSwapLineInvisibility(TRUE);
SetSwapLineSpritesInvisibility(sStateDataPtr->swapLineSpriteIds, ITEMMENU_SWAP_LINE_LENGTH, TRUE);
gTasks[taskId].func = Task_ItemPcMain;
}
@ -872,7 +908,7 @@ static void Task_ItemPcSubmenuRun(u8 taskId)
static void Task_ItemPcWithdraw(u8 taskId)
{
s16 * data = gTasks[taskId].data;
s16 *data = gTasks[taskId].data;
ClearStdWindowAndFrameToTransparent(4, FALSE);
ItemPc_DestroySubwindow(0);

View File

@ -55,19 +55,20 @@ enum
struct ShopData
{
/*0x00*/ void (*callback)(void);
/*0x04*/ const u16 *itemList;
/*0x08*/ u32 itemPrice;
/*0x0C*/ u16 selectedRow;
/*0x0E*/ u16 scrollOffset;
/*0x10*/ u16 itemCount;
/*0x12*/ u16 itemsShowed;
/*0x14*/ u16 maxQuantity;
/*0x16*/ u16 martType:4; // 0x1 if tm list
u16 fontId:5;
u16 itemSlot:2;
u16 unk16_11:5;
/*0x18*/ u16 unk18;
void (*callback)(void);
const u16 *itemList;
u32 itemPrice;
u16 selectedRow;
u16 scrollOffset;
u16 itemCount;
u16 itemsShowed;
u16 maxQuantity;
u16 martType:4; // 0x1 if tm list
u16 fontId:5;
u16 itemSlot:2;
u16 unk16_11:5;
u16 unk18;
u8 itemSpriteIds[2];
};
static EWRAM_DATA s16 sViewportObjectEvents[OBJECT_EVENTS_COUNT][4] = {0};
@ -513,7 +514,8 @@ static void CB2_InitBuyMenu(void)
ResetSpriteData();
ResetTasks();
ClearScheduledBgCopiesToVram();
ResetItemMenuIconState();
sShopData.itemSpriteIds[0] = SPRITE_NONE;
sShopData.itemSpriteIds[1] = SPRITE_NONE;
if (!(InitShopData()) || !(BuyMenuBuildListMenuTemplate()))
return;
BuyMenuInitBgs();
@ -754,6 +756,39 @@ static void PokeMartWriteNameAndIdAt(struct ListMenuItem *list, u16 index, u8 *d
list->id = index;
}
static void BuyMenuAddItemIcon(u16 item, u8 iconSlot)
{
u8 *spriteIdPtr = &sShopData.itemSpriteIds[iconSlot];
if (*spriteIdPtr == SPRITE_NONE)
{
u8 spriteId;
// Either TAG_ITEM_ICON or TAG_ITEM_ICON_ALT
FreeSpriteTilesByTag(TAG_ITEM_ICON + iconSlot);
FreeSpritePaletteByTag(TAG_ITEM_ICON + iconSlot);
spriteId = AddItemIconSprite(TAG_ITEM_ICON + iconSlot, TAG_ITEM_ICON + iconSlot, item);
if (spriteId != MAX_SPRITES)
{
*spriteIdPtr = spriteId;
gSprites[spriteId].x2 = 24;
gSprites[spriteId].y2 = 140;
}
}
}
static void BuyMenuRemoveItemIcon(u8 iconSlot)
{
u8 *spriteIdPtr = &sShopData.itemSpriteIds[iconSlot];
if (*spriteIdPtr == SPRITE_NONE)
return;
FreeSpriteTilesByTag(iconSlot + TAG_ITEM_ICON);
FreeSpritePaletteByTag(iconSlot + TAG_ITEM_ICON);
DestroySprite(&gSprites[*spriteIdPtr]);
*spriteIdPtr = SPRITE_NONE;
}
static void BuyMenuPrintItemDescriptionAndShowItemIcon(s32 item, bool8 onInit, struct ListMenu *list)
{
const u8 *description;
@ -769,11 +804,11 @@ static void BuyMenuPrintItemDescriptionAndShowItemIcon(s32 item, bool8 onInit, s
FillWindowPixelBuffer(5, PIXEL_FILL(0));
if (sShopData.martType != MART_TYPE_TMHM)
{
RemoveBagItemIconSprite(sShopData.itemSlot ^ 1);
if (item != INDEX_CANCEL)
AddBagItemIconSprite(item, sShopData.itemSlot);
BuyMenuAddItemIcon(item, sShopData.itemSlot);
else
AddBagItemIconSprite(ITEMS_COUNT, sShopData.itemSlot);
BuyMenuAddItemIcon(ITEMS_COUNT, sShopData.itemSlot);
BuyMenuRemoveItemIcon(sShopData.itemSlot ^ 1);
sShopData.itemSlot ^= 1;
BuyMenuPrint(5, FONT_NORMAL, description, 0, 3, 2, 1, 0, 0);