diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/money.c | 3 | ||||
-rwxr-xr-x | src/shop.c | 360 |
2 files changed, 361 insertions, 2 deletions
diff --git a/src/money.c b/src/money.c index 98f25a42a..9f2348f18 100644 --- a/src/money.c +++ b/src/money.c @@ -6,10 +6,9 @@ #include "menu.h" #include "window.h" #include "sprite.h" +#include "strings.h" #include "decompress.h" -extern const u8 gText_PokedollarVar1[]; - extern const u8 gMenuMoneyGfx[]; extern const u8 gMenuMoneyPal[]; diff --git a/src/shop.c b/src/shop.c new file mode 100755 index 000000000..5dc85859b --- /dev/null +++ b/src/shop.c @@ -0,0 +1,360 @@ +#include "global.h" +#include "bg.h" +#include "decoration.h" +#include "field_screen.h" +#include "field_weather.h" +#include "international_string_util.h" +#include "item.h" +#include "list_menu.h" +#include "main.h" +#include "malloc.h" +#include "menu.h" +#include "menu_helpers.h" +#include "overworld.h" +#include "palette.h" +#include "scanline_effect.h" +#include "script.h" +#include "shop.h" +#include "sound.h" +#include "string_util.h" +#include "strings.h" +#include "tv.h" +#include "constants/rgb.h" +#include "constants/songs.h" + +extern struct ShopData *gShopDataPtr; +extern struct ListMenuItem *gUnknown_02039F74; +extern u8 (*gUnknown_02039F78)[16]; +extern struct MartInfo gMartInfo; + +extern const struct WindowTemplate gUnknown_08589A38[2]; +extern const struct MenuAction gUnknown_08589A10[3]; +extern const struct MenuAction gUnknown_08589A28[2]; +extern const struct ListMenuTemplate gUnknown_08589A48; +extern const u8 gUnknown_08589AB3[]; + +static void Task_ShopMenu(u8 taskId); +void HandleShopMenuQuit(u8 taskId); +void CB2_InitBuyMenu(void); +static void Task_GoToBuyOrSellMenu(u8 taskId); +void CB2_GoToSellMenu(void); +void MapPostLoadHook_ExitBuyOrSellMenu(void); +void Task_ExitSellMenu(u8 taskId); +void ReturnToShopMenuAfterExitingSellMenu(u8 taskId); +void BuyMenuDrawGraphics(void); +void BuyMenuAddScrollIndicatorArrows(void); +void Task_BuyMenu(u8 taskId); +void BuyMenuBuildListMenuTemplate(void); +void BuyMenuInitBgs(void); +void BuyMenuInitWindows(void); +void BuyMenuDecompressBgGraphics(void); +void BuyMenuSetListEntry(struct ListMenuItem*, u16, u8*); +void BuyMenuAddItemIcon(u16, u8); +void BuyMenuRemoveItemIcon(u16, u8); +void BuyMenuPrint(u8, const u8*, u8, u8, u8, u8); + + +/*static*/ u8 CreateShopMenu(u8 martType) +{ + int numMenuItems; + + ScriptContext2_Enable(); + gMartInfo.martType = martType; + + if (martType == MART_TYPE_0) + { + struct WindowTemplate winTemplate; + winTemplate = gUnknown_08589A38[0]; + winTemplate.width = GetMaxWidthInMenuTable(gUnknown_08589A10, ARRAY_COUNT(gUnknown_08589A10)); + gMartInfo.windowId = AddWindow(&winTemplate); + gMartInfo.menuActions = gUnknown_08589A10; + numMenuItems = ARRAY_COUNT(gUnknown_08589A10); + } + else + { + struct WindowTemplate winTemplate; + winTemplate = gUnknown_08589A38[1]; + winTemplate.width = GetMaxWidthInMenuTable(gUnknown_08589A28, ARRAY_COUNT(gUnknown_08589A28)); + gMartInfo.windowId = AddWindow(&winTemplate); + gMartInfo.menuActions = gUnknown_08589A28; + numMenuItems = ARRAY_COUNT(gUnknown_08589A28); + } + + SetStandardWindowBorderStyle(gMartInfo.windowId, 0); + PrintMenuTable(gMartInfo.windowId, numMenuItems, gMartInfo.menuActions); + InitMenuInUpperLeftCornerPlaySoundWhenAPressed(gMartInfo.windowId, numMenuItems, 0); + PutWindowTilemap(gMartInfo.windowId); + CopyWindowToVram(gMartInfo.windowId, 1); + + return CreateTask(Task_ShopMenu, 8); +} + +/*static*/ void SetShopMenuCallback(void (* callback)(void)) +{ + gMartInfo.callback = callback; +} + +/*static*/ void SetShopItemsForSale(const u16 *items) +{ + u16 i = 0; + + gMartInfo.itemList = items; + gMartInfo.itemCount = 0; + + while (gMartInfo.itemList[i]) + { + gMartInfo.itemCount++; + i++; + } +} + +static void Task_ShopMenu(u8 taskId) +{ + s8 inputCode = Menu_ProcessInputNoWrapAround(); + switch (inputCode) + { + case -2: + break; + case -1: + PlaySE(SE_SELECT); + HandleShopMenuQuit(taskId); + break; + default: + gMartInfo.menuActions[inputCode].func.void_u8(taskId); + break; + } +} + +void HandleShopMenuBuy(u8 taskId) +{ + s16 *taskData = gTasks[taskId].data; + taskData[8] = (u32)CB2_InitBuyMenu >> 16; + taskData[9] = (u32)CB2_InitBuyMenu; + gTasks[taskId].func = Task_GoToBuyOrSellMenu; + FadeScreen(1, 0); +} + +void HandleShopMenuSell(u8 taskId) +{ + s16 *taskData = gTasks[taskId].data; + taskData[8] = (u32)CB2_GoToSellMenu >> 16; + taskData[9] = (u32)CB2_GoToSellMenu; + gTasks[taskId].func = Task_GoToBuyOrSellMenu; + FadeScreen(1, 0); +} + +void CB2_ExitSellMenu(void) +{ + gFieldCallback = MapPostLoadHook_ExitBuyOrSellMenu; + SetMainCallback2(CB2_ReturnToField); +} + +/*static*/ void HandleShopMenuQuit(u8 taskId) +{ + sub_8198070(gMartInfo.windowId, 2); + RemoveWindow(gMartInfo.windowId); + SaveRecordedItemPurchasesForTVShow(); + ScriptContext2_Disable(); + DestroyTask(taskId); + + if (gMartInfo.callback) + gMartInfo.callback(); +} + +static void Task_GoToBuyOrSellMenu(u8 taskId) +{ + s16 *taskData = gTasks[taskId].data; + if (!gPaletteFade.active) + { + DestroyTask(taskId); + SetMainCallback2((void *)((u16)taskData[8] << 16 | (u16)taskData[9])); + } +} + +void MapPostLoadHook_ExitBuyOrSellMenu(void) +{ + pal_fill_black(); + CreateTask(Task_ExitSellMenu, 8); +} + +void Task_ExitSellMenu(u8 taskId) +{ + if (IsWeatherNotFadingIn() == TRUE) + { + if (gMartInfo.martType == MART_TYPE_2) + DisplayItemMessageOnField(taskId, gText_CanIHelpWithAnythingElse, ReturnToShopMenuAfterExitingSellMenu); + else + DisplayItemMessageOnField(taskId, gText_AnythingElseICanHelp, ReturnToShopMenuAfterExitingSellMenu); + } +} + +void ReturnToShopMenuAfterExitingSellMenu(u8 taskId) +{ + CreateShopMenu(gMartInfo.martType); + DestroyTask(taskId); +} + +void CB2_BuyMenu(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + do_scheduled_bg_tilemap_copies_to_vram(); + UpdatePaletteFade(); +} + +void VBlankCB_BuyMenu(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +void CB2_InitBuyMenu(void) +{ + u8 taskId; + + switch (gMain.state) + { + case 0: + SetVBlankHBlankCallbacksToNull(); + CpuFastFill(0, (void *)OAM, 0x400); + ScanlineEffect_Stop(); + reset_temp_tile_data_buffers(); + FreeAllSpritePalettes(); + ResetPaletteFade(); + ResetSpriteData(); + ResetTasks(); + clear_scheduled_bg_copies_to_vram(); + gShopDataPtr = AllocZeroed(sizeof(struct ShopData)); + gShopDataPtr->unk200B = 0xFF; + gShopDataPtr->unk200D = -1; + gShopDataPtr->unk200E = -1; + BuyMenuBuildListMenuTemplate(); + BuyMenuInitBgs(); + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x20, 0x20); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 0x20, 0x20); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 0x20, 0x20); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 0x20, 0x20); + BuyMenuInitWindows(); + BuyMenuDecompressBgGraphics(); + gMain.state++; + break; + case 1: + if (!free_temp_tile_data_buffers_if_possible()) + gMain.state++; + break; + default: + BuyMenuDrawGraphics(); + BuyMenuAddScrollIndicatorArrows(); + taskId = CreateTask(Task_BuyMenu, 8); + gTasks[taskId].data[7] = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0); + BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); + SetVBlankCallback(VBlankCB_BuyMenu); + SetMainCallback2(CB2_BuyMenu); + break; + } +} + +void BuyMenuFreeMemory(void) +{ + Free(gShopDataPtr); + Free(gUnknown_02039F74); + Free(gUnknown_02039F78); + FreeAllWindowBuffers(); +} + +void BuyMenuBuildListMenuTemplate(void) +{ + u16 i; + u16 itemCount; + + gUnknown_02039F74 = Alloc((gMartInfo.itemCount + 1) * sizeof(*gUnknown_02039F74)); + gUnknown_02039F78 = Alloc((gMartInfo.itemCount + 1) * sizeof(*gUnknown_02039F78)); + for (i = 0; i < gMartInfo.itemCount; i++) + BuyMenuSetListEntry(&gUnknown_02039F74[i], gMartInfo.itemList[i], gUnknown_02039F78[i]); + + StringCopy(gUnknown_02039F78[i], gText_Cancel2); + gUnknown_02039F74[i].name = gUnknown_02039F78[i]; + gUnknown_02039F74[i].id = -2; + + gMultiuseListMenuTemplate = gUnknown_08589A48; + gMultiuseListMenuTemplate.items = gUnknown_02039F74; + gMultiuseListMenuTemplate.totalItems = gMartInfo.itemCount + 1; + if (gMultiuseListMenuTemplate.totalItems > 8) + gMultiuseListMenuTemplate.maxShowed = 8; + else + gMultiuseListMenuTemplate.maxShowed = gMultiuseListMenuTemplate.totalItems; + + gShopDataPtr->unk2004 = gMultiuseListMenuTemplate.maxShowed; +} + +void BuyMenuSetListEntry(struct ListMenuItem *menuItem, u16 item, u8 *name) +{ + if (gMartInfo.martType == MART_TYPE_0) + CopyItemName(item, name); + else + StringCopy(name, gDecorations[item].name); + + menuItem->name = name; + menuItem->id = item; +} + +void BuyMenuPrintItemDescriptionAndShowItemIcon(int item, bool8 onInit, struct ListMenu *list) +{ + const u8 *description; + if (onInit != TRUE) + PlaySE(SE_SELECT); + + if (item != -2) + BuyMenuAddItemIcon(item, gShopDataPtr->unk200C); + else + BuyMenuAddItemIcon(-1, gShopDataPtr->unk200C); + + BuyMenuRemoveItemIcon(item, gShopDataPtr->unk200C ^ 1); + gShopDataPtr->unk200C ^= 1; + if (item != -2) + { + if (gMartInfo.martType == MART_TYPE_0) + description = ItemId_GetDescription(item); + else + description = gDecorations[item].description; + } + else + { + description = gText_QuitShopping; + } + + FillWindowPixelBuffer(2, 0); + BuyMenuPrint(2, description, 3, 1, 0, 0); +} + +void BuyMenuPrintPriceInList(u8 windowId, int item, u8 y) +{ + u8 x; + + if (item != -2) + { + if (gMartInfo.martType == MART_TYPE_0) + { + ConvertIntToDecimalStringN( + gStringVar1, + ItemId_GetPrice(item) >> GetPriceReduction(1), + STR_CONV_MODE_LEFT_ALIGN, + 5); + } + else + { + ConvertIntToDecimalStringN( + gStringVar1, + gDecorations[item].price, + STR_CONV_MODE_LEFT_ALIGN, + 5); + } + + StringExpandPlaceholders(gStringVar4, gText_PokedollarVar1); + x = GetStringRightAlignXOffset(7, gStringVar4, 0x78); + AddTextPrinterParameterized2(windowId, 7, x, y, 0, 0, gUnknown_08589AB3, -1, gStringVar4); + } +} |