11 #include <w32api/windows.h>
13 #include <sys/wcefile.h>
19 #define PPU_IGNORE_FIXEDCOLCHANGES (1<<0)
20 #define PPU_IGNORE_WINDOW (1<<1)
21 #define PPU_IGNORE_ADDSUB (1<<2)
22 #define PPU_IGNORE_PALWRITE (1<<3)
23 #define GFX_IGNORE_OBJ (1<<4)
24 #define GFX_IGNORE_BG0 (1<<5)
25 #define GFX_IGNORE_BG1 (1<<6)
26 #define GFX_IGNORE_BG2 (1<<7)
27 #define GFX_IGNORE_BG3 (1<<8)
29 char romDir[MAX_PATH+1];
30 char snesRomDir[MAX_PATH+1];
32 #define ROM_SELECTOR_DEFAULT_FOCUS 3
36 unsigned short cpuSpeedLookup[40]={
46 extern volatile int timer;
47 static int menutileXscroll=0;
48 static int menutileYscroll=0;
49 static int headerDone[4]; // variable that records if header graphics have been rendered or not
50 int quickSavePresent=0;
51 struct ROM_LIST_RECORD
53 char filename[MAX_PATH+1];
57 static struct ROM_LIST_RECORD romList[MAX_ROMS];
58 struct SNES_MENU_OPTIONS snesMenuOptions;
61 char currentRomFilename[MAX_PATH+1]="";
64 int currentEmuMode=EMU_MODE_SNES;
66 char currentWorkingDir[MAX_PATH+1];
67 char snesOptionsDir[MAX_PATH+1];
68 char snesSramDir[MAX_PATH+1];
69 char snesSaveStateDir[MAX_PATH+1];
70 float soundRates[5]={8250.0,11025.0,16500.0,22050.0,44100.0};
71 char menutext[256][50];
73 struct SAVE_STATE saveState[10]; // holds the filenames for the savestate and "inuse" flags
74 char saveStateName[MAX_PATH+MAX_PATH+2]; // holds the last filename to be scanned for save states
76 unsigned char gammaConv[32*29]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
77 0, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, 29, 30, 31,
78 0, 3, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31,
79 0, 4, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 30, 31,
80 0, 6, 8, 10, 11, 12, 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31,
81 0, 7, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
82 0, 8, 10, 12, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, 31, 31,
83 0, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, 30, 30, 31, 31,
84 0, 10, 12, 14, 16, 17, 18, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, 30, 31, 31,
85 0, 11, 13, 15, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31,
86 0, 12, 14, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31,
87 0, 12, 15, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31,
88 0, 13, 16, 17, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31,
89 0, 14, 16, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 31, 31, 31,
90 0, 14, 17, 18, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31,
91 0, 15, 17, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31,
92 0, 16, 18, 19, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31,
93 0, 16, 18, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31,
94 0, 17, 19, 20, 21, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31,
95 0, 17, 19, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31,
96 0, 17, 20, 21, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31,
97 0, 18, 20, 21, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31,
98 0, 18, 20, 22, 23, 23, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, 31,
99 0, 19, 21, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, 31,
100 0, 19, 21, 22, 23, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31,
101 0, 19, 21, 22, 23, 24, 25, 25, 26, 26, 27, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31,
102 0, 20, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31,
103 0, 20, 22, 23, 24, 24, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31,
104 0, 20, 22, 23, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31};
107 void UpdateMenuGraphicsGamma(void)
109 unsigned int currPix=0;
110 unsigned short pixel=0;
112 for(currPix=0;currPix<15360;currPix++)
114 // md 0000 bbb0 ggg0 rrr0
115 // gp rrrr rggg ggbb bbbi
116 pixel=menuHeaderOrig[currPix];
117 R=(pixel>>11)&0x1F; // 0000 0RRR - 3 bits Red
121 // Do gamma correction
122 R=gammaConv[R+(0<<5)];
123 G=gammaConv[G+(0<<5)];
124 B=gammaConv[B+(0<<5)];
126 pixel=MENU_RGB(R,G,B);
127 menuHeader[currPix]=pixel;
129 for(currPix=0;currPix<5120;currPix++)
131 // md 0000 bbb0 ggg0 rrr0
132 // gp rrrr rggg ggbb bbbi
133 pixel=highLightBarOrig[currPix];
134 R=(pixel>>11)&0x1F; // 0000 0RRR - 3 bits Red
138 // Do gamma correction
139 R=gammaConv[R+(0<<5)];
140 G=gammaConv[G+(0<<5)];
141 B=gammaConv[B+(0<<5)];
143 pixel=MENU_RGB(R,G,B);
144 highLightBar[currPix]=pixel;
148 for(currPix=0;currPix<(MENU_TILE_WIDTH*MENU_TILE_HEIGHT);currPix++)
150 // md 0000 bbb0 ggg0 rrr0
151 // gp rrrr rggg ggbb bbbi
152 pixel=menuTileOrig[currPix];
153 R=(pixel>>11)&0x1F; // 0000 0RRR - 3 bits Red
157 // Do gamma correction
158 R=gammaConv[R+(0<<5)];
159 G=gammaConv[G+(0<<5)];
160 B=gammaConv[B+(0<<5)];
162 pixel=MENU_RGB(R,G,B);
163 menuTile[currPix]=pixel;
168 void SnesDefaultMenuOptions(void)
170 // no options file loaded, so set to defaults
171 snesMenuOptions.menuVer=SNES_OPTIONS_VER;
172 snesMenuOptions.frameSkip=0;
173 snesMenuOptions.soundOn = 1;
174 snesMenuOptions.volume=100;
175 memset(snesMenuOptions.padConfig,0xFF,sizeof(snesMenuOptions.padConfig));
176 snesMenuOptions.showFps=1;
177 snesMenuOptions.gamma=0;
178 snesMenuOptions.soundRate=2;
179 snesMenuOptions.cpuSpeed=19;
182 int LoadMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage)
184 char fullFilename[MAX_PATH+MAX_PATH+1];
185 char _filename[MAX_PATH+1];
186 char _ext[MAX_PATH+1];
191 sprintf(text,"Loading...");
192 //Sometimes the on screen messages are not required
195 PrintBar(prevFB,240-16);
196 gp_drawString(40,228,strlen(text),text,(unsigned short)MENU_RGB(0,0,0),framebuffer16[prevFB]);
199 SplitFilename(filename, _filename, _ext);
200 sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEP,_filename,ext);
201 stream=fopen(fullFilename,"rb");
204 // File exists do try to load it
205 fseek(stream,0,SEEK_END);
207 if (size>maxsize) size=maxsize;
208 fseek(stream,0,SEEK_SET);
209 fread(optionsmem, 1, size, stream);
219 int SaveMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage)
221 char fullFilename[MAX_PATH+MAX_PATH+1];
222 char _filename[MAX_PATH+1];
223 char _ext[MAX_PATH+1];
227 sprintf(text,"Saving...");
228 //Sometimes the on screen messages are not required
231 PrintBar(prevFB,240-16);
232 gp_drawString(40,228,strlen(text),text,(unsigned short)MENU_RGB(0,0,0),framebuffer16[prevFB]);
235 SplitFilename(filename, _filename, _ext);
236 sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEP,_filename,ext);
237 stream=fopen(fullFilename,"wb");
240 fwrite(optionsmem, 1, maxsize, stream);
251 int DeleteMenuOptions(char *path, char *filename, char *ext, int showMessage)
253 char fullFilename[MAX_PATH+MAX_PATH+1];
254 char _filename[MAX_PATH+1];
255 char _ext[MAX_PATH+1];
258 sprintf(text,"Deleting...");
259 //Sometimes the on screen messages are not required
262 PrintBar(prevFB,240-16);
263 gp_drawString(40,228,strlen(text),text,(unsigned short)MENU_RGB(0,0,0),framebuffer16[prevFB]);
266 SplitFilename(filename, _filename, _ext);
267 sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEP,_filename,ext);
268 remove(fullFilename);
279 static void WaitForButtonsUp(void)
291 if (Inp.held[j]) z=1;
301 // wait for keys to be released
302 for(i=0;i<100;i++) // deal with keybounce by checking a few times
310 if (Inp.held[j]) z=1;
316 for(i=0;i<100;i++) // deal with keybounce by checking a few times
324 if (Inp.held[j]) z=1;
330 #if defined (__GP2X__)
334 gp_setFramebuffer(currFB,1);
339 #if defined (__GIZ__)
343 gp_setFramebuffer(currFB,0);
346 void SplitFilename(char *wholeFilename, char *filename, char *ext)
348 int len=strlen(wholeFilename);
353 //Check given string is not null
361 if (wholeFilename[i]=='.')
370 memcpy(filename,wholeFilename,y);
371 filename[y]=0; // change "." to zero to end string
372 memcpy(ext,wholeFilename+y+1,len-(y+1));
373 //ext[len-(y+1)+1]=0;
378 strcpy(filename,wholeFilename);
382 //Ensures all directory seperators are valid for system
383 void CheckDirSep(char *path)
386 char dirSepBad[2]={DIR_SEP_BAD};
387 char dirSep[2]={DIR_SEP};
388 for(i=0;i<strlen(path);i++)
390 if(path[i] == dirSepBad[0]) path[i]=dirSep[0];
395 int MenuMessageBox(char *message1,char *message2,char *message3,int mode)
403 if (Inp.repeat[INP_BUTTON_UP])
407 if (Inp.repeat[INP_BUTTON_DOWN])
411 if ((Inp.held[INP_BUTTON_MENU_SELECT]==1) || (Inp.held[INP_BUTTON_MENU_CANCEL]==1))
417 len=strlen(message1);
419 gp_drawString(8,50,len,message1,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
420 len=strlen(message2);
422 gp_drawString(8,60,len,message2,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
423 len=strlen(message3);
425 gp_drawString(8,70,len,message3,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
428 case 0: // yes no input
431 PrintBar(currFB, 120-4);
432 gp_drawString(8,120,3,"YES",(unsigned short)MENU_RGB(0,0,0),framebuffer16[currFB]);
433 gp_drawString(8,140,2,"NO",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
437 PrintBar(currFB, 140-4);
438 gp_drawString(8,120,3,"YES",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
439 gp_drawString(8,140,2,"NO",(unsigned short)MENU_RGB(0,0,0),framebuffer16[currFB]);
450 int deleterom(int romindex)
452 char text[MAX_PATH+1];
453 char fullfilename[MAX_PATH+MAX_PATH+1];
461 sprintf(text,"Deleting Rom..");
462 gp_drawString(8,50,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[prevFB]);
464 sprintf(text,"%s",romList[romindex].filename);
467 gp_drawString(0,60,x,text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[prevFB]);
469 sprintf(fullfilename,"%s%s%s",romDir,DIR_SEP,romList[romindex].filename);
470 remove(fullfilename);
473 sprintf(text,"Updating Rom List..");
474 gp_drawString(8,70,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[prevFB]);
475 for(x=romindex;x<romCount;x++)
477 strcpy(romList[x].filename, romList[x+1].filename);
478 romList[x].type = romList[x+1].type;
485 static int tileCounter=0;
486 void PrintTile(int flip)
490 unsigned short *framebuffer1 = framebuffer16[flip]+(48*320);
491 unsigned short *graphics1 = NULL;
494 y2=(menutileYscroll*MENU_TILE_WIDTH);
495 graphics1 = menuTile+y2;
496 for (y=0; y<(240-48); y++)
498 for (x=0; x<320; x++)
500 *framebuffer1++ = graphics1[x2];
502 x2&=(MENU_TILE_WIDTH-1);
505 y2&=((MENU_TILE_HEIGHT*MENU_TILE_WIDTH)-1);
506 graphics1=menuTile+y2;
514 if(menutileXscroll>=MENU_TILE_WIDTH) menutileXscroll=0;
517 if(menutileYscroll>=MENU_TILE_HEIGHT) menutileYscroll=0;
522 void PrintTitle(int flip)
524 unsigned short *framebuffer = (unsigned short*)framebuffer16[flip];
525 unsigned short *graphics = (unsigned short*)menuHeader;
528 //If header already drawn for this layer exit
529 if (headerDone[flip]) return;
533 for (x=0; x<320; x++)
535 *framebuffer++ = *graphics++;
539 sprintf(text,"%s",DRSNES_VERSION);
540 gp_drawString(175,15,strlen(text),text,(unsigned short)MENU_RGB(0,0,31),framebuffer16[flip]);
541 headerDone[currFB] = 1;
544 void PrintBar(int flip, unsigned int givenY)
546 unsigned int *framebuffer1 = NULL;
547 unsigned int *graphics1 = (unsigned int *)highLightBar;
550 framebuffer1 = (unsigned int*)framebuffer16[flip]+(givenY*160);
553 for (x=0; x<160; x++)
555 *framebuffer1++ = *graphics1++;
560 static int StringCompare(char *string1, char *string2)
568 // check for string end
570 if ((c1 == 0) && (c2 == 0)) return 0;
571 if (c1 == 0) return 1;
572 if (c2 == 0) return -1;
574 if ((c1 >= 0x61)&&(c1<=0x7A)) c1-=0x20;
575 if ((c2 >= 0x61)&&(c2<=0x7A)) c2-=0x20;
586 static BOOL CharToWChar(wchar_t *wc, char *c)
605 char dirCheck[MAX_PATH+1];
607 char _filename[MAX_PATH+1];
608 char _ext[MAX_PATH+1];
611 wchar_t wc[MAX_PATH+1];
613 WIN32_FIND_DATAW fileInfo;
618 gp_drawString(8,120,25,"Getting Directory Info...",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
621 for (i=0;i<MAX_ROMS;i++)
623 romList[i].filename[0] = 0;
626 //Get rom directory details
629 // Now sort the directory details
630 sprintf(romList[0].filename,"Save As Default Directory");
631 sprintf(romList[1].filename,"Back To Main Menu");
632 sprintf(romList[2].filename,"Parent Directory");
633 romList[3].filename[0] = 0;
640 while ((de = readdir(d)))
642 if (de->d_name[0] != '.')
645 if (de->d_type == 4) // Directory
648 sprintf(dirCheck,"%s%s%s",romDir,DIR_SEP,de->d_name);
649 CharToWChar(wc, dirCheck);
650 hTest=FindFirstFileW(wc, &fileInfo);
651 if (fileInfo.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
655 for (i=ROM_SELECTOR_DEFAULT_FOCUS+1;i<=(romCount+1);i++)
657 if (romList[i].filename[0] == 0) // string is empty so shove new value in
659 strcpy(romList[i].filename,de->d_name);
660 romList[i].type=FILE_TYPE_DIRECTORY;//de->d_type;
665 if ((StringCompare(romList[i].filename,de->d_name) > 0) ||
666 (romList[i].type != FILE_TYPE_DIRECTORY))
668 // new entry is lower than current string so move all entries up one and insert
670 for (j=romCount;j>=i;j--)
672 strcpy(romList[j+1].filename,romList[j].filename);
673 romList[j+1].type=romList[j].type;
675 strcpy(romList[i].filename,de->d_name);
676 romList[i].type=FILE_TYPE_DIRECTORY;//de->d_type;
686 // only interested in Zip and SMC files
687 SplitFilename(de->d_name,_filename,_ext);
688 if ((StringCompare(_ext,"zip") == 0) ||
689 (StringCompare(_ext,"smc") == 0) ||
690 (StringCompare(_ext,"sfc") == 0))
692 for (i=ROM_SELECTOR_DEFAULT_FOCUS+1+dirCount;i<=(romCount+1);i++)
694 if (romList[i].filename[0] == 0) // string is empty so shove new value in
696 strcpy(romList[i].filename,de->d_name);
697 romList[i].type=FILE_TYPE_FILE;//de->d_type;
702 if (StringCompare(romList[i].filename,de->d_name) > 0)
704 // new entry is lower than current string so move all entries up one and insert
706 for (j=romCount;j>=i;j--)
708 strcpy(romList[j+1].filename,romList[j].filename);
709 romList[j+1].type=romList[j].type;
711 strcpy(romList[i].filename,de->d_name);
712 romList[i].type=FILE_TYPE_FILE;//de->d_type;
722 if (romCount > MAX_ROMS)
726 sprintf(text,"Max rom limit exceeded! %d max",MAX_ROMS);
727 gp_drawString(8,120,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
728 sprintf(text,"Please reduce number of roms");
729 gp_drawString(8,130,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
742 sprintf(text,"Failed to open directory!");
743 gp_drawString(8,120,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
751 int FileSelect(int mode)
757 unsigned short color=0;
759 int focus=ROM_SELECTOR_DEFAULT_FOCUS;
761 int scanstart=0,scanend=0;
762 char dirSep[2]={DIR_SEP};
763 char dirSepBad[2]={DIR_SEP_BAD};
773 // Change which rom is focused on:
774 if (Inp.repeat[INP_BUTTON_UP])
778 if (Inp.repeat[INP_BUTTON_DOWN])
783 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) {action=0; menuExit=1;}
785 if (Inp.repeat[INP_BUTTON_LEFT] || Inp.repeat[INP_BUTTON_RIGHT] )
787 if (Inp.repeat[INP_BUTTON_LEFT])
792 else if (Inp.repeat[INP_BUTTON_RIGHT])
798 if (focus>romCount-1)
810 if (focus>romCount-1)
821 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
825 case 0: //Save default directory
826 SaveMenuOptions(snesOptionsDir, DEFAULT_ROM_DIR_FILENAME, DEFAULT_ROM_DIR_EXT, romDir, strlen(romDir),1);
827 strcpy(snesRomDir,romDir);
830 case 1: //Return to menu
835 case 2: //Goto Parent Directory
837 //Remove a directory from RomPath and rescan
838 //Code below will never let you go further up than \SD Card\ on the Gizmondo
840 for(i=strlen(romDir)-1;i>0;i--) // don't want to change first char in screen
842 if((romDir[i] == dirSep[0]) || (romDir[i] == dirSepBad[0]))
849 focus=ROM_SELECTOR_DEFAULT_FOCUS; // default menu to non menu item
850 // just to stop directory scan being started
852 memset(&headerDone,0,sizeof(headerDone)); //clear header
855 case ROM_SELECTOR_DEFAULT_FOCUS: //blank space - do nothing
859 // normal file or dir selected
860 if (romList[focus].type == FILE_TYPE_DIRECTORY)
862 //Just check we are not in root dir as this will always have
863 //a trailing directory seperater which screws with things
864 sprintf(romDir,"%s%s%s",romDir,DIR_SEP,romList[focus].filename);
866 focus=ROM_SELECTOR_DEFAULT_FOCUS; // default menu to non menu item
867 // just to stop directory scan being started
872 // user has selected a rom, so load it
873 sprintf(currentRomFilename,romList[focus].filename);
874 quickSavePresent=0; // reset any quick saves
882 if (Inp.held[INP_BUTTON_MENU_DELETE]==1)
884 if(focus>ROM_SELECTOR_DEFAULT_FOCUS)
887 if (romList[focus].type != FILE_TYPE_DIRECTORY)
889 sprintf(text,"%s",romList[focus].filename);
891 if(MenuMessageBox("Are you sure you want to delete",text,"",0)==0)
902 sprintf(text,"%s:%s",mode?"Select Rom":"Delete Rom",romDir);
903 gp_drawString(6,35,strlen(text)>=40?39:strlen(text),text,(unsigned short)MENU_RGB(31,0,0),framebuffer16[currFB]);
905 smooth=smooth*7+(focus<<8); smooth>>=3;
908 if (scanstart<0) scanstart=0;
910 if (scanend>romCount) scanend=romCount;
912 for (i=scanstart;i<scanend;i++)
916 y=(i<<4)-(smooth>>4);
919 if (y<=48 || y>=232) continue;
923 color=(unsigned short)MENU_RGB(0,0,0);
924 PrintBar(currFB,y-4);
928 color=(unsigned short)MENU_RGB(31,31,31);
931 // Draw Directory icon if current entry is a directory
932 if(romList[i].type == FILE_TYPE_DIRECTORY)
934 gp_drawString(x-8,y,1,"+",color,framebuffer16[currFB]);
937 romname_length=strlen(romList[i].filename);
938 if(romname_length>39) romname_length=39;
939 gp_drawString(x,y,romname_length,romList[i].filename,color,framebuffer16[currFB]);
948 static void ScanSaveStates(char *romname)
952 char savename[MAX_PATH+1];
953 char filename[MAX_PATH+1];
954 char ext[MAX_PATH+1];
956 if(!strcmp(romname,saveStateName)) return; // is current save state rom so exit
958 SplitFilename(romname,filename,ext);
960 sprintf(savename,"%s.%s",filename,SAVESTATE_EXT);
965 need to build a save state filename
966 all saves are held in current working directory (snesSaveStateDir)
967 save filename has following format
968 shortname(minus file ext) + SV + saveno ( 0 to 9 )
970 sprintf(saveState[i].filename,"%s%d",savename,i);
971 sprintf(saveState[i].fullFilename,"%s%s%s",snesSaveStateDir,DIR_SEP,saveState[i].filename);
972 stream=(FILE*)fopen(saveState[i].fullFilename,"rb");
975 // we have a savestate
976 saveState[i].inUse = 1;
982 saveState[i].inUse = 0;
985 strcpy(saveStateName,romname); // save the last scanned romname
988 void LoadStateFile(char *filename)
990 S9xUnfreezeGame(filename);
993 static void SaveStateFile(char *filename)
995 S9xFreezeGame(filename);
999 static int SaveStateSelect(int mode)
1005 if(currentRomFilename[0]==0)
1008 // display error message and exit
1012 memset(&headerDone,0,sizeof(headerDone));
1013 ScanSaveStates(currentRomFilename);
1015 while (action!=0&&action!=100)
1018 if(Inp.held[INP_BUTTON_UP]==1) {saveno--; action=1;}
1019 if(Inp.held[INP_BUTTON_DOWN]==1) {saveno++; action=1;}
1020 if(saveno<-1) saveno=9;
1021 if(saveno>9) saveno=-1;
1023 if(Inp.held[INP_BUTTON_MENU_CANCEL]==1) action=0; // exit
1024 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(saveno==-1)) action=0; // exit
1025 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==0)&&((action==2)||(action==5))) action=6; // pre-save mode
1026 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==1)&&(action==5)) action=8; // pre-load mode
1027 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==2)&&(action==5))
1029 if(MenuMessageBox("Are you sure you want to delete","this save?","",0)==0) action=13; //delete slot with no preview
1031 //else if((Inp.held[INP_BUTTON_R]==1)&&(action==12)) action=3; // preview slot mode
1032 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==1)&&(action==12)) action=8; //load slot with no preview
1033 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==0)&&(action==12)) action=6; //save slot with no preview
1034 else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==2)&&(action==12))
1036 if(MenuMessageBox("Are you sure you want to delete","this save?","",0)==0) action=13; //delete slot with no preview
1041 if(mode==SAVESTATE_MODE_SAVE) gp_drawString(6,35,10,"Save State",(unsigned short)MENU_RGB(31,0,0),framebuffer16[currFB]);
1042 if(mode==SAVESTATE_MODE_LOAD) gp_drawString(6,35,10,"Load State",(unsigned short)MENU_RGB(31,0,0),framebuffer16[currFB]);
1043 if(mode==SAVESTATE_MODE_DELETE) gp_drawString(6,35,12,"Delete State",(unsigned short)MENU_RGB(31,0,0),framebuffer16[currFB]);
1044 sprintf(text,"Press UP and DOWN to change save slot");
1045 gp_drawString(12,230,strlen(text),text,(unsigned short)MENU_RGB(31,15,5),framebuffer16[currFB]);
1049 if(action!=10&&action!=0)
1056 PrintBar(currFB,60-4);
1057 sprintf(text,"SLOT %d",saveno);
1058 gp_drawString(136,60,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1064 //gp_drawString(112,145,14,"Checking....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1067 gp_drawString(144,145,4,"FREE",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1070 gp_drawString(104,145,14,"Previewing....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1073 gp_drawString(88,145,18,"Previewing....fail",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1076 gp_drawString(112,145,17, "Not gonna happen!",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1077 if(mode==1) gp_drawString((320-(strlen(MENU_TEXT_LOAD_SAVESTATE)<<3))>>1,210,strlen(MENU_TEXT_LOAD_SAVESTATE), MENU_TEXT_LOAD_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1078 else if(mode==0) gp_drawString((320-(strlen(MENU_TEXT_OVERWRITE_SAVESTATE)<<3))>>1,210,strlen(MENU_TEXT_OVERWRITE_SAVESTATE), MENU_TEXT_OVERWRITE_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1079 else if(mode==2) gp_drawString((320-(strlen(MENU_TEXT_DELETE_SAVESTATE)<<3))>>1,210,strlen(MENU_TEXT_DELETE_SAVESTATE), MENU_TEXT_DELETE_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1082 gp_drawString(124,145,9,"Saving...",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1085 gp_drawString(124,145,14,"Saving...Fail!",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1088 gp_drawString(116,145,11,"loading....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1091 gp_drawString(116,145,15,"loading....Fail",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1094 PrintBar(currFB,145-4);
1095 gp_drawString(104,145,14,"Return To Menu",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1098 gp_drawString(124,145,9,"Slot used",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1099 //gp_drawString((320-(strlen(MENU_TEXT_PREVIEW_SAVESTATE)<<3))>>1,165,strlen(MENU_TEXT_PREVIEW_SAVESTATE),MENU_TEXT_PREVIEW_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1100 if(mode==1) gp_drawString((320-(strlen(MENU_TEXT_LOAD_SAVESTATE)<<3))>>1,175,strlen(MENU_TEXT_LOAD_SAVESTATE), MENU_TEXT_LOAD_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1101 else if(mode==0) gp_drawString((320-(strlen(MENU_TEXT_OVERWRITE_SAVESTATE)<<3))>>1,175,strlen(MENU_TEXT_OVERWRITE_SAVESTATE), MENU_TEXT_OVERWRITE_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1102 else if(mode==2) gp_drawString((320-(strlen(MENU_TEXT_DELETE_SAVESTATE)<<3))>>1,175,strlen(MENU_TEXT_DELETE_SAVESTATE), MENU_TEXT_DELETE_SAVESTATE,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1105 gp_drawString(116,145,11,"Deleting....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1114 if(saveState[saveno].inUse)
1124 LoadStateFile(saveState[saveno].fullFilename);
1128 SaveStateFile(saveState[saveno].fullFilename);
1129 saveState[saveno].inUse=1;
1136 LoadStateFile(saveState[saveno].fullFilename);
1137 action=100; // loaded ok so exit
1146 remove(saveState[saveno].fullFilename);
1148 saveState[saveno].inUse = 0;
1153 memset(&headerDone,0,sizeof(headerDone));
1158 void RenderMenu(char *menuName, int menuCount, int menuSmooth, int menufocus)
1163 unsigned short color=0;
1167 gp_drawString(6,35,strlen(menuName),menuName,(unsigned short)MENU_RGB(31,0,0),framebuffer16[currFB]);
1169 // RRRRRGGGGGBBBBBI gp32 color format
1170 for (i=0;i<menuCount;i++)
1174 y=(i<<4)-(menuSmooth>>4);
1178 if (y<=48 || y>=232) continue;
1182 color=(unsigned short)MENU_RGB(0,0,0);
1183 PrintBar(currFB,y-4);
1187 color=(unsigned short)MENU_RGB(31,31,31);
1190 sprintf(text,"%s",menutext[i]);
1191 gp_drawString(x,y,strlen(text),text,color,framebuffer16[currFB]);
1197 int LoadRomMenu(void)
1199 int menuExit=0,menuCount=LOAD_ROM_MENU_COUNT,menufocus=0,menuSmooth=0;
1203 memset(&headerDone,0,sizeof(headerDone));
1204 strcpy(romDir,snesRomDir);
1205 subaction=FileSelect(0);
1206 memset(&headerDone,0,sizeof(headerDone));
1209 action=EVENT_LOAD_SNES_ROM;
1217 int SaveStateMenu(void)
1219 int menuExit=0,menuCount=SAVESTATE_MENU_COUNT,menufocus=0,menuSmooth=0;
1223 memset(&headerDone,0,sizeof(headerDone));
1226 sprintf(menutext[SAVESTATE_MENU_LOAD],"Load State");
1227 sprintf(menutext[SAVESTATE_MENU_SAVE],"Save State");
1228 sprintf(menutext[SAVESTATE_MENU_DELETE],"Delete State");
1229 sprintf(menutext[SAVESTATE_MENU_RETURN],"Back");
1235 // Change which rom is focused on:
1236 if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up
1237 if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down
1239 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1241 if (menufocus>menuCount-1)
1244 menuSmooth=(menufocus<<8)-1;
1246 else if (menufocus<0)
1248 menufocus=menuCount-1;
1249 menuSmooth=(menufocus<<8)-1;
1252 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1256 case SAVESTATE_MENU_LOAD:
1257 subaction=SaveStateSelect(SAVESTATE_MODE_LOAD);
1264 case SAVESTATE_MENU_SAVE:
1265 SaveStateSelect(SAVESTATE_MODE_SAVE);
1267 case SAVESTATE_MENU_DELETE:
1268 SaveStateSelect(SAVESTATE_MODE_DELETE);
1270 case SAVESTATE_MENU_RETURN:
1276 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
1277 RenderMenu("Save States", menuCount,menuSmooth,menufocus);
1288 int menuExit=0,menuCount=SRAM_MENU_COUNT,menufocus=0,menuSmooth=0;
1294 memset(&headerDone,0,sizeof(headerDone));
1297 sprintf(menutext[SRAM_MENU_LOAD],"Load SRAM");
1298 sprintf(menutext[SRAM_MENU_SAVE],"Save SRAM");
1299 sprintf(menutext[SRAM_MENU_DELETE],"Delete SRAM");
1300 sprintf(menutext[SRAM_MENU_RETURN],"Back");
1306 // Change which rom is focused on:
1307 if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up
1308 if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down
1310 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1312 if (menufocus>menuCount-1)
1315 menuSmooth=(menufocus<<8)-1;
1317 else if (menufocus<0)
1319 menufocus=menuCount-1;
1320 menuSmooth=(menufocus<<8)-1;
1323 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1327 case SRAM_MENU_LOAD:
1328 //LoadSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT,(char*)&sram);
1330 case SRAM_MENU_SAVE:
1331 //SaveSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT,(char*)&sram);
1333 case SRAM_MENU_DELETE:
1334 //DeleteSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT);
1336 case SRAM_MENU_RETURN:
1342 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
1343 RenderMenu("SRAM", menuCount,menuSmooth,menufocus);
1352 void SNESOptionsUpdateText(int menu_index)
1356 case SNES_MENU_SOUND:
1357 switch(snesMenuOptions.soundOn)
1360 sprintf(menutext[SNES_MENU_SOUND],"Sound: OFF");
1363 sprintf(menutext[SNES_MENU_SOUND],"Sound: ON");
1368 case SNES_MENU_SOUND_RATE:
1369 if (snesMenuOptions.stereo)
1370 sprintf(menutext[SNES_MENU_SOUND_RATE],"Sound Rate: %d stereo",(unsigned int)soundRates[snesMenuOptions.soundRate]);
1372 sprintf(menutext[SNES_MENU_SOUND_RATE],"Sound Rate: %d mono",(unsigned int)soundRates[snesMenuOptions.soundRate]);
1374 #if defined(__GP2X__)
1375 case SNES_MENU_CPUSPEED:
1376 sprintf(menutext[SNES_MENU_CPUSPEED],"Cpu Speed: %d",(unsigned int)cpuSpeedLookup[snesMenuOptions.cpuSpeed]);
1379 case SNES_MENU_SOUND_VOL:
1380 sprintf(menutext[SNES_MENU_SOUND_VOL],"Volume: %d",snesMenuOptions.volume);
1383 case SNES_MENU_FRAMESKIP:
1384 switch(snesMenuOptions.frameSkip)
1387 sprintf(menutext[SNES_MENU_FRAMESKIP],"Frameskip: AUTO");
1390 sprintf(menutext[SNES_MENU_FRAMESKIP],"Frameskip: %d",snesMenuOptions.frameSkip-1);
1395 case SNES_MENU_REGION:
1396 switch(snesMenuOptions.region)
1399 sprintf(menutext[SNES_MENU_REGION],"Region: AUTO");
1402 sprintf(menutext[SNES_MENU_REGION],"Region: NTSC");
1405 sprintf(menutext[SNES_MENU_REGION],"Region: PAL");
1411 switch(snesMenuOptions.showFps)
1414 sprintf(menutext[SNES_MENU_FPS],"Show FPS: OFF");
1417 sprintf(menutext[SNES_MENU_FPS],"Show FPS: ON");
1421 #if defined(__GP2X__)
1422 case SNES_MENU_GAMMA:
1423 sprintf(menutext[SNES_MENU_GAMMA],"Brightness: %d",snesMenuOptions.gamma+100);
1426 case SNES_MENU_TRANSPARENCY:
1427 switch(snesMenuOptions.transparency)
1430 sprintf(menutext[SNES_MENU_TRANSPARENCY],"Transparencies: OFF");
1433 sprintf(menutext[SNES_MENU_TRANSPARENCY],"Transparencies: ON");
1438 case SNES_MENU_LOAD_GLOBAL:
1439 sprintf(menutext[SNES_MENU_LOAD_GLOBAL],"Load Global Settings");
1442 case SNES_MENU_SAVE_GLOBAL:
1443 sprintf(menutext[SNES_MENU_SAVE_GLOBAL],"Save Global Settings");
1446 case SNES_MENU_DELETE_GLOBAL:
1447 sprintf(menutext[SNES_MENU_DELETE_GLOBAL],"Delete Global Settings");
1450 case SNES_MENU_LOAD_CURRENT:
1451 sprintf(menutext[SNES_MENU_LOAD_CURRENT],"Load Settings For Current Game");
1454 case SNES_MENU_SAVE_CURRENT:
1455 sprintf(menutext[SNES_MENU_SAVE_CURRENT],"Save Settings For Current Game");
1458 case SNES_MENU_DELETE_CURRENT:
1459 sprintf(menutext[SNES_MENU_DELETE_CURRENT],"Delete Settings For Current Game");
1462 case SNES_MENU_SET_ROMDIR:
1463 sprintf(menutext[SNES_MENU_SET_ROMDIR],"Save Current Rom Directory");
1466 case SNES_MENU_CLEAR_ROMDIR:
1467 sprintf(menutext[SNES_MENU_CLEAR_ROMDIR],"Reset Default Rom Directory");
1470 case SNES_MENU_RETURN:
1471 sprintf(menutext[SNES_MENU_RETURN],"Back");
1473 #if defined(__GP2X__)
1474 case SNES_MENU_RENDER_MODE:
1475 switch(snesMenuOptions.renderMode)
1477 case RENDER_MODE_UNSCALED:
1478 sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Unscaled");
1480 case RENDER_MODE_SCALED:
1481 sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Scaled");
1484 sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Unscaled");
1488 case SNES_MENU_ACTION_BUTTONS:
1489 switch(snesMenuOptions.actionButtons)
1492 sprintf(menutext[SNES_MENU_ACTION_BUTTONS],"Action Buttons: Normal");
1495 sprintf(menutext[SNES_MENU_ACTION_BUTTONS],"Action Buttons: Swapped");
1500 case SNES_MENU_AUTO_SAVE_SRAM:
1501 switch(snesMenuOptions.autoSram)
1504 sprintf(menutext[SNES_MENU_AUTO_SAVE_SRAM],"Saving SRAM: Manual");
1507 sprintf(menutext[SNES_MENU_AUTO_SAVE_SRAM],"Saving SRAM: Automatic");
1511 #if defined(__GP2X__)
1512 case SNES_MENU_RAM_SETTINGS:
1513 switch(snesMenuOptions.ramSettings)
1516 sprintf(menutext[SNES_MENU_RAM_SETTINGS],"RAM timing (Restart Required): NORMAL");
1519 sprintf(menutext[SNES_MENU_RAM_SETTINGS],"RAM timing (Restart Required): CRAIG");
1523 case SNES_MENU_MMU_HACK:
1524 switch(snesMenuOptions.mmuHack)
1527 sprintf(menutext[SNES_MENU_MMU_HACK],"MMU Hack (Restart Required): OFF");
1530 sprintf(menutext[SNES_MENU_MMU_HACK],"MMU Hack (Restart Required): ON");
1535 case SNES_MENU_ADVANCED_HACKS:
1536 sprintf(menutext[SNES_MENU_ADVANCED_HACKS],"Advanced hacks");
1542 void SNESHacksUpdateText(int menu_index)
1546 case HACKS_MENU_AUDIO:
1547 if(snesMenuOptions.soundHack)
1548 sprintf(menutext[HACKS_MENU_AUDIO],"Audio Performance hack: ON");
1550 sprintf(menutext[HACKS_MENU_AUDIO],"Audio Performance hack: OFF");
1552 case HACKS_MENU_PALETTE:
1553 if(snesMenuOptions.graphHacks & PPU_IGNORE_PALWRITE)
1554 sprintf(menutext[HACKS_MENU_PALETTE],"Ignore Palette writes: ON");
1556 sprintf(menutext[HACKS_MENU_PALETTE],"Ignore Palette writes: OFF");
1558 case HACKS_MENU_FIXEDCOL:
1559 if(snesMenuOptions.graphHacks & PPU_IGNORE_FIXEDCOLCHANGES)
1560 sprintf(menutext[HACKS_MENU_FIXEDCOL],"Ignore Fixed Colour: ON");
1562 sprintf(menutext[HACKS_MENU_FIXEDCOL],"Ignore Fixed Colour: OFF");
1564 case HACKS_MENU_WINDOW:
1565 if(snesMenuOptions.graphHacks & PPU_IGNORE_WINDOW)
1566 sprintf(menutext[HACKS_MENU_WINDOW],"Ignore Windows clipping: ON");
1568 sprintf(menutext[HACKS_MENU_WINDOW],"Ignore Windows clipping: OFF");
1570 case HACKS_MENU_ADDSUB:
1571 if(snesMenuOptions.graphHacks & PPU_IGNORE_ADDSUB)
1572 sprintf(menutext[HACKS_MENU_ADDSUB],"Ignore Add/Sub modes: ON");
1574 sprintf(menutext[HACKS_MENU_ADDSUB],"Ignore Add/Sub modes: OFF");
1576 case HACKS_MENU_OBJ:
1577 if(snesMenuOptions.graphHacks & GFX_IGNORE_OBJ)
1578 sprintf(menutext[HACKS_MENU_OBJ],"Ignore objects layer: ON");
1580 sprintf(menutext[HACKS_MENU_OBJ],"Ignore objects layer: OFF");
1582 case HACKS_MENU_BG0:
1583 if(snesMenuOptions.graphHacks & GFX_IGNORE_BG0)
1584 sprintf(menutext[HACKS_MENU_BG0],"Ignore background layer 0: ON");
1586 sprintf(menutext[HACKS_MENU_BG0],"Ignore background layer 0: OFF");
1588 case HACKS_MENU_BG1:
1589 if(snesMenuOptions.graphHacks & GFX_IGNORE_BG1)
1590 sprintf(menutext[HACKS_MENU_BG1],"Ignore background layer 1: ON");
1592 sprintf(menutext[HACKS_MENU_BG1],"Ignore background layer 1: OFF");
1594 case HACKS_MENU_BG2:
1595 if(snesMenuOptions.graphHacks & GFX_IGNORE_BG2)
1596 sprintf(menutext[HACKS_MENU_BG2],"Ignore background layer 2: ON");
1598 sprintf(menutext[HACKS_MENU_BG2],"Ignore background layer 2: OFF");
1600 case HACKS_MENU_BG3:
1601 if(snesMenuOptions.graphHacks & GFX_IGNORE_BG3)
1602 sprintf(menutext[HACKS_MENU_BG3],"Ignore background layer 3: ON");
1604 sprintf(menutext[HACKS_MENU_BG3],"Ignore background layer 3: OFF");
1606 case HACKS_MENU_RETURN:
1607 sprintf(menutext[HACKS_MENU_RETURN],"Back");
1615 void SNESHacksUpdateText_All()
1617 SNESHacksUpdateText(HACKS_MENU_AUDIO);
1618 SNESHacksUpdateText(HACKS_MENU_PALETTE);
1619 SNESHacksUpdateText(HACKS_MENU_FIXEDCOL);
1620 SNESHacksUpdateText(HACKS_MENU_WINDOW);
1621 SNESHacksUpdateText(HACKS_MENU_ADDSUB);
1622 SNESHacksUpdateText(HACKS_MENU_OBJ);
1623 SNESHacksUpdateText(HACKS_MENU_BG0);
1624 SNESHacksUpdateText(HACKS_MENU_BG1);
1625 SNESHacksUpdateText(HACKS_MENU_BG2);
1626 SNESHacksUpdateText(HACKS_MENU_BG3);
1627 SNESHacksUpdateText(HACKS_MENU_RETURN);
1631 int SNESHacksMenu(void)
1633 int menuExit=0,menuCount=HACKS_MENU_COUNT,menufocus=0,menuSmooth=0;
1637 memset(&headerDone,0,sizeof(headerDone));
1640 SNESHacksUpdateText_All();
1646 // Change which rom is focused on:
1647 if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up
1648 if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down
1650 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1652 if (menufocus>menuCount-1)
1655 menuSmooth=(menufocus<<8)-1;
1657 else if (menufocus<0)
1659 menufocus=menuCount-1;
1660 menuSmooth=(menufocus<<8)-1;
1663 if (Inp.held[INP_BUTTON_LEFT]==1||
1664 Inp.held[INP_BUTTON_RIGHT]==1||
1665 Inp.repeat[INP_BUTTON_LEFT]||
1666 Inp.repeat[INP_BUTTON_RIGHT])
1670 case HACKS_MENU_AUDIO:
1671 snesMenuOptions.soundHack^=1;
1672 SNESHacksUpdateText(HACKS_MENU_AUDIO);
1674 case HACKS_MENU_PALETTE:
1675 if (snesMenuOptions.graphHacks & PPU_IGNORE_PALWRITE)
1676 snesMenuOptions.graphHacks &= ~PPU_IGNORE_PALWRITE;
1678 snesMenuOptions.graphHacks |= PPU_IGNORE_PALWRITE;
1679 SNESHacksUpdateText(HACKS_MENU_PALETTE);
1681 case HACKS_MENU_FIXEDCOL:
1682 if (snesMenuOptions.graphHacks & PPU_IGNORE_FIXEDCOLCHANGES)
1683 snesMenuOptions.graphHacks &= ~PPU_IGNORE_FIXEDCOLCHANGES;
1685 snesMenuOptions.graphHacks |= PPU_IGNORE_FIXEDCOLCHANGES;
1686 SNESHacksUpdateText(HACKS_MENU_FIXEDCOL);
1688 case HACKS_MENU_WINDOW:
1689 if (snesMenuOptions.graphHacks & PPU_IGNORE_WINDOW)
1690 snesMenuOptions.graphHacks &= ~PPU_IGNORE_WINDOW;
1692 snesMenuOptions.graphHacks |= PPU_IGNORE_WINDOW;
1693 SNESHacksUpdateText(HACKS_MENU_WINDOW);
1695 case HACKS_MENU_ADDSUB:
1696 if (snesMenuOptions.graphHacks & PPU_IGNORE_ADDSUB)
1697 snesMenuOptions.graphHacks &= ~PPU_IGNORE_ADDSUB;
1699 snesMenuOptions.graphHacks |= PPU_IGNORE_ADDSUB;
1700 SNESHacksUpdateText(HACKS_MENU_ADDSUB);
1702 case HACKS_MENU_OBJ:
1703 if (snesMenuOptions.graphHacks & GFX_IGNORE_OBJ)
1704 snesMenuOptions.graphHacks &= ~GFX_IGNORE_OBJ;
1706 snesMenuOptions.graphHacks |= GFX_IGNORE_OBJ;
1707 SNESHacksUpdateText(HACKS_MENU_OBJ);
1709 case HACKS_MENU_BG0:
1710 if (snesMenuOptions.graphHacks & GFX_IGNORE_BG0)
1711 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG0;
1713 snesMenuOptions.graphHacks |= GFX_IGNORE_BG0;
1714 SNESHacksUpdateText(HACKS_MENU_BG0);
1716 case HACKS_MENU_BG1:
1717 if (snesMenuOptions.graphHacks & GFX_IGNORE_BG1)
1718 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG1;
1720 snesMenuOptions.graphHacks |= GFX_IGNORE_BG1;
1721 SNESHacksUpdateText(HACKS_MENU_BG1);
1723 case HACKS_MENU_BG2:
1724 if (snesMenuOptions.graphHacks & GFX_IGNORE_BG2)
1725 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG2;
1727 snesMenuOptions.graphHacks |= GFX_IGNORE_BG2;
1728 SNESHacksUpdateText(HACKS_MENU_BG2);
1730 case HACKS_MENU_BG3:
1731 if (snesMenuOptions.graphHacks & GFX_IGNORE_BG3)
1732 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG3;
1734 snesMenuOptions.graphHacks |= GFX_IGNORE_BG3;
1735 SNESHacksUpdateText(HACKS_MENU_BG3);
1739 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1743 case HACKS_MENU_RETURN:
1749 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
1750 RenderMenu("SNES Advanced Hacks", menuCount,menuSmooth,menufocus);
1759 void SNESOptionsUpdateText_All()
1761 SNESOptionsUpdateText(SNES_MENU_SOUND);
1762 SNESOptionsUpdateText(SNES_MENU_SOUND_RATE);
1763 SNESOptionsUpdateText(SNES_MENU_SOUND_VOL);
1764 SNESOptionsUpdateText(SNES_MENU_FRAMESKIP);
1765 SNESOptionsUpdateText(SNES_MENU_REGION);
1766 SNESOptionsUpdateText(SNES_MENU_FPS);
1767 SNESOptionsUpdateText(SNES_MENU_TRANSPARENCY);
1768 SNESOptionsUpdateText(SNES_MENU_LOAD_GLOBAL);
1769 SNESOptionsUpdateText(SNES_MENU_SAVE_GLOBAL);
1770 SNESOptionsUpdateText(SNES_MENU_DELETE_GLOBAL);
1771 SNESOptionsUpdateText(SNES_MENU_LOAD_CURRENT);
1772 SNESOptionsUpdateText(SNES_MENU_SAVE_CURRENT);
1773 SNESOptionsUpdateText(SNES_MENU_DELETE_CURRENT);
1774 SNESOptionsUpdateText(SNES_MENU_SET_ROMDIR);
1775 SNESOptionsUpdateText(SNES_MENU_CLEAR_ROMDIR);
1776 SNESOptionsUpdateText(SNES_MENU_RETURN);
1777 #if defined(__GP2X__)
1778 SNESOptionsUpdateText(SNES_MENU_RENDER_MODE);
1779 SNESOptionsUpdateText(SNES_MENU_GAMMA);
1780 SNESOptionsUpdateText(SNES_MENU_RAM_SETTINGS);
1781 SNESOptionsUpdateText(SNES_MENU_MMU_HACK);
1782 SNESOptionsUpdateText(SNES_MENU_CPUSPEED);
1783 SNESOptionsUpdateText(SNES_MENU_ACTION_BUTTONS);
1785 SNESOptionsUpdateText(SNES_MENU_AUTO_SAVE_SRAM);
1786 SNESOptionsUpdateText(SNES_MENU_ADVANCED_HACKS);
1790 int SNESOptionsMenu(void)
1792 int menuExit=0,menuCount=SNES_MENU_COUNT,menufocus=0,menuSmooth=0;
1796 memset(&headerDone,0,sizeof(headerDone));
1799 SNESOptionsUpdateText_All();
1805 // Change which rom is focused on:
1806 if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up
1807 if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down
1809 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1811 if (menufocus>menuCount-1)
1814 menuSmooth=(menufocus<<8)-1;
1816 else if (menufocus<0)
1818 menufocus=menuCount-1;
1819 menuSmooth=(menufocus<<8)-1;
1822 if (Inp.held[INP_BUTTON_LEFT]==1||
1823 Inp.held[INP_BUTTON_RIGHT]==1||
1824 Inp.repeat[INP_BUTTON_LEFT]||
1825 Inp.repeat[INP_BUTTON_RIGHT])
1829 case SNES_MENU_SOUND:
1830 snesMenuOptions.soundOn^=1;
1831 SNESOptionsUpdateText(SNES_MENU_SOUND);
1833 case SNES_MENU_SOUND_RATE:
1834 if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1836 if (!snesMenuOptions.stereo)
1837 snesMenuOptions.stereo = 1;
1840 snesMenuOptions.soundRate++;
1841 snesMenuOptions.stereo = 0;
1843 if(snesMenuOptions.soundRate>4) snesMenuOptions.soundRate=0;
1847 if (snesMenuOptions.stereo)
1848 snesMenuOptions.stereo = 0;
1851 snesMenuOptions.soundRate--;
1852 snesMenuOptions.stereo = 1;
1854 if(snesMenuOptions.soundRate>4) snesMenuOptions.soundRate=4;
1856 SNESOptionsUpdateText(SNES_MENU_SOUND_RATE);
1858 case SNES_MENU_SOUND_VOL:
1859 if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1861 snesMenuOptions.volume+=1;
1862 if(snesMenuOptions.volume>100) snesMenuOptions.volume=0;
1866 snesMenuOptions.volume-=1;
1867 if(snesMenuOptions.volume>100) snesMenuOptions.volume=100;
1869 SNESOptionsUpdateText(SNES_MENU_SOUND_VOL);
1871 #if defined(__GP2X__)
1872 case SNES_MENU_CPUSPEED:
1873 if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1875 snesMenuOptions.cpuSpeed++;
1876 if(snesMenuOptions.cpuSpeed>40) snesMenuOptions.cpuSpeed=0;
1880 snesMenuOptions.cpuSpeed--;
1881 if(snesMenuOptions.cpuSpeed>40) snesMenuOptions.cpuSpeed=0;
1883 SNESOptionsUpdateText(SNES_MENU_CPUSPEED);
1886 case SNES_MENU_FRAMESKIP:
1887 if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1889 snesMenuOptions.frameSkip++;
1890 if(snesMenuOptions.frameSkip>6) snesMenuOptions.frameSkip=0;
1894 snesMenuOptions.frameSkip--;
1895 if(snesMenuOptions.frameSkip>6) snesMenuOptions.frameSkip=6;
1897 SNESOptionsUpdateText(SNES_MENU_FRAMESKIP);
1899 case SNES_MENU_REGION:
1900 if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1902 snesMenuOptions.region++;
1903 if(snesMenuOptions.region>2) snesMenuOptions.region=0;
1907 snesMenuOptions.region--;
1908 if(snesMenuOptions.region>2) snesMenuOptions.region=2;
1910 SNESOptionsUpdateText(SNES_MENU_REGION);
1913 snesMenuOptions.showFps^=1;
1914 SNESOptionsUpdateText(SNES_MENU_FPS);
1916 #if defined(__GP2X__)
1917 case SNES_MENU_GAMMA:
1918 if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1920 snesMenuOptions.gamma++;
1921 if(snesMenuOptions.gamma>100) snesMenuOptions.gamma=100;
1925 snesMenuOptions.gamma--;
1926 if(snesMenuOptions.gamma<-100) snesMenuOptions.gamma=-100;
1928 set_gamma(snesMenuOptions.gamma+100);
1929 SNESOptionsUpdateText(SNES_MENU_GAMMA);
1931 case SNES_MENU_ACTION_BUTTONS:
1932 snesMenuOptions.actionButtons^=1;
1933 SNESOptionsUpdateText(SNES_MENU_ACTION_BUTTONS);
1936 case SNES_MENU_TRANSPARENCY:
1937 snesMenuOptions.transparency^=1;
1938 SNESOptionsUpdateText(SNES_MENU_TRANSPARENCY);
1940 #if defined(__GP2X__)
1941 case SNES_MENU_RENDER_MODE:
1942 snesMenuOptions.renderMode^=1;
1943 SNESOptionsUpdateText(SNES_MENU_RENDER_MODE);
1946 case SNES_MENU_AUTO_SAVE_SRAM:
1947 snesMenuOptions.autoSram^=1;
1948 SNESOptionsUpdateText(SNES_MENU_AUTO_SAVE_SRAM);
1950 #if defined(__GP2X__)
1951 case SNES_MENU_RAM_SETTINGS:
1952 snesMenuOptions.ramSettings^=1;
1953 SNESOptionsUpdateText(SNES_MENU_RAM_SETTINGS);
1955 case SNES_MENU_MMU_HACK:
1956 snesMenuOptions.mmuHack^=1;
1957 SNESOptionsUpdateText(SNES_MENU_MMU_HACK);
1962 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1966 case SNES_MENU_ADVANCED_HACKS:
1967 memset(&headerDone,0,sizeof(headerDone));
1968 subaction = SNESHacksMenu();
1969 memset(&headerDone,0,sizeof(headerDone));
1970 SNESOptionsUpdateText_All();
1972 case SNES_MENU_LOAD_GLOBAL:
1973 LoadMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1974 SNESOptionsUpdateText_All();
1976 case SNES_MENU_SAVE_GLOBAL:
1977 SaveMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1979 case SNES_MENU_DELETE_GLOBAL:
1980 DeleteMenuOptions(snesOptionsDir,MENU_OPTIONS_FILENAME,MENU_OPTIONS_EXT,1);
1982 case SNES_MENU_LOAD_CURRENT:
1983 if(currentRomFilename[0]!=0)
1985 LoadMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1986 SNESOptionsUpdateText_All();
1989 case SNES_MENU_SAVE_CURRENT:
1990 if(currentRomFilename[0]!=0)
1992 SaveMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1995 case SNES_MENU_DELETE_CURRENT:
1996 if(currentRomFilename[0]!=0)
1998 DeleteMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT,1);
2001 case SNES_MENU_SET_ROMDIR:
2002 SaveMenuOptions(snesOptionsDir, DEFAULT_ROM_DIR_FILENAME, DEFAULT_ROM_DIR_EXT, romDir, strlen(romDir),1);
2003 strcpy(snesRomDir,romDir);
2005 case SNES_MENU_CLEAR_ROMDIR:
2006 DeleteMenuOptions(snesOptionsDir, DEFAULT_ROM_DIR_FILENAME, DEFAULT_ROM_DIR_EXT,1);
2007 strcpy(snesRomDir,currentWorkingDir);
2009 case SNES_MENU_RETURN:
2015 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
2016 RenderMenu("SNES Options", menuCount,menuSmooth,menufocus);
2025 void MainMenuUpdateText(void)
2027 sprintf(menutext[MAIN_MENU_ROM_SELECT],"Select Rom");
2028 sprintf(menutext[MAIN_MENU_MANAGE_SAVE_STATE],"Manage Save States");
2029 sprintf(menutext[MAIN_MENU_SAVE_SRAM],"Save SRAM");
2030 sprintf(menutext[MAIN_MENU_SNES_OPTIONS],"SNES Options");
2031 sprintf(menutext[MAIN_MENU_RESET_GAME ],"Reset Game");
2032 sprintf(menutext[MAIN_MENU_EXIT_APP],"Exit Application");
2033 sprintf(menutext[MAIN_MENU_RETURN],"Return To Game");
2037 int MainMenu(int prevaction)
2039 int menuExit=0,menuCount=MAIN_MENU_COUNT,menufocus=0,menuSmooth=0;
2040 int action=prevaction;
2043 gp_setCpuspeed(MENU_CPU_SPEED);
2045 gp_initGraphics(16,currFB,snesMenuOptions.mmuHack);
2046 gp_clearFramebuffer16((unsigned short*)framebuffer16[currFB],0x0);
2048 gp2x_video_RGB_setscaling(320,240);
2050 memset(&headerDone,0,sizeof(headerDone));
2051 MainMenuUpdateText();
2057 // Change which rom is focused on:
2058 if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up
2059 if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down
2061 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 )
2063 if(currentRomFilename[0]!=0)
2069 if (menufocus>menuCount-1)
2072 menuSmooth=(menufocus<<8)-1;
2074 else if (menufocus<0)
2076 menufocus=menuCount-1;
2077 menuSmooth=(menufocus<<8)-1;
2080 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
2084 case MAIN_MENU_ROM_SELECT:
2085 memset(&headerDone,0,sizeof(headerDone));
2086 subaction=LoadRomMenu();
2087 memset(&headerDone,0,sizeof(headerDone));
2093 MainMenuUpdateText();
2096 case MAIN_MENU_MANAGE_SAVE_STATE:
2097 if(currentRomFilename[0]!=0)
2099 memset(&headerDone,0,sizeof(headerDone));
2100 subaction=SaveStateMenu();
2105 memset(&headerDone,0,sizeof(headerDone));
2107 MainMenuUpdateText();
2109 case MAIN_MENU_SAVE_SRAM:
2110 if(currentRomFilename[0]!=0)
2115 case MAIN_MENU_SNES_OPTIONS:
2117 memset(&headerDone,0,sizeof(headerDone));
2118 subaction=SNESOptionsMenu();
2119 memset(&headerDone,0,sizeof(headerDone));
2120 MainMenuUpdateText();
2122 case MAIN_MENU_RESET_GAME :
2123 if(currentRomFilename[0]!=0)
2125 switch(currentEmuMode)
2128 action=EVENT_RESET_SNES_ROM;
2134 case MAIN_MENU_RETURN:
2135 if(currentRomFilename[0]!=0)
2140 case MAIN_MENU_EXIT_APP:
2141 action=EVENT_EXIT_APP;
2147 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
2148 RenderMenu("Main Menu", menuCount,menuSmooth,menufocus);