gamegenie.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. /*
  2. * Code Breaker plugin - The peTI-NESulator Project
  3. * gamegenie.c: Hack your games with unlimited lives of add new powers!
  4. *
  5. * Created by Manoël Trapier.
  6. * Copyright (c) 2002-2019 986-Studio.
  7. *
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <os_dependent.h>
  12. #define __TINES_PLUGINS__
  13. #include <plugins/manager.h>
  14. #undef __TINES_PLUGINS_
  15. #include <memory/manager.h>
  16. #include <types.h>
  17. #if 0
  18. typedef enum gg_States_
  19. {
  20. GG_S00_MAIN_STATE = 0,
  21. GG_S01_SEARCH_VALUE,
  22. GG_S02_SEARCH_BAR
  23. } gg_States;
  24. /* Actual State Machine state */
  25. gg_States gg_state = GG_S00_MAIN_STATE;
  26. /* Own representation of memory */
  27. uint8_t gg_MainRAM[0x800];
  28. uint8_t gg_OldMainRAM[0x800];
  29. uint8_t gg_SRAM[0x2000];
  30. /* Field used to now which uint8_t are currently marked as pertinent or not */
  31. uint8_t gg_use_MainRAM[0x800];
  32. uint8_t gg_use_SRAM[0x2000];
  33. int gg_ResultNumber;
  34. uint8_t gg_PatchUsed[10];
  35. uint8_t gg_PatchedPage[10];
  36. uint8_t gg_PatchedAddr[10];
  37. uint8_t gg_PatchedValue[10];
  38. func_rdhook gg_rdhookPtr[10];
  39. #define GG_RDHOOKPATCH(d) \
  40. uint8_t gg_RdHookPatch##d(uint8_t addr) \
  41. { \
  42. if (addr == gg_PatchedAddr[d]) \
  43. { \
  44. return gg_PatchedValue[d]; \
  45. } \
  46. else \
  47. { \
  48. if (gg_rdhookPtr[d] != NULL) \
  49. return gg_rdhookPtr[d](addr); \
  50. else \
  51. return (get_page_ptr(gg_PatchedPage[d])[addr]); \
  52. } \
  53. }
  54. #define GG_MAX_PATCH 10
  55. /* Defines the rdhook patches */
  56. GG_RDHOOKPATCH(0)
  57. GG_RDHOOKPATCH(1)
  58. GG_RDHOOKPATCH(2)
  59. GG_RDHOOKPATCH(3)
  60. GG_RDHOOKPATCH(4)
  61. GG_RDHOOKPATCH(5)
  62. GG_RDHOOKPATCH(6)
  63. GG_RDHOOKPATCH(7)
  64. GG_RDHOOKPATCH(8)
  65. GG_RDHOOKPATCH(9)
  66. void gg_SetPatch(int id, uint8_t page, uint8_t addr, uint8_t value)
  67. {
  68. func_rdhook fptr;
  69. if (id >= GG_MAX_PATCH)
  70. {
  71. return;
  72. }
  73. /* Set parameters for the patch */
  74. if (gg_PatchUsed[id] == 0x00)
  75. {
  76. gg_rdhookPtr[id] = get_page_rdhook(page);
  77. }
  78. gg_PatchedPage[id] = page;
  79. gg_PatchedAddr[id] = addr;
  80. gg_PatchedValue[id] = value;
  81. gg_PatchUsed[id] = 0xFF;
  82. /* Set a ReadHook on the page */
  83. switch (id)
  84. {
  85. default:
  86. case 0:
  87. fptr = gg_RdHookPatch0;
  88. break;
  89. case 1:
  90. fptr = gg_RdHookPatch1;
  91. break;
  92. case 2:
  93. fptr = gg_RdHookPatch2;
  94. break;
  95. case 3:
  96. fptr = gg_RdHookPatch3;
  97. break;
  98. case 4:
  99. fptr = gg_RdHookPatch4;
  100. break;
  101. case 5:
  102. fptr = gg_RdHookPatch5;
  103. break;
  104. case 6:
  105. fptr = gg_RdHookPatch6;
  106. break;
  107. case 7:
  108. fptr = gg_RdHookPatch7;
  109. break;
  110. case 8:
  111. fptr = gg_RdHookPatch8;
  112. break;
  113. case 9:
  114. fptr = gg_RdHookPatch9;
  115. break;
  116. }
  117. set_page_rd_hook(page, fptr);
  118. }
  119. /* Access to the bitmap Buffer */
  120. extern BITMAP *Buffer;
  121. BITMAP *gg_Buffer;
  122. void MessageBox(char *title, char *msg)
  123. {
  124. int sc_w, sc_h;
  125. int box_h, box_t, box_l, box_w;
  126. sc_w = screen->w;
  127. sc_h = screen->h;
  128. gg_Buffer = create_bitmap(sc_w, sc_h);
  129. blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
  130. box_w = text_length(font, title) + 10;
  131. box_w = (box_w > text_length(font, msg)) ? box_w : text_length(font, msg);
  132. box_w += 15 * 2; /*sc_w/2;*/
  133. box_h = 15 * 2 + 10;
  134. /* Set the box center */
  135. box_t = (sc_h - box_h) / 2;
  136. box_l = (sc_w - box_w) / 2;
  137. rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
  138. rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
  139. /* Display the title */
  140. textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
  141. /* Display the message */
  142. textout_centre_ex(gg_Buffer, font, msg, box_w / 2 + box_l, 15 + box_t + 2, 34, 60);
  143. blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
  144. sleep(1);
  145. release_bitmap(gg_Buffer);
  146. }
  147. uint16_t SelectNumber(char *title, char *msg, uint8_t size)
  148. {
  149. int sc_w, sc_h;
  150. int box_h, box_t, box_l, box_w;
  151. char valueText[10];
  152. uint16_t value;
  153. uint8_t digit = 0;
  154. sc_w = screen->w;
  155. sc_h = screen->h;
  156. gg_Buffer = create_bitmap(sc_w, sc_h);
  157. blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
  158. box_w = text_length(font, title) + 10;
  159. box_w = (box_w > text_length(font, msg)) ? box_w : text_length(font, msg);
  160. sprintf(valueText, "0000");
  161. box_w = (box_w > text_length(font, valueText)) ? box_w : text_length(font, msg);
  162. box_w += 15 * 2; /*sc_w/2;*/
  163. box_h = 15 * 2 + 30;
  164. /* Set the box center */
  165. box_t = (sc_h - box_h) / 2;
  166. box_l = (sc_w - box_w) / 2;
  167. value = 0;
  168. while (!key[KEY_ENTER])
  169. {
  170. rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
  171. rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
  172. /* Display the title */
  173. textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
  174. /* Display the message */
  175. textout_centre_ex(gg_Buffer, font, msg, box_w / 2 + box_l, 15 + box_t + 2, 34, 60);
  176. if (size == 2)
  177. {
  178. sprintf(valueText, " %02X", value & 0xFF);
  179. }
  180. else
  181. {
  182. sprintf(valueText, "%04X", value);
  183. }
  184. textout_centre_ex(gg_Buffer, font, valueText, box_w / 2 + box_l, 15 + box_t + 2 + 10, 34, 60);
  185. switch (digit)
  186. {
  187. default:
  188. case 0:
  189. textout_centre_ex(gg_Buffer, font, " ^", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
  190. break;
  191. case 1:
  192. textout_centre_ex(gg_Buffer, font, " ^ ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
  193. break;
  194. case 2:
  195. textout_centre_ex(gg_Buffer, font, " ^ ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
  196. break;
  197. case 3:
  198. textout_centre_ex(gg_Buffer, font, "^ ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
  199. break;
  200. }
  201. blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
  202. if (key[KEY_UP])
  203. {
  204. usleep(100000);
  205. value += ((digit == 0) ? 0x0001 : ((digit == 1) ? 0x0010 : ((digit == 2) ? 0x0100 : 0x1000)));
  206. value &= (size == 2) ? 0xFF : 0xFFFF;
  207. }
  208. if (key[KEY_DOWN])
  209. {
  210. usleep(100000);
  211. value -= ((digit == 0) ? 0x0001 : ((digit == 1) ? 0x0010 : ((digit == 2) ? 0x0100 : 0x1000)));
  212. value &= (size == 2) ? 0xFF : 0xFFFF;
  213. }
  214. if (key[KEY_RIGHT])
  215. {
  216. usleep(100000);
  217. if (digit <= 0)
  218. {
  219. digit = size - 1;
  220. }
  221. else
  222. {
  223. digit--;
  224. }
  225. }
  226. if (key[KEY_LEFT])
  227. {
  228. usleep(100000);
  229. if (digit >= size - 1)
  230. {
  231. digit = 0;
  232. }
  233. else
  234. {
  235. digit++;
  236. }
  237. }
  238. }
  239. release_bitmap(gg_Buffer);
  240. while (key[KEY_ENTER])
  241. {
  242. }
  243. return value;
  244. }
  245. int DispMenu(int itemc, char *itemv[], char *title)
  246. {
  247. //console_printf(Console_Default, "%s(%d, %p, \"%s\");\n", __func__, itemc, itemv, title);
  248. int selection = 0;
  249. int i;
  250. int sc_w, sc_h;
  251. int box_h, box_t, box_l, box_w;
  252. sc_w = screen->w;
  253. sc_h = screen->h;
  254. gg_Buffer = create_bitmap(sc_w, sc_h);
  255. blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
  256. box_w = text_length(font, title) + 10;
  257. for (i = 0 ; i < itemc ; i++)
  258. {
  259. box_w = (box_w > text_length(font, itemv[i])) ? box_w : text_length(font, itemv[i]);
  260. }
  261. box_w += 15 * 2; /*sc_w/2;*/
  262. box_h = 15 * 2 + itemc * 10;
  263. /* Set the box center */
  264. box_t = (sc_h - box_h) / 2;
  265. box_l = (sc_w - box_w) / 2;
  266. while (!key[KEY_ENTER])
  267. {
  268. /* Draw the box and highlight the selected item */
  269. rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
  270. rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
  271. /* Display the title */
  272. textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
  273. /* Display the highlight item */
  274. rectfill(gg_Buffer, box_l + 15, 15 + box_t + (selection * 10), box_l + box_w - 15,
  275. 15 + box_t + (selection * 10) + 10, 34);
  276. textout_centre_ex(gg_Buffer, font, itemv[selection], box_w / 2 + box_l, 15 + box_t + (selection * 10) + 2, 60,
  277. 34);
  278. /* Display other items */
  279. for (i = 0 ; i < itemc ; i++)
  280. {
  281. if (i != selection)
  282. {
  283. textout_centre_ex(gg_Buffer, font, itemv[i], box_w / 2 + box_l, 15 + box_t + (i * 10) + 2, 34, 60);
  284. }
  285. }
  286. /* Blit the screen buffer */
  287. blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
  288. /* Now get the keyboard state */
  289. if (key[KEY_UP])
  290. {
  291. usleep(100000);
  292. if (selection <= 0)
  293. {
  294. selection = itemc - 1;
  295. }
  296. else
  297. {
  298. selection--;
  299. }
  300. }
  301. if (key[KEY_DOWN])
  302. {
  303. usleep(100000);
  304. if (selection >= (itemc - 1))
  305. {
  306. selection = 0;
  307. }
  308. else
  309. {
  310. selection++;
  311. }
  312. }
  313. }
  314. release_bitmap(gg_Buffer);
  315. while (key[KEY_ENTER])
  316. {
  317. }
  318. return selection;
  319. }
  320. uint8_t AskYesNo(char *title)
  321. {
  322. char *YesNo[] = { "No", "Yes" };
  323. return DispMenu(2, YesNo, title);
  324. }
  325. uint8_t gg_CalcChk(uint16_t addr, uint8_t value)
  326. {
  327. int chk = 0x42;
  328. chk += (addr & 0xFF00) >> 8;
  329. chk -= (addr & 0x00FF);
  330. chk += (value & 0x00FF);
  331. return chk;
  332. }
  333. /*
  334. Code is AAAAVVCC where
  335. AAAA = address,
  336. VV = value,
  337. CC = cheksum
  338. */
  339. uint32_t gg_MakeCode(uint16_t addr, uint8_t value)
  340. {
  341. uint32_t code = addr << 16;
  342. code |= (value << 8);
  343. code |= (gg_CalcChk(addr, value) & 0x00FF);
  344. return code ^ 0x246FF53A;
  345. }
  346. uint8_t gg_SelectPatch()
  347. {
  348. char *Items[GG_MAX_PATCH + 1];
  349. char *tmp;
  350. int i;
  351. uint8_t ret;
  352. for (i = 0 ; i < GG_MAX_PATCH ; i++)
  353. {
  354. tmp = (char *)malloc(0x100);
  355. console_printf(Console_Default, "Items[%d]: %p\n", i, tmp);
  356. if (gg_PatchUsed[i] == 0x00)
  357. {
  358. sprintf(tmp, "Patch %d: Not used", i);
  359. }
  360. else
  361. {
  362. sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08lX)",
  363. i, gg_PatchedValue[i], gg_PatchedPage[i], gg_PatchedAddr[i],
  364. gg_MakeCode((gg_PatchedPage[i] << 8) | gg_PatchedAddr[i], gg_PatchedValue[i]));
  365. }
  366. Items[i] = tmp;
  367. }
  368. tmp = (char *)malloc(0x100);
  369. sprintf(tmp, "Return");
  370. Items[GG_MAX_PATCH] = tmp;
  371. ret = DispMenu(GG_MAX_PATCH + 1, Items, "Code Breaker - Select a patch");
  372. for (i = 0 ; i < GG_MAX_PATCH ; i++)
  373. {
  374. free(Items[i]);
  375. }
  376. if (ret == GG_MAX_PATCH)
  377. {
  378. return 0xFF;
  379. }
  380. return ret;
  381. }
  382. void gg_PatchManager()
  383. {
  384. console_printf(Console_Default, "DTC!\n");
  385. }
  386. void gg_InitSearch()
  387. {
  388. uint16_t addr;
  389. for (addr = 0x000 ; addr < 0x800 ; addr++)
  390. {
  391. gg_MainRAM[addr] = ReadMemory((addr & 0xFF00) >> 8, addr & 0x00FF);
  392. gg_use_MainRAM[addr] = 0xFF;
  393. }
  394. gg_ResultNumber = 0x800;
  395. }
  396. typedef enum gg_SearchForMode_
  397. {
  398. GG_SEARCHFOR_LOWER = 0,
  399. GG_SEARCHFOR_HIGHER,
  400. GG_SEARCHFOR_IDENTIC,
  401. GG_SEARCHFOR_DIFFERENT
  402. } gg_SearchForMode;
  403. void gg_SearchForValue(uint8_t value)
  404. {
  405. uint16_t addr;
  406. //uint8_t oldValue;
  407. uint8_t currentValue;
  408. gg_ResultNumber = 0x00;
  409. for (addr = 0x000 ; addr < 0x800 ; addr++)
  410. {
  411. if (gg_use_MainRAM[addr] == 0xFF)
  412. {
  413. /* "Backup" the old ram */
  414. memcpy(gg_OldMainRAM, gg_MainRAM, 0x800);
  415. //oldValue = gg_MainRAM[addr];
  416. currentValue = ReadMemory((addr & 0xFF00) >> 8, addr & 0x00FF);
  417. if (currentValue != value)
  418. { /* This is not the good one ! */
  419. gg_use_MainRAM[addr] = 0x00;
  420. }
  421. else
  422. { /* This can be the good one ! */
  423. gg_ResultNumber++;
  424. gg_MainRAM[addr] = currentValue;
  425. }
  426. }
  427. }
  428. }
  429. void gg_SearchFor(gg_SearchForMode mode)
  430. {
  431. uint16_t addr;
  432. uint8_t oldValue;
  433. uint8_t currentValue;
  434. gg_ResultNumber = 0x00;
  435. for (addr = 0x000 ; addr < 0x800 ; addr++)
  436. {
  437. if (gg_use_MainRAM[addr] == 0xFF)
  438. {
  439. /* "Backup" the old ram */
  440. memcpy(gg_OldMainRAM, gg_MainRAM, 0x800);
  441. oldValue = gg_MainRAM[addr];
  442. currentValue = ReadMemory((addr & 0xFF00) >> 8, addr & 0x00FF);
  443. switch (mode)
  444. {
  445. case GG_SEARCHFOR_LOWER:
  446. if (currentValue >= oldValue)
  447. { /* This is not the good one ! */
  448. gg_use_MainRAM[addr] = 0x00;
  449. }
  450. else
  451. { /* This can be the good one ! */
  452. gg_ResultNumber++;
  453. gg_MainRAM[addr] = currentValue;
  454. }
  455. break;
  456. case GG_SEARCHFOR_HIGHER:
  457. if (currentValue <= oldValue)
  458. { /* This is not the good one ! */
  459. gg_use_MainRAM[addr] = 0x00;
  460. }
  461. else
  462. { /* This can be the good one ! */
  463. gg_ResultNumber++;
  464. gg_MainRAM[addr] = currentValue;
  465. }
  466. break;
  467. case GG_SEARCHFOR_IDENTIC:
  468. if (currentValue != oldValue)
  469. { /* This is not the good one ! */
  470. gg_use_MainRAM[addr] = 0x00;
  471. }
  472. else
  473. { /* This can be the good one ! */
  474. gg_ResultNumber++;
  475. gg_MainRAM[addr] = currentValue;
  476. }
  477. break;
  478. case GG_SEARCHFOR_DIFFERENT:
  479. if (currentValue == oldValue)
  480. { /* This is not the good one ! */
  481. gg_use_MainRAM[addr] = 0x00;
  482. }
  483. else
  484. { /* This can be the good one ! */
  485. gg_ResultNumber++;
  486. gg_MainRAM[addr] = currentValue;
  487. }
  488. break;
  489. }
  490. }
  491. }
  492. }
  493. uint8_t gg_DisplayResults()
  494. {
  495. char *Items[100];
  496. char *tmp;
  497. int i, addr = 0x0000;
  498. uint8_t ret = 0;
  499. uint16_t AddrList[21];
  500. if (gg_ResultNumber > 20)
  501. {
  502. MessageBox("Code Breaker", "Too many results for displaying them!");
  503. }
  504. else
  505. {
  506. for (i = 0 ; i < gg_ResultNumber ; i++)
  507. {
  508. while (gg_use_MainRAM[addr] != 0xFF)
  509. {
  510. addr++;
  511. }
  512. console_printf(Console_Default, "0x%04X [%d]\n", addr, i);
  513. tmp = (char *)malloc(0x100);
  514. sprintf(tmp, "Patch: %08XAddress 0x%04X - Was: 0x%02X - Actual: 0x%02X",
  515. i,
  516. addr,
  517. gg_OldMainRAM[addr],
  518. gg_MainRAM[addr]);
  519. Items[i] = tmp;
  520. AddrList[i] = addr;
  521. addr++;
  522. }
  523. tmp = (char *)malloc(0x100);
  524. sprintf(tmp, "Return");
  525. Items[i] = tmp;
  526. ret = DispMenu(gg_ResultNumber + 1, Items, "Code Breaker - Search");
  527. if (ret < i)
  528. {
  529. if (AskYesNo("Code Breaker: Apply this patch?"))
  530. {
  531. /* Now patch it ! */
  532. gg_SetPatch(gg_SelectPatch(), (AddrList[ret] & 0xFF00) >> 8, (AddrList[ret] & 0x00FF),
  533. SelectNumber("Code Breaker", "Value to apply:", 2) & 0x00FF);
  534. ret = 1;
  535. }
  536. }
  537. for (i = 0 ; i < gg_ResultNumber + 1 ; i++)
  538. {
  539. free(Items[i]);
  540. }
  541. }
  542. return ret;
  543. }
  544. void gg_Start()
  545. {
  546. char *S00_MenuList[] = { "Search a specific Value", "Search for an Unknown Value", "Enter code",
  547. "Manage Patches", "Exit" };
  548. char *S01_MenuList[] = { "Value is identical", "New Value...", "Value is different",
  549. "Value is greater", "Value is lower", "Result", "Restart", "Exit" };
  550. char *S02_MenuList[] = { "Value is identical", "Value is different", "Value is greater",
  551. "Value is lower", "Result", "Restart", "Exit" };
  552. char Buffer[100];
  553. int ret;
  554. uint8_t value;
  555. uint16_t addr;
  556. switch (gg_state)
  557. {
  558. default:
  559. case GG_S00_MAIN_STATE:
  560. ret = DispMenu(5, S00_MenuList, "Code Breaker - Main");
  561. switch (ret)
  562. {
  563. case 0:
  564. gg_InitSearch();
  565. gg_state = GG_S01_SEARCH_VALUE;
  566. value = SelectNumber("Code Breaker", "Select the value:", 2) & 0x00FF;
  567. gg_SearchForValue(value);
  568. MessageBox("Code Breaker", "Search initialized !");
  569. break;
  570. case 1:
  571. gg_InitSearch();
  572. gg_state = GG_S02_SEARCH_BAR;
  573. MessageBox("Code Breaker", "Search initialized !");
  574. break;
  575. case 2: /* Enter code */
  576. addr = SelectNumber("Code Breaker", "Select the address", 4);
  577. value = SelectNumber("Code Breaker", "Select the value:", 2) & 0x00FF;
  578. if (AskYesNo("Code Breaker: Apply this patch?"))
  579. {
  580. /* Now patch it ! */
  581. gg_SetPatch(gg_SelectPatch(),
  582. (addr & 0xFF00) >> 8, (addr & 0x00FF),
  583. value);
  584. }
  585. break;
  586. case 3: /* Patch manager */
  587. gg_PatchManager();
  588. break;
  589. }
  590. break;
  591. case GG_S01_SEARCH_VALUE:
  592. S01_MENU:
  593. ret = DispMenu(8, S01_MenuList, "Code Breaker - Search");
  594. switch (ret)
  595. {
  596. case 0:
  597. gg_SearchFor(GG_SEARCHFOR_IDENTIC);
  598. //goto S02_MENU;
  599. break;
  600. case 1:
  601. value = SelectNumber("Code Breaker", "Select the value:", 2) & 0x00FF;
  602. gg_SearchForValue(value);
  603. break;
  604. case 2:
  605. gg_SearchFor(GG_SEARCHFOR_DIFFERENT);
  606. //goto S02_MENU;
  607. break;
  608. case 3:
  609. gg_SearchFor(GG_SEARCHFOR_HIGHER);
  610. //goto S02_MENU;
  611. break;
  612. case 4:
  613. gg_SearchFor(GG_SEARCHFOR_LOWER);
  614. //goto S02_MENU;
  615. break;
  616. case 5: /* Results */
  617. if (gg_DisplayResults() == 1)
  618. {
  619. gg_state = GG_S00_MAIN_STATE;
  620. }
  621. else
  622. {
  623. goto S01_MENU;
  624. }
  625. break;
  626. case 6:
  627. if (AskYesNo("Code Breaker: Restart?"))
  628. {
  629. gg_state = GG_S00_MAIN_STATE;
  630. gg_Start();
  631. }
  632. else
  633. {
  634. goto S01_MENU;
  635. }
  636. break;
  637. }
  638. sprintf(Buffer, "Results found: %d", gg_ResultNumber);
  639. MessageBox("Code Breaker", Buffer);
  640. break;
  641. case GG_S02_SEARCH_BAR:
  642. S02_MENU:
  643. ret = DispMenu(7, S02_MenuList, "Code Breaker - Search");
  644. switch (ret)
  645. {
  646. case 0:
  647. gg_SearchFor(GG_SEARCHFOR_IDENTIC);
  648. //goto S02_MENU;
  649. break;
  650. case 1:
  651. gg_SearchFor(GG_SEARCHFOR_DIFFERENT);
  652. //goto S02_MENU;
  653. break;
  654. case 2:
  655. gg_SearchFor(GG_SEARCHFOR_HIGHER);
  656. //goto S02_MENU;
  657. break;
  658. case 3:
  659. gg_SearchFor(GG_SEARCHFOR_LOWER);
  660. //goto S02_MENU;
  661. break;
  662. case 4: /* Results */
  663. if (gg_DisplayResults() == 1)
  664. {
  665. gg_state = GG_S00_MAIN_STATE;
  666. }
  667. else
  668. {
  669. goto S02_MENU;
  670. }
  671. break;
  672. case 5:
  673. if (AskYesNo("Code Breaker: Restart?"))
  674. {
  675. gg_state = GG_S00_MAIN_STATE;
  676. gg_Start();
  677. }
  678. else
  679. {
  680. goto S02_MENU;
  681. }
  682. break;
  683. }
  684. sprintf(Buffer, "Results found: %d", gg_ResultNumber);
  685. MessageBox("Code Breaker", Buffer);
  686. break;
  687. }
  688. }
  689. int gg_Init()
  690. {
  691. int i;
  692. console_printf(Console_Default, "Initializing GG plugin...\n");
  693. plugin_install_keypressHandler('g', gg_Start);
  694. for (i = 0 ; i < GG_MAX_PATCH ; i++)
  695. {
  696. gg_PatchUsed[i] = 0x00;
  697. }
  698. return 0;
  699. }
  700. int gg_Deinit()
  701. {
  702. return 0;
  703. }
  704. #endif