gamegenie.c 20 KB

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