1407 lines
40 KiB
C
1407 lines
40 KiB
C
#include "task.h"
|
|
#include "menu.h"
|
|
#include "palette.h"
|
|
#include "sprite.h"
|
|
#include "menu_helpers.h"
|
|
#include "new_menu_helpers.h"
|
|
#include "sound.h"
|
|
#include "malloc.h"
|
|
#include "scanline_effect.h"
|
|
#include "bg.h"
|
|
#include "gpu_regs.h"
|
|
#include "decompress.h"
|
|
#include "window.h"
|
|
#include "list_menu.h"
|
|
#include "item_menu.h"
|
|
#include "item.h"
|
|
#include "menu_indicators.h"
|
|
#include "event_object_movement.h"
|
|
#include "random.h"
|
|
#include "text.h"
|
|
#include "constants/songs.h"
|
|
#include "constants/items.h"
|
|
#include "event_data.h"
|
|
#include "load_save.h"
|
|
#include "battle_transition.h"
|
|
#include "battle_main.h"
|
|
#include "battle.h"
|
|
#include "battle_controllers.h"
|
|
#include "global.fieldmap.h"
|
|
#include "teachy_tv.h"
|
|
#include "help_system.h"
|
|
#include "overworld.h"
|
|
#include "graphics.h"
|
|
#include "fieldmap.h"
|
|
#include "strings.h"
|
|
|
|
struct TeachyTvCtrlBlk
|
|
{
|
|
MainCallback callback;
|
|
u8 mode;
|
|
u8 whichScript;
|
|
u16 scrollOffset;
|
|
u16 selectedRow;
|
|
};
|
|
|
|
struct TeachyTvBuf
|
|
{
|
|
MainCallback savedCallback;
|
|
u16 buffer1[0x800];
|
|
u16 buffer2[0x800];
|
|
u16 buffer3[0x800];
|
|
u16 buffer4[0x800];
|
|
u8 grassAnimCounterLo;
|
|
u8 grassAnimCounterHi;
|
|
u8 grassAnimDisabled;
|
|
u8 scrollIndicatorArrowPairId;
|
|
};
|
|
|
|
static EWRAM_DATA struct TeachyTvCtrlBlk sStaticResources = {0};
|
|
static EWRAM_DATA struct TeachyTvBuf * sResources = NULL;
|
|
|
|
static void TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos(u8 taskId);
|
|
static void TTVcmd_ClearBg2TeachyTvGraphic(u8 taskId);
|
|
static void TTVcmd_NpcMoveAndSetupTextPrinter(u8 taskId);
|
|
static void TTVcmd_IdleIfTextPrinterIsActive(u8 taskId);
|
|
static void TTVcmd_TextPrinterSwitchStringByOptionChosen(u8 taskId);
|
|
static void TTVcmd_TextPrinterSwitchStringByOptionChosen2(u8 taskId);
|
|
static void TTVcmd_IdleIfTextPrinterIsActive2(u8 taskId);
|
|
static void TTVcmd_EraseTextWindowIfKeyPressed(u8 taskId);
|
|
static void TTVcmd_StartAnimNpcWalkIntoGrass(u8 taskId);
|
|
static void TTVcmd_DudeMoveUp(u8 taskId);
|
|
static void TTVcmd_DudeMoveRight(u8 taskId);
|
|
static void TTVcmd_DudeTurnLeft(u8 taskId);
|
|
static void TTVcmd_DudeMoveLeft(u8 taskId);
|
|
static void TTVcmd_RenderAndRemoveBg1EndGraphic(u8 taskId);
|
|
static void TTVcmd_TaskBattleOrFadeByOptionChosen(u8 taskId);
|
|
static void TeachyTvCallback(void);
|
|
static void TeachyTvMainCallback(void);
|
|
static void TeachyTvVblankHandler(void);
|
|
static void TeachyTvCreateAndRenderRbox(void);
|
|
static void TeachyTvInitIo(void);
|
|
static u8 TeachyTvSetupObjEventAndOam(void);
|
|
static void TeachyTvSetupPostBattleWindowAndObj(u8);
|
|
static u8 TeachyTvSetupWindow(void);
|
|
static void TeachyTvSetupScrollIndicatorArrowPair(void);
|
|
static void TeachyTvSetWindowRegs(void);
|
|
static void TeachyTvSetupBg(void);
|
|
static void TeachyTvLoadGraphic(void);
|
|
static void TeachyTvPostBattleFadeControl(u8);
|
|
static void TeachyTvOptionListController(u8);
|
|
static void TeachyTvAudioByInput(s32, bool8, struct ListMenu *);
|
|
static void TeachyTvQuitFadeControlAndTaskDel(u8 taskId);
|
|
static void TeachyTvRenderMsgAndSwitchClusterFuncs(u8 taskId);
|
|
static void TeachyTvClearBg1EndGraphicText(void);
|
|
static void TTVcmd_End(u8 taskId);
|
|
static void TeachyTvSetupBagItemsByOptionChosen(void);
|
|
static void TeachyTvPrepBattle(u8 taskId);
|
|
static void TeachyTvGrassAnimationMain(u8 taskId, s16 x, s16 y, u8 subpriority, bool8 mode);
|
|
static void TeachyTvLoadBg3Map(u16 *);
|
|
static u8 TeachyTvGrassAnimationCheckIfNeedsToGenerateGrassObj(s16 x, s16 y);
|
|
static void TeachyTvGrassAnimationObjCallback(struct Sprite *sprite);
|
|
static void TeachyTvRestorePlayerPartyCallback(void);
|
|
static void TeachyTvPreBattleAnimAndSetBattleCallback(u8 taskId);
|
|
static void TeachyTvLoadMapTilesetToBuffer(struct Tileset *ts, u8 *dstBuffer, u16 size);
|
|
static void TeachyTvPushBackNewMapPalIndexArrayEntry(const struct MapLayout *mStruct, u16 *buf1, u8 *palIndexArray, u16 mapEntry, u16 offset);
|
|
static void TeachyTvComputeMapTilesFromTilesetAndMetaTiles(u16 *metaTilesArray, u8 *blockBuf, u8 *tileset);
|
|
static void TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(u8 *blockBuf, u8 *tileset, u8 metaTile);
|
|
static u16 TeachyTvComputePalIndexArrayEntryByMetaTile(u8 *palIndexArrayBuf, u16 metaTile);
|
|
static void TeachyTvLoadMapPalette(const struct MapLayout * mStruct, const u8 *palIndexArray);
|
|
|
|
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,
|
|
},
|
|
{
|
|
.bg = 3,
|
|
.charBaseIndex = 2,
|
|
.mapBaseIndex = 28,
|
|
.screenSize = 0,
|
|
.paletteMode = 0,
|
|
.priority = 3,
|
|
.baseTile = 0x000,
|
|
},
|
|
};
|
|
|
|
static const struct WindowTemplate sWindowTemplates[] =
|
|
{
|
|
{
|
|
.bg = 1,
|
|
.tilemapLeft = 2,
|
|
.tilemapTop = 15,
|
|
.width = 26,
|
|
.height = 4,
|
|
.paletteNum = 0x3,
|
|
.baseBlock = 0x0EA,
|
|
},
|
|
{
|
|
.bg = 0,
|
|
.tilemapLeft = 4,
|
|
.tilemapTop = 1,
|
|
.width = 22,
|
|
.height = 12,
|
|
.paletteNum = 0x3,
|
|
.baseBlock = 0x152,
|
|
},
|
|
DUMMY_WIN_TEMPLATE,
|
|
};
|
|
|
|
static const struct ListMenuItem sListMenuItems[] =
|
|
{
|
|
{
|
|
.label = gTeachyTvString_TeachBattle,
|
|
.index = TTVSCR_BATTLE
|
|
},
|
|
{
|
|
.label = gTeachyTvString_StatusProblems,
|
|
.index = TTVSCR_STATUS
|
|
},
|
|
{
|
|
.label = gTeachyTvString_TypeMatchups,
|
|
.index = TTVSCR_MATCHUPS
|
|
},
|
|
{
|
|
.label = gTeachyTvString_CatchPkmn,
|
|
.index = TTVSCR_CATCHING
|
|
},
|
|
{
|
|
.label = gTeachyTvString_AboutTMs,
|
|
.index = TTVSCR_TMS
|
|
},
|
|
{
|
|
.label = gTeachyTvString_RegisterItem,
|
|
.index = TTVSCR_REGISTER
|
|
},
|
|
|
|
{
|
|
.label = gTeachyTvString_Cancel,
|
|
.index = -2
|
|
},
|
|
};
|
|
|
|
static const struct ListMenuItem sListMenuItems_NoTMCase[] =
|
|
{
|
|
{
|
|
.label = gTeachyTvString_TeachBattle,
|
|
.index = TTVSCR_BATTLE
|
|
},
|
|
{
|
|
.label = gTeachyTvString_StatusProblems,
|
|
.index = TTVSCR_STATUS
|
|
},
|
|
{
|
|
.label = gTeachyTvString_TypeMatchups,
|
|
.index = TTVSCR_MATCHUPS
|
|
},
|
|
{
|
|
.label = gTeachyTvString_CatchPkmn,
|
|
.index = TTVSCR_CATCHING
|
|
},
|
|
{
|
|
.label = gTeachyTvString_Cancel,
|
|
.index = -2
|
|
},
|
|
};
|
|
|
|
static const struct ListMenuTemplate sListMenuTemplate =
|
|
{
|
|
.items = sListMenuItems,
|
|
.moveCursorFunc = NULL,
|
|
.itemPrintFunc = NULL,
|
|
.totalItems = 7,
|
|
.maxShowed = 6,
|
|
.windowId = 0,
|
|
.header_X = 0,
|
|
.item_X = 8,
|
|
.cursor_X = 0,
|
|
.upText_Y = 6,
|
|
.cursorPal = 0x1,
|
|
.fillValue = 0x0,
|
|
.cursorShadowPal = 0x2,
|
|
.lettersSpacing = 0x0,
|
|
.itemVerticalPadding = 0x0,
|
|
.scrollMultiple = 0x1,
|
|
.fontId = 0x2,
|
|
.cursorKind = 0x0,
|
|
};
|
|
|
|
static const struct ScrollArrowsTemplate sScrollIndicatorArrowPair =
|
|
{
|
|
.firstArrowType = 0x2,
|
|
.firstX = 0x78,
|
|
.firstY = 0xC,
|
|
.secondArrowType = 0x3,
|
|
.secondX = 0x78,
|
|
.secondY = 0x64,
|
|
.fullyUpThreshold = 0,
|
|
.fullyDownThreshold = 1,
|
|
.tileTag = 0x800,
|
|
.palTag = 0x800,
|
|
.palNum = 0x0,
|
|
};
|
|
|
|
static const u8 sWhereToReturnToFromBattle[] =
|
|
{
|
|
12,
|
|
12,
|
|
12,
|
|
12,
|
|
9,
|
|
9
|
|
};
|
|
|
|
static void (* const sBattleScript[])(u8) =
|
|
{
|
|
TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos,
|
|
TTVcmd_ClearBg2TeachyTvGraphic,
|
|
TTVcmd_NpcMoveAndSetupTextPrinter,
|
|
TTVcmd_IdleIfTextPrinterIsActive,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_StartAnimNpcWalkIntoGrass,
|
|
TTVcmd_DudeMoveUp,
|
|
TTVcmd_DudeMoveRight,
|
|
TTVcmd_TaskBattleOrFadeByOptionChosen,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen2,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_DudeTurnLeft,
|
|
TTVcmd_DudeMoveLeft,
|
|
TTVcmd_RenderAndRemoveBg1EndGraphic,
|
|
TTVcmd_End,
|
|
};
|
|
|
|
static void (* const sStatusScript[])(u8) =
|
|
{
|
|
TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos,
|
|
TTVcmd_ClearBg2TeachyTvGraphic,
|
|
TTVcmd_NpcMoveAndSetupTextPrinter,
|
|
TTVcmd_IdleIfTextPrinterIsActive,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_StartAnimNpcWalkIntoGrass,
|
|
TTVcmd_DudeMoveUp,
|
|
TTVcmd_DudeMoveRight,
|
|
TTVcmd_TaskBattleOrFadeByOptionChosen,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen2,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_DudeTurnLeft,
|
|
TTVcmd_DudeMoveLeft,
|
|
TTVcmd_RenderAndRemoveBg1EndGraphic,
|
|
TTVcmd_End,
|
|
};
|
|
|
|
static void (* const sMatchupsScript[])(u8) =
|
|
{
|
|
TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos,
|
|
TTVcmd_ClearBg2TeachyTvGraphic,
|
|
TTVcmd_NpcMoveAndSetupTextPrinter,
|
|
TTVcmd_IdleIfTextPrinterIsActive,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_StartAnimNpcWalkIntoGrass,
|
|
TTVcmd_DudeMoveUp,
|
|
TTVcmd_DudeMoveRight,
|
|
TTVcmd_TaskBattleOrFadeByOptionChosen,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen2,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_DudeTurnLeft,
|
|
TTVcmd_DudeMoveLeft,
|
|
TTVcmd_RenderAndRemoveBg1EndGraphic,
|
|
TTVcmd_End,
|
|
};
|
|
|
|
static void (* const sCatchingScript[])(u8) =
|
|
{
|
|
TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos,
|
|
TTVcmd_ClearBg2TeachyTvGraphic,
|
|
TTVcmd_NpcMoveAndSetupTextPrinter,
|
|
TTVcmd_IdleIfTextPrinterIsActive,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_StartAnimNpcWalkIntoGrass,
|
|
TTVcmd_DudeMoveUp,
|
|
TTVcmd_DudeMoveRight,
|
|
TTVcmd_TaskBattleOrFadeByOptionChosen,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen2,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_DudeTurnLeft,
|
|
TTVcmd_DudeMoveLeft,
|
|
TTVcmd_RenderAndRemoveBg1EndGraphic,
|
|
TTVcmd_End,
|
|
};
|
|
|
|
static void (* const sTMsScript[])(u8) =
|
|
{
|
|
TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos,
|
|
TTVcmd_ClearBg2TeachyTvGraphic,
|
|
TTVcmd_NpcMoveAndSetupTextPrinter,
|
|
TTVcmd_IdleIfTextPrinterIsActive,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_TaskBattleOrFadeByOptionChosen,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen2,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_DudeTurnLeft,
|
|
TTVcmd_DudeMoveLeft,
|
|
TTVcmd_RenderAndRemoveBg1EndGraphic,
|
|
TTVcmd_End,
|
|
};
|
|
|
|
static void (* const sRegisterKeyItemScript[])(u8) =
|
|
{
|
|
TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos,
|
|
TTVcmd_ClearBg2TeachyTvGraphic,
|
|
TTVcmd_NpcMoveAndSetupTextPrinter,
|
|
TTVcmd_IdleIfTextPrinterIsActive,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_TaskBattleOrFadeByOptionChosen,
|
|
TTVcmd_TextPrinterSwitchStringByOptionChosen2,
|
|
TTVcmd_IdleIfTextPrinterIsActive2,
|
|
TTVcmd_EraseTextWindowIfKeyPressed,
|
|
TTVcmd_DudeTurnLeft,
|
|
TTVcmd_DudeMoveLeft,
|
|
TTVcmd_RenderAndRemoveBg1EndGraphic,
|
|
TTVcmd_End,
|
|
};
|
|
|
|
static void TeachyTvCallback(void)
|
|
{
|
|
RunTasks();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
DoScheduledBgTilemapCopiesToVram();
|
|
UpdatePaletteFade();
|
|
}
|
|
|
|
static void TeachyTvVblankHandler(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
TransferPlttBuffer();
|
|
}
|
|
|
|
void InitTeachyTvController(u8 mode, MainCallback cb)
|
|
{
|
|
sStaticResources.mode = mode;
|
|
sStaticResources.callback = cb;
|
|
if (mode == 0)
|
|
{
|
|
sStaticResources.scrollOffset = 0;
|
|
sStaticResources.selectedRow = 0;
|
|
sStaticResources.whichScript = TTVSCR_BATTLE;
|
|
}
|
|
if (mode == 1)
|
|
{
|
|
sStaticResources.mode = 0;
|
|
}
|
|
SetMainCallback2(TeachyTvMainCallback);
|
|
}
|
|
|
|
void CB2_ReturnToTeachyTV(void)
|
|
{
|
|
if (sStaticResources.mode == 1)
|
|
InitTeachyTvController(1, sStaticResources.callback);
|
|
else
|
|
InitTeachyTvController(2, sStaticResources.callback);
|
|
}
|
|
|
|
void SetTeachyTvControllerModeToResume(void)
|
|
{
|
|
sStaticResources.mode = 1;
|
|
}
|
|
|
|
static void TeachyTvMainCallback(void)
|
|
{
|
|
u8 taskId;
|
|
struct Task *taskAddr;
|
|
|
|
switch (gMain.state)
|
|
{
|
|
case 0:
|
|
sResources = AllocZeroed(sizeof(struct TeachyTvBuf));
|
|
sResources->savedCallback = NULL;
|
|
sResources->grassAnimDisabled = 0;
|
|
sResources->scrollIndicatorArrowPairId = 0xFF;
|
|
SetVBlankHBlankCallbacksToNull();
|
|
ClearScheduledBgCopiesToVram();
|
|
ScanlineEffect_Stop();
|
|
FreeAllSpritePalettes();
|
|
ResetPaletteFade();
|
|
ResetSpriteData();
|
|
ResetTasks();
|
|
TeachyTvSetupBg();
|
|
TeachyTvLoadGraphic();
|
|
++gMain.state;
|
|
break;
|
|
case 1:
|
|
if (FreeTempTileDataBuffersIfPossible() == TRUE)
|
|
return;
|
|
TeachyTvCreateAndRenderRbox();
|
|
TeachyTvInitIo();
|
|
if (sStaticResources.mode == 2)
|
|
{
|
|
taskId = CreateTask(TeachyTvPostBattleFadeControl, 0);
|
|
gTasks[taskId].data[1] = TeachyTvSetupObjEventAndOam();
|
|
TeachyTvSetupPostBattleWindowAndObj(taskId);
|
|
}
|
|
else
|
|
{
|
|
taskId = CreateTask(TeachyTvOptionListController, 0);
|
|
gTasks[taskId].data[0] = TeachyTvSetupWindow();
|
|
gTasks[taskId].data[1] = TeachyTvSetupObjEventAndOam();
|
|
TeachyTvSetupScrollIndicatorArrowPair();
|
|
PlayNewMapMusic(MUS_TVNOIZE);
|
|
TeachyTvSetWindowRegs();
|
|
}
|
|
ScheduleBgCopyTilemapToVram(0);
|
|
ScheduleBgCopyTilemapToVram(1);
|
|
ScheduleBgCopyTilemapToVram(2);
|
|
ScheduleBgCopyTilemapToVram(3);
|
|
HelpSystem_SetSomeVariable(9); // help system something
|
|
BlendPalettes(0xFFFFFFFF, 0x10, 0);
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, 0);
|
|
SetVBlankCallback(TeachyTvVblankHandler);
|
|
SetMainCallback2(TeachyTvCallback);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void TeachyTvSetupBg(void)
|
|
{
|
|
ResetAllBgsCoordinatesAndBgCntRegs();
|
|
ResetBgsAndClearDma3BusyFlags(0);
|
|
InitBgsFromTemplates(0, sBgTemplates, 4);
|
|
SetBgTilemapBuffer(1, sResources->buffer1);
|
|
SetBgTilemapBuffer(2, sResources->buffer2);
|
|
SetBgTilemapBuffer(3, sResources->buffer3);
|
|
SetGpuReg(REG_OFFSET_DISPCNT, 0x3040);
|
|
ShowBg(0);
|
|
ShowBg(1);
|
|
ShowBg(2);
|
|
ShowBg(3);
|
|
ChangeBgX(3, 0x1000, 2);
|
|
ChangeBgY(3, 0x2800, 1);
|
|
sResources->grassAnimCounterLo = 0;
|
|
sResources->grassAnimCounterHi = 3;
|
|
SetGpuReg(REG_OFFSET_BLDCNT, 0);
|
|
}
|
|
|
|
static void TeachyTvLoadGraphic(void)
|
|
{
|
|
u16 src = RGB_BLACK;
|
|
ResetTempTileDataBuffers();
|
|
DecompressAndCopyTileDataToVram(1, gUnknown_8E86240, 0, 0, 0);
|
|
LZDecompressWram(gUnknown_8E86BE8, sResources->buffer1);
|
|
LZDecompressWram(gUnknown_8E86D6C, sResources->buffer4);
|
|
LoadCompressedPalette(gUnknown_8E86F98, 0, 0x80);
|
|
LoadPalette(&src, 0, sizeof(src));
|
|
LoadSpritePalette(&gUnknown_83A5348);
|
|
TeachyTvLoadBg3Map(sResources->buffer3);
|
|
}
|
|
|
|
static void TeachyTvCreateAndRenderRbox(void)
|
|
{
|
|
InitWindows(sWindowTemplates);
|
|
DeactivateAllTextPrinters();
|
|
FillWindowPixelBuffer(0, 0xCC);
|
|
PutWindowTilemap(0);
|
|
PutWindowTilemap(1);
|
|
CopyWindowToVram(0, 2);
|
|
}
|
|
|
|
static u8 TeachyTvSetupWindow(void)
|
|
{
|
|
gMultiuseListMenuTemplate = sListMenuTemplate;
|
|
gMultiuseListMenuTemplate.windowId = 1;
|
|
gMultiuseListMenuTemplate.moveCursorFunc = TeachyTvAudioByInput;
|
|
if (!CheckBagHasItem(ITEM_TM_CASE, 1))
|
|
{
|
|
gMultiuseListMenuTemplate.items = sListMenuItems_NoTMCase;
|
|
gMultiuseListMenuTemplate.totalItems = 5;
|
|
gMultiuseListMenuTemplate.maxShowed = 5;
|
|
gMultiuseListMenuTemplate.upText_Y = (gMultiuseListMenuTemplate.upText_Y + 8) & 0xF;
|
|
}
|
|
return ListMenuInit(
|
|
&gMultiuseListMenuTemplate,
|
|
sStaticResources.scrollOffset,
|
|
sStaticResources.selectedRow
|
|
);
|
|
}
|
|
|
|
static void TeachyTvSetupScrollIndicatorArrowPair(void)
|
|
{
|
|
if (!CheckBagHasItem(ITEM_TM_CASE, 1))
|
|
{
|
|
struct TeachyTvBuf * temp = sResources;
|
|
temp->scrollIndicatorArrowPairId = 0xFF;
|
|
}
|
|
else
|
|
{
|
|
sResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPair(&sScrollIndicatorArrowPair, &(sStaticResources.scrollOffset));
|
|
}
|
|
}
|
|
|
|
static void TeachyTvRemoveScrollIndicatorArrowPair(void)
|
|
{
|
|
if (sResources->scrollIndicatorArrowPairId != 0xFF)
|
|
{
|
|
RemoveScrollIndicatorArrowPair(sResources->scrollIndicatorArrowPairId);
|
|
sResources->scrollIndicatorArrowPairId = 0xFF;
|
|
}
|
|
}
|
|
|
|
static void TeachyTvAudioByInput(s32 notUsed, bool8 play, struct ListMenu *notUsedAlt)
|
|
{
|
|
if (play != TRUE)
|
|
PlaySE(SE_SELECT);
|
|
}
|
|
|
|
static void TeachyTvInitIo(void)
|
|
{
|
|
SetGpuReg(REG_OFFSET_WININ, 0x3F);
|
|
SetGpuReg(REG_OFFSET_WINOUT, 0x1F);
|
|
SetGpuReg(REG_OFFSET_BLDCNT, 0xCC);
|
|
SetGpuReg(REG_OFFSET_BLDY, 0x5);
|
|
}
|
|
|
|
static u8 TeachyTvSetupObjEventAndOam(void)
|
|
{
|
|
u8 objId = AddPseudoObjectEvent(90, SpriteCallbackDummy, 0, 0, 8);
|
|
gSprites[objId].oam.priority = 2;
|
|
gSprites[objId].invisible = 1;
|
|
return objId;
|
|
}
|
|
|
|
static void TeachyTvSetSpriteCoordsAndSwitchFrame(u8 objId, u16 x, u16 y, u8 frame)
|
|
{
|
|
gSprites[objId].pos2.x = x;
|
|
gSprites[objId].pos2.y = y;
|
|
gSprites[objId].invisible = 0;
|
|
StartSpriteAnim(&gSprites[objId], frame);
|
|
}
|
|
|
|
static void TeachyTvSetWindowRegs(void)
|
|
{
|
|
SetGpuReg(REG_OFFSET_WIN0V, 0xC64);
|
|
SetGpuReg(REG_OFFSET_WIN0H, 0x1CD4);
|
|
}
|
|
|
|
static void TeachyTvClearWindowRegs(void)
|
|
{
|
|
SetGpuReg(REG_OFFSET_WIN0V, 0x0);
|
|
SetGpuReg(REG_OFFSET_WIN0H, 0x0);
|
|
}
|
|
|
|
static void TeachyTvBg2AnimController(void)
|
|
{
|
|
u16 * tilemapBuffer = GetBgTilemapBuffer(2);
|
|
u8 i, j;
|
|
for (i = 1; i < 13; i++)
|
|
{
|
|
for (j = 2; j < 28; j++)
|
|
{
|
|
tilemapBuffer[32 * i + j] = ((Random() & 3) << 10) + 0x301F;
|
|
}
|
|
}
|
|
ScheduleBgCopyTilemapToVram(2);
|
|
}
|
|
|
|
static void TeachyTvSetupPostBattleWindowAndObj(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
struct Sprite *objAddr = &gSprites[data[1]];
|
|
|
|
ClearWindowTilemap(1);
|
|
TeachyTvClearWindowRegs();
|
|
switch (sStaticResources.whichScript)
|
|
{
|
|
case TTVSCR_BATTLE:
|
|
case TTVSCR_STATUS:
|
|
case TTVSCR_MATCHUPS:
|
|
case TTVSCR_CATCHING:
|
|
TeachyTvSetSpriteCoordsAndSwitchFrame(data[1], 0x78, 0x38, 0);
|
|
ChangeBgX(3, 0x3000, 1);
|
|
ChangeBgY(3, 0x3000, 2);
|
|
sResources->grassAnimCounterLo += 3;
|
|
sResources->grassAnimCounterHi -= 3;
|
|
break;
|
|
case TTVSCR_TMS:
|
|
case TTVSCR_REGISTER:
|
|
TeachyTvSetSpriteCoordsAndSwitchFrame(data[1], 0x78, 0x38, 0);
|
|
break;
|
|
}
|
|
|
|
data[4] = 0;
|
|
data[5] = 0;
|
|
TeachyTvGrassAnimationMain(taskId, objAddr->pos2.x, objAddr->pos2.y, 0, 1);
|
|
}
|
|
|
|
static void TeachyTvInitTextPrinter(const u8 *text)
|
|
{
|
|
gTextFlags.autoScroll = 0;
|
|
AddTextPrinterParameterized2(0, 4, text, GetTextSpeedSetting(), 0, 1, 0xC, 3);
|
|
}
|
|
|
|
static void TeachyTvFree(void)
|
|
{
|
|
Free(sResources);
|
|
sResources = NULL;
|
|
FreeAllWindowBuffers();
|
|
}
|
|
|
|
static void TeachyTvQuitBeginFade(u8 taskId)
|
|
{
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, 0);
|
|
gTasks[taskId].func = TeachyTvQuitFadeControlAndTaskDel;
|
|
}
|
|
|
|
static void TeachyTvQuitFadeControlAndTaskDel(u8 taskId)
|
|
{
|
|
if (!(gPaletteFade.active))
|
|
{
|
|
if (sResources->savedCallback != NULL)
|
|
{
|
|
SetMainCallback2(sResources->savedCallback);
|
|
}
|
|
else
|
|
{
|
|
Overworld_PlaySpecialMapMusic();
|
|
SetMainCallback2(sStaticResources.callback);
|
|
}
|
|
TeachyTvFree();
|
|
DestroyTask(taskId);
|
|
}
|
|
}
|
|
|
|
static void TeachyTvOptionListController(u8 taskId)
|
|
{
|
|
s16 * data = gTasks[taskId].data;
|
|
s32 input;
|
|
|
|
TeachyTvBg2AnimController();
|
|
if (!gPaletteFade.active)
|
|
{
|
|
input = ListMenu_ProcessInput(data[0]);
|
|
ListMenuGetScrollAndRow(data[0], &sStaticResources.scrollOffset, &sStaticResources.selectedRow);
|
|
if ((JOY_NEW(SELECT_BUTTON) && sStaticResources.callback != CB2_BagMenuFromStartMenu))
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
TeachyTvQuitBeginFade(taskId);
|
|
}
|
|
else
|
|
{
|
|
switch (input)
|
|
{
|
|
case -1:
|
|
break;
|
|
case -2:
|
|
PlaySE(SE_SELECT);
|
|
TeachyTvQuitBeginFade(taskId);
|
|
break;
|
|
default:
|
|
PlaySE(SE_SELECT);
|
|
sStaticResources.whichScript = input;
|
|
DestroyListMenuTask(data[0], &sStaticResources.scrollOffset, &sStaticResources.selectedRow);
|
|
TeachyTvClearWindowRegs();
|
|
ClearWindowTilemap(1);
|
|
ScheduleBgCopyTilemapToVram(0);
|
|
TeachyTvRemoveScrollIndicatorArrowPair();
|
|
data[3] = 0;
|
|
data[2] = 0;
|
|
gTasks[taskId].func = TeachyTvRenderMsgAndSwitchClusterFuncs;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_TransitionRenderBg2TeachyTvGraphicInitNpcPos(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
TeachyTvBg2AnimController();
|
|
if (++data[2] > 63)
|
|
{
|
|
CopyToBgTilemapBufferRect_ChangePalette(2, sResources->buffer4, 0, 0, 0x20, 0x20, 0x11);
|
|
TeachyTvSetSpriteCoordsAndSwitchFrame(data[1], 8, 0x38, 7);
|
|
ScheduleBgCopyTilemapToVram(2);
|
|
data[2] = 0;
|
|
++data[3];
|
|
PlayNewMapMusic(MUS_ANNAI);
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_ClearBg2TeachyTvGraphic(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (++data[2] == 134)
|
|
{
|
|
FillBgTilemapBufferRect_Palette0(2, 0, 2, 1, 0x1A, 0xC);
|
|
ScheduleBgCopyTilemapToVram(2);
|
|
data[2] = 0;
|
|
++data[3];
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_NpcMoveAndSetupTextPrinter(u8 taskId)
|
|
{
|
|
s16 * data = gTasks[taskId].data;
|
|
struct Sprite * spriteAddr = &gSprites[data[1]];
|
|
if (data[2] != 35)
|
|
++data[2];
|
|
else {
|
|
if (spriteAddr->pos2.x == 0x78)
|
|
{
|
|
StartSpriteAnim(&gSprites[data[1]], 0);
|
|
TeachyTvInitTextPrinter(gTeachyTvText_PokedudeSaysHello);
|
|
data[2] = 0;
|
|
++data[3];
|
|
}
|
|
else
|
|
++spriteAddr->pos2.x;
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_IdleIfTextPrinterIsActive(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (!RunTextPrinters_CheckActive(0))
|
|
++data[3];
|
|
}
|
|
|
|
static void TeachyTvRenderMsgAndSwitchClusterFuncs(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (JOY_NEW(B_BUTTON))
|
|
{
|
|
sResources->grassAnimDisabled = 1;
|
|
TeachyTvSetSpriteCoordsAndSwitchFrame(data[1], 0, 0, 0);
|
|
FillWindowPixelBuffer(0, 0xCC);
|
|
CopyWindowToVram(0, 2);
|
|
TeachyTvClearBg1EndGraphicText();
|
|
data[2] = 0;
|
|
data[3] = 0;
|
|
gTasks[taskId].func = TTVcmd_End;
|
|
}
|
|
else
|
|
{
|
|
static void (* const * const array[])(u8) =
|
|
{
|
|
sBattleScript,
|
|
sStatusScript,
|
|
sMatchupsScript,
|
|
sCatchingScript,
|
|
sTMsScript,
|
|
sRegisterKeyItemScript,
|
|
};
|
|
void (*const *cluster)(u8) = array[sStaticResources.whichScript];
|
|
cluster[data[3]](taskId);
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_TextPrinterSwitchStringByOptionChosen(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
static const u8 *const texts[] = {
|
|
gTeachyTvText_BattleScript1,
|
|
gTeachyTvText_StatusScript1,
|
|
gTeachyTvText_MatchupsScript1,
|
|
gTeachyTvText_CatchingScript1,
|
|
gTeachyTvText_TMsScript1,
|
|
gTeachyTvText_RegisterScript1,
|
|
};
|
|
TeachyTvInitTextPrinter(texts[sStaticResources.whichScript]);
|
|
++data[3];
|
|
}
|
|
|
|
static void TTVcmd_TextPrinterSwitchStringByOptionChosen2(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
static const u8 *const texts[] =
|
|
{
|
|
gTeachyTvText_BattleScript2,
|
|
gTeachyTvText_StatusScript2,
|
|
gTeachyTvText_MatchupsScript2,
|
|
gTeachyTvText_CatchingScript2,
|
|
gTeachyTvText_TMsScript2,
|
|
gTeachyTvText_RegisterScript2,
|
|
};
|
|
TeachyTvInitTextPrinter(texts[sStaticResources.whichScript]);
|
|
++data[3];
|
|
}
|
|
|
|
static const u16 sBg1EndGraphic[] =
|
|
{
|
|
0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8,
|
|
0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,
|
|
};
|
|
|
|
static const struct Subsprite sSubspriteArray[] =
|
|
{
|
|
{
|
|
.x = -0x8,
|
|
.y = -0x8,
|
|
.shape = 0x1,
|
|
.size = 0x0,
|
|
.tileOffset = 0x0,
|
|
.priority = 0x3,
|
|
},
|
|
{
|
|
.x = -0x8,
|
|
.y = 0x0,
|
|
.shape = 0x1,
|
|
.size = 0x0,
|
|
.tileOffset = 0x2,
|
|
.priority = 0x2,
|
|
},
|
|
};
|
|
|
|
static const struct SubspriteTable sSubspriteTableArray[] =
|
|
{
|
|
{
|
|
.subspriteCount = 0,
|
|
.subsprites = NULL,
|
|
},
|
|
{
|
|
.subspriteCount = 2,
|
|
.subsprites = sSubspriteArray,
|
|
},
|
|
};
|
|
|
|
static const u8 sGrassAnimArray[] =
|
|
{
|
|
0, 0, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 0, 0,
|
|
};
|
|
|
|
static void TTVcmd_IdleIfTextPrinterIsActive2(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (!RunTextPrinters_CheckActive(0))
|
|
++data[3];
|
|
}
|
|
|
|
static void TTVcmd_EraseTextWindowIfKeyPressed(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (JOY_NEW(A_BUTTON | B_BUTTON))
|
|
{
|
|
FillWindowPixelBuffer(0, 0xCC);
|
|
CopyWindowToVram(0, 2);
|
|
++data[3];
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_StartAnimNpcWalkIntoGrass(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
StartSpriteAnim(&gSprites[data[1]], 5);
|
|
data[2] = 0;
|
|
data[4] = 0;
|
|
data[5] = 1;
|
|
++data[3];
|
|
}
|
|
|
|
static void TTVcmd_DudeMoveUp(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
struct Sprite *obj = &gSprites[data[1]];
|
|
ChangeBgY(3, 0x100, 2);
|
|
if (!(++data[2] & 0xF))
|
|
{
|
|
--sResources->grassAnimCounterHi;
|
|
TeachyTvGrassAnimationMain(taskId, obj->pos2.x, obj->pos2.y, 0, 0);
|
|
}
|
|
if (data[2] == 48)
|
|
{
|
|
data[2] = 0;
|
|
data[4] = -1;
|
|
data[5] = 0;
|
|
StartSpriteAnim(obj, 7);
|
|
++data[3];
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_DudeMoveRight(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
struct Sprite *obj = &gSprites[data[1]];
|
|
ChangeBgX(3, 0x100, 1);
|
|
if (!(++data[2] & 0xF))
|
|
++sResources->grassAnimCounterLo;
|
|
if (!((data[2] + 8) & 0xF))
|
|
TeachyTvGrassAnimationMain(taskId, obj->pos2.x + 8, obj->pos2.y, 0, 0);
|
|
if (data[2] == 0x30)
|
|
{
|
|
data[2] = 0;
|
|
data[4] = 0;
|
|
data[5] = 0;
|
|
StartSpriteAnim(obj, 3);
|
|
++data[3];
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_DudeTurnLeft(u8 taskId)
|
|
{
|
|
|
|
s16 *data = gTasks[taskId].data;
|
|
struct Sprite *objAddr = &gSprites[data[1]];
|
|
StartSpriteAnim(objAddr, 6);
|
|
++data[3];
|
|
data[4] = 0;
|
|
data[5] = 0;
|
|
TeachyTvGrassAnimationMain(taskId, objAddr->pos2.x, objAddr->pos2.y, 0, 0);
|
|
}
|
|
|
|
static void TTVcmd_DudeMoveLeft(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
struct Sprite *objAddr = &gSprites[data[1]];
|
|
|
|
if (!(objAddr->pos2.x & 0xF))
|
|
TeachyTvGrassAnimationMain(taskId, objAddr->pos2.x - 8, objAddr->pos2.y, 0, 0);
|
|
if (objAddr->pos2.x == 8)
|
|
++data[3];
|
|
else
|
|
--objAddr->pos2.x;
|
|
}
|
|
|
|
static void TTVcmd_RenderAndRemoveBg1EndGraphic(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (!data[2])
|
|
{
|
|
CopyToBgTilemapBufferRect_ChangePalette(1, sBg1EndGraphic, 20, 10, 8, 2, 0x11);
|
|
ScheduleBgCopyTilemapToVram(1);
|
|
}
|
|
if (++data[2] > 126)
|
|
{
|
|
TeachyTvClearBg1EndGraphicText();
|
|
data[2] = 0;
|
|
++data[3];
|
|
}
|
|
}
|
|
|
|
static void TeachyTvClearBg1EndGraphicText(void)
|
|
{
|
|
FillBgTilemapBufferRect_Palette0(1, 0, 20, 10, 8, 2);
|
|
ScheduleBgCopyTilemapToVram(1);
|
|
}
|
|
|
|
static void TTVcmd_End(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (data[2] == 0)
|
|
PlayNewMapMusic(MUS_TVNOIZE);
|
|
TeachyTvBg2AnimController();
|
|
if (++data[2] > 63)
|
|
{
|
|
data[2] = 0;
|
|
data[3] = 0;
|
|
data[0] = TeachyTvSetupWindow();
|
|
gTasks[taskId].func = TeachyTvOptionListController;
|
|
PutWindowTilemap(0);
|
|
TeachyTvSetupScrollIndicatorArrowPair();
|
|
TeachyTvSetWindowRegs();
|
|
ScheduleBgCopyTilemapToVram(0);
|
|
ChangeBgX(3, 0x0, 0);
|
|
ChangeBgY(3, 0x0, 0);
|
|
ChangeBgX(3, 0x1000, 2);
|
|
ChangeBgY(3, 0x2800, 1);
|
|
sResources->grassAnimCounterLo = 0;
|
|
sResources->grassAnimCounterHi = 3;
|
|
sResources->grassAnimDisabled = 0;
|
|
}
|
|
}
|
|
|
|
static void TTVcmd_TaskBattleOrFadeByOptionChosen(u8 taskId)
|
|
{
|
|
switch (sStaticResources.whichScript)
|
|
{
|
|
case TTVSCR_BATTLE:
|
|
case TTVSCR_STATUS:
|
|
case TTVSCR_MATCHUPS:
|
|
case TTVSCR_CATCHING:
|
|
TeachyTvPrepBattle(taskId);
|
|
break;
|
|
case TTVSCR_TMS:
|
|
case TTVSCR_REGISTER:
|
|
sResources->savedCallback = TeachyTvSetupBagItemsByOptionChosen;
|
|
TeachyTvQuitBeginFade(taskId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void TeachyTvSetupBagItemsByOptionChosen(void)
|
|
{
|
|
if (sStaticResources.whichScript == TTVSCR_TMS)
|
|
InitPokedudeBag(ITEMMENULOCATION_TTVSCR_TMS);
|
|
else
|
|
InitPokedudeBag(ITEMMENULOCATION_TTVSCR_REGISTER);
|
|
}
|
|
|
|
static void TeachyTvPostBattleFadeControl(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
if (!(gPaletteFade.active))
|
|
{
|
|
data[3] = sWhereToReturnToFromBattle[sStaticResources.whichScript];
|
|
gTasks[taskId].func = TeachyTvRenderMsgAndSwitchClusterFuncs;
|
|
}
|
|
}
|
|
|
|
static void TeachyTvGrassAnimationMain(u8 taskId, s16 x, s16 y, u8 subpriority, bool8 mode)
|
|
{
|
|
struct Sprite *obj;
|
|
u8 spriteId;
|
|
|
|
if (sResources->grassAnimDisabled != 1 && TeachyTvGrassAnimationCheckIfNeedsToGenerateGrassObj(x - 0x10, y))
|
|
{
|
|
spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[4], 0, 0, subpriority);
|
|
obj = &gSprites[spriteId];
|
|
obj->pos2.x = x;
|
|
obj->pos2.y = y + 8;
|
|
obj->callback = TeachyTvGrassAnimationObjCallback;
|
|
obj->data[0] = taskId;
|
|
if (mode == 1)
|
|
{
|
|
SeekSpriteAnim(obj, 4);
|
|
obj->oam.priority = 2;
|
|
}
|
|
else
|
|
{
|
|
SetSubspriteTables(obj, sSubspriteTableArray);
|
|
obj->subspriteTableNum = 0;
|
|
obj->subspriteMode = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void TeachyTvGrassAnimationObjCallback(struct Sprite *sprite)
|
|
{
|
|
s16 diff1, diff2;
|
|
s16 *data = gTasks[sprite->data[0]].data;
|
|
struct Sprite *objAddr = &gSprites[data[1]];
|
|
|
|
if (sResources->grassAnimDisabled == 1)
|
|
DestroySprite(sprite);
|
|
else
|
|
{
|
|
if (sprite->animCmdIndex == 0)
|
|
sprite->subspriteTableNum = 1;
|
|
else
|
|
sprite->subspriteTableNum = 0;
|
|
sprite->pos2.x += data[4];
|
|
sprite->pos2.y += data[5];
|
|
if (sprite->animEnded)
|
|
{
|
|
sprite->subpriority = 0;
|
|
diff1 = sprite->pos2.x - objAddr->pos2.x;
|
|
diff2 = sprite->pos2.y - objAddr->pos2.y;
|
|
if (diff1 <= -16 || diff1 >= 16 || diff2 <= -16 || diff2 >= 24)
|
|
DestroySprite(sprite);
|
|
}
|
|
}
|
|
}
|
|
|
|
static u8 TeachyTvGrassAnimationCheckIfNeedsToGenerateGrassObj(s16 x, s16 y)
|
|
{
|
|
const u8 * arr;
|
|
struct TeachyTvBuf *ptr;
|
|
int high, low;
|
|
if ((x < 0) || (y < 0))
|
|
return 0;
|
|
arr = sGrassAnimArray;
|
|
high = ((y >> 4) + sResources->grassAnimCounterHi) << 4;
|
|
low = ((x >> 4) + sResources->grassAnimCounterLo);
|
|
return arr[high+low];
|
|
}
|
|
|
|
static void TeachyTvPrepBattle(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
TeachyTvFree();
|
|
gSpecialVar_0x8004 = sStaticResources.whichScript;
|
|
gMain.savedCallback = TeachyTvRestorePlayerPartyCallback;
|
|
SavePlayerParty();
|
|
InitPokedudePartyAndOpponent();
|
|
PlayMapChosenOrBattleBGM(MUS_DUMMY);
|
|
if (sStaticResources.whichScript == TTVSCR_BATTLE)
|
|
data[6] = 9;
|
|
else
|
|
data[6] = 8;
|
|
data[7] = 0;
|
|
gTasks[taskId].func = TeachyTvPreBattleAnimAndSetBattleCallback;
|
|
}
|
|
|
|
static void TeachyTvPreBattleAnimAndSetBattleCallback(u8 taskId)
|
|
{
|
|
s16 *data = gTasks[taskId].data;
|
|
switch (data[7])
|
|
{
|
|
case 0:
|
|
BT_StartOnField(data[6]);
|
|
++data[7];
|
|
break;
|
|
case 1:
|
|
if (BT_IsDone())
|
|
{
|
|
SetMainCallback2(CB2_InitBattle);
|
|
DestroyTask(taskId);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void TeachyTvRestorePlayerPartyCallback(void)
|
|
{
|
|
LoadPlayerParty();
|
|
if (gBattleOutcome == B_OUTCOME_DREW)
|
|
SetTeachyTvControllerModeToResume();
|
|
else
|
|
PlayNewMapMusic(MUS_ANNAI);
|
|
CB2_ReturnToTeachyTV();
|
|
}
|
|
|
|
static void TeachyTvLoadBg3Map(u16 *buffer)
|
|
{
|
|
u16 * bgTilesBuffer;
|
|
u8 * mapTilesRowBuffer;
|
|
u16 i, j, k;
|
|
u16 currentBlockIdx;
|
|
void * tilesetsBuffer;
|
|
void * palIndicesBuffer;
|
|
u16 numMapTilesRows = 0;
|
|
const struct MapLayout *layout = &Route1_Layout;
|
|
u16 * blockIndicesBuffer = AllocZeroed(0x800);
|
|
tilesetsBuffer = AllocZeroed(0x8000);
|
|
palIndicesBuffer = Alloc(16);
|
|
memset(palIndicesBuffer, 0xFF, 16);
|
|
|
|
TeachyTvLoadMapTilesetToBuffer(layout->primaryTileset, tilesetsBuffer, 0x280);
|
|
TeachyTvLoadMapTilesetToBuffer(layout->secondaryTileset, tilesetsBuffer + 0x5000, 0x180);
|
|
|
|
for (i = 0; i < 9; i++)
|
|
{
|
|
for (j = 0; j < 16; j++)
|
|
{
|
|
currentBlockIdx = layout->map[8 + (i + 6) * layout->width + j] & 0x3FF;
|
|
for (k = 0; k < (i << 4) + j; k++)
|
|
{
|
|
if (blockIndicesBuffer[k] == 0)
|
|
break;
|
|
if (blockIndicesBuffer[k] == currentBlockIdx)
|
|
break;
|
|
}
|
|
if (blockIndicesBuffer[k] == 0)
|
|
{
|
|
blockIndicesBuffer[k] = currentBlockIdx;
|
|
numMapTilesRows++;
|
|
}
|
|
TeachyTvPushBackNewMapPalIndexArrayEntry(layout, &buffer[64 * i + 2 * j], palIndicesBuffer, currentBlockIdx, k);
|
|
}
|
|
}
|
|
|
|
bgTilesBuffer = Alloc(numMapTilesRows * 0x80);
|
|
mapTilesRowBuffer = Alloc(0x80);
|
|
for (i = 0; i < numMapTilesRows; i++)
|
|
{
|
|
memset(mapTilesRowBuffer, 0, 0x80);
|
|
if (blockIndicesBuffer[i] < 0x280)
|
|
{
|
|
TeachyTvComputeMapTilesFromTilesetAndMetaTiles(layout->primaryTileset->metatiles + blockIndicesBuffer[i] * 16, mapTilesRowBuffer, tilesetsBuffer);
|
|
}
|
|
else
|
|
{
|
|
TeachyTvComputeMapTilesFromTilesetAndMetaTiles(layout->secondaryTileset->metatiles + (blockIndicesBuffer[i] - 0x280) * 16, mapTilesRowBuffer, tilesetsBuffer);
|
|
}
|
|
CpuFastCopy(mapTilesRowBuffer, bgTilesBuffer + i * 0x40, 0x80);
|
|
}
|
|
|
|
LoadBgTiles(3, bgTilesBuffer, numMapTilesRows * 0x80, 0);
|
|
TeachyTvLoadMapPalette(layout, palIndicesBuffer);
|
|
|
|
Free(mapTilesRowBuffer);
|
|
Free(bgTilesBuffer);
|
|
Free(palIndicesBuffer);
|
|
Free(tilesetsBuffer);
|
|
Free(blockIndicesBuffer);
|
|
}
|
|
|
|
static void TeachyTvLoadMapTilesetToBuffer(struct Tileset *ts, u8 *dstBuffer, u16 size)
|
|
{
|
|
if (ts)
|
|
{
|
|
if (!ts->isCompressed)
|
|
CpuFastSet(ts->tiles, dstBuffer, 8 * size);
|
|
else
|
|
LZDecompressWram(ts->tiles, dstBuffer);
|
|
}
|
|
}
|
|
|
|
static void TeachyTvPushBackNewMapPalIndexArrayEntry(const struct MapLayout *mStruct, u16 *buf1, u8 *palIndexArray, u16 mapEntry, u16 offset)
|
|
{
|
|
u16 * metaTileEntryAddr = mapEntry <= 0x27F ? &((u16*)(mStruct->primaryTileset->metatiles))[8 * mapEntry] : &((u16*)(mStruct->secondaryTileset->metatiles))[8 * (mapEntry - 0x280)];
|
|
buf1[0] = (TeachyTvComputePalIndexArrayEntryByMetaTile(palIndexArray, metaTileEntryAddr[0]) << 12) + 4 * offset;
|
|
buf1[1] = (TeachyTvComputePalIndexArrayEntryByMetaTile(palIndexArray, metaTileEntryAddr[1]) << 12) + 4 * offset + 1;
|
|
buf1[32] = (TeachyTvComputePalIndexArrayEntryByMetaTile(palIndexArray, metaTileEntryAddr[2]) << 12) + 4 * offset + 2;
|
|
buf1[33] = (TeachyTvComputePalIndexArrayEntryByMetaTile(palIndexArray, metaTileEntryAddr[3]) << 12) + 4 * offset + 3;
|
|
}
|
|
|
|
static void TeachyTvComputeMapTilesFromTilesetAndMetaTiles(u16 *metaTilesArray, u8 *blockBuf, u8 *tileset)
|
|
{
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf, &tileset[0x20 * (*metaTilesArray & 0x3FF)], (*metaTilesArray >> 10) & 3);
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf, &tileset[0x20 * (metaTilesArray[4] & 0x3FF)], (metaTilesArray[4] >> 10) & 3);
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf + 0x20, &tileset[0x20 * (metaTilesArray[1] & 0x3FF)], (metaTilesArray[1] >> 10) & 3);
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf + 0x20, &tileset[0x20 * (metaTilesArray[5] & 0x3FF)], (metaTilesArray[5] >> 10) & 3);
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf + 0x40, &tileset[0x20 * (metaTilesArray[2] & 0x3FF)], (metaTilesArray[2] >> 10) & 3);
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf + 0x40, &tileset[0x20 * (metaTilesArray[6] & 0x3FF)], (metaTilesArray[6] >> 10) & 3);
|
|
blockBuf += 0x60;
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf, &tileset[0x20 * (metaTilesArray[3] & 0x3FF)], (metaTilesArray[3] >> 10) & 3);
|
|
TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(blockBuf, &tileset[0x20 * (metaTilesArray[7] & 0x3FF)], (metaTilesArray[7] >> 10) & 3);
|
|
}
|
|
|
|
static void TeachyTvComputeSingleMapTileBlockFromTilesetAndMetaTiles(u8 *blockBuf, u8 *tileset, u8 metaTile)
|
|
{
|
|
u8 i, j;
|
|
u8 * buffer = AllocZeroed(0x20);
|
|
u8 * src = AllocZeroed(0x20);
|
|
CpuFastSet(tileset, buffer, 8);
|
|
if (metaTile & 1)
|
|
{
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
for (j = 0; j < 4; ++j)
|
|
{
|
|
u32 offset = j - 3;
|
|
u8 value = buffer[(i << 2) - offset];
|
|
src[(i << 2) + j] = ((value & 0xF) << 4) + ((value & 0xF0) >> 4);
|
|
}
|
|
}
|
|
CpuFastSet(src, buffer, 8);
|
|
}
|
|
if (metaTile & 2)
|
|
{
|
|
for (i = 0; i < 8; ++i)
|
|
memcpy(&src[4 * i], &buffer[4 * (7 - i)], 4);
|
|
CpuFastSet(src, buffer, 8);
|
|
}
|
|
for (i = 0; i < 32; ++i)
|
|
{
|
|
if (buffer[i] & 0xF0)
|
|
blockBuf[i] = (blockBuf[i] & 0xF) + (buffer[i] & 0xF0);
|
|
if (buffer[i] & 0xF)
|
|
blockBuf[i] = (blockBuf[i] & 0xF0) + (buffer[i] & 0xF);
|
|
}
|
|
Free(src);
|
|
Free(buffer);
|
|
}
|
|
|
|
static u16 TeachyTvComputePalIndexArrayEntryByMetaTile(u8 *palIndexArrayBuf, u16 metaTile)
|
|
{
|
|
u16 i;
|
|
int firstEntry;
|
|
int temp;
|
|
u32 pal = metaTile >> 12;
|
|
i = 0;
|
|
firstEntry = *palIndexArrayBuf;
|
|
if (firstEntry != pal)
|
|
{
|
|
if (firstEntry == 0xFF)
|
|
{
|
|
*palIndexArrayBuf = pal;
|
|
}
|
|
else
|
|
{
|
|
while (++i < 16)
|
|
{
|
|
temp = palIndexArrayBuf[i];
|
|
if (temp == pal)
|
|
break;
|
|
if (temp == 0xFF)
|
|
{
|
|
palIndexArrayBuf[i] = pal;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (0xF - i);
|
|
}
|
|
|
|
static void TeachyTvLoadMapPalette(const struct MapLayout * mStruct, const u8 * palIndexArray)
|
|
{
|
|
u8 i;
|
|
const struct Tileset * ts;
|
|
u16 * dest;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
if (palIndexArray[i] == 0xFF)
|
|
break;
|
|
if (palIndexArray[i] > 6)
|
|
dest = (u16 *)mStruct->secondaryTileset->palettes + 0x10 * palIndexArray[i];
|
|
else
|
|
dest = (u16 *)mStruct->primaryTileset->palettes + 0x10 * palIndexArray[i];
|
|
LoadPalette(dest, 0x10 * (15 - i), 0x20);
|
|
}
|
|
}
|