magicmenu.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. //
  2. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  3. // All rights reserved.
  4. //
  5. // This file is part of SDLPAL.
  6. //
  7. // SDLPAL is free software: you can redistribute it and/or modify
  8. // it under the terms of the GNU General Public License as published by
  9. // the Free Software Foundation, either version 3 of the License, or
  10. // (at your option) any later version.
  11. //
  12. // This program is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. // GNU General Public License for more details.
  16. //
  17. // You should have received a copy of the GNU General Public License
  18. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. //
  20. #include "main.h"
  21. static struct MAGICITEM
  22. {
  23. WORD wMagic;
  24. WORD wMP;
  25. BOOL fEnabled;
  26. } rgMagicItem[MAX_PLAYER_MAGICS];
  27. static int g_iNumMagic = 0;
  28. static int g_iCurrentItem = 0;
  29. static WORD g_wPlayerMP = 0;
  30. WORD
  31. PAL_MagicSelectionMenuUpdate(
  32. VOID
  33. )
  34. /*++
  35. Purpose:
  36. Update the magic selection menu.
  37. Parameters:
  38. None.
  39. Return value:
  40. The selected magic. 0 if cancelled, 0xFFFF if not confirmed.
  41. --*/
  42. {
  43. int i, j, k;
  44. BYTE bColor;
  45. //
  46. // Check for inputs
  47. //
  48. if (g_InputState.dwKeyPress & kKeyUp)
  49. {
  50. g_iCurrentItem -= 3;
  51. }
  52. else if (g_InputState.dwKeyPress & kKeyDown)
  53. {
  54. g_iCurrentItem += 3;
  55. }
  56. else if (g_InputState.dwKeyPress & kKeyLeft)
  57. {
  58. g_iCurrentItem--;
  59. }
  60. else if (g_InputState.dwKeyPress & kKeyRight)
  61. {
  62. g_iCurrentItem++;
  63. }
  64. else if (g_InputState.dwKeyPress & kKeyPgUp)
  65. {
  66. g_iCurrentItem -= 3 * 5;
  67. }
  68. else if (g_InputState.dwKeyPress & kKeyPgDn)
  69. {
  70. g_iCurrentItem += 3 * 5;
  71. }
  72. else if (g_InputState.dwKeyPress & kKeyMenu)
  73. {
  74. return 0;
  75. }
  76. //
  77. // Make sure the current menu item index is in bound
  78. //
  79. if (g_iCurrentItem < 0)
  80. {
  81. g_iCurrentItem = 0;
  82. }
  83. else if (g_iCurrentItem >= g_iNumMagic)
  84. {
  85. g_iCurrentItem = g_iNumMagic - 1;
  86. }
  87. //
  88. // Create the box.
  89. //
  90. PAL_CreateBox(PAL_XY(10, 42), 4, 16, 1, FALSE);
  91. if (gpGlobals->lpObjectDesc == NULL)
  92. {
  93. //
  94. // Draw the cash amount.
  95. //
  96. PAL_CreateSingleLineBox(PAL_XY(0, 0), 5, FALSE);
  97. PAL_DrawText(PAL_GetWord(CASH_LABEL), PAL_XY(10, 10), 0, FALSE, FALSE);
  98. PAL_DrawNumber(gpGlobals->dwCash, 6, PAL_XY(49, 14), kNumColorYellow, kNumAlignRight);
  99. //
  100. // Draw the MP of the selected magic.
  101. //
  102. PAL_CreateSingleLineBox(PAL_XY(215, 0), 5, FALSE);
  103. PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH),
  104. gpScreen, PAL_XY(260, 14));
  105. PAL_DrawNumber(rgMagicItem[g_iCurrentItem].wMP, 4, PAL_XY(230, 14),
  106. kNumColorYellow, kNumAlignRight);
  107. PAL_DrawNumber(g_wPlayerMP, 4, PAL_XY(265, 14), kNumColorCyan, kNumAlignRight);
  108. }
  109. else
  110. {
  111. char szDesc[512], *next;
  112. const char *d = PAL_GetObjectDesc(gpGlobals->lpObjectDesc, rgMagicItem[g_iCurrentItem].wMagic);
  113. //
  114. // Draw the magic description.
  115. //
  116. if (d != NULL)
  117. {
  118. k = 3;
  119. strcpy(szDesc, d);
  120. d = szDesc;
  121. while (TRUE)
  122. {
  123. next = strchr(d, '*');
  124. if (next != NULL)
  125. {
  126. *next = '\0';
  127. next++;
  128. }
  129. PAL_DrawText(d, PAL_XY(100, k), DESCTEXT_COLOR, TRUE, FALSE);
  130. k += 16;
  131. if (next == NULL)
  132. {
  133. break;
  134. }
  135. d = next;
  136. }
  137. }
  138. //
  139. // Draw the MP of the selected magic.
  140. //
  141. PAL_CreateSingleLineBox(PAL_XY(0, 0), 5, FALSE);
  142. PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_SLASH),
  143. gpScreen, PAL_XY(45, 14));
  144. PAL_DrawNumber(rgMagicItem[g_iCurrentItem].wMP, 4, PAL_XY(15, 14),
  145. kNumColorYellow, kNumAlignRight);
  146. PAL_DrawNumber(g_wPlayerMP, 4, PAL_XY(50, 14), kNumColorCyan, kNumAlignRight);
  147. }
  148. //
  149. // Draw the texts of the current page
  150. //
  151. i = g_iCurrentItem / 3 * 3 - 3 * 2;
  152. if (i < 0)
  153. {
  154. i = 0;
  155. }
  156. for (j = 0; j < 5; j++)
  157. {
  158. for (k = 0; k < 3; k++)
  159. {
  160. bColor = MENUITEM_COLOR;
  161. if (i >= g_iNumMagic)
  162. {
  163. //
  164. // End of the list reached
  165. //
  166. j = 5;
  167. break;
  168. }
  169. if (i == g_iCurrentItem)
  170. {
  171. if (rgMagicItem[i].fEnabled)
  172. {
  173. bColor = MENUITEM_COLOR_SELECTED;
  174. }
  175. else
  176. {
  177. bColor = MENUITEM_COLOR_SELECTED_INACTIVE;
  178. }
  179. }
  180. else if (!rgMagicItem[i].fEnabled)
  181. {
  182. bColor = MENUITEM_COLOR_INACTIVE;
  183. }
  184. //
  185. // Draw the text
  186. //
  187. PAL_DrawText(PAL_GetWord(rgMagicItem[i].wMagic),
  188. PAL_XY(35 + k * 87, 54 + j * 18), bColor, TRUE, FALSE);
  189. //
  190. // Draw the cursor on the current selected item
  191. //
  192. if (i == g_iCurrentItem)
  193. {
  194. PAL_RLEBlitToSurface(PAL_SpriteGetFrame(gpSpriteUI, SPRITENUM_CURSOR),
  195. gpScreen, PAL_XY(60 + k * 87, 64 + j * 18));
  196. }
  197. i++;
  198. }
  199. }
  200. if (g_InputState.dwKeyPress & kKeySearch)
  201. {
  202. if (rgMagicItem[g_iCurrentItem].fEnabled)
  203. {
  204. j = g_iCurrentItem % 3;
  205. k = (g_iCurrentItem < 3 * 2) ? (g_iCurrentItem / 3) : 2;
  206. j = 35 + j * 87;
  207. k = 54 + k * 18;
  208. PAL_DrawText(PAL_GetWord(rgMagicItem[g_iCurrentItem].wMagic), PAL_XY(j, k),
  209. MENUITEM_COLOR_CONFIRMED, FALSE, TRUE);
  210. return rgMagicItem[g_iCurrentItem].wMagic;
  211. }
  212. }
  213. return 0xFFFF;
  214. }
  215. VOID
  216. PAL_MagicSelectionMenuInit(
  217. WORD wPlayerRole,
  218. BOOL fInBattle,
  219. WORD wDefaultMagic
  220. )
  221. /*++
  222. Purpose:
  223. Initialize the magic selection menu.
  224. Parameters:
  225. [IN] wPlayerRole - the player ID.
  226. [IN] fInBattle - TRUE if in battle, FALSE if not.
  227. [IN] wDefaultMagic - the default magic item.
  228. Return value:
  229. None.
  230. --*/
  231. {
  232. WORD w;
  233. int i, j;
  234. g_iCurrentItem = 0;
  235. g_iNumMagic = 0;
  236. g_wPlayerMP = gpGlobals->g.PlayerRoles.rgwMP[wPlayerRole];
  237. //
  238. // Put all magics of this player to the array
  239. //
  240. for (i = 0; i < MAX_PLAYER_MAGICS; i++)
  241. {
  242. w = gpGlobals->g.PlayerRoles.rgwMagic[i][wPlayerRole];
  243. if (w != 0)
  244. {
  245. rgMagicItem[g_iNumMagic].wMagic = w;
  246. w = gpGlobals->g.rgObject[w].magic.wMagicNumber;
  247. rgMagicItem[g_iNumMagic].wMP = gpGlobals->g.lprgMagic[w].wCostMP;
  248. rgMagicItem[g_iNumMagic].fEnabled = TRUE;
  249. if (rgMagicItem[g_iNumMagic].wMP > g_wPlayerMP)
  250. {
  251. rgMagicItem[g_iNumMagic].fEnabled = FALSE;
  252. }
  253. w = gpGlobals->g.rgObject[rgMagicItem[g_iNumMagic].wMagic].magic.wFlags;
  254. if (fInBattle)
  255. {
  256. if (!(w & kMagicFlagUsableInBattle))
  257. {
  258. rgMagicItem[g_iNumMagic].fEnabled = FALSE;
  259. }
  260. }
  261. else
  262. {
  263. if (!(w & kMagicFlagUsableOutsideBattle))
  264. {
  265. rgMagicItem[g_iNumMagic].fEnabled = FALSE;
  266. }
  267. }
  268. g_iNumMagic++;
  269. }
  270. }
  271. //
  272. // Sort the array
  273. //
  274. for (i = 0; i < g_iNumMagic - 1; i++)
  275. {
  276. BOOL fCompleted = TRUE;
  277. for (j = 0; j < g_iNumMagic - 1 - i; j++)
  278. {
  279. if (rgMagicItem[j].wMagic > rgMagicItem[j + 1].wMagic)
  280. {
  281. struct MAGICITEM t = rgMagicItem[j];
  282. rgMagicItem[j] = rgMagicItem[j + 1];
  283. rgMagicItem[j + 1] = t;
  284. fCompleted = FALSE;
  285. }
  286. }
  287. if (fCompleted)
  288. {
  289. break;
  290. }
  291. }
  292. //
  293. // Place the cursor to the default item
  294. //
  295. for (i = 0; i < g_iNumMagic; i++)
  296. {
  297. if (rgMagicItem[i].wMagic == wDefaultMagic)
  298. {
  299. g_iCurrentItem = i;
  300. break;
  301. }
  302. }
  303. }
  304. WORD
  305. PAL_MagicSelectionMenu(
  306. WORD wPlayerRole,
  307. BOOL fInBattle,
  308. WORD wDefaultMagic
  309. )
  310. /*++
  311. Purpose:
  312. Show the magic selection menu.
  313. Parameters:
  314. [IN] wPlayerRole - the player ID.
  315. [IN] fInBattle - TRUE if in battle, FALSE if not.
  316. [IN] wDefaultMagic - the default magic item.
  317. Return value:
  318. The selected magic. 0 if cancelled.
  319. --*/
  320. {
  321. WORD w;
  322. int i;
  323. DWORD dwTime;
  324. PAL_MagicSelectionMenuInit(wPlayerRole, fInBattle, wDefaultMagic);
  325. PAL_ClearKeyState();
  326. dwTime = SDL_GetTicks();
  327. while (TRUE)
  328. {
  329. PAL_MakeScene();
  330. w = 45;
  331. for (i = 0; i <= gpGlobals->wMaxPartyMemberIndex; i++)
  332. {
  333. PAL_PlayerInfoBox(PAL_XY(w, 165), gpGlobals->rgParty[i].wPlayerRole, 100,
  334. TIMEMETER_COLOR_DEFAULT, FALSE);
  335. w += 78;
  336. }
  337. w = PAL_MagicSelectionMenuUpdate();
  338. VIDEO_UpdateScreen(NULL);
  339. PAL_ClearKeyState();
  340. if (w != 0xFFFF)
  341. {
  342. return w;
  343. }
  344. PAL_ProcessEvent();
  345. while (SDL_GetTicks() < dwTime)
  346. {
  347. PAL_ProcessEvent();
  348. if (g_InputState.dwKeyPress != 0)
  349. {
  350. break;
  351. }
  352. SDL_Delay(5);
  353. }
  354. dwTime = SDL_GetTicks() + FRAME_TIME;
  355. }
  356. return 0; // should not really reach here
  357. }