diff options
author | PikalaxALT <PikalaxALT@users.noreply.github.com> | 2019-04-15 13:59:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-15 13:59:00 -0400 |
commit | 5bf1c29cee223cba17a1ec93af0196e380e8cbf1 (patch) | |
tree | 15e666997001cf39d482f2636953c654d255af3e /src | |
parent | 0cb1417de441af6e688fc4784da498bb677cc888 (diff) | |
parent | 0f569270391f68ef10a703a9e37f1a4e298a0cee (diff) |
Merge pull request #49 from PikalaxALT/tm_case
Tm case
Diffstat (limited to 'src')
-rw-r--r-- | src/fame_checker.c | 2 | ||||
-rw-r--r-- | src/text.c | 4 | ||||
-rw-r--r-- | src/tm_case.c | 1537 | ||||
-rw-r--r-- | src/window.c | 2 |
4 files changed, 1541 insertions, 4 deletions
diff --git a/src/fame_checker.c b/src/fame_checker.c index 29b888a32..c47e52f06 100644 --- a/src/fame_checker.c +++ b/src/fame_checker.c @@ -853,7 +853,7 @@ static void Task_DestroyAssetsAndCloseFameChecker(u8 taskId) FreeQuestionMarkSpriteResources(); FreeListMenuSelectorArrowPairResources(); SetMainCallback2(sFameCheckerData->savedCallback); - sub_810713C(sFameCheckerData->listMenuTaskId, 0, 0); + DestroyListMenu(sFameCheckerData->listMenuTaskId, NULL, NULL); Free(sBg3TilemapBuffer); Free(sBg1TilemapBuffer); Free(sBg2TilemapBuffer); diff --git a/src/text.c b/src/text.c index d83b36f88..d74d77e2f 100644 --- a/src/text.c +++ b/src/text.c @@ -8,7 +8,7 @@ extern u8 gGlyphInfo[0x90]; extern u8 gUnknown_203ADFA; -extern u16 gUnknown_841F408[]; +extern u16 gTMCaseMainWindowPalette[]; extern const struct OamData gOamData_83AC9D0; extern void FillBitmapRect4Bit(struct Bitmap *surface, u16 x, u16 y, u16 width, u16 height, u8 fillValue); @@ -52,7 +52,7 @@ const struct SpriteSheet gUnknown_81EA68C[] = const struct SpritePalette gUnknown_81EA6A4[] = { - {gUnknown_841F408, 0x8000}, + {gTMCaseMainWindowPalette, 0x8000}, {NULL} }; diff --git a/src/tm_case.c b/src/tm_case.c new file mode 100644 index 000000000..2fc30da2d --- /dev/null +++ b/src/tm_case.c @@ -0,0 +1,1537 @@ +#include "global.h" +#include "malloc.h" +#include "bg.h" +#include "decompress.h" +#include "gpu_regs.h" +#include "palette.h" +#include "graphics.h" +#include "task.h" +#include "text.h" +#include "text_window.h" +#include "menu.h" +#include "menu_helpers.h" +#include "new_menu_helpers.h" +#include "list_menu.h" +#include "item.h" +#include "item_menu.h" +#include "link.h" +#include "money.h" +#include "shop.h" +#include "teachy_tv.h" +#include "pokemon_storage_system.h" +#include "string_util.h" +#include "party_menu.h" +#include "data2.h" +#include "scanline_effect.h" +#include "sound.h" +#include "strings.h" +#include "tm_case.h" +#include "menu_indicators.h" +#include "constants/items.h" +#include "constants/songs.h" + +#define TM_CASE_TM_TAG 400 + +struct UnkStruct_203B10C +{ + void (* savedCallback)(void); + u8 tmCaseMenuType; + u8 unk_05; + u8 unk_06; + u16 selectedRow; + u16 scrollOffset; +}; + +struct UnkStruct_203B118 +{ + void (* savedCallback)(void); + u8 tmSpriteId; + u8 maxTMsShown; + u8 numTMs; + u8 contextMenuWindowId; + u8 scrollIndicatorArrowPairId; + u16 currItem; + const u8 * menuActionIndices; + u8 numMenuActions; + s16 seqId; + u8 filler_14[8]; +}; + +struct UnkStruct_203B11C +{ + struct ItemSlot bagPocket_TMHM[BAG_TMHM_COUNT]; + struct ItemSlot bagPocket_KeyItems[BAG_KEYITEMS_COUNT]; + u16 unk_160; + u16 unk_162; +}; + +static EWRAM_DATA struct UnkStruct_203B10C sTMCaseStaticResources = {}; +static EWRAM_DATA struct UnkStruct_203B118 * sTMCaseDynamicResources = NULL; +static EWRAM_DATA struct UnkStruct_203B11C * sPokeDudePackBackup = NULL; +static EWRAM_DATA void * sTilemapBuffer = NULL; // tilemap buffer +static EWRAM_DATA struct ListMenuItem * sListMenuItemsBuffer = NULL; +static EWRAM_DATA u8 (* sListMenuStringsBuffer)[29] = NULL; +static EWRAM_DATA u16 * sTMSpritePaletteBuffer = NULL; + +static void CB2_SetUpTMCaseUI_Blocking(void); +static bool8 DoSetUpTMCaseUI(void); +static void ResetBufferPointers_NoFree(void); +static void LoadBGTemplates(void); +static bool8 HandleLoadTMCaseGraphicsAndPalettes(void); +static void CreateTMCaseListMenuBuffers(void); +static void InitTMCaseListMenuItems(void); +static void GetTMNumberAndMoveString(u8 * dest, u16 itemId); +static void TMCase_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list); +static void TMCase_ItemPrintFunc(u8 windowId, s32 itemId, u8 y); +static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex); +static void PrintListMenuCursorAt_WithColorIdx(u8 a0, u8 a1); +static void CreateTMCaseScrollIndicatorArrowPair_Main(void); +static void TMCaseSetup_GetTMCount(void); +static void TMCaseSetup_InitListMenuPositions(void); +static void TMCaseSetup_UpdateVisualMenuOffset(void); +static void Task_FadeOutAndCloseTMCase(u8 taskId); +static void Task_TMCaseMain(u8 taskId); +static void Task_SelectTMAction_FromFieldBag(u8 taskId); +static void Task_TMContextMenu_HandleInput(u8 taskId); +static void TMHMContextMenuAction_Use(u8 taskId); +static void TMHMContextMenuAction_Give(u8 taskId); +static void PrintError_ThereIsNoPokemon(u8 taskId); +static void PrintError_ItemCantBeHeld(u8 taskId); +static void Task_WaitButtonAfterErrorPrint(u8 taskId); +static void Subtask_CloseContextMenuAndReturnToMain(u8 taskId); +static void TMHMContextMenuAction_Exit(u8 taskId); +static void Task_SelectTMAction_Type1(u8 taskId); +static void Task_SelectTMAction_Type3(u8 taskId); +static void Task_SelectTMAction_FromSellMenu(u8 taskId); +static void Task_AskConfirmSaleWithAmount(u8 taskId); +static void Task_PlaceYesNoBox(u8 taskId); +static void Task_SaleOfTMsCancelled(u8 taskId); +static void Task_InitQuantitySelectUI(u8 taskId); +static void SellTM_PrintQuantityAndSalePrice(s16 quantity, s32 value); +static void Task_QuantitySelect_HandleInput(u8 taskId); +static void Task_PrintSaleConfirmedText(u8 taskId); +static void Task_DoSaleOfTMs(u8 taskId); +static void Task_AfterSale_ReturnToList(u8 taskId); +static void Task_TMCaseDude1(u8 taskId); +static void Task_TMCaseDude_Playback(u8 taskId); +static void InitWindowTemplatesAndPals(void); +static void AddTextPrinterParameterized_ColorByIndex(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx); +static void TMCase_SetWindowBorder1(u8 windowId); +static void TMCase_SetWindowBorder2(u8 windowId); +static void TMCase_PrintMessageWithFollowupTask(u8 taskId, u8 windowId, const u8 * str, TaskFunc func); +static void PrintStringTMCaseOnWindow3(void); +static void DrawMoveInfoUIMarkers(void); +static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId); +static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y); +static void HandlePrintMoneyOnHand(void); +static void HandleCreateYesNoMenu(u8 taskId, const struct YesNoFuncTable * ptrs); +static u8 AddTMContextMenu(u8 * a0, u8 a1); +static void RemoveTMContextMenu(u8 * a0); +static u8 CreateTMSprite(u16 itemId); +static void SetTMSpriteAnim(struct Sprite * sprite, u8 var); +static void TintTMSpriteByType(u8 type); +static void UpdateTMSpritePosition(struct Sprite * sprite, u8 var); +static void InitSelectedTMSpriteData(u8 a0, u16 itemId); +static void SpriteCB_MoveTMSpriteInCase(struct Sprite * sprite); +static void LoadTMTypePalettes(void); + +static const struct BgTemplate sBGTemplates[] = { + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0x000 + }, { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0x000 + }, { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0x000 + } +}; + +static void (*const sSelectTMActionTasks[])(u8 taskId) = { + Task_SelectTMAction_FromFieldBag, + Task_SelectTMAction_Type1, + Task_SelectTMAction_FromSellMenu, + Task_SelectTMAction_Type3 +}; + +static const struct MenuAction sMenuActions_UseGiveExit[] = { + {gOtherText_Use, TMHMContextMenuAction_Use }, + {gOtherText_Give, TMHMContextMenuAction_Give}, + {gOtherText_Exit, TMHMContextMenuAction_Exit}, +}; + +static const u8 sMenuActionIndices_Field[] = {0, 1, 2}; +static const u8 sMenuActionIndices_UnionRoom[] = {1, 2}; +static const struct YesNoFuncTable sYesNoFuncTable = {Task_PrintSaleConfirmedText, Task_SaleOfTMsCancelled}; + +static const u8 sText_ClearTo18[] = _("{CLEAR_TO 18}"); +static const u8 sText_SingleSpace[] = _(" "); + +static ALIGNED(4) const u16 sPal3Override[] = {RGB(8, 8, 8), RGB(30, 16, 6)}; + +static const struct TextColor sTextColors[] = { + {0, 1, 2}, + {0, 2, 3}, + {0, 3, 6}, + {0, 14, 10} +}; + +static const struct WindowTemplate sWindowTemplates[] = { + {0x00, 0x0a, 0x01, 0x13, 0x0a, 0x0f, 0x0081}, + {0x00, 0x0c, 0x0c, 0x12, 0x08, 0x0a, 0x013f}, + {0x01, 0x05, 0x0f, 0x0f, 0x04, 0x0d, 0x01f9}, + {0x00, 0x00, 0x01, 0x0a, 0x02, 0x0f, 0x0235}, + {0x00, 0x01, 0x0d, 0x05, 0x06, 0x0c, 0x0249}, + {0x00, 0x07, 0x0d, 0x05, 0x06, 0x0c, 0x0267}, + {0x01, 0x02, 0x0f, 0x1a, 0x04, 0x0b, 0x0285}, + {0x01, 0x11, 0x09, 0x0c, 0x04, 0x0f, 0x02ed}, + {0x01, 0x01, 0x01, 0x08, 0x03, 0x0d, 0x031d}, + DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sYesNoWindowTemplate = {0x01, 0x15, 0x09, 0x06, 0x04, 0x0f, 0x0335}; + +static const struct WindowTemplate sTMContextWindowTemplates[] = { + {0x01, 0x16, 0x0d, 0x07, 0x06, 0x0f, 0x01cf}, + {0x01, 0x16, 0x0f, 0x07, 0x04, 0x0f, 0x01cf} +}; + +static const struct OamData sTMSpriteOamData = { + .size = 2, + .priority = 2 +}; + +static const union AnimCmd sTMSpriteAnim0[] = { + ANIMCMD_FRAME(0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sTMSpriteAnim1[] = { + ANIMCMD_FRAME(16, 0), + ANIMCMD_END +}; + +static const union AnimCmd *const sTMSpriteAnims[] = { + sTMSpriteAnim0, + sTMSpriteAnim1 +}; + +static const struct CompressedSpriteSheet sTMSpriteSheet = { + (const void *)gTMCase_TMSpriteGfx, + 0x400, + TM_CASE_TM_TAG +}; + +static const struct SpriteTemplate sTMSpriteTemplate = { + TM_CASE_TM_TAG, + TM_CASE_TM_TAG, + &sTMSpriteOamData, + sTMSpriteAnims, + NULL, + gDummySpriteAffineAnimTable, + SpriteCallbackDummy +}; + +static const u16 sTMSpritePaletteOffsetByType[] = { + [TYPE_NORMAL] = 0x000, + [TYPE_FIRE] = 0x010, + [TYPE_WATER] = 0x020, + [TYPE_GRASS] = 0x030, + [TYPE_ELECTRIC] = 0x040, + [TYPE_ROCK] = 0x050, + [TYPE_GROUND] = 0x060, + [TYPE_ICE] = 0x070, + [TYPE_FLYING] = 0x080, + [TYPE_FIGHTING] = 0x090, + [TYPE_GHOST] = 0x0a0, + [TYPE_BUG] = 0x0b0, + [TYPE_POISON] = 0x0c0, + [TYPE_PSYCHIC] = 0x0d0, + [TYPE_STEEL] = 0x0e0, + [TYPE_DARK] = 0x0f0, + [TYPE_DRAGON] = 0x100 +}; + +void InitTMCase(u8 type, void (* callback)(void), u8 a2) +{ + ResetBufferPointers_NoFree(); + sTMCaseDynamicResources = Alloc(sizeof(struct UnkStruct_203B118)); + sTMCaseDynamicResources->savedCallback = 0; + sTMCaseDynamicResources->scrollIndicatorArrowPairId = 0xFF; + sTMCaseDynamicResources->contextMenuWindowId = 0xFF; + if (type != 5) + sTMCaseStaticResources.tmCaseMenuType = type; + if (callback != NULL) + sTMCaseStaticResources.savedCallback = callback; + if (a2 != 0xFF) + sTMCaseStaticResources.unk_05 = a2; + gTextFlags.flag_2 = FALSE; + SetMainCallback2(CB2_SetUpTMCaseUI_Blocking); +} + +static void CB2_Idle(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + do_scheduled_bg_tilemap_copies_to_vram(); + UpdatePaletteFade(); +} + +static void VBlankCB_Idle(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_SetUpTMCaseUI_Blocking(void) +{ + while (1) + { + if (sub_80BF72C() == TRUE) + break; + if (DoSetUpTMCaseUI() == TRUE) + break; + if (sub_80BF708() == TRUE) + break; + } +} + +static bool8 DoSetUpTMCaseUI(void) +{ + u8 taskId; + + switch (gMain.state) + { + case 0: + sub_80BF768(); + clear_scheduled_bg_copies_to_vram(); + gMain.state++; + break; + case 1: + ScanlineEffect_Stop(); + gMain.state++; + break; + case 2: + FreeAllSpritePalettes(); + gMain.state++; + break; + case 3: + ResetPaletteFade(); + gMain.state++; + break; + case 4: + ResetSpriteData(); + gMain.state++; + break; + case 5: + ResetTasks(); + gMain.state++; + break; + case 6: + LoadBGTemplates(); + sTMCaseDynamicResources->seqId = 0; + gMain.state++; + break; + case 7: + InitWindowTemplatesAndPals(); + gMain.state++; + break; + case 8: + if (HandleLoadTMCaseGraphicsAndPalettes()) + gMain.state++; + break; + case 9: + sub_809A5E4(&gBagPockets[POCKET_TM_CASE - 1]); + gMain.state++; + break; + case 10: + TMCaseSetup_GetTMCount(); + TMCaseSetup_InitListMenuPositions(); + TMCaseSetup_UpdateVisualMenuOffset(); + gMain.state++; + break; + case 11: + DrawMoveInfoUIMarkers(); + gMain.state++; + break; + case 12: + CreateTMCaseListMenuBuffers(); + InitTMCaseListMenuItems(); + gMain.state++; + break; + case 13: + PrintStringTMCaseOnWindow3(); + gMain.state++; + break; + case 14: + if (sTMCaseStaticResources.tmCaseMenuType == 4) + taskId = CreateTask(Task_TMCaseDude1, 0); + else + taskId = CreateTask(Task_TMCaseMain, 0); + gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + gMain.state++; + break; + case 15: + CreateTMCaseScrollIndicatorArrowPair_Main(); + gMain.state++; + break; + case 16: + sTMCaseDynamicResources->tmSpriteId = CreateTMSprite(BagGetItemIdByPocketPosition(POCKET_TM_CASE, sTMCaseStaticResources.scrollOffset + sTMCaseStaticResources.selectedRow)); + gMain.state++; + break; + case 17: + BlendPalettes(0xFFFFFFFF, 16, 0); + gMain.state++; + break; + case 18: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB_BLACK); + gMain.state++; + break; + default: + SetVBlankCallback(VBlankCB_Idle); + SetMainCallback2(CB2_Idle); + return TRUE; + } + + return FALSE; +} + +static void ResetBufferPointers_NoFree(void) +{ + sTMCaseDynamicResources = NULL; + sTilemapBuffer = NULL; + sListMenuItemsBuffer = NULL; + sListMenuStringsBuffer = NULL; + sTMSpritePaletteBuffer = NULL; +} + +static void LoadBGTemplates(void) +{ + void ** ptr; + sub_80BF7C8(); + ptr = &sTilemapBuffer; + *ptr = AllocZeroed(0x800); + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates)); + SetBgTilemapBuffer(2, *ptr); + schedule_bg_copy_tilemap_to_vram(1); + schedule_bg_copy_tilemap_to_vram(2); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + ShowBg(0); + ShowBg(1); + ShowBg(2); +} + +static bool8 HandleLoadTMCaseGraphicsAndPalettes(void) +{ + switch (sTMCaseDynamicResources->seqId) + { + case 0: + reset_temp_tile_data_buffers(); + decompress_and_copy_tile_data_to_vram(1, gUnknown_8E845D8, 0, 0, 0); + sTMCaseDynamicResources->seqId++; + break; + case 1: + if (free_temp_tile_data_buffers_if_possible() != TRUE) + { + LZDecompressWram(gUnknown_8E84A24, sTilemapBuffer); + sTMCaseDynamicResources->seqId++; + } + break; + case 2: + LZDecompressWram(gUnknown_8E84B70, GetBgTilemapBuffer(1)); + sTMCaseDynamicResources->seqId++; + break; + case 3: + if (gSaveBlock2Ptr->playerGender == MALE) + LoadCompressedPalette(gUnknown_8E84CB0, 0, 0x80); + else + LoadCompressedPalette(gUnknown_8E84D20, 0, 0x80); + sTMCaseDynamicResources->seqId++; + break; + case 4: + LoadCompressedObjectPic(&sTMSpriteSheet); + sTMCaseDynamicResources->seqId++; + break; + default: + LoadTMTypePalettes(); + sTMCaseDynamicResources->seqId = 0; + return TRUE; + } + + return FALSE; +} + +static void CreateTMCaseListMenuBuffers(void) +{ + struct BagPocket * pocket = &gBagPockets[POCKET_TM_CASE - 1]; + sListMenuItemsBuffer = Alloc((pocket->capacity + 1) * sizeof(struct ListMenuItem)); + sListMenuStringsBuffer = Alloc(sTMCaseDynamicResources->numTMs * 29); +} + +static void InitTMCaseListMenuItems(void) +{ + struct BagPocket * pocket = &gBagPockets[POCKET_TM_CASE - 1]; + u16 i; + + for (i = 0; i < sTMCaseDynamicResources->numTMs; i++) + { + GetTMNumberAndMoveString(sListMenuStringsBuffer[i], pocket->itemSlots[i].itemId); + sListMenuItemsBuffer[i].unk_00 = sListMenuStringsBuffer[i]; + sListMenuItemsBuffer[i].unk_04 = i; + } + sListMenuItemsBuffer[i].unk_00 = gText_Close; + sListMenuItemsBuffer[i].unk_04 = -2; + gMultiuseListMenuTemplate.items = sListMenuItemsBuffer; + gMultiuseListMenuTemplate.totalItems = sTMCaseDynamicResources->numTMs + 1; + gMultiuseListMenuTemplate.windowId = 0; + gMultiuseListMenuTemplate.header_X = 0; + gMultiuseListMenuTemplate.item_X = 8; + gMultiuseListMenuTemplate.cursor_X = 0; + gMultiuseListMenuTemplate.lettersSpacing = 0; + gMultiuseListMenuTemplate.itemVerticalPadding = 2; + gMultiuseListMenuTemplate.upText_Y = 2; + gMultiuseListMenuTemplate.maxShowed = sTMCaseDynamicResources->maxTMsShown; + gMultiuseListMenuTemplate.fontId = 2; + gMultiuseListMenuTemplate.cursorPal = 2; + gMultiuseListMenuTemplate.fillValue = 0; + gMultiuseListMenuTemplate.cursorShadowPal = 3; + gMultiuseListMenuTemplate.moveCursorFunc = TMCase_MoveCursorFunc; + gMultiuseListMenuTemplate.itemPrintFunc = TMCase_ItemPrintFunc; + gMultiuseListMenuTemplate.cursorKind = 0; + gMultiuseListMenuTemplate.scrollMultiple = 0; +} + +static void GetTMNumberAndMoveString(u8 * dest, u16 itemId) +{ + StringCopy(gStringVar4, gText_FontSize0); + if (itemId >= ITEM_HM01) + { + StringAppend(gStringVar4, sText_ClearTo18); + StringAppend(gStringVar4, gOtherText_UnkF9_08_Clear_01); + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_HM01 + 1, STR_CONV_MODE_LEADING_ZEROS, 1); + StringAppend(gStringVar4, gStringVar1); + } + else + { + StringAppend(gStringVar4, gOtherText_UnkF9_08_Clear_01); + ConvertIntToDecimalStringN(gStringVar1, itemId - ITEM_TM01 + 1, STR_CONV_MODE_LEADING_ZEROS, 2); + StringAppend(gStringVar4, gStringVar1); + } + StringAppend(gStringVar4, sText_SingleSpace); + StringAppend(gStringVar4, gText_FontSize2); + StringAppend(gStringVar4, gMoveNames[ItemIdToBattleMoveId(itemId)]); + StringCopy(dest, gStringVar4); +} + +static void TMCase_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list) +{ + u16 itemId; + + if (itemIndex == -2) + itemId = 0; + else + itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex); + + if (onInit != TRUE) + { + PlaySE(SE_SELECT); + InitSelectedTMSpriteData(sTMCaseDynamicResources->tmSpriteId, itemId); + } + TMCase_MoveCursor_UpdatePrintedDescription(itemIndex); + TMCase_MoveCursor_UpdatePrintedTMInfo(itemId); +} + +static void TMCase_ItemPrintFunc(u8 windowId, s32 itemId, u8 y) +{ + if (itemId != -2) + { + if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemId))) + { + ConvertIntToDecimalStringN(gStringVar1, BagGetQuantityByPocketPosition(POCKET_TM_CASE, itemId), STR_CONV_MODE_RIGHT_ALIGN, 3); + StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); + AddTextPrinterParameterized_ColorByIndex(windowId, 0, gStringVar4, 0x7E, y, 0, 0, 0xFF, 1); + } + else + { + PlaceHMTileInWindow(windowId, 8, y); + } + } +} + +static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex) +{ + const u8 * str; + if (itemIndex != -2) + { + str = ItemId_GetDescription(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex)); + } + else + { + str = gText_TMCaseWillBePutAway; + } + FillWindowPixelBuffer(1, 0); + AddTextPrinterParameterized_ColorByIndex(1, 2, str, 2, 3, 1, 0, 0, 0); +} + +static void FillBG2RowWithPalette_2timesNplus1(s32 a0) +{ + sub_80F6B08(2, 0, 12, 30, 8, 2 * a0 + 1); + schedule_bg_copy_tilemap_to_vram(2); +} + +static void PrintListMenuCursorByID_WithColorIdx(u8 a0, u8 a1) +{ + PrintListMenuCursorAt_WithColorIdx(ListMenuGetYCoordForPrintingArrowCursor(a0), a1); +} + +static void PrintListMenuCursorAt_WithColorIdx(u8 a0, u8 a1) +{ + if (a1 == 0xFF) + { + FillWindowPixelRect(0, 0, 0, a0, GetFontAttribute(2, 0), GetFontAttribute(2, 1)); + CopyWindowToVram(0, 2); + } + else + { + AddTextPrinterParameterized_ColorByIndex(0, 2, gFameCheckerText_ListMenuCursor, 0, a0, 0, 0, 0, a1); + } +} + +static void CreateTMCaseScrollIndicatorArrowPair_Main(void) +{ + sTMCaseDynamicResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPairParametrized(2, 0xA0, 0x08, 0x58, sTMCaseDynamicResources->numTMs - sTMCaseDynamicResources->maxTMsShown + 1, 0x6E, 0x6E, &sTMCaseStaticResources.scrollOffset); +} + +static void CreateTMCaseScrollIndicatorArrowPair_SellQuantitySelect(void) +{ + sTMCaseDynamicResources->currItem = 1; + sTMCaseDynamicResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPairParametrized(2, 0x98, 0x48, 0x68, 2, 0x6E, 0x6E, &sTMCaseDynamicResources->currItem); +} + +static void RemoveTMCaseScrollIndicatorArrowPair(void) +{ + if (sTMCaseDynamicResources->scrollIndicatorArrowPairId != 0xFF) + { + RemoveScrollIndicatorArrowPair(sTMCaseDynamicResources->scrollIndicatorArrowPairId); + sTMCaseDynamicResources->scrollIndicatorArrowPairId = 0xFF; + } +} + +void ResetTMCaseCursorPos(void) +{ + sTMCaseStaticResources.selectedRow = 0; + sTMCaseStaticResources.scrollOffset = 0; +} + +static void TMCaseSetup_GetTMCount(void) +{ + struct BagPocket * pocket = &gBagPockets[POCKET_TM_CASE - 1]; + u16 i; + + sub_809A584(pocket->itemSlots, pocket->capacity); + sTMCaseDynamicResources->numTMs = 0; + for (i = 0; i < pocket->capacity; i++) + { + if (pocket->itemSlots[i].itemId == ITEM_NONE) + break; + sTMCaseDynamicResources->numTMs++; + } + sTMCaseDynamicResources->maxTMsShown = min(sTMCaseDynamicResources->numTMs + 1, 5); +} + +static void TMCaseSetup_InitListMenuPositions(void) +{ + if (sTMCaseStaticResources.scrollOffset != 0) + { + if (sTMCaseStaticResources.scrollOffset + sTMCaseDynamicResources->maxTMsShown > sTMCaseDynamicResources->numTMs + 1) + sTMCaseStaticResources.scrollOffset = sTMCaseDynamicResources->numTMs + 1 - sTMCaseDynamicResources->maxTMsShown; + } + if (sTMCaseStaticResources.scrollOffset + sTMCaseStaticResources.selectedRow >= sTMCaseDynamicResources->numTMs + 1) + { + if (sTMCaseDynamicResources->numTMs + 1 < 2) + sTMCaseStaticResources.selectedRow = 0; + else + sTMCaseStaticResources.selectedRow = sTMCaseDynamicResources->numTMs; + } +} + +static void TMCaseSetup_UpdateVisualMenuOffset(void) +{ + u8 i; + if (sTMCaseStaticResources.selectedRow > 3) + { + for (i = 0; i <= sTMCaseStaticResources.selectedRow - 3 && sTMCaseStaticResources.scrollOffset + sTMCaseDynamicResources->maxTMsShown != sTMCaseDynamicResources->numTMs + 1; i++) + { + do {} while (0); + sTMCaseStaticResources.selectedRow--; + sTMCaseStaticResources.scrollOffset++; + } + } +} + +static void DestroyTMCaseBuffers(void) +{ + if (sTMCaseDynamicResources != NULL) + Free(sTMCaseDynamicResources); + if (sTilemapBuffer != NULL) + Free(sTilemapBuffer); + if (sListMenuItemsBuffer != NULL) + Free(sListMenuItemsBuffer); + if (sListMenuStringsBuffer != NULL) + Free(sListMenuStringsBuffer); + if (sTMSpritePaletteBuffer != NULL) + Free(sTMSpritePaletteBuffer); + FreeAllWindowBuffers(); +} + +static void Task_BeginFadeOutFromTMCase(u8 taskId) +{ + BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, RGB_BLACK); + gTasks[taskId].func = Task_FadeOutAndCloseTMCase; +} + +static void Task_FadeOutAndCloseTMCase(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + DestroyListMenu(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + if (sTMCaseDynamicResources->savedCallback != NULL) + SetMainCallback2(sTMCaseDynamicResources->savedCallback); + else + SetMainCallback2(sTMCaseStaticResources.savedCallback); + RemoveTMCaseScrollIndicatorArrowPair(); + DestroyTMCaseBuffers(); + DestroyTask(taskId); + } +} + +static void Task_TMCaseMain(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + s32 input; + + if (!gPaletteFade.active) + { + if (sub_80BF72C() != TRUE) + { + input = ListMenuHandleInput(data[0]); + get_coro_args_x18_x1A(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + if (JOY_NEW(SELECT_BUTTON) && sTMCaseStaticResources.unk_05 == 1) + { + PlaySE(SE_SELECT); + gSpecialVar_ItemId = ITEM_NONE; + Task_BeginFadeOutFromTMCase(taskId); + } + else + { + switch (input) + { + case -1: + break; + case -2: + PlaySE(SE_SELECT); + gSpecialVar_ItemId = 0; + Task_BeginFadeOutFromTMCase(taskId); + break; + default: + PlaySE(SE_SELECT); + FillBG2RowWithPalette_2timesNplus1(1); + RemoveTMCaseScrollIndicatorArrowPair(); + PrintListMenuCursorByID_WithColorIdx(data[0], 2); + data[1] = input; + data[2] = BagGetQuantityByPocketPosition(POCKET_TM_CASE, input); + gSpecialVar_ItemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, input); + gTasks[taskId].func = sSelectTMActionTasks[sTMCaseStaticResources.tmCaseMenuType]; + break; + } + } + } + } +} + +static void Subtask_ReturnToTMCaseMain(u8 taskId) +{ + FillBG2RowWithPalette_2timesNplus1(0); + CreateTMCaseScrollIndicatorArrowPair_Main(); + gTasks[taskId].func = Task_TMCaseMain; +} + +static void Task_SelectTMAction_FromFieldBag(u8 taskId) +{ + u8 * strbuf; + TMCase_SetWindowBorder2(2); + if (!sub_80BF708() && InUnionRoom() != TRUE) + { + AddTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, 0); + sTMCaseDynamicResources->menuActionIndices = sMenuActionIndices_Field; + sTMCaseDynamicResources->numMenuActions = NELEMS(sMenuActionIndices_Field); + } + else + { + AddTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, 1); + sTMCaseDynamicResources->menuActionIndices = sMenuActionIndices_UnionRoom; + sTMCaseDynamicResources->numMenuActions = NELEMS(sMenuActionIndices_UnionRoom); + } + AddItemMenuActionTextPrinters(sTMCaseDynamicResources->contextMenuWindowId, 2, GetMenuCursorDimensionByFont(2, 0), 2, 0, GetFontAttribute(2, 1) + 2, sTMCaseDynamicResources->numMenuActions, sMenuActions_UseGiveExit, sTMCaseDynamicResources->menuActionIndices); + ProgramAndPlaceMenuCursorOnWindow(sTMCaseDynamicResources->contextMenuWindowId, 2, 0, 2, GetFontAttribute(2, 1) + 2, sTMCaseDynamicResources->numMenuActions, 0); + strbuf = Alloc(256); + GetTMNumberAndMoveString(strbuf, gSpecialVar_ItemId); + StringAppend(strbuf, gText_IsSelected); + AddTextPrinterParameterized_ColorByIndex(2, 2, strbuf, 0, 2, 1, 0, 0, 1); + Free(strbuf); + if (itemid_is_unique(gSpecialVar_ItemId)) + { + PlaceHMTileInWindow(2, 0, 2); + CopyWindowToVram(2, 2); + } + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + gTasks[taskId].func = Task_TMContextMenu_HandleInput; +} + +static void Task_TMContextMenu_HandleInput(u8 taskId) +{ + s8 input; + + if (sub_80BF72C() != TRUE) + { + input = ProcessMenuInputNoWrapAround(); + switch (input) + { + case -1: + PlaySE(SE_SELECT); + sMenuActions_UseGiveExit[sTMCaseDynamicResources->menuActionIndices[sTMCaseDynamicResources->numMenuActions - 1]].func.void_u8(taskId); + break; + case -2: + break; + default: + PlaySE(SE_SELECT); + sMenuActions_UseGiveExit[sTMCaseDynamicResources->menuActionIndices[input]].func.void_u8(taskId); + break; + } + } +} + +static void TMHMContextMenuAction_Use(u8 taskId) +{ + RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + sub_810F4D8(2, 0); + ClearWindowTilemap(2); + PutWindowTilemap(0); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + if (CalculatePlayerPartyCount() == 0) + { + PrintError_ThereIsNoPokemon(taskId); + } + else + { + gUnknown_3005E98 = sub_8125B40; + sTMCaseDynamicResources->savedCallback = sub_8124C8C; + Task_BeginFadeOutFromTMCase(taskId); + } +} + +static void TMHMContextMenuAction_Give(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + u16 itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]); + RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + sub_810F4D8(2, 0); + ClearWindowTilemap(2); + PutWindowTilemap(1); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + if (!itemid_is_unique(itemId)) + { + if (CalculatePlayerPartyCount() == 0) + { + PrintError_ThereIsNoPokemon(taskId); + } + else + { + sTMCaseDynamicResources->savedCallback = sub_8126EDC; + Task_BeginFadeOutFromTMCase(taskId); + } + } + else + { + PrintError_ItemCantBeHeld(taskId); + } +} + +static void PrintError_ThereIsNoPokemon(u8 taskId) +{ + TMCase_PrintMessageWithFollowupTask(taskId, 2, gText_ThereIsNoPokemon, Task_WaitButtonAfterErrorPrint); +} + +static void PrintError_ItemCantBeHeld(u8 taskId) +{ + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_ItemCantBeHeld); + TMCase_PrintMessageWithFollowupTask(taskId, 2, gStringVar4, Task_WaitButtonAfterErrorPrint); +} + +static void Task_WaitButtonAfterErrorPrint(u8 taskId) +{ + if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + Subtask_CloseContextMenuAndReturnToMain(taskId); + } +} + +static void Subtask_CloseContextMenuAndReturnToMain(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + DestroyListMenu(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + sub_810F260(6, 0); + ClearWindowTilemap(6); + PutWindowTilemap(1); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + Subtask_ReturnToTMCaseMain(taskId); +} + +static void TMHMContextMenuAction_Exit(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + sub_810F4D8(2, 0); + ClearWindowTilemap(2); + PutWindowTilemap(0); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + PutWindowTilemap(1); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + Subtask_ReturnToTMCaseMain(taskId); +} + +static void Task_SelectTMAction_Type1(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]))) + { + sTMCaseDynamicResources->savedCallback = c2_8123744; + Task_BeginFadeOutFromTMCase(taskId); + } + else + { + PrintError_ItemCantBeHeld(taskId); + } +} + +static void Task_SelectTMAction_Type3(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]))) + { + sTMCaseDynamicResources->savedCallback = sub_808CE60; + Task_BeginFadeOutFromTMCase(taskId); + } + else + { + PrintError_ItemCantBeHeld(taskId); + } +} + +static void Task_SelectTMAction_FromSellMenu(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (itemid_get_market_price(gSpecialVar_ItemId) == 0) + { + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_OhNoICantBuyThat); + TMCase_PrintMessageWithFollowupTask(taskId, sub_80BF8E4(), gStringVar4, Subtask_CloseContextMenuAndReturnToMain); + } + else + { + data[8] = 1; + if (data[2] == 1) + { + HandlePrintMoneyOnHand(); + Task_AskConfirmSaleWithAmount(taskId); + } + else + { + if (data[2] > 99) + data[2] = 99; + CopyItemName(gSpecialVar_ItemId, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_HowManyWouldYouLikeToSell); + TMCase_PrintMessageWithFollowupTask(taskId, sub_80BF8E4(), gStringVar4, Task_InitQuantitySelectUI); + } + } +} + +static void Task_AskConfirmSaleWithAmount(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + StringExpandPlaceholders(gStringVar4, gText_ICanPayThisMuch_WouldThatBeOkay); + TMCase_PrintMessageWithFollowupTask(taskId, sub_80BF8E4(), gStringVar4, Task_PlaceYesNoBox); +} + +static void Task_PlaceYesNoBox(u8 taskId) +{ + HandleCreateYesNoMenu(taskId, &sYesNoFuncTable); +} + +static void Task_SaleOfTMsCancelled(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + sub_810F4D8(8, 0); + sub_810F260(6, 0); + PutWindowTilemap(0); + PutWindowTilemap(1); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + Subtask_ReturnToTMCaseMain(taskId); +} + +static void Task_InitQuantitySelectUI(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + TMCase_SetWindowBorder1(7); + ConvertIntToDecimalStringN(gStringVar1, 1, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); + AddTextPrinterParameterized_ColorByIndex(7, 0, gStringVar4, 4, 10, 1, 0, 0, 1); + SellTM_PrintQuantityAndSalePrice(1, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8]); + HandlePrintMoneyOnHand(); + CreateTMCaseScrollIndicatorArrowPair_SellQuantitySelect(); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + gTasks[taskId].func = Task_QuantitySelect_HandleInput; +} + +static void SellTM_PrintQuantityAndSalePrice(s16 quantity, s32 amount) +{ + FillWindowPixelBuffer(7, 0x11); + ConvertIntToDecimalStringN(gStringVar1, quantity, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); + AddTextPrinterParameterized_ColorByIndex(7, 0, gStringVar4, 4, 10, 1, 0, 0, 1); + PrintMoneyAmount(7, 0x38, 0x0A, amount, 0); +} + +static void Task_QuantitySelect_HandleInput(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (sub_80BF848(&data[8], data[2]) == 1) + { + SellTM_PrintQuantityAndSalePrice(data[8], itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8]); + } + else if (JOY_NEW(A_BUTTON)) + { + PlaySE(SE_SELECT); + sub_810F4D8(7, 0); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + RemoveTMCaseScrollIndicatorArrowPair(); + Task_AskConfirmSaleWithAmount(taskId); + } + else if (JOY_NEW(B_BUTTON)) + { + PlaySE(SE_SELECT); + sub_810F4D8(7, 0); + sub_810F4D8(8, 0); + sub_810F260(6, 0); + PutWindowTilemap(3); + PutWindowTilemap(0); + PutWindowTilemap(1); + schedule_bg_copy_tilemap_to_vram(0); + schedule_bg_copy_tilemap_to_vram(1); + RemoveTMCaseScrollIndicatorArrowPair(); + PrintListMenuCursorByID_WithColorIdx(data[0], 1); + Subtask_ReturnToTMCaseMain(taskId); + } +} + +static void Task_PrintSaleConfirmedText(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + PutWindowTilemap(0); + schedule_bg_copy_tilemap_to_vram(0); + CopyItemName(gSpecialVar_ItemId, gStringVar1); + ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + StringExpandPlaceholders(gStringVar4, gText_TurnedOverItemsWorthYen); + TMCase_PrintMessageWithFollowupTask(taskId, 2, gStringVar4, Task_DoSaleOfTMs); +} + +static void Task_DoSaleOfTMs(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + PlaySE(0xF8); + RemoveBagItem(gSpecialVar_ItemId, data[8]); + AddMoney(&gSaveBlock1Ptr->money, itemid_get_market_price(gSpecialVar_ItemId) / 2 * data[8]); + sub_809C09C(gSpecialVar_ItemId, data[8], 2); + DestroyListMenu(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + TMCaseSetup_GetTMCount(); + TMCaseSetup_InitListMenuPositions(); + InitTMCaseListMenuItems(); + data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + PrintListMenuCursorByID_WithColorIdx(data[0], 2); + PrintMoneyAmountInMoneyBox(8, GetMoney(&gSaveBlock1Ptr->money), 0); + gTasks[taskId].func = Task_AfterSale_ReturnToList; +} + +static void Task_AfterSale_ReturnToList(u8 taskId) +{ + if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) + { + PlaySE(SE_SELECT); + sub_810F4D8(8, 0); + sub_810F260(6, 0); + PutWindowTilemap(1); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + Subtask_CloseContextMenuAndReturnToMain(taskId); + } +} + +void PokeDude_InitTMCase(void) +{ + sPokeDudePackBackup = AllocZeroed(sizeof(*sPokeDudePackBackup)); + memcpy(sPokeDudePackBackup->bagPocket_TMHM, gSaveBlock1Ptr->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); + memcpy(sPokeDudePackBackup->bagPocket_KeyItems, gSaveBlock1Ptr->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); + sPokeDudePackBackup->unk_160 = sTMCaseStaticResources.selectedRow; + sPokeDudePackBackup->unk_162 = sTMCaseStaticResources.scrollOffset; + ClearItemSlots(gSaveBlock1Ptr->bagPocket_TMHM, NELEMS(gSaveBlock1Ptr->bagPocket_TMHM)); + ClearItemSlots(gSaveBlock1Ptr->bagPocket_KeyItems, NELEMS(gSaveBlock1Ptr->bagPocket_KeyItems)); + ResetTMCaseCursorPos(); + AddBagItem(ITEM_TM01, 1); + AddBagItem(ITEM_TM03, 1); + AddBagItem(ITEM_TM09, 1); + AddBagItem(ITEM_TM35, 1); + InitTMCase(4, CB2_ReturnToTeachyTV, 0); +} + +static void Task_TMCaseDude1(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (!gPaletteFade.active) + { + data[8] = 0; + data[9] = 0; + gTasks[taskId].func = Task_TMCaseDude_Playback; + } +} + +static void Task_TMCaseDude_Playback(u8 taskId) +{ + s16 * data = gTasks[taskId].data; + + if (JOY_NEW(B_BUTTON)) + { + if (data[8] < 21) + { + data[8] = 21; + sub_815AC20(); + } + } + + switch (data[8]) + { + case 0: + BeginNormalPaletteFade(0xFFFF8405, 4, 0, 6, 0); + FillBG2RowWithPalette_2timesNplus1(1); + data[8]++; + break; + case 1: + case 11: + if (!gPaletteFade.active) + { + data[9]++; + if (data[9] > 0x65) + { + data[9] = 0; + data[8]++; + } + } + break; + case 2: + case 3: + case 4: + case 12: + case 13: + case 14: + if (data[9] == 0) + { + gMain.newKeys = 0; + gMain.newAndRepeatedKeys = DPAD_DOWN; + ListMenuHandleInput(data[0]); + } + data[9]++; + if (data[9] > 0x65) + { + data[9] = 0; + data[8]++; + } + break; + case 5: + case 6: + case 7: + case 15: + case 16: + case 17: + if (data[9] == 0) + { + gMain.newKeys = 0; + gMain.newAndRepeatedKeys = DPAD_UP; + ListMenuHandleInput(data[0]); + } + data[9]++; + if (data[9] > 0x65) + { + data[9] = 0; + data[8]++; + } + break; + case 8: + FillBG2RowWithPalette_2timesNplus1(1); + TMCase_PrintMessageWithFollowupTask(taskId, 4, gPokeDudeText_TMTypes, 0); + gTasks[taskId].func = Task_TMCaseDude_Playback; + data[8]++; + break; + case 9: + case 19: + RunTextPrinters(); + if (!IsTextPrinterActive(6)) + data[8]++; + break; + case 10: + if (JOY_NEW(A_BUTTON | B_BUTTON)) + { + FillBG2RowWithPalette_2timesNplus1(0); + BeginNormalPaletteFade(0x00000400, 0, 6, 0, 0); + sub_810F260(6, 0); + schedule_bg_copy_tilemap_to_vram(1); + data[8]++; + } + break; + case 18: + FillBG2RowWithPalette_2timesNplus1(1); + TMCase_PrintMessageWithFollowupTask(taskId, 4, gPokeDudeText_ReadTMDescription, NULL); + gTasks[taskId].func = Task_TMCaseDude_Playback; // this function + data[8]++; + break; + case 20: + if (JOY_NEW(A_BUTTON | B_BUTTON)) + data[8]++; + break; + case 21: + if (!gPaletteFade.active) + { + memcpy(gSaveBlock1Ptr->bagPocket_TMHM, sPokeDudePackBackup->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); + memcpy(gSaveBlock1Ptr->bagPocket_KeyItems, sPokeDudePackBackup->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); + DestroyListMenu(data[0], NULL, NULL); + sTMCaseStaticResources.selectedRow = sPokeDudePackBackup->unk_160; + sTMCaseStaticResources.scrollOffset = sPokeDudePackBackup->unk_162; + Free(sPokeDudePackBackup); + CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); + sub_8108CF0(); + BeginNormalPaletteFade(0xFFFFFFFF, -2, 0, 16, 0); + data[8]++; + } + break; + default: + if (!gPaletteFade.active) + { + SetMainCallback2(sTMCaseStaticResources.savedCallback); + RemoveTMCaseScrollIndicatorArrowPair(); + DestroyTMCaseBuffers(); + DestroyTask(taskId); + } + break; + } +} + +static void InitWindowTemplatesAndPals(void) +{ + u8 i; + + InitWindows(sWindowTemplates); + DeactivateAllTextPrinters(); + sub_815001C(0, 0x5B, 0xE0); + sub_814FEAC(0, 0x64, 0xB0); + sub_814FF2C(0, 0x78, 0xD0); + LoadPalette(gTMCaseMainWindowPalette, 0xF0, 0x20); + LoadPalette(gTMCaseMainWindowPalette, 0xA0, 0x20); + LoadPalette(sPal3Override, 0xF6, 0x04); + LoadPalette(sPal3Override, 0xD6, 0x04); + sub_8107D38(0xc0, 0x01); + for (i = 0; i < 9; i++) + FillWindowPixelBuffer(i, 0x00); + PutWindowTilemap(0); + PutWindowTilemap(1); + PutWindowTilemap(3); + PutWindowTilemap(4); + PutWindowTilemap(5); + schedule_bg_copy_tilemap_to_vram(0); +} + +static void AddTextPrinterParameterized_ColorByIndex(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx) +{ + AddTextPrinterParametrized2(windowId, fontId, x, y, letterSpacing, lineSpacing, &sTextColors[colorIdx], speed, str); +} + +static void TMCase_SetWindowBorder1(u8 windowId) +{ + SetWindowBorderStyle(windowId, FALSE, 0x5B, 0x0E); +} + +static void TMCase_SetWindowBorder2(u8 windowId) +{ + SetWindowBorderStyle(windowId, FALSE, 0x78, 0x0D); +} + +static void TMCase_PrintMessageWithFollowupTask(u8 taskId, u8 windowId, const u8 * str, TaskFunc func) +{ + DisplayMessageAndContinueTask(taskId, 6, 0x64, 0x0B, windowId, GetTextSpeedSetting(), str, func); + schedule_bg_copy_tilemap_to_vram(1); +} + +static void PrintStringTMCaseOnWindow3(void) +{ + u32 distance = 72 - GetStringWidth(1, gText_TMCase, 0); + box_print(3, 1, distance / 2, 1, &sTextColors[0], 0, gText_TMCase); +} + +static void DrawMoveInfoUIMarkers(void) +{ + blit_move_info_icon(4, 19, 0, 0); + blit_move_info_icon(4, 20, 0, 12); + blit_move_info_icon(4, 21, 0, 24); + blit_move_info_icon(4, 22, 0, 36); + CopyWindowToVram(4, 2); +} + +static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId) +{ + u8 i; + u16 move; + const u8 * str; + + FillWindowPixelRect(5, 0, 0, 0, 40, 48); + if (itemId == ITEM_NONE) + { + for (i = 0; i < 4; i++) + { + AddTextPrinterParameterized_ColorByIndex(5, 3, gText_ThreeHyphens, 7, 12 * i, 0, 0, 0xFF, 3); + } + CopyWindowToVram(5, 2); + } + else + { + move = ItemIdToBattleMoveId(itemId); + blit_move_info_icon(5, gBattleMoves[move].type + 1, 0, 0); + if (gBattleMoves[move].power < 2) + str = gText_ThreeHyphens; + else + { + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].power, STR_CONV_MODE_RIGHT_ALIGN, 3); + str = gStringVar1; + } + AddTextPrinterParameterized_ColorByIndex(5, 3, str, 7, 12, 0, 0, 0xFF, 3); + if (gBattleMoves[move].accuracy == 0) + str = gText_ThreeHyphens; + else + { + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); + str = gStringVar1; + } + AddTextPrinterParameterized_ColorByIndex(5, 3, str, 7, 24, 0, 0, 0xFF, 3); + ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].pp, STR_CONV_MODE_RIGHT_ALIGN, 3); + AddTextPrinterParameterized_ColorByIndex(5, 3, gStringVar1, 7, 36, 0, 0, 0xFF, 3); + CopyWindowToVram(5, 2); + } +} + +static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y) +{ + BlitBitmapToWindow(windowId, gUnknown_8E99118, x, y, 16, 12); +} + +static void HandlePrintMoneyOnHand(void) +{ + PrintMoneyAmountInMoneyBoxWithBorder(8, 0x78, 0xD, GetMoney(&gSaveBlock1Ptr->money)); +} + +static void HandleCreateYesNoMenu(u8 taskId, const struct YesNoFuncTable *ptrs) +{ + CreateYesNoMenuWithCallbacks(taskId, &sYesNoWindowTemplate, 2, 0, 2, 0x5B, 0x0E, ptrs); +} + +static u8 AddTMContextMenu(u8 * a0, u8 a1) +{ + if (*a0 == 0xFF) + { + *a0 = AddWindow(&sTMContextWindowTemplates[a1]); + TMCase_SetWindowBorder1(*a0); + schedule_bg_copy_tilemap_to_vram(0); + } + return *a0; +} + +static void RemoveTMContextMenu(u8 * a0) +{ + sub_810F4D8(*a0, FALSE); + ClearWindowTilemap(*a0); + RemoveWindow(*a0); + schedule_bg_copy_tilemap_to_vram(0); + *a0 = 0xFF; +} + +static u8 CreateTMSprite(u16 itemId) +{ + u8 spriteId = CreateSprite(&sTMSpriteTemplate, 0x29, 0x2E, 0); + u8 r5; + if (itemId == ITEM_NONE) + { + UpdateTMSpritePosition(&gSprites[spriteId], 0xFF); + return spriteId; + } + else + { + r5 = itemId - 33; + SetTMSpriteAnim(&gSprites[spriteId], r5); + TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(itemId)].type); + UpdateTMSpritePosition(&gSprites[spriteId], r5); + return spriteId; + } +} + +static void SetTMSpriteAnim(struct Sprite * sprite, u8 idx) +{ + if (idx >= 50) + StartSpriteAnim(sprite, 1); + else + StartSpriteAnim(sprite, 0); +} + +static void TintTMSpriteByType(u8 type) +{ + u8 palIndex = IndexOfSpritePaletteTag(TM_CASE_TM_TAG) << 4; + LoadPalette(sTMSpritePaletteBuffer + sTMSpritePaletteOffsetByType[type], 0x100 | palIndex, 0x20); + if (sTMCaseStaticResources.tmCaseMenuType == 4) + { + BlendPalettes(1 << (0x10 + palIndex), 4, RGB_BLACK); + } +} + +static void UpdateTMSpritePosition(struct Sprite * sprite, u8 var) +{ + s32 x, y; + if (var == 0xFF) + { + x = 0x1B; + y = 0x36; + sprite->pos2.y = 0x14; + } + else + { + if (var >= 50) + var -= 50; + else + var += 8; + x = 0x29 - (((0xE00 * var) / 58) >> 8); + y = 0x2E + (((0x800 * var) / 58) >> 8); + } + sprite->pos1.x = x; + sprite->pos1.y = y; +} + +static void InitSelectedTMSpriteData(u8 spriteId, u16 itemId) +{ + gSprites[spriteId].data[0] = itemId; + gSprites[spriteId].data[1] = 0; + gSprites[spriteId].callback = SpriteCB_MoveTMSpriteInCase; +} + +static void SpriteCB_MoveTMSpriteInCase(struct Sprite * sprite) +{ + switch (sprite->data[1]) + { + case 0: + if (sprite->pos2.y >= 20) + { + if (sprite->data[0] != ITEM_NONE) + { + sprite->data[1]++; + TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(sprite->data[0])].type); + sprite->data[0] -= ITEM_TM01; + SetTMSpriteAnim(sprite, sprite->data[0]); + UpdateTMSpritePosition(sprite, sprite->data[0]); + } + else + sprite->callback = SpriteCallbackDummy; + } + else + { + sprite->pos2.y += 10; + } + break; + case 1: + if (sprite->pos2.y <= 0) + sprite->callback = SpriteCallbackDummy; + else + sprite->pos2.y -= 10; + } +} + +static void LoadTMTypePalettes(void) +{ + struct SpritePalette spritePalette; + + sTMSpritePaletteBuffer = Alloc(0x110 * sizeof(u16)); + LZDecompressWram(gUnknown_8E84F20, sTMSpritePaletteBuffer); + LZDecompressWram(gUnknown_8E85068, sTMSpritePaletteBuffer + 0x100); + spritePalette.data = sTMSpritePaletteBuffer + 0x110; + spritePalette.tag = TM_CASE_TM_TAG; + LoadSpritePalette(&spritePalette); +} diff --git a/src/window.c b/src/window.c index e760fc8e4..71cfa6898 100644 --- a/src/window.c +++ b/src/window.c @@ -320,7 +320,7 @@ void PutWindowRectTilemap(u8 windowId, u8 x, u8 y, u8 width, u8 height) } } -void BlitBitmapToWindow(u8 windowId, u8 *pixels, u16 x, u16 y, u16 width, u16 height) +void BlitBitmapToWindow(u8 windowId, const u8 *pixels, u16 x, u16 y, u16 width, u16 height) { BlitBitmapRectToWindow(windowId, pixels, 0, 0, width, height, x, y, width, height); } |