gamegenie.c 21 KB

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