Advertisement
EliteAnax17

speedchoice.c

May 26th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.19 KB | None | 0 0
  1. #include "global.h"
  2. #include "option_menu.h"
  3. #include "main.h"
  4. #include "menu.h"
  5. #include "palette.h"
  6. #include "sprite.h"
  7. #include "task.h"
  8. #include "sound.h"
  9. #include "songs.h"
  10. #include "string_util.h"
  11. #include "text.h"
  12. #include "speedchoice.h"
  13.  
  14. extern void Task_NewGameSpeech1(u8);
  15. extern void remove_some_task(void);
  16.  
  17. extern u8 gUnknown_0839F63C[];
  18. extern u8 gUnknown_0839F5FC[]; //palette
  19.  
  20. extern u8 gSystemText_Terminator[];
  21.  
  22. const u8 gSpeedchoiceCurrentVersion[] = _("{PALETTE 9}BETA8");
  23.  
  24. const u8 gSpeedchoiceTextHeader[] = _("{PALETTE 9}SPEEDCHOICE MENU");
  25.  
  26. // OPTION CHOICES
  27. const u8 gSpeedchoiceTextYes[] = _("{PALETTE 15}YES");
  28. const u8 gSpeedchoiceTextNo[] = _("{PALETTE 15}NO");
  29. const u8 gSpeedchoiceTextOn[] = _("{PALETTE 15}ON");
  30. const u8 gSpeedchoiceTextOff[] = _("{PALETTE 15}OFF");
  31. const u8 gSpeedchoiceTextNerf[] = _("{PALETTE 15}NERF");
  32. const u8 gSpeedchoiceTextKeep[] = _("{PALETTE 15}KEEP");
  33. const u8 gSpeedchoiceTextHell[] = _("{PALETTE 15}HELL");
  34. const u8 gSpeedchoiceTextSemi[] = _("{PALETTE 15}SEMI");
  35. const u8 gSpeedchoiceTextFull[] = _("{PALETTE 15}FULL");
  36.  
  37. // PAGE 1
  38. const u8 gSpeedchoiceOptionBWExp[] = _("{PALETTE 8}B/W EXP");
  39. const u8 gSpeedchoiceOptionAqualess[] = _("{PALETTE 15}AQUALESS");
  40. const u8 gSpeedchoiceOptionInstantText[] = _("{PALETTE 15}INSTANT TEXT");
  41. const u8 gSpeedchoiceOptionSpinners[] = _("{PALETTE 15}SPINNERS");
  42. const u8 gSpeedchoiceOptionMaxVision[] = _("{PALETTE 15}MAX VISION");
  43.  
  44. // PAGE 2
  45. const u8 gSpeedchoiceOptionNerfRoxanne[] = _("{PALETTE 15}NERF ROXANNE");
  46. const u8 gSpeedchoiceOptionSuperBike[] = _("{PALETTE 15}SUPER BIKE");
  47. const u8 gSpeedchoiceOptionNewWildEnc[] = _("{PALETTE 15}NEW WILD ENC.");
  48. const u8 gSpeedchoiceOptionEarlyFly[] = _("{PALETTE 15}EARLY FLY");
  49. const u8 gSpeedchoiceOptionRunEverywhere[] = _("{PALETTE 15}RUN EVERYWHERE");
  50.  
  51. // PAGE 3
  52. const u8 gSpeedchoiceOptionMemeIsland[] = _("{PALETTE 15}MEME ISLAND");
  53. const u8 gSpeedchoiceOptionEmeraldDoubles[] = _("{PALETTE 15}EMERALD DOUBLES");
  54. const u8 gSpeedchoiceOptionGlitchRod[] = _("{PALETTE 15}GLITCH ROD");
  55. const u8 gSpeedchoiceOptionBetterMarts[] = _("{PALETTE 15}BETTER MARTS");
  56.  
  57. // CONSTANT OPTIONS
  58. const u8 gSpeedchoiceOptionPage[] = _("{PALETTE 15}PAGE");
  59. const u8 gSpeedchoiceOptionStartGame[] = _("{PALETTE 15}START GAME");
  60.  
  61. // TOOLTIPS
  62. const u8 gSpeedchoiceTooltipBWEXP[] = _("(WIP) Will replace the\ncurrent experience system\pin favor of Black/White’s\nimplementation.");
  63. const u8 gSpeedchoiceTooltipAqualess[] = _("SEMI: Stops villian team events\nafter Mt. Chimney.\pFULL: Skips all the villian team\nevents. Also allows Dive to be used\pwithout Gym 7’s badge.");
  64. const u8 gSpeedchoiceTooltipInstantText[] = _("Self-explanatory.\nHold A or B to mash.");
  65. const u8 gSpeedchoiceTooltipSpinners[] = _("NERF: Will prevent\nspinners from noticing\pthe player while running.\pHELL: Rapidly spins\nevery spinner every frame.\pAlso fixes bag manip.");
  66. const u8 gSpeedchoiceTooltipMaxVision[] = _("Extends trainer vision to 8.");
  67. const u8 gSpeedchoiceTooltipNerfRoxanne[] = _("Reduces Gym Leader Roxanne’s\nteam levels by 2 and\premoves 1 of her potions.");
  68. const u8 gSpeedchoiceTooltipSuperBike[] = _("While riding the bicycle, you\ncan switch between bikes with\pthe R button.");
  69. const u8 gSpeedchoiceTooltipNewWildEnc[] = _("Intended to be used with\nthe randomizer.\pTreats grass and fishing slots\nas 6 and 2 slots respectively.");
  70. const u8 gSpeedchoiceTooltipEarlyFly[] = _("Recieve HM02 instead of\nItemfinder at Rival 2.\pAllows use of Fly without use of\nGym 6’s badge.");
  71. const u8 gSpeedchoiceTooltipRunEverywhere[] = _("Allows the Running Shoes to\nbe used anywhere, including\pinside of houses.\pAlso allows bike in most places.");
  72. const u8 gSpeedchoiceTooltipMemeIsland[] = _("Mirage Island always appears.");
  73. const u8 gSpeedchoiceTooltipEmeraldDoubles[] = _("Treat double battle trainers\n(such as twins) as having either\p0 vision or greater than 1 vision.");
  74. const u8 gSpeedchoiceTooltipGlitchRod[] = _("Restores the old behavior\nof fishing from BETA 7 where\plevel is not accounted for\nby the rod type.");
  75. const u8 gSpeedchoiceTooltipBetterMarts[] = _("Improves the item selections\nof many Pokemon marts.\pAdds repels to Oldale Mart.\pAdds repels and super repels to\nMauville Mart.\pAdds X Specials to Rustboro\nMart.");
  76.  
  77. // START GAME
  78. const u8 gSpeedchoiceStartGameText[] = _("CV: {STR_VAR_1}\nStart the game?");
  79.  
  80. const struct OptionChoiceConfig OptionChoiceConfigYesNo[MAX_CHOICES] =
  81. {
  82. { 184, 40, (u8 *)&gSpeedchoiceTextYes },
  83. { 155, 40, (u8 *)&gSpeedchoiceTextNo },
  84. { -1, -1, NULL },
  85. { -1, -1, NULL },
  86. { -1, -1, NULL },
  87. { -1, -1, NULL }
  88. };
  89.  
  90. const struct OptionChoiceConfig OptionChoiceConfigOnOff[MAX_CHOICES] =
  91. {
  92. { 184, 40, (u8 *)&gSpeedchoiceTextOn },
  93. { 155, 40, (u8 *)&gSpeedchoiceTextOff },
  94. { -1, -1, NULL },
  95. { -1, -1, NULL },
  96. { -1, -1, NULL },
  97. { -1, -1, NULL }
  98. };
  99.  
  100. const struct OptionChoiceConfig OptionChoiceConfigNerfKeep[MAX_CHOICES] =
  101. {
  102. { 124, 40, (u8 *)&gSpeedchoiceTextNerf },
  103. { 154, 40, (u8 *)&gSpeedchoiceTextKeep },
  104. { 184, 40, (u8 *)&gSpeedchoiceTextHell },
  105. { -1, -1, NULL },
  106. { -1, -1, NULL },
  107. { -1, -1, NULL }
  108. };
  109.  
  110. const struct OptionChoiceConfig OptionChoiceConfigSemiFull[MAX_CHOICES] =
  111. {
  112. { 124, 40, (u8 *)&gSpeedchoiceTextSemi },
  113. { 154, 40, (u8 *)&gSpeedchoiceTextKeep },
  114. { 184, 40, (u8 *)&gSpeedchoiceTextFull },
  115. { -1, -1, NULL },
  116. { -1, -1, NULL },
  117. { -1, -1, NULL }
  118. };
  119.  
  120. // this is totally weird, but in order to use ProcessGeneralInput, a struct is needed for page, so, I opt to have a dummy struct which only has the number of choices relevent to the calculation of the selection.
  121. const struct OptionChoiceConfig OptionChoiceConfigPage[MAX_CHOICES] =
  122. {
  123. { -1, -1, NULL },
  124. { -1, -1, NULL },
  125. { -1, -1, NULL },
  126. { -1, -1, NULL },
  127. { -1, -1, NULL },
  128. { -1, -1, NULL }
  129. };
  130.  
  131. const struct SpeedchoiceOption SpeedchoiceOptions[CURRENT_OPTIONS_NUM + 1] = // plus one for page.
  132. {
  133. { 2, (u8 *)&gSpeedchoiceOptionBWExp, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipBWEXP, OFF, FALSE },
  134. { 3, (u8 *)&gSpeedchoiceOptionAqualess, (struct OptionChoiceConfig *)OptionChoiceConfigSemiFull, (u8 *)&gSpeedchoiceTooltipAqualess, KEEP, TRUE },
  135. { 2, (u8 *)&gSpeedchoiceOptionInstantText, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipInstantText, OFF, TRUE },
  136. { 3, (u8 *)&gSpeedchoiceOptionSpinners, (struct OptionChoiceConfig *)OptionChoiceConfigNerfKeep, (u8 *)&gSpeedchoiceTooltipSpinners, KEEP, TRUE },
  137. { 2, (u8 *)&gSpeedchoiceOptionMaxVision, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipMaxVision, OFF, TRUE },
  138. { 2, (u8 *)&gSpeedchoiceOptionNerfRoxanne, (struct OptionChoiceConfig *)OptionChoiceConfigYesNo, (u8 *)&gSpeedchoiceTooltipNerfRoxanne, NO, TRUE },
  139. { 2, (u8 *)&gSpeedchoiceOptionSuperBike, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipSuperBike, OFF, TRUE },
  140. { 2, (u8 *)&gSpeedchoiceOptionNewWildEnc, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipNewWildEnc, OFF, TRUE },
  141. { 2, (u8 *)&gSpeedchoiceOptionEarlyFly, (struct OptionChoiceConfig *)OptionChoiceConfigYesNo, (u8 *)&gSpeedchoiceTooltipEarlyFly, NO, TRUE },
  142. { 2, (u8 *)&gSpeedchoiceOptionRunEverywhere, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipRunEverywhere, OFF, TRUE },
  143. { 2, (u8 *)&gSpeedchoiceOptionMemeIsland, (struct OptionChoiceConfig *)OptionChoiceConfigYesNo, (u8 *)&gSpeedchoiceTooltipMemeIsland, NO, TRUE },
  144. { 2, (u8 *)&gSpeedchoiceOptionEmeraldDoubles, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipEmeraldDoubles, OFF, TRUE },
  145. { 2, (u8 *)&gSpeedchoiceOptionGlitchRod, (struct OptionChoiceConfig *)OptionChoiceConfigYesNo, (u8 *)&gSpeedchoiceTooltipGlitchRod, NO, TRUE },
  146. { 2, (u8 *)&gSpeedchoiceOptionBetterMarts, (struct OptionChoiceConfig *)OptionChoiceConfigOnOff, (u8 *)&gSpeedchoiceTooltipBetterMarts, OFF, TRUE },
  147. { MAX_PAGES, (u8 *)&gSpeedchoiceOptionPage, (struct OptionChoiceConfig *)OptionChoiceConfigPage, NULL, 1, TRUE } // see above comment.
  148. };
  149.  
  150. extern u32 gRandomizerCheckValue;
  151.  
  152. EWRAM_DATA u8 gStoredPageNum = 0; // default is 0, only renders options again if it's different than the task data's page number.
  153. EWRAM_DATA struct SpeedchoiceConfigStruct gLocalSpeedchoiceConfig = {0};
  154. EWRAM_DATA struct MapObjectTimerBackup gMapObjectTimerBackup[MAX_SPRITES] = {0};
  155. EWRAM_DATA bool8 gLastMenuWasSubmenu = {0};
  156.  
  157. static void Task_SpeedchoiceMenuFadeIn(u8);
  158. static void Task_SpeedchoiceMenuProcessInput(u8);
  159. static void HighlightOptionMenuItem(u8);
  160. static void DrawGeneralChoices(struct SpeedchoiceOption *option, u8 selection, u8 row);
  161. static void DrawPageChoice(u8);
  162. static void Task_SpeedchoiceMenuSave(u8);
  163. static void Task_DrawYesNoText(u8);
  164. static void HighlightTextBox(void);
  165.  
  166. void InitializeOptionChoicesAndConfig(u8 taskId)
  167. {
  168. u8 i;
  169.  
  170. // set the local config for the current menu.
  171. for(i = 0; i < CURRENT_OPTIONS_NUM; i++)
  172. gLocalSpeedchoiceConfig.optionConfig[i] = SpeedchoiceOptions[i].defaultOption;
  173.  
  174. gSaveBlock2.speedchoiceConfig.bwexp = SpeedchoiceOptions[BWEXP].defaultOption;
  175. gSaveBlock2.speedchoiceConfig.aqualess = SpeedchoiceOptions[AQUALESS].defaultOption;
  176. gSaveBlock2.speedchoiceConfig.instantText = SpeedchoiceOptions[INSTANTTEXT].defaultOption;
  177. gSaveBlock2.speedchoiceConfig.spinners = SpeedchoiceOptions[SPINNERS].defaultOption;
  178. gSaveBlock2.speedchoiceConfig.maxVision = SpeedchoiceOptions[MAXVISION].defaultOption;
  179. gSaveBlock2.speedchoiceConfig.nerfRoxanne = SpeedchoiceOptions[NERFROXANNE].defaultOption;
  180. gSaveBlock2.speedchoiceConfig.superbike = SpeedchoiceOptions[SUPERBIKE].defaultOption;
  181. gSaveBlock2.speedchoiceConfig.newwildencounters = SpeedchoiceOptions[NEWWILDENC].defaultOption;
  182. gSaveBlock2.speedchoiceConfig.earlyfly = SpeedchoiceOptions[EARLYFLY].defaultOption;
  183. gSaveBlock2.speedchoiceConfig.runEverywhere = SpeedchoiceOptions[RUN_EVERYWHERE].defaultOption;
  184. gSaveBlock2.speedchoiceConfig.memeIsland = SpeedchoiceOptions[MEME_ISLAND].defaultOption;
  185. gSaveBlock2.speedchoiceConfig.emeraldDoubles = SpeedchoiceOptions[EMERALD_DOUBLES].defaultOption;
  186. gSaveBlock2.speedchoiceConfig.glitchRod = SpeedchoiceOptions[GLITCH_ROD].defaultOption;
  187. gSaveBlock2.speedchoiceConfig.betterMarts = SpeedchoiceOptions[BETTER_MARTS].defaultOption;
  188. }
  189.  
  190. bool8 CheckSpeedchoiceOption(u8 option, u8 selection)
  191. {
  192. switch(option)
  193. {
  194. case BWEXP:
  195. return gSaveBlock2.speedchoiceConfig.bwexp == selection;
  196. case AQUALESS:
  197. return gSaveBlock2.speedchoiceConfig.aqualess == selection;
  198. case INSTANTTEXT:
  199. return gSaveBlock2.speedchoiceConfig.instantText == selection;
  200. case SPINNERS:
  201. return gSaveBlock2.speedchoiceConfig.spinners == selection;
  202. case MAXVISION:
  203. return gSaveBlock2.speedchoiceConfig.maxVision == selection;
  204. case NERFROXANNE:
  205. return gSaveBlock2.speedchoiceConfig.nerfRoxanne == selection;
  206. case SUPERBIKE:
  207. return gSaveBlock2.speedchoiceConfig.superbike == selection;
  208. case NEWWILDENC:
  209. return gSaveBlock2.speedchoiceConfig.newwildencounters == selection;
  210. case EARLYFLY:
  211. return gSaveBlock2.speedchoiceConfig.earlyfly == selection;
  212. case RUN_EVERYWHERE:
  213. return gSaveBlock2.speedchoiceConfig.runEverywhere == selection;
  214. case MEME_ISLAND:
  215. return gSaveBlock2.speedchoiceConfig.memeIsland == selection;
  216. case EMERALD_DOUBLES:
  217. return gSaveBlock2.speedchoiceConfig.emeraldDoubles == selection;
  218. case GLITCH_ROD:
  219. return gSaveBlock2.speedchoiceConfig.glitchRod == selection;
  220. case BETTER_MARTS:
  221. return gSaveBlock2.speedchoiceConfig.betterMarts == selection;
  222. default:
  223. return FALSE;
  224. }
  225. }
  226.  
  227. static void DrawOptionMenuChoice(u8 *text, u8 x, u8 y, u8 style)
  228. {
  229. u8 dst[16];
  230. u16 i;
  231.  
  232. for(i = 0; *text != EOS && i <= 14; i++)
  233. dst[i] = *(text++);
  234.  
  235. dst[2] = style;
  236. dst[i] = EOS;
  237. MenuPrint_PixelCoords(dst, x, y, 1);
  238. }
  239.  
  240. // for selecting options. not unstubbed yet.
  241. static u8 ProcessGeneralInput(struct SpeedchoiceOption *option, u8 selection)
  242. {
  243. if(gMain.newKeys & DPAD_RIGHT)
  244. {
  245. if(option->enabled == FALSE)
  246. {
  247. PlaySE(SE_HAZURE);
  248. return selection;
  249. }
  250. if(selection == (option->optionCount - 1)) // options are indexed by 0.
  251. selection = 0;
  252. else
  253. selection++;
  254. PlaySE(SE_SELECT);
  255. }
  256. // i dont return immediately because emulators could hold both right and left down.
  257. if(gMain.newKeys & DPAD_LEFT)
  258. {
  259. if(option->enabled == FALSE)
  260. {
  261. PlaySE(SE_HAZURE);
  262. return selection;
  263. }
  264. if(selection == 0)
  265. selection = (option->optionCount - 1); // indexed by 0.
  266. else
  267. selection--;
  268. PlaySE(SE_SELECT);
  269. }
  270. return selection;
  271. }
  272.  
  273. // todo: combine with above function
  274. static u8 ProcessGeneralInputIndexedToOne(struct SpeedchoiceOption *option, u8 selection)
  275. {
  276. if(gMain.newKeys & DPAD_RIGHT)
  277. {
  278. if(selection == (option->optionCount)) // pages are indexed by 1.
  279. selection = 1;
  280. else
  281. selection++;
  282. }
  283. // i dont return immediately because emulators could hold both right and left down.
  284. if(gMain.newKeys & DPAD_LEFT)
  285. {
  286. if(selection == 1)
  287. selection = (option->optionCount); // indexed by 1.
  288. else
  289. selection--;
  290. }
  291.  
  292. // sanity check, but im unsure if it matters. do NOT let page escape the allowed number of pages!
  293. if(selection < 1)
  294. selection = 1;
  295. if(selection > (option->optionCount))
  296. selection = option->optionCount;
  297.  
  298. return selection;
  299. }
  300.  
  301. static void MainCB(void)
  302. {
  303. RunTasks();
  304. AnimateSprites();
  305. BuildOamBuffer();
  306. UpdatePaletteFade();
  307. }
  308.  
  309. static void VBlankCB(void)
  310. {
  311. LoadOam();
  312. ProcessSpriteCopyRequests();
  313. TransferPlttBuffer();
  314. }
  315.  
  316. void RedrawSpeedchoiceWindows(void)
  317. {
  318. MenuDrawTextWindow(2, 4, 27, 19); // only the lower menu needs to be redrawn.
  319. }
  320.  
  321. u8 GetPageDrawCount(u8 page)
  322. {
  323. if ((page * OPTIONS_PER_PAGE) > CURRENT_OPTIONS_NUM)
  324. return CURRENT_OPTIONS_NUM % OPTIONS_PER_PAGE;
  325.  
  326. return OPTIONS_PER_PAGE;
  327. }
  328.  
  329. void DrawPageOptions(u8 taskId, u8 page)
  330. {
  331. u8 i;
  332. u8 drawCount = GetPageDrawCount(page);
  333.  
  334. RedrawSpeedchoiceWindows();
  335.  
  336. // print page options.
  337. for(i = 0; i < drawCount; i++)
  338. {
  339. struct SpeedchoiceOption *option = (struct SpeedchoiceOption *)&SpeedchoiceOptions[i + (OPTIONS_PER_PAGE * (page - 1))];
  340. u8 *string = option->string;
  341.  
  342. MenuPrint(string, 4, MENUOPTIONCOORDS(i)); // the 5 here does not represent options_per_page, it's just a coincidence.
  343. DrawGeneralChoices(option, gLocalSpeedchoiceConfig.optionConfig[i + ((page-1) * 5)], i);
  344. }
  345.  
  346. MenuPrint(gSpeedchoiceOptionPage, 4, MENUOPTIONCOORDS(5));
  347. MenuPrint(gSpeedchoiceOptionStartGame, 4, MENUOPTIONCOORDS(6));
  348. }
  349.  
  350. void SetPageIndexFromTrueIndex(u8 taskId, s16 index) // data is s16.
  351. {
  352. if(index == PAGE)
  353. gLocalSpeedchoiceConfig.pageIndex = 5;
  354. else if(index == START_GAME)
  355. gLocalSpeedchoiceConfig.pageIndex = 6;
  356. else
  357. gLocalSpeedchoiceConfig.pageIndex = (min((index % OPTIONS_PER_PAGE), OPTIONS_PER_PAGE));
  358. }
  359.  
  360. void HighlightHeaderBox(void)
  361. {
  362. REG_WIN0H = WIN_RANGE(17, 223);
  363. REG_WIN0V = WIN_RANGE(1, 31);
  364. }
  365.  
  366. void CB2_InitSpeedchoiceMenu(void)
  367. {
  368. switch (gMain.state)
  369. {
  370. default:
  371. case 0:
  372. {
  373. u8 *addr;
  374. u32 size;
  375.  
  376. SetVBlankCallback(NULL);
  377. REG_DISPCNT = 0;
  378. REG_BG2CNT = 0;
  379. REG_BG1CNT = 0;
  380. REG_BG0CNT = 0;
  381. REG_BG2HOFS = 0;
  382. REG_BG2VOFS = 0;
  383. REG_BG1HOFS = 0;
  384. REG_BG1VOFS = 0;
  385. REG_BG0HOFS = 0;
  386. REG_BG0VOFS = 0;
  387. addr = (u8 *)VRAM;
  388. size = 0x18000;
  389. while (1)
  390. {
  391. DmaFill16(3, 0, addr, 0x1000);
  392. addr += 0x1000;
  393. size -= 0x1000;
  394. if (size <= 0x1000)
  395. {
  396. DmaFill16(3, 0, addr, size);
  397. break;
  398. }
  399. }
  400. DmaClear32(3, OAM, OAM_SIZE);
  401. DmaClear16(3, PLTT, PLTT_SIZE);
  402. gMain.state++;
  403. break;
  404. }
  405. case 1:
  406. ResetPaletteFade();
  407. remove_some_task();
  408. ResetTasks();
  409. ResetSpriteData();
  410. gMain.state++;
  411. break;
  412. case 2:
  413. SetUpWindowConfig(&gWindowConfig_81E71B4);
  414. gMain.state++;
  415. break;
  416. case 3:
  417. MultistepInitMenuWindowBegin(&gWindowConfig_81E71B4);
  418. gMain.state++;
  419. break;
  420. case 4:
  421. if (!MultistepInitMenuWindowContinue())
  422. return;
  423. gMain.state++;
  424. break;
  425. case 5:
  426. LoadPalette(gUnknown_0839F5FC, 0x80, 0x40);
  427. CpuCopy16(gUnknown_0839F63C, (void *)0x0600BEE0, 0x40);
  428. gMain.state++;
  429. break;
  430. case 6:
  431. BeginNormalPaletteFade(-1, 0, 0x10, 0, 0);
  432. gMain.state++;
  433. break;
  434. case 7:
  435. {
  436. u16 savedIme;
  437.  
  438. REG_WIN0H = 0;
  439. REG_WIN0V = 0;
  440. REG_WIN1H = 0;
  441. REG_WIN1V = 0;
  442. REG_WININ = 0x1111;
  443. REG_WINOUT = 0x31;
  444. REG_BLDCNT = 0xE1;
  445. REG_BLDALPHA = 0;
  446. REG_BLDY = 7;
  447. savedIme = REG_IME;
  448. REG_IME = 0;
  449. REG_IE |= INTR_FLAG_VBLANK;
  450. REG_IME = savedIme;
  451. REG_DISPSTAT |= DISPSTAT_VBLANK_INTR;
  452. SetVBlankCallback(VBlankCB);
  453. REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | DISPCNT_OBJ_ON |
  454. DISPCNT_WIN0_ON | DISPCNT_WIN1_ON;
  455. gMain.state++;
  456. break;
  457. }
  458. case 8:
  459. {
  460. u8 taskId = CreateTask(Task_SpeedchoiceMenuFadeIn, 0);
  461.  
  462. gStoredPageNum = 1;
  463.  
  464. // set default options and current selection.
  465. gLocalSpeedchoiceConfig.trueIndex = 0;
  466. gLocalSpeedchoiceConfig.pageIndex = 0;
  467. gLocalSpeedchoiceConfig.pageNum = 1; // pages are indexed by 1.
  468.  
  469. InitializeOptionChoicesAndConfig(taskId);
  470.  
  471. MenuDrawTextWindow(2, 0, 27, 3);
  472. MenuPrint(gSpeedchoiceTextHeader, 4, 1); // draw header.
  473. MenuPrint(gSpeedchoiceCurrentVersion, 22, 1);
  474.  
  475. DrawPageOptions(taskId, gLocalSpeedchoiceConfig.pageNum);
  476. DrawPageChoice(gLocalSpeedchoiceConfig.pageNum);
  477.  
  478. HighlightHeaderBox();
  479. HighlightOptionMenuItem(gLocalSpeedchoiceConfig.pageIndex);
  480. PlayBGM(BGM_CONLOBBY);
  481. gMain.state++;
  482. break;
  483. }
  484. case 9:
  485. SetMainCallback2(MainCB);
  486. return;
  487. }
  488. }
  489.  
  490. static void Task_SpeedchoiceMenuFadeIn(u8 taskId)
  491. {
  492. if (!gPaletteFade.active)
  493. {
  494. gTasks[taskId].func = Task_SpeedchoiceMenuProcessInput;
  495. }
  496. }
  497.  
  498. // lastOrFirst, TRUE means last, FALSE means first available
  499. u8 GetPageOptionTrueIndex(bool8 lastOrFirst, u8 page)
  500. {
  501. if(lastOrFirst == LAST)
  502. return (OPTIONS_PER_PAGE * (page - 1)) + GetPageDrawCount(page) - 1;
  503. else
  504. return (OPTIONS_PER_PAGE * (page - 1));
  505. }
  506.  
  507. // same as above, but return the page index.
  508. u8 GetPageOptionPageIndex(bool8 lastOrFirst, u8 page)
  509. {
  510. return (lastOrFirst) ? GetPageDrawCount(page) : 1;
  511. }
  512.  
  513. //This version uses addition '+' instead of OR '|'.
  514. #define WIN_RANGE_(a, b) (((a) << 8) + (b))
  515.  
  516. static void HighlightOptionMenuItem(u8 index)
  517. {
  518. REG_WIN1H = WIN_RANGE(24, 215);
  519. REG_WIN1V = WIN_RANGE_(index * 16 + 40, index * 16 + 56);
  520. }
  521.  
  522. // used for all but page.
  523. static void DrawGeneralChoices(struct SpeedchoiceOption *option, u8 selection, u8 row)
  524. {
  525. u8 styles[MAX_CHOICES];
  526. u8 numChoices = option->optionCount;
  527. u8 i;
  528.  
  529. styles[0] = 0xF;
  530. styles[1] = 0xF;
  531. styles[2] = 0xF;
  532. styles[3] = 0xF;
  533. styles[4] = 0xF;
  534. styles[5] = 0xF;
  535. styles[selection] = 0x8;
  536.  
  537. for(i = 0; i < numChoices; i++)
  538. {
  539. s16 x = option->options[i].x;
  540. s16 y = 40 + (row * 16);
  541. u8 *string = option->options[i].string;
  542.  
  543. DrawOptionMenuChoice(string, x, y, styles[i]);
  544. }
  545. }
  546.  
  547. #define CHAR_0 0xA1 //Character code of '0' character
  548.  
  549. static void DrawPageChoice(u8 selection)
  550. {
  551. u8 text[5];
  552.  
  553. memcpy(text, gSystemText_Terminator, 3); // copy the palette control code.
  554.  
  555. // there are no more than 10 pages, so format it as a single digit.
  556. text[3] = selection + CHAR_0;
  557. text[4] = EOS;
  558.  
  559. MenuPrint(text, 8, MENUOPTIONCOORDS(5));
  560. }
  561.  
  562. void Task_WaitForTooltip(u8 taskId)
  563. {
  564. if (MenuUpdateWindowText())
  565. {
  566. if (gMain.newKeys & A_BUTTON)
  567. {
  568. MenuZeroFillWindowRect(2, 14, 27, 19);
  569. HighlightOptionMenuItem(gLocalSpeedchoiceConfig.pageIndex);
  570. DrawPageOptions(taskId, gLocalSpeedchoiceConfig.pageNum);
  571. DrawPageChoice(gLocalSpeedchoiceConfig.pageNum);
  572. gTasks[taskId].func = Task_SpeedchoiceMenuProcessInput;
  573. }
  574. }
  575. }
  576.  
  577. static void DrawTooltip(u8 taskId, struct SpeedchoiceOption *option)
  578. {
  579. REG_WIN1H = WIN_RANGE(1, 241);
  580. REG_WIN1V = WIN_RANGE_(114, 160);
  581. MenuDrawTextWindow(2, 14, 27, 19);
  582. MenuPrintMessage(option->tooltip, 3, 15);
  583. gTasks[taskId].func = Task_WaitForTooltip;
  584. }
  585.  
  586. static void Task_SpeedchoiceMenuProcessInput(u8 taskId)
  587. {
  588. if (gMain.newKeys & A_BUTTON)
  589. {
  590. if (gLocalSpeedchoiceConfig.trueIndex == START_GAME) // START_GAME
  591. {
  592. gTasks[taskId].func = Task_SpeedchoiceMenuSave;
  593. }
  594. }
  595. else if (gMain.newKeys & SELECT_BUTTON) // do tooltip.
  596. {
  597. if(gLocalSpeedchoiceConfig.trueIndex <= CURRENT_OPTIONS_NUM)
  598. DrawTooltip(taskId, (struct SpeedchoiceOption *)&SpeedchoiceOptions[gLocalSpeedchoiceConfig.trueIndex]);
  599. }
  600. else if (gMain.newKeys & DPAD_UP)
  601. {
  602. if(gLocalSpeedchoiceConfig.trueIndex == PAGE)
  603. gLocalSpeedchoiceConfig.trueIndex = GetPageOptionTrueIndex(LAST, gLocalSpeedchoiceConfig.pageNum); // set the entry to the last available option.
  604. else if(gLocalSpeedchoiceConfig.trueIndex > GetPageOptionTrueIndex(FIRST, gLocalSpeedchoiceConfig.pageNum))
  605. gLocalSpeedchoiceConfig.trueIndex--;
  606. else
  607. gLocalSpeedchoiceConfig.trueIndex = START_GAME;
  608.  
  609. SetPageIndexFromTrueIndex(taskId, gLocalSpeedchoiceConfig.trueIndex);
  610. HighlightOptionMenuItem(gLocalSpeedchoiceConfig.pageIndex);
  611. }
  612. else if (gMain.newKeys & DPAD_DOWN)
  613. {
  614. if(gLocalSpeedchoiceConfig.trueIndex == GetPageOptionTrueIndex(LAST, gLocalSpeedchoiceConfig.pageNum))
  615. gLocalSpeedchoiceConfig.trueIndex = PAGE; // you are at the last option when you press down, go to page index.
  616. else if(gLocalSpeedchoiceConfig.trueIndex == START_GAME)
  617. gLocalSpeedchoiceConfig.trueIndex = GetPageOptionTrueIndex(FIRST, gLocalSpeedchoiceConfig.pageNum);
  618. else
  619. gLocalSpeedchoiceConfig.trueIndex++;
  620.  
  621. SetPageIndexFromTrueIndex(taskId, gLocalSpeedchoiceConfig.trueIndex);
  622. HighlightOptionMenuItem(gLocalSpeedchoiceConfig.pageIndex);
  623. }
  624. else
  625. {
  626. u8 trueIndex = gLocalSpeedchoiceConfig.trueIndex;
  627. u8 selection = gLocalSpeedchoiceConfig.optionConfig[trueIndex];
  628. switch (trueIndex)
  629. {
  630. default:
  631. if(trueIndex < CURRENT_OPTIONS_NUM)
  632. {
  633. gLocalSpeedchoiceConfig.optionConfig[trueIndex] = ProcessGeneralInput((struct SpeedchoiceOption *)&SpeedchoiceOptions[trueIndex], selection);
  634. DrawGeneralChoices((struct SpeedchoiceOption *)&SpeedchoiceOptions[trueIndex], selection, gLocalSpeedchoiceConfig.pageIndex);
  635. }
  636. break;
  637. case PAGE:
  638. gLocalSpeedchoiceConfig.pageNum = ProcessGeneralInputIndexedToOne((struct SpeedchoiceOption *)&SpeedchoiceOptions[CURRENT_OPTIONS_NUM], gLocalSpeedchoiceConfig.pageNum);
  639. DrawPageChoice(gLocalSpeedchoiceConfig.pageNum);
  640. if(gLocalSpeedchoiceConfig.pageNum != gStoredPageNum) // only redraw if the page updates!
  641. {
  642. PlaySE(SE_WIN_OPEN);
  643. DrawPageOptions(taskId, gLocalSpeedchoiceConfig.pageNum);
  644. gStoredPageNum = gLocalSpeedchoiceConfig.pageNum; // update the page.
  645. }
  646. break;
  647. case START_GAME:
  648. break;
  649. }
  650. }
  651. }
  652.  
  653. u32 CalculateCheckValue(u8 taskId)
  654. {
  655. u32 checkValue;
  656. u8 i;
  657.  
  658. for(checkValue = 0, i = 0; i < CURRENT_OPTIONS_NUM; i++)
  659. checkValue += gLocalSpeedchoiceConfig.optionConfig[i] << (i + (SpeedchoiceOptions[i].optionCount - 2));
  660.  
  661. // seed RNG with checkValue for more hash-like number.
  662. checkValue = 0x41c64e6d * checkValue + 0x00006073;
  663.  
  664. // xor with randomizer value, if one is present.
  665. checkValue = checkValue ^ gRandomizerCheckValue;
  666.  
  667. // get rid of sign extension.
  668. checkValue = (checkValue << 1) >> 1;
  669.  
  670. return checkValue;
  671. }
  672.  
  673. static void SaveSpeedchoiceOptions(u8 taskId)
  674. {
  675. gSaveBlock2.speedchoiceConfig.bwexp = gLocalSpeedchoiceConfig.optionConfig[BWEXP];
  676. gSaveBlock2.speedchoiceConfig.aqualess = gLocalSpeedchoiceConfig.optionConfig[AQUALESS];
  677. gSaveBlock2.speedchoiceConfig.instantText = gLocalSpeedchoiceConfig.optionConfig[INSTANTTEXT];
  678. gSaveBlock2.speedchoiceConfig.spinners = gLocalSpeedchoiceConfig.optionConfig[SPINNERS];
  679. gSaveBlock2.speedchoiceConfig.maxVision = gLocalSpeedchoiceConfig.optionConfig[MAXVISION];
  680. gSaveBlock2.speedchoiceConfig.nerfRoxanne = gLocalSpeedchoiceConfig.optionConfig[NERFROXANNE];
  681. gSaveBlock2.speedchoiceConfig.superbike = gLocalSpeedchoiceConfig.optionConfig[SUPERBIKE];
  682. gSaveBlock2.speedchoiceConfig.newwildencounters = gLocalSpeedchoiceConfig.optionConfig[NEWWILDENC];
  683. gSaveBlock2.speedchoiceConfig.earlyfly = gLocalSpeedchoiceConfig.optionConfig[EARLYFLY];
  684. gSaveBlock2.speedchoiceConfig.runEverywhere = gLocalSpeedchoiceConfig.optionConfig[RUN_EVERYWHERE];
  685. gSaveBlock2.speedchoiceConfig.memeIsland = gLocalSpeedchoiceConfig.optionConfig[MEME_ISLAND];
  686. gSaveBlock2.speedchoiceConfig.emeraldDoubles = gLocalSpeedchoiceConfig.optionConfig[EMERALD_DOUBLES];
  687. gSaveBlock2.speedchoiceConfig.glitchRod = gLocalSpeedchoiceConfig.optionConfig[GLITCH_ROD];
  688. gSaveBlock2.speedchoiceConfig.betterMarts = gLocalSpeedchoiceConfig.optionConfig[BETTER_MARTS];
  689. }
  690.  
  691. static void Task_SpeedchoiceMenuSave(u8 taskId)
  692. {
  693. // calculate check Value. a pass into a local variable is required for ConvertIntToHexStringN to not raise a warning, even though the local variable is unused.
  694. ConvertIntToHexStringN(gStringVar1, CalculateCheckValue(taskId), STR_CONV_MODE_LEADING_ZEROS, 8);
  695.  
  696. gTasks[taskId].func = Task_DrawYesNoText;
  697. }
  698.  
  699. static void HighlightYesNoMenu(void)
  700. {
  701. REG_WIN0H = WIN_RANGE(168, 242);
  702. REG_WIN0V = WIN_RANGE_(64, 112);
  703. }
  704.  
  705. static void HighlightTextBox(void)
  706. {
  707. REG_WIN1H = WIN_RANGE(1, 241);
  708. REG_WIN1V = WIN_RANGE(114, 160);
  709. }
  710.  
  711. static void Task_SpeedchoiceMenuFadeOut(u8 taskId)
  712. {
  713. if(!gPaletteFade.active)
  714. {
  715. gTasks[taskId].func = Task_NewGameSpeech1;
  716. }
  717. }
  718.  
  719. static void Task_HandleYesNoStartGame(u8 taskId)
  720. {
  721. switch (ProcessMenuInputNoWrap_())
  722. {
  723. case 0: // YES
  724. PlayBGM(BGM_STOP);
  725. PlaySE(SE_SELECT);
  726. SaveSpeedchoiceOptions(taskId);
  727. BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
  728. gTasks[taskId].func = Task_SpeedchoiceMenuFadeOut;
  729. break;
  730. case -1:
  731. case 1: // NO
  732. PlaySE(SE_SELECT);
  733. REG_WIN1H = WIN_RANGE(0, 0); // unhighlight the text box and YES/NO window before redrawing.
  734. REG_WIN1V = WIN_RANGE(0, 0);
  735. REG_WIN0H = WIN_RANGE(0, 0);
  736. REG_WIN0V = WIN_RANGE_(0, 0);
  737. DrawPageOptions(taskId, gLocalSpeedchoiceConfig.pageNum);
  738. DrawPageChoice(gLocalSpeedchoiceConfig.pageNum);
  739. HighlightOptionMenuItem(6);
  740. HighlightHeaderBox();
  741. gTasks[taskId].func = Task_SpeedchoiceMenuProcessInput;
  742. break;
  743. }
  744. }
  745.  
  746. static void Task_AskToStartGame(u8 taskId)
  747. {
  748. if (MenuUpdateWindowText())
  749. {
  750. DisplayYesNoMenu(21, 8, 1);
  751. HighlightYesNoMenu();
  752. gTasks[taskId].func = Task_HandleYesNoStartGame;
  753. }
  754. }
  755.  
  756. static void Task_DrawYesNoText(u8 taskId)
  757. {
  758. MenuDrawTextWindow(2, 14, 27, 19);
  759. HighlightTextBox();
  760. MenuPrint(gSpeedchoiceStartGameText, 3, 15);
  761.  
  762. gTasks[taskId].func = Task_AskToStartGame;
  763. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement