gamegenie.c 21 KB

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