1 /* FCE Ultra - NES/Famicom Emulator
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Xodnizel
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "../../driver.h"
25 static void GetString(char *s, int max)
38 /* Get unsigned 16-bit integer from stdin in hex. */
39 static uint32 GetH16(unsigned int def)
47 sscanf(buf+1,"%04x",&def);
49 sscanf(buf,"%04x",&def);
53 /* Get unsigned 8-bit integer from stdin in decimal. */
54 static uint8 Get8(unsigned int def)
61 sscanf(buf,"%u",&def);
65 static int GetI(int def)
72 sscanf(buf,"%d",&def);
76 static int GetYN(int def)
79 printf("(Y/N)[%s]: ",def?"Y":"N");
81 if(buf[0]=='y' || buf[0]=='Y')
83 if(buf[0]=='n' || buf[0]=='N')
93 static int listids[16];
97 void BeginListShow(void)
104 /* Hmm =0 for in list choices, hmm=1 for end of list choices. */
105 /* Return equals 0 to continue, -1 to stop, otherwise a number. */
106 int ListChoice(int hmm)
115 printf(" <'Enter' to continue, (S)top, or enter a number.> ");
117 if(buf[0]=='s' || buf[0]=='S') return(-1);
118 if(buf[0]=='\n') return(0);
119 if(!sscanf(buf,"%d",&num))
121 if(num<1) goto tryagain;
129 printf(" <'Enter' to make no selection or enter a number.> ");
131 if(buf[0]=='\n') return(0);
132 if(!sscanf(buf,"%d",&num))
134 if(num<1) goto tryagain2;
139 int EndListShow(void)
144 if(r>0 && r<=listcount)
145 listsel=listids[r-1];
150 /* Returns 0 to stop listing, 1 to continue. */
151 int AddToList(char *text, uint32 id)
157 if(t==-1) return(0); // Stop listing.
160 listsel=listids[t-1];
166 listids[listcount]=id;
167 printf("%2d) %s\n",listcount+1,text);
177 typedef struct MENU {
180 int type; // 0 for menu, 1 for function.
183 static void SetOC(void)
185 FCEUI_CheatSearchSetCurrentAsOriginal();
188 static void UnhideEx(void)
190 FCEUI_CheatSearchShowExcluded();
193 static void ToggleCheat(int num)
195 printf("Cheat %d %sabled.\n",1+num,
196 FCEUI_ToggleCheat(num)?"en":"dis");
199 static void ModifyCheat(int num)
211 FCEUI_GetCheat(num, &name, &A, &V, &compare, &s, &type);
213 printf("Name [%s]: ",name);
216 /* This obviously doesn't allow for cheats with no names. Bah. Who wants
217 nameless cheats anyway...
221 name=buf; // Change name when FCEUI_SetCheat() is called.
223 name=0; // Don't change name when FCEUI_SetCheat() is called.
225 printf("Address [$%04x]: ",(unsigned int)A);
228 printf("Value [%03d]: ",(unsigned int)V);
231 printf("Compare [%3d]: ",compare);
232 compare=GetI(compare);
234 printf("Type(0=Old Style, 1=Read Substitute) [%1d]: ",type);
237 printf("Enable [%s]: ",s?"Y":"N");
239 if(t=='Y' || t=='y') s=1;
240 else if(t=='N' || t=='n') s=0;
242 FCEUI_SetCheat(num,name,A,V,compare,s,type);
246 static void AddCheatGGPAR(int which)
252 char name[256],code[256];
260 printf("Add cheat \"%s\" for code \"%s\"?",name,code);
265 if(!FCEUI_DecodePAR(code,&A,&V,&C,&type))
267 puts("Invalid Game Genie code.");
273 if(!FCEUI_DecodeGG(code,&A,&V,&C))
275 puts("Invalid Game Genie code.");
281 if(FCEUI_AddCheat(name,A,V,C,type))
282 puts("Cheat added.");
284 puts("Error adding cheat.");
288 static void AddCheatGG(void)
293 static void AddCheatPAR(void)
298 static void AddCheatParam(uint32 A, uint8 V)
304 printf("Address [$%04x]: ",(unsigned int)A);
306 printf("Value [%03d]: ",(unsigned int)V);
308 printf("Add cheat \"%s\" for address $%04x with value %03d?",name,(unsigned int)A,(unsigned int)V);
311 if(FCEUI_AddCheat(name,A,V,-1,0))
312 puts("Cheat added.");
314 puts("Error adding cheat.");
318 static void AddCheat(void)
324 static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data)
330 sprintf(tmp,"%s $%04x:%03d:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,compare,name);
332 sprintf(tmp,"%s $%04x:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,name);
335 ret=AddToList(tmp,lid);
340 static void ListCheats(void)
346 FCEUI_ListCheats(clistcallb,0);
351 printf(" <(T)oggle status, (M)odify, or (D)elete this cheat.> ");
353 switch(tolower(tmp[0]))
355 case 't':ToggleCheat(which);
357 case 'd':if(!FCEUI_DelCheat(which))
358 puts("Error deleting cheat!");
360 puts("Cheat has been deleted.");
362 case 'm':ModifyCheat(which);
368 static void ResetSearch(void)
370 FCEUI_CheatSearchBegin();
374 static int srescallb(uint32 a, uint8 last, uint8 current, void *data)
377 sprintf(tmp, "$%04x:%03d:%03d",(unsigned int)a,(unsigned int)last,(unsigned int)current);
378 return(AddToList(tmp,a));
381 static void ShowRes(void)
383 int n=FCEUI_CheatSearchGetCount();
384 printf(" %d results:\n",n);
389 FCEUI_CheatSearchGet(srescallb,0);
392 AddCheatParam(which,0);
396 static int ShowShortList(char *moe[], int n, int def)
404 printf("%d) %s\n",x+1,moe[x]);
405 puts("D) Display List");
408 printf("\nSelection [%d]> ",def+1);
409 fgets(tmp,256,stdin);
421 puts("Invalid selection.");
426 static void DoSearch(void)
428 static int v1=0,v2=0;
430 char *m[6]={"O==V1 && C==V2","O==V1 && |O-C|==V2","|O-C|==V2","O!=C","Value decreased","Value increased"};
431 printf("\nSearch Filter:\n");
433 method=ShowShortList(m,6,method);
436 printf("V1 [%03d]: ",v1);
441 printf("V2 [%03d]: ",v2);
444 FCEUI_CheatSearchEnd(method,v1,v2);
445 puts("Search completed.\n");
449 static MENU NewCheatsMenu[]={
450 {"Add Cheat",(void *)AddCheat,1},
451 {"Reset Search",(void *)ResetSearch,1},
452 {"Do Search",(void *)DoSearch,1},
453 {"Set Original to Current",(void *)SetOC,1},
454 {"Unhide Excluded",(void *)UnhideEx,1},
455 {"Show Results",(void *)ShowRes,1},
456 {"Add Game Genie Cheat",(void *)AddCheatGG,1},
457 {"Add PAR Cheat",(void *)AddCheatPAR,1},
461 static MENU MainMenu[]={
462 {"List Cheats",(void *)ListCheats,1},
463 {"New Cheats...",(void *)NewCheatsMenu,0},
467 static void DoMenu(MENU *men)
476 printf("%d) %s\n",x+1,men[x].text);
479 puts("D) Display Menu\nX) Return to Previous\n");
496 else if(sscanf(buf,"%d",&c))
498 if(c>x) goto invalid;
501 void (*func)(void)=(void(*)())men[c-1].action;
505 DoMenu((MENU*)men[c-1].action); /* Mmm...recursivey goodness. */
511 puts("Invalid command.\n");
518 void DoConsoleCheatConfig(void)
520 MENU *curmenu=MainMenu;