trying to use osso-games-startup as gui
[drnoksnes] / menu.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <dirent.h>
6 #include <errno.h>
7 #include "snapshot.h"
8 #include "memmap.h"
9
10 #ifdef __GIZ__
11 #include <w32api/windows.h>
12 #include <wchar.h>
13 #include <sys/wcefile.h>
14 #include "giz_sdk.h"
15 #endif
16
17 #include "menu.h"
18
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)
28
29 char romDir[MAX_PATH+1];
30 char snesRomDir[MAX_PATH+1];
31
32 #define ROM_SELECTOR_DEFAULT_FOCUS              3
33
34 DIRDATA dir;
35
36 unsigned short cpuSpeedLookup[40]={ 
37                                         10,20, 30, 40, 50,
38                                         60,70, 80, 90,100,
39                                         110,120,130,144,150,
40                                         160,170,180,190,200,
41                                         210,220,230,240,250,
42                                         260,270,280,290,300,
43                                         310,320,330,340,350,
44                                         360,370,380,390,400};
45
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
52 {
53         char filename[MAX_PATH+1];
54         char type;
55 };
56
57 static struct ROM_LIST_RECORD romList[MAX_ROMS];
58 struct SNES_MENU_OPTIONS snesMenuOptions;
59
60 static int romCount;
61 char currentRomFilename[MAX_PATH+1]="";
62 int currFB=0;
63 int prevFB=0;
64 int currentEmuMode=EMU_MODE_SNES;
65
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];
72
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
75
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};
105
106                                                                         
107 void UpdateMenuGraphicsGamma(void)
108 {
109    unsigned int currPix=0;
110    unsigned short pixel=0;
111    unsigned char R,G,B;
112    for(currPix=0;currPix<15360;currPix++)
113    {
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
118       G=(pixel>>6)&0x1F; 
119       B=(pixel>>1)&0x1F;
120       
121       // Do gamma correction  
122       R=gammaConv[R+(0<<5)];
123       G=gammaConv[G+(0<<5)];
124       B=gammaConv[B+(0<<5)];
125
126       pixel=MENU_RGB(R,G,B);
127       menuHeader[currPix]=pixel;
128    }
129    for(currPix=0;currPix<5120;currPix++)
130    {
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
135       G=(pixel>>6)&0x1F; 
136       B=(pixel>>1)&0x1F;
137       
138       // Do gamma correction  
139       R=gammaConv[R+(0<<5)];
140       G=gammaConv[G+(0<<5)];
141       B=gammaConv[B+(0<<5)];
142
143       pixel=MENU_RGB(R,G,B);
144       highLightBar[currPix]=pixel;
145    
146    }
147    
148    for(currPix=0;currPix<(MENU_TILE_WIDTH*MENU_TILE_HEIGHT);currPix++)
149    {
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
154       G=(pixel>>6)&0x1F; 
155       B=(pixel>>1)&0x1F;
156       
157       // Do gamma correction  
158       R=gammaConv[R+(0<<5)];
159       G=gammaConv[G+(0<<5)];
160       B=gammaConv[B+(0<<5)];
161
162       pixel=MENU_RGB(R,G,B);
163       menuTile[currPix]=pixel;
164    
165    }
166 }
167
168 void SnesDefaultMenuOptions(void)
169 {
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;
180 }
181
182 int LoadMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage)
183 {
184         char fullFilename[MAX_PATH+MAX_PATH+1];
185         char _filename[MAX_PATH+1];
186         char _ext[MAX_PATH+1];
187         FILE *stream;
188         int size=0;
189         char text[50];
190         
191         sprintf(text,"Loading...");
192         //Sometimes the on screen messages are not required
193         if (showMessage)
194         {
195                 PrintBar(prevFB,240-16);
196                 gp_drawString(40,228,strlen(text),text,(unsigned short)MENU_RGB(0,0,0),framebuffer16[prevFB]);
197         }
198         
199     SplitFilename(filename, _filename, _ext);
200         sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEP,_filename,ext);
201         stream=fopen(fullFilename,"rb");
202         if(stream)
203         {
204                 // File exists do try to load it
205                 fseek(stream,0,SEEK_END);
206                 size=ftell(stream);
207                 if (size>maxsize) size=maxsize;
208                 fseek(stream,0,SEEK_SET);
209                 fread(optionsmem, 1, size, stream);
210                 fclose(stream);
211                 return(0);
212         }
213         else
214         {
215                 return(1);
216         }
217 }
218
219 int SaveMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage)
220 {
221         char fullFilename[MAX_PATH+MAX_PATH+1];
222         char _filename[MAX_PATH+1];
223         char _ext[MAX_PATH+1];
224         FILE *stream;
225         char text[50];
226         
227         sprintf(text,"Saving...");
228         //Sometimes the on screen messages are not required
229         if (showMessage)
230         {
231                 PrintBar(prevFB,240-16);
232                 gp_drawString(40,228,strlen(text),text,(unsigned short)MENU_RGB(0,0,0),framebuffer16[prevFB]);
233         }
234         
235         SplitFilename(filename, _filename, _ext);
236         sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEP,_filename,ext);
237         stream=fopen(fullFilename,"wb");
238         if(stream)
239         {
240                 fwrite(optionsmem, 1, maxsize, stream);
241                 fclose(stream);
242                 sync();
243                 return(0);
244         }
245         else
246         {
247                 return(1);
248         }
249 }
250
251 int DeleteMenuOptions(char *path, char *filename, char *ext, int showMessage)
252 {
253         char fullFilename[MAX_PATH+MAX_PATH+1];
254         char _filename[MAX_PATH+1];
255         char _ext[MAX_PATH+1];
256         char text[50];
257         
258         sprintf(text,"Deleting...");
259         //Sometimes the on screen messages are not required
260         if (showMessage)
261         {
262                 PrintBar(prevFB,240-16);
263                 gp_drawString(40,228,strlen(text),text,(unsigned short)MENU_RGB(0,0,0),framebuffer16[prevFB]);
264         }
265         
266         SplitFilename(filename, _filename, _ext);
267         sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEP,_filename,ext);
268         remove(fullFilename);
269         sync();
270         return(0);
271 }
272
273 #ifdef __GIZ__
274 void sync(void)
275 {
276 }
277 #endif
278
279 static void WaitForButtonsUp(void)
280 {
281         int i=0,j=0,z=0;
282         
283         for(i=0;i<100;i++)
284         {
285                 while(1)
286                 {     
287                         InputUpdate(0);
288                         z=0;
289                         for (j=0;j<32;j++)
290                         {
291                                 if (Inp.held[j]) z=1;
292                         }
293                         if (z==0) break;
294                 }
295         }
296 }
297
298 void MenuPause()
299 {
300         int i=0,j=0,z=0;
301         // wait for keys to be released
302         for(i=0;i<100;i++)  // deal with keybounce by checking a few times
303         {
304                 while(1)
305                 {     
306                         InputUpdate(0);
307                         z=0;
308                         for (j=0;j<32;j++)
309                         {
310                                 if (Inp.held[j]) z=1;
311                         }
312                         if (z==0) break;
313                 }
314         }
315         
316         for(i=0;i<100;i++)  // deal with keybounce by checking a few times
317         {
318                 while(1)
319                 {     
320                         InputUpdate(0);
321                         z=0;
322                         for (j=0;j<32;j++)
323                         {
324                                 if (Inp.held[j]) z=1;
325                         }
326                         if (z==1) break;
327                 }
328         }
329 }
330 #if defined (__GP2X__)  
331 void MenuFlip()
332 {
333         prevFB=currFB;
334         gp_setFramebuffer(currFB,1);
335     currFB++;
336         currFB&=3;
337 }
338 #endif
339 #if defined (__GIZ__)   
340 void MenuFlip()
341 {
342         prevFB=currFB=0;
343         gp_setFramebuffer(currFB,0);
344 }
345 #endif
346 void SplitFilename(char *wholeFilename, char *filename, char *ext)
347 {
348         int len=strlen(wholeFilename);
349         int i=0,y=-1;
350
351         ext[0]=0;
352         filename[0]=0;
353         //Check given string is not null
354         if (len<=0)
355         {
356                 return;
357         }
358         y=-1;
359         for(i=len-2;i>0;i--)
360         {
361                 if (wholeFilename[i]=='.')
362                 {
363                         y=i;
364                         break;
365                 }
366         }
367         
368         if (y>=0)
369         {
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;
374                 ext[len-(y+1)]=0;
375         }
376         else
377         {
378                 strcpy(filename,wholeFilename);
379         }
380 }
381
382 //Ensures all directory seperators are valid for system
383 void CheckDirSep(char *path)
384 {
385         int i=0;
386         char dirSepBad[2]={DIR_SEP_BAD};
387         char dirSep[2]={DIR_SEP};
388         for(i=0;i<strlen(path);i++)
389         {
390                 if(path[i] == dirSepBad[0]) path[i]=dirSep[0];
391         }
392 }
393
394
395 int MenuMessageBox(char *message1,char *message2,char *message3,int mode)
396 {
397   int select=0;
398   int subaction=-1;
399   int len=0;
400   while(subaction==-1)
401   {
402      InputUpdate(0);
403      if (Inp.repeat[INP_BUTTON_UP]) 
404      {
405        select^=1; // Up
406      }
407      if (Inp.repeat[INP_BUTTON_DOWN]) 
408      {
409        select^=1; // Down
410      }
411      if ((Inp.held[INP_BUTTON_MENU_SELECT]==1) || (Inp.held[INP_BUTTON_MENU_CANCEL]==1))
412      {
413         subaction=select;
414      }
415      PrintTile(currFB);
416      PrintTitle(currFB);
417          len=strlen(message1);
418          if(len>39)len=39;
419      gp_drawString(8,50,len,message1,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
420      len=strlen(message2);
421          if(len>39)len=39;
422          gp_drawString(8,60,len,message2,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
423      len=strlen(message3);
424          if(len>39)len=39;
425          gp_drawString(8,70,len,message3,(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
426      switch(mode)
427      {
428         case 0: // yes no input
429                if(select==0)
430                {
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]);
434                }
435                else
436                {
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]);
440                
441                }
442                break;
443      }
444      MenuFlip();
445   }
446   return(subaction);
447 }
448
449 static
450 int deleterom(int romindex)
451 {
452         char text[MAX_PATH+1];
453         char fullfilename[MAX_PATH+MAX_PATH+1];
454         int x;
455         FILE *stream=NULL;
456         
457     PrintTile(currFB);
458     PrintTitle(currFB);
459     MenuFlip();
460         
461     sprintf(text,"Deleting Rom..");
462     gp_drawString(8,50,strlen(text),text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[prevFB]);
463         
464     sprintf(text,"%s",romList[romindex].filename);
465         x=strlen(text);
466         if(x>40) x=40;
467         gp_drawString(0,60,x,text,(unsigned short)MENU_RGB(31,31,31),framebuffer16[prevFB]);
468         
469         sprintf(fullfilename,"%s%s%s",romDir,DIR_SEP,romList[romindex].filename);
470     remove(fullfilename);
471         sync();
472         
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++)
476     {
477                 strcpy(romList[x].filename, romList[x+1].filename);
478                 romList[x].type = romList[x+1].type;
479     }
480     romCount--;
481         
482         return(1);
483 }
484
485 static int tileCounter=0;
486 void PrintTile(int flip)
487 {
488         short x=0,x2=0;
489         short y=0,y2=0;
490         unsigned short *framebuffer1 = framebuffer16[flip]+(48*320);
491         unsigned short *graphics1 = NULL;
492
493         x2=menutileXscroll;
494         y2=(menutileYscroll*MENU_TILE_WIDTH);
495         graphics1 = menuTile+y2;
496         for (y=0; y<(240-48); y++)
497         {
498                 for (x=0; x<320; x++)
499                 {
500                         *framebuffer1++ = graphics1[x2];
501                         x2++;
502                         x2&=(MENU_TILE_WIDTH-1);
503                 }
504                 y2+=MENU_TILE_WIDTH;
505                 y2&=((MENU_TILE_HEIGHT*MENU_TILE_WIDTH)-1);
506                 graphics1=menuTile+y2;
507         }
508
509         tileCounter++;
510         if (tileCounter > 5)
511         {
512                 tileCounter=0;
513                 menutileXscroll++;
514                 if(menutileXscroll>=MENU_TILE_WIDTH) menutileXscroll=0;
515           
516                 menutileYscroll++;
517                 if(menutileYscroll>=MENU_TILE_HEIGHT) menutileYscroll=0;
518         }  
519         return; 
520 }
521
522 void PrintTitle(int flip)
523 {
524         unsigned short *framebuffer = (unsigned short*)framebuffer16[flip];
525         unsigned short *graphics = (unsigned short*)menuHeader;
526         unsigned int x,y;
527         char text[256];
528         //If header already drawn for this layer exit
529         if (headerDone[flip]) return;
530   
531         for (y=0; y<48; y++)
532         {
533                 for (x=0; x<320; x++)
534                 {
535                         *framebuffer++ = *graphics++;
536                 }
537         }
538   
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;
542 }
543
544 void PrintBar(int flip, unsigned int givenY)
545 {
546   unsigned int *framebuffer1 = NULL;
547   unsigned int *graphics1 = (unsigned int *)highLightBar;
548   unsigned int x,y;
549
550         framebuffer1 = (unsigned int*)framebuffer16[flip]+(givenY*160);
551         for (y=0; y<16; y++)
552         {
553                 for (x=0; x<160; x++)
554                 {
555                         *framebuffer1++ = *graphics1++;
556                 }
557         }
558 }
559
560 static int StringCompare(char *string1, char *string2)
561 {
562         int i=0;
563         char c1=0,c2=0;
564         while(1)
565         {
566                 c1=string1[i];
567                 c2=string2[i];
568                 // check for string end
569                 
570                 if ((c1 == 0) && (c2 == 0)) return 0;
571                 if (c1 == 0) return 1;
572                 if (c2 == 0) return -1;
573                 
574                 if ((c1 >= 0x61)&&(c1<=0x7A)) c1-=0x20;
575                 if ((c2 >= 0x61)&&(c2<=0x7A)) c2-=0x20;
576                 if (c1>c2)
577                         return 1;
578                 else if (c1<c2)
579                         return -1;
580                 i++;
581         }
582
583 }
584
585 #ifdef __GIZ__
586 static BOOL CharToWChar(wchar_t *wc, char *c)
587 {
588         int len=strlen(c);
589         int x=0;
590         for (x=0;x<len;x++)
591         {
592                 wc[x] = btowc(c[x]);
593         }
594         wc[len]=0;
595         return TRUE;
596 }
597 #endif
598
599 int FileScan()
600 {
601         int i=0,j=0;
602         char text[256];
603         DIR *d;
604         struct dirent  *de;
605         char dirCheck[MAX_PATH+1];
606         int dirCount=0;
607         char _filename[MAX_PATH+1];
608         char _ext[MAX_PATH+1];
609
610 #ifdef __GIZ__  
611         wchar_t  wc[MAX_PATH+1];
612         HANDLE hTest;
613     WIN32_FIND_DATAW fileInfo;
614 #endif
615  
616         PrintTile(currFB);
617         PrintTitle(currFB);
618         gp_drawString(8,120,25,"Getting Directory Info...",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
619         MenuFlip();
620         
621         for (i=0;i<MAX_ROMS;i++)
622         {
623                 romList[i].filename[0] = 0;
624         }
625
626         //Get rom directory details
627         romCount=0;
628         
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;
634         romCount=4;
635
636         d = opendir(romDir);
637
638         if (d)
639         {
640                 while ((de = readdir(d)))
641                 {
642                         if (de->d_name[0] != '.')
643                         {
644 #ifdef __GP2X__
645                                 if (de->d_type == 4) // Directory
646 #endif
647 #ifdef __GIZ__
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)
652 #endif  
653                                 {
654                         
655                                         for (i=ROM_SELECTOR_DEFAULT_FOCUS+1;i<=(romCount+1);i++)
656                                         {
657                                                 if (romList[i].filename[0] == 0) // string is empty so shove new value in
658                                                 {
659                                                         strcpy(romList[i].filename,de->d_name);
660                                                         romList[i].type=FILE_TYPE_DIRECTORY;//de->d_type;
661                                                         break;
662                                                 }
663                                                 else
664                                                 {
665                                                         if ((StringCompare(romList[i].filename,de->d_name) > 0) ||
666                                                                   (romList[i].type != FILE_TYPE_DIRECTORY))
667                                                         {
668                                                                 // new entry is lower than current string so move all entries up one and insert
669                                                                 // new value in
670                                                                 for (j=romCount;j>=i;j--)
671                                                                 {
672                                                                         strcpy(romList[j+1].filename,romList[j].filename);
673                                                                         romList[j+1].type=romList[j].type;
674                                                                 }
675                                                                 strcpy(romList[i].filename,de->d_name);
676                                                                 romList[i].type=FILE_TYPE_DIRECTORY;//de->d_type;
677                                                                 break;
678                                                         }
679                                                 }
680                                         }
681                                         dirCount++;
682                                         romCount++;
683                                 }
684                                 else // File
685                                 {
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))
691                                         {
692                                                 for (i=ROM_SELECTOR_DEFAULT_FOCUS+1+dirCount;i<=(romCount+1);i++)
693                                                 {
694                                                         if (romList[i].filename[0] == 0) // string is empty so shove new value in
695                                                         {
696                                                                 strcpy(romList[i].filename,de->d_name);
697                                                                 romList[i].type=FILE_TYPE_FILE;//de->d_type;
698                                                                 break;
699                                                         }
700                                                         else
701                                                         {
702                                                                 if (StringCompare(romList[i].filename,de->d_name) > 0)
703                                                                 {
704                                                                         // new entry is lower than current string so move all entries up one and insert
705                                                                         // new value in
706                                                                         for (j=romCount;j>=i;j--)
707                                                                         {
708                                                                                 strcpy(romList[j+1].filename,romList[j].filename);
709                                                                                 romList[j+1].type=romList[j].type;
710                                                                         }
711                                                                         strcpy(romList[i].filename,de->d_name);
712                                                                         romList[i].type=FILE_TYPE_FILE;//de->d_type;
713                                                                         break;
714                                                                 }
715                                                         }
716                                                 }
717                                                 romCount++;
718                                         }
719                                 }
720
721                                 
722                                 if (romCount > MAX_ROMS)
723                                 {
724                                         PrintTile(currFB);
725                                         PrintTitle(currFB);
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]);
730                                         MenuFlip();
731                                         MenuPause();
732                                         break;
733                                 }
734                         }
735                 }
736                 closedir(d);
737         }
738         else
739         {
740                 PrintTile(currFB);
741                 PrintTitle(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]);
744                 MenuFlip();
745                 MenuPause();
746         }
747
748         return romCount;
749 }
750
751 int FileSelect(int mode)
752 {
753         char text[256];
754         int romname_length;
755         int action=0;
756         int smooth=0;
757         unsigned short color=0;
758         int i=0;
759         int focus=ROM_SELECTOR_DEFAULT_FOCUS;
760         int menuExit=0;
761         int scanstart=0,scanend=0;
762         char dirSep[2]={DIR_SEP};
763         char dirSepBad[2]={DIR_SEP_BAD};
764         
765         FileScan();
766
767         smooth=focus<<8;
768
769         while (menuExit==0)
770         {
771                 InputUpdate(0);
772
773                 // Change which rom is focused on:
774                 if (Inp.repeat[INP_BUTTON_UP])
775                 {
776                         focus--; // Up
777                 }
778                 if (Inp.repeat[INP_BUTTON_DOWN])
779                 {
780                         focus++; // Down
781                 }
782
783                 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) {action=0; menuExit=1;}
784    
785                 if (Inp.repeat[INP_BUTTON_LEFT] || Inp.repeat[INP_BUTTON_RIGHT]   )
786                 {
787                         if (Inp.repeat[INP_BUTTON_LEFT]) 
788                         {
789                                 focus-=12;
790                                 smooth=(focus<<8)-1;
791                         }      
792                         else if (Inp.repeat[INP_BUTTON_RIGHT])
793                         {
794                                 focus+=12;
795                                 smooth=(focus<<8)-1;
796                         }
797                         
798                         if (focus>romCount-1) 
799                         {
800                                 focus=romCount-1;
801                                 smooth=(focus<<8)-1;
802                         }
803                         else if (focus<0)
804                         {
805                                 focus=0;
806                                 smooth=(focus<<8)-1;
807                         }
808                 }
809
810                 if (focus>romCount-1) 
811                 {
812                         focus=0;
813                         smooth=(focus<<8)-1;
814                 }
815                 else if (focus<0)
816                 {
817                         focus=romCount-1;
818                         smooth=(focus<<8)-1;
819                 }
820                 
821                 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
822             {
823                         switch(focus)
824                         {
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);
828                                         break;
829                                         
830                                 case 1: //Return to menu
831                                         action=0;
832                                         menuExit=1;
833                                         break;
834                                         
835                                 case 2: //Goto Parent Directory
836                                         // up a 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
839                                         //This is by design.
840                                         for(i=strlen(romDir)-1;i>0;i--) // don't want to change first char in screen
841                                         {
842                                                 if((romDir[i] == dirSep[0]) || (romDir[i] == dirSepBad[0]))
843                                                 {
844                                                         romDir[i] = 0;
845                                                         break;
846                                                 }
847                                         }
848                                         FileScan();
849                                         focus=ROM_SELECTOR_DEFAULT_FOCUS; // default menu to non menu item
850                                                                                                         // just to stop directory scan being started 
851                                         smooth=focus<<8;
852                                         memset(&headerDone,0,sizeof(headerDone)); //clear header
853                                         break;
854                                         
855                                 case ROM_SELECTOR_DEFAULT_FOCUS: //blank space - do nothing
856                                         break;
857                                         
858                                 default:
859                                         // normal file or dir selected
860                                         if (romList[focus].type == FILE_TYPE_DIRECTORY)
861                                         {
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);
865                                                 FileScan();
866                                                 focus=ROM_SELECTOR_DEFAULT_FOCUS; // default menu to non menu item
867                                                                                                                 // just to stop directory scan being started 
868                                                 smooth=focus<<8;
869                                         }
870                                         else
871                                         {
872                                                 // user has selected a rom, so load it
873                                                 sprintf(currentRomFilename,romList[focus].filename);
874                                                 quickSavePresent=0;  // reset any quick saves
875                                                 action=1;
876                                                 menuExit=1;
877                                         }
878                                         break;
879                         }
880             }
881
882                 if (Inp.held[INP_BUTTON_MENU_DELETE]==1)
883                 {
884                         if(focus>ROM_SELECTOR_DEFAULT_FOCUS)
885                         {
886                                 //delete current rom
887                                 if (romList[focus].type != FILE_TYPE_DIRECTORY)
888                                 {
889                                         sprintf(text,"%s",romList[focus].filename);
890
891                                         if(MenuMessageBox("Are you sure you want to delete",text,"",0)==0)
892                                         {
893                                                 deleterom(focus);
894                                         }
895                                 }
896                         }
897                 }
898
899                 // Draw screen:
900                 PrintTile(currFB);
901                 PrintTitle(currFB);
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]); 
904                 
905                 smooth=smooth*7+(focus<<8); smooth>>=3;
906
907                 scanstart=focus-15;
908                 if (scanstart<0) scanstart=0;
909                 scanend = focus+15;
910                 if (scanend>romCount) scanend=romCount;
911                 
912                 for (i=scanstart;i<scanend;i++)
913                 {
914                         int x=0,y=0;
915       
916                         y=(i<<4)-(smooth>>4);
917                         x=8;
918                         y+=112;
919                         if (y<=48 || y>=232) continue;
920            
921                         if (i==focus)
922                         {
923                                 color=(unsigned short)MENU_RGB(0,0,0);
924                                 PrintBar(currFB,y-4);
925                         }
926                         else
927                         {
928                                 color=(unsigned short)MENU_RGB(31,31,31);
929                         }
930
931                         // Draw Directory icon if current entry is a directory
932                         if(romList[i].type == FILE_TYPE_DIRECTORY)
933                         {
934                                 gp_drawString(x-8,y,1,"+",color,framebuffer16[currFB]); 
935                         }
936                         
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]); 
940                 }
941
942                 MenuFlip();
943         }
944
945         return action;
946 }
947
948 static void ScanSaveStates(char *romname)
949 {
950         FILE *stream;
951         int i=0;
952         char savename[MAX_PATH+1];
953         char filename[MAX_PATH+1];
954         char ext[MAX_PATH+1];
955
956         if(!strcmp(romname,saveStateName)) return; // is current save state rom so exit
957         
958         SplitFilename(romname,filename,ext);
959
960         sprintf(savename,"%s.%s",filename,SAVESTATE_EXT);
961   
962         for(i=0;i<10;i++)
963         {
964                 /*
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 )
969                 */
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");
973                 if(stream)
974                 {
975                         // we have a savestate
976                         saveState[i].inUse = 1;
977                         fclose(stream); 
978                 }
979                 else
980                 {
981                         // no save state
982                         saveState[i].inUse = 0;
983                 }
984         }
985         strcpy(saveStateName,romname);  // save the last scanned romname
986 }
987
988 void LoadStateFile(char *filename)
989 {
990         S9xUnfreezeGame(filename);
991 }
992
993 static void SaveStateFile(char *filename)
994 {
995         S9xFreezeGame(filename);
996         sync();
997 }
998
999 static int SaveStateSelect(int mode)
1000 {
1001         char text[128];
1002         int action=11;
1003         int saveno=0;
1004         
1005         if(currentRomFilename[0]==0)
1006         {
1007                 // no rom loaded
1008                 // display error message and exit
1009                 return(0);
1010         }
1011         
1012         memset(&headerDone,0,sizeof(headerDone));
1013         ScanSaveStates(currentRomFilename);
1014
1015         while (action!=0&&action!=100)
1016         {
1017                 InputUpdate(0);
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;
1022               
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))
1028                 {
1029                         if(MenuMessageBox("Are you sure you want to delete","this save?","",0)==0) action=13;  //delete slot with no preview
1030                 }
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))
1035                 {
1036                         if(MenuMessageBox("Are you sure you want to delete","this save?","",0)==0) action=13;  //delete slot with no preview
1037                 }
1038
1039                 PrintTile(currFB);
1040                 PrintTitle(currFB);
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]);
1046       
1047                 if(saveno==-1) 
1048                 {
1049                         if(action!=10&&action!=0) 
1050                         {
1051                                 action=10;
1052                         }
1053                 }
1054                 else
1055                 {
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]);
1059                 }
1060       
1061                 switch(action)
1062                 {
1063                         case 1:
1064                                 //gp_drawString(112,145,14,"Checking....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1065                                 break;
1066                         case 2:
1067                                 gp_drawString(144,145,4,"FREE",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1068                                 break;
1069                         case 3:
1070                                 gp_drawString(104,145,14,"Previewing....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1071                                 break;
1072                         case 4:
1073                                 gp_drawString(88,145,18,"Previewing....fail",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1074                                 break;
1075                         case 5: 
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]);
1080                                 break;
1081                         case 6:
1082                                 gp_drawString(124,145,9,"Saving...",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1083                                 break;
1084                         case 7:
1085                                 gp_drawString(124,145,14,"Saving...Fail!",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1086                                 break;
1087                         case 8:
1088                                 gp_drawString(116,145,11,"loading....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1089                                 break;
1090                                 case 9:
1091                                 gp_drawString(116,145,15,"loading....Fail",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1092                                 break;
1093                         case 10:        
1094                                 PrintBar(currFB,145-4);
1095                                 gp_drawString(104,145,14,"Return To Menu",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1096                                 break;
1097                         case 12:
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]);
1103                                 break;
1104                         case 13:
1105                                 gp_drawString(116,145,11,"Deleting....",(unsigned short)MENU_RGB(31,31,31),framebuffer16[currFB]);
1106                                 break;
1107                 }
1108       
1109                 MenuFlip();
1110       
1111                 switch(action)
1112                 {
1113                         case 1:
1114                                 if(saveState[saveno].inUse) 
1115                                 {
1116                                         action=12;
1117                                 }
1118                                 else 
1119                                 {
1120                                         action=2;
1121                                 }
1122                                 break;
1123                         case 3:
1124                                 LoadStateFile(saveState[saveno].fullFilename);
1125                                 action=5;
1126                                 break;
1127                         case 6:
1128                                 SaveStateFile(saveState[saveno].fullFilename);
1129                                 saveState[saveno].inUse=1;
1130                                 action=1;
1131                                 break;
1132                         case 7:
1133                                 action=1;
1134                                 break;
1135                         case 8:
1136                                 LoadStateFile(saveState[saveno].fullFilename);
1137                                 action=100;  // loaded ok so exit
1138                                 break;
1139                         case 9:
1140                                 action=1;
1141                                 break;
1142                         case 11:
1143                                 action=1;
1144                                 break;
1145                         case 13:
1146                                 remove(saveState[saveno].fullFilename);
1147                                 sync();
1148                                 saveState[saveno].inUse = 0;
1149                                 action=1;
1150                                 break;
1151                 }
1152         }
1153         memset(&headerDone,0,sizeof(headerDone));
1154         return(action);
1155 }
1156
1157 static
1158 void RenderMenu(char *menuName, int menuCount, int menuSmooth, int menufocus)
1159 {
1160         
1161         int i=0;
1162         char text[50];
1163         unsigned short color=0;
1164         PrintTile(currFB);
1165         PrintTitle(currFB);
1166
1167         gp_drawString(6,35,strlen(menuName),menuName,(unsigned short)MENU_RGB(31,0,0),framebuffer16[currFB]); 
1168     
1169     // RRRRRGGGGGBBBBBI  gp32 color format
1170     for (i=0;i<menuCount;i++)
1171     {
1172       int x=0,y=0;
1173
1174       y=(i<<4)-(menuSmooth>>4);
1175       x=8;
1176       y+=112;
1177
1178       if (y<=48 || y>=232) continue;
1179       
1180       if (i==menufocus)
1181       {
1182         color=(unsigned short)MENU_RGB(0,0,0);
1183                 PrintBar(currFB,y-4);
1184       }
1185       else
1186       {
1187         color=(unsigned short)MENU_RGB(31,31,31);
1188       }
1189
1190       sprintf(text,"%s",menutext[i]);
1191       gp_drawString(x,y,strlen(text),text,color,framebuffer16[currFB]);
1192     }
1193
1194 }
1195
1196 static
1197 int LoadRomMenu(void)
1198 {
1199         int menuExit=0,menuCount=LOAD_ROM_MENU_COUNT,menufocus=0,menuSmooth=0;
1200         int action=0;
1201         int subaction=0;
1202
1203         memset(&headerDone,0,sizeof(headerDone));
1204         strcpy(romDir,snesRomDir);
1205         subaction=FileSelect(0);
1206         memset(&headerDone,0,sizeof(headerDone));
1207         if(subaction)
1208         {
1209                 action=EVENT_LOAD_SNES_ROM;
1210                 menuExit=1;
1211         }
1212
1213         return action;
1214 }
1215
1216 static
1217 int SaveStateMenu(void)
1218 {
1219         int menuExit=0,menuCount=SAVESTATE_MENU_COUNT,menufocus=0,menuSmooth=0;
1220         int action=0;
1221         int subaction=0;
1222
1223         memset(&headerDone,0,sizeof(headerDone));
1224   
1225         //Update
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");
1230         
1231         while (!menuExit)
1232         {
1233                 InputUpdate(0);
1234
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
1238     
1239                 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1240     
1241                 if (menufocus>menuCount-1)
1242                 {
1243                         menufocus=0;
1244                         menuSmooth=(menufocus<<8)-1;
1245                 }   
1246                 else if (menufocus<0) 
1247                 {
1248                         menufocus=menuCount-1;
1249                         menuSmooth=(menufocus<<8)-1;
1250                 }
1251
1252                 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1253                 {
1254                         switch(menufocus)
1255                         {
1256                                 case SAVESTATE_MENU_LOAD:
1257                                         subaction=SaveStateSelect(SAVESTATE_MODE_LOAD);
1258                                         if(subaction==100)
1259                                         {
1260                                                 menuExit=1;
1261                                                 action=100;
1262                                         }
1263                                         break;
1264                                 case SAVESTATE_MENU_SAVE:
1265                                         SaveStateSelect(SAVESTATE_MODE_SAVE);
1266                                         break;
1267                                 case SAVESTATE_MENU_DELETE:
1268                                         SaveStateSelect(SAVESTATE_MODE_DELETE);
1269                                         break;
1270                                 case SAVESTATE_MENU_RETURN:
1271                                         menuExit=1;
1272                                         break;
1273                         }       
1274                 }
1275                 // Draw screen:
1276                 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
1277                 RenderMenu("Save States", menuCount,menuSmooth,menufocus);
1278                 MenuFlip();
1279        
1280         }
1281   
1282   return action;
1283 }
1284
1285 static
1286 int SramMenu(void)
1287 {
1288         int menuExit=0,menuCount=SRAM_MENU_COUNT,menufocus=0,menuSmooth=0;
1289         int action=0;
1290         int subaction=0;
1291         char *srammem=NULL;
1292         
1293
1294         memset(&headerDone,0,sizeof(headerDone));
1295   
1296         //Update
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");
1301         
1302         while (!menuExit)
1303         {
1304                 InputUpdate(0);
1305
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
1309     
1310                 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1311     
1312                 if (menufocus>menuCount-1)
1313                 {
1314                         menufocus=0;
1315                         menuSmooth=(menufocus<<8)-1;
1316                 }   
1317                 else if (menufocus<0) 
1318                 {
1319                         menufocus=menuCount-1;
1320                         menuSmooth=(menufocus<<8)-1;
1321                 }
1322
1323                 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1324                 {
1325                         switch(menufocus)
1326                         {
1327                                 case SRAM_MENU_LOAD:
1328                                         //LoadSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT,(char*)&sram);
1329                                         break;
1330                                 case SRAM_MENU_SAVE:
1331                                         //SaveSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT,(char*)&sram);
1332                                         break;
1333                                 case SRAM_MENU_DELETE:
1334                                         //DeleteSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT);
1335                                         break;
1336                                 case SRAM_MENU_RETURN:
1337                                         menuExit=1;
1338                                         break;
1339                         }       
1340                 }
1341                 // Draw screen:
1342                 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
1343                 RenderMenu("SRAM", menuCount,menuSmooth,menufocus);
1344                 MenuFlip();
1345        
1346         }
1347   
1348   return action;
1349 }
1350
1351 static 
1352 void SNESOptionsUpdateText(int menu_index)
1353 {
1354         switch(menu_index)
1355         {
1356                 case SNES_MENU_SOUND:
1357                 switch(snesMenuOptions.soundOn)
1358                 {
1359                         case 0:
1360                                 sprintf(menutext[SNES_MENU_SOUND],"Sound: OFF");
1361                                 break;
1362                         case 1:
1363                                 sprintf(menutext[SNES_MENU_SOUND],"Sound: ON");
1364                                 break;
1365                 }
1366                 break;
1367                 
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]);
1371                         else
1372                                 sprintf(menutext[SNES_MENU_SOUND_RATE],"Sound Rate: %d mono",(unsigned int)soundRates[snesMenuOptions.soundRate]);
1373                         break;
1374 #if defined(__GP2X__)   
1375                 case SNES_MENU_CPUSPEED:
1376                         sprintf(menutext[SNES_MENU_CPUSPEED],"Cpu Speed: %d",(unsigned int)cpuSpeedLookup[snesMenuOptions.cpuSpeed]);
1377                         break;
1378 #endif                  
1379                 case SNES_MENU_SOUND_VOL:
1380                         sprintf(menutext[SNES_MENU_SOUND_VOL],"Volume: %d",snesMenuOptions.volume);
1381                         break;
1382                 
1383                 case SNES_MENU_FRAMESKIP:
1384                         switch(snesMenuOptions.frameSkip)
1385                         {
1386                                 case 0:
1387                                         sprintf(menutext[SNES_MENU_FRAMESKIP],"Frameskip: AUTO");
1388                                         break;
1389                                 default:
1390                                         sprintf(menutext[SNES_MENU_FRAMESKIP],"Frameskip: %d",snesMenuOptions.frameSkip-1);
1391                                         break;
1392                         }
1393                         break;
1394                         
1395                 case SNES_MENU_REGION:
1396                         switch(snesMenuOptions.region)
1397                         {
1398                                 case 0:
1399                                         sprintf(menutext[SNES_MENU_REGION],"Region: AUTO");
1400                                         break;
1401                                 case 1:
1402                                         sprintf(menutext[SNES_MENU_REGION],"Region: NTSC");
1403                                         break;
1404                                 case 2:
1405                                         sprintf(menutext[SNES_MENU_REGION],"Region: PAL");
1406                                         break;
1407                         }
1408                         break;
1409
1410                 case SNES_MENU_FPS:
1411                         switch(snesMenuOptions.showFps)
1412                         {
1413                                 case 0:
1414                                         sprintf(menutext[SNES_MENU_FPS],"Show FPS: OFF");
1415                                         break;
1416                                 case 1:
1417                                         sprintf(menutext[SNES_MENU_FPS],"Show FPS: ON");
1418                                         break;
1419                         }
1420                         break;
1421 #if defined(__GP2X__)                   
1422                 case SNES_MENU_GAMMA:
1423                         sprintf(menutext[SNES_MENU_GAMMA],"Brightness: %d",snesMenuOptions.gamma+100);
1424                         break;
1425 #endif          
1426                 case SNES_MENU_TRANSPARENCY:
1427                         switch(snesMenuOptions.transparency)
1428                         {
1429                                 case 0:
1430                                         sprintf(menutext[SNES_MENU_TRANSPARENCY],"Transparencies: OFF");
1431                                         break;
1432                                 case 1:
1433                                         sprintf(menutext[SNES_MENU_TRANSPARENCY],"Transparencies: ON");
1434                                         break;
1435                         }
1436                         break;
1437                         
1438                 case SNES_MENU_LOAD_GLOBAL:
1439                         sprintf(menutext[SNES_MENU_LOAD_GLOBAL],"Load Global Settings");
1440                         break;
1441                         
1442                 case SNES_MENU_SAVE_GLOBAL:
1443                         sprintf(menutext[SNES_MENU_SAVE_GLOBAL],"Save Global Settings");
1444                         break;
1445                         
1446                 case SNES_MENU_DELETE_GLOBAL:
1447                         sprintf(menutext[SNES_MENU_DELETE_GLOBAL],"Delete Global Settings");
1448                         break;
1449                         
1450                 case SNES_MENU_LOAD_CURRENT:
1451                         sprintf(menutext[SNES_MENU_LOAD_CURRENT],"Load Settings For Current Game");
1452                         break;
1453                 
1454                 case SNES_MENU_SAVE_CURRENT:
1455                         sprintf(menutext[SNES_MENU_SAVE_CURRENT],"Save Settings For Current Game");
1456                         break;
1457                         
1458                 case SNES_MENU_DELETE_CURRENT:
1459                         sprintf(menutext[SNES_MENU_DELETE_CURRENT],"Delete Settings For Current Game");
1460                         break;
1461                         
1462                 case SNES_MENU_SET_ROMDIR:
1463                         sprintf(menutext[SNES_MENU_SET_ROMDIR],"Save Current Rom Directory");
1464                         break;
1465                 
1466                 case SNES_MENU_CLEAR_ROMDIR:
1467                         sprintf(menutext[SNES_MENU_CLEAR_ROMDIR],"Reset Default Rom Directory");
1468                         break;
1469                         
1470                 case SNES_MENU_RETURN:
1471                         sprintf(menutext[SNES_MENU_RETURN],"Back");
1472                         break;
1473 #if defined(__GP2X__)
1474                 case SNES_MENU_RENDER_MODE:
1475                         switch(snesMenuOptions.renderMode)
1476                         {
1477                                 case RENDER_MODE_UNSCALED:
1478                                         sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Unscaled");
1479                                         break;
1480                                 case RENDER_MODE_SCALED:
1481                                         sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Scaled");
1482                                         break;
1483                                 default:
1484                                         sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Unscaled");
1485                                         break;
1486                         }
1487                         break;
1488                 case SNES_MENU_ACTION_BUTTONS:
1489                         switch(snesMenuOptions.actionButtons)
1490                         {
1491                                 case 0:
1492                                         sprintf(menutext[SNES_MENU_ACTION_BUTTONS],"Action Buttons: Normal");
1493                                         break;
1494                                 case 1:
1495                                         sprintf(menutext[SNES_MENU_ACTION_BUTTONS],"Action Buttons: Swapped");
1496                                         break;
1497                         }
1498                         break;
1499 #endif
1500                 case SNES_MENU_AUTO_SAVE_SRAM:
1501                         switch(snesMenuOptions.autoSram)
1502                         {
1503                                 case 0:
1504                                         sprintf(menutext[SNES_MENU_AUTO_SAVE_SRAM],"Saving SRAM: Manual");
1505                                         break;
1506                                 case 1:
1507                                         sprintf(menutext[SNES_MENU_AUTO_SAVE_SRAM],"Saving SRAM: Automatic");
1508                                         break;
1509                         }
1510                         break;
1511 #if defined(__GP2X__)
1512                 case SNES_MENU_RAM_SETTINGS:
1513                         switch(snesMenuOptions.ramSettings)
1514                         {
1515                                 case 0:
1516                                         sprintf(menutext[SNES_MENU_RAM_SETTINGS],"RAM timing (Restart Required): NORMAL");
1517                                         break;
1518                                 case 1:
1519                                         sprintf(menutext[SNES_MENU_RAM_SETTINGS],"RAM timing (Restart Required): CRAIG");
1520                                         break;
1521                         }
1522                         break;
1523                 case SNES_MENU_MMU_HACK:
1524                         switch(snesMenuOptions.mmuHack)
1525                         {
1526                                 case 0:
1527                                         sprintf(menutext[SNES_MENU_MMU_HACK],"MMU Hack (Restart Required): OFF");
1528                                         break;
1529                                 case 1:
1530                                         sprintf(menutext[SNES_MENU_MMU_HACK],"MMU Hack (Restart Required): ON");
1531                                         break;
1532                         }
1533                         break;
1534 #endif
1535                 case SNES_MENU_ADVANCED_HACKS:
1536                         sprintf(menutext[SNES_MENU_ADVANCED_HACKS],"Advanced hacks");
1537                         break;
1538         }
1539 }
1540
1541 static 
1542 void SNESHacksUpdateText(int menu_index)
1543 {
1544         switch(menu_index)
1545         {
1546                 case HACKS_MENU_AUDIO:
1547                         if(snesMenuOptions.soundHack)
1548                                 sprintf(menutext[HACKS_MENU_AUDIO],"Audio Performance hack: ON");
1549                         else
1550                                 sprintf(menutext[HACKS_MENU_AUDIO],"Audio Performance hack: OFF");
1551                 break;
1552                 case HACKS_MENU_PALETTE:
1553                         if(snesMenuOptions.graphHacks & PPU_IGNORE_PALWRITE)
1554                                 sprintf(menutext[HACKS_MENU_PALETTE],"Ignore Palette writes: ON");
1555                         else
1556                                 sprintf(menutext[HACKS_MENU_PALETTE],"Ignore Palette writes: OFF");
1557                 break;
1558                 case HACKS_MENU_FIXEDCOL:
1559                         if(snesMenuOptions.graphHacks & PPU_IGNORE_FIXEDCOLCHANGES)
1560                                 sprintf(menutext[HACKS_MENU_FIXEDCOL],"Ignore Fixed Colour: ON");
1561                         else
1562                                 sprintf(menutext[HACKS_MENU_FIXEDCOL],"Ignore Fixed Colour: OFF");
1563                 break;
1564                 case HACKS_MENU_WINDOW:
1565                         if(snesMenuOptions.graphHacks & PPU_IGNORE_WINDOW)
1566                                 sprintf(menutext[HACKS_MENU_WINDOW],"Ignore Windows clipping: ON");
1567                         else
1568                                 sprintf(menutext[HACKS_MENU_WINDOW],"Ignore Windows clipping: OFF");
1569                 break;
1570                 case HACKS_MENU_ADDSUB:
1571                         if(snesMenuOptions.graphHacks & PPU_IGNORE_ADDSUB)
1572                                 sprintf(menutext[HACKS_MENU_ADDSUB],"Ignore Add/Sub modes: ON");
1573                         else
1574                                 sprintf(menutext[HACKS_MENU_ADDSUB],"Ignore Add/Sub modes: OFF");
1575                 break;
1576                 case HACKS_MENU_OBJ:
1577                         if(snesMenuOptions.graphHacks & GFX_IGNORE_OBJ)
1578                                 sprintf(menutext[HACKS_MENU_OBJ],"Ignore objects layer: ON");
1579                         else
1580                                 sprintf(menutext[HACKS_MENU_OBJ],"Ignore objects layer: OFF");
1581                 break;
1582                 case HACKS_MENU_BG0:
1583                         if(snesMenuOptions.graphHacks & GFX_IGNORE_BG0)
1584                                 sprintf(menutext[HACKS_MENU_BG0],"Ignore background layer 0: ON");
1585                         else
1586                                 sprintf(menutext[HACKS_MENU_BG0],"Ignore background layer 0: OFF");
1587                 break;
1588                 case HACKS_MENU_BG1:
1589                         if(snesMenuOptions.graphHacks & GFX_IGNORE_BG1)
1590                                 sprintf(menutext[HACKS_MENU_BG1],"Ignore background layer 1: ON");
1591                         else
1592                                 sprintf(menutext[HACKS_MENU_BG1],"Ignore background layer 1: OFF");
1593                 break;
1594                 case HACKS_MENU_BG2:
1595                         if(snesMenuOptions.graphHacks & GFX_IGNORE_BG2)
1596                                 sprintf(menutext[HACKS_MENU_BG2],"Ignore background layer 2: ON");
1597                         else
1598                                 sprintf(menutext[HACKS_MENU_BG2],"Ignore background layer 2: OFF");
1599                 break;
1600                 case HACKS_MENU_BG3:
1601                         if(snesMenuOptions.graphHacks & GFX_IGNORE_BG3)
1602                                 sprintf(menutext[HACKS_MENU_BG3],"Ignore background layer 3: ON");
1603                         else
1604                                 sprintf(menutext[HACKS_MENU_BG3],"Ignore background layer 3: OFF");
1605                 break;
1606                 case HACKS_MENU_RETURN:
1607                         sprintf(menutext[HACKS_MENU_RETURN],"Back");
1608                         break;
1609
1610
1611         }
1612 }
1613
1614 static
1615 void SNESHacksUpdateText_All()
1616 {
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);
1628 }
1629
1630 static
1631 int SNESHacksMenu(void)
1632 {
1633         int menuExit=0,menuCount=HACKS_MENU_COUNT,menufocus=0,menuSmooth=0;
1634         int action=0;
1635         int subaction=0;
1636
1637         memset(&headerDone,0,sizeof(headerDone));
1638   
1639         //Update all items
1640         SNESHacksUpdateText_All();
1641         
1642         while (!menuExit)
1643         {
1644                 InputUpdate(0);
1645
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
1649     
1650                 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1651     
1652                 if (menufocus>menuCount-1)
1653                 {
1654                         menufocus=0;
1655                         menuSmooth=(menufocus<<8)-1;
1656                 }   
1657                 else if (menufocus<0) 
1658                 {
1659                         menufocus=menuCount-1;
1660                         menuSmooth=(menufocus<<8)-1;
1661                 }
1662
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])
1667                 {
1668                         switch(menufocus)
1669                         {
1670                                 case HACKS_MENU_AUDIO:
1671                                         snesMenuOptions.soundHack^=1;
1672                                         SNESHacksUpdateText(HACKS_MENU_AUDIO);
1673                                         break;
1674                                 case HACKS_MENU_PALETTE:
1675                                         if (snesMenuOptions.graphHacks & PPU_IGNORE_PALWRITE)
1676                                                 snesMenuOptions.graphHacks &= ~PPU_IGNORE_PALWRITE;
1677                                         else
1678                                                 snesMenuOptions.graphHacks |= PPU_IGNORE_PALWRITE;                                      
1679                                         SNESHacksUpdateText(HACKS_MENU_PALETTE);
1680                                         break;
1681                                 case HACKS_MENU_FIXEDCOL:
1682                                         if (snesMenuOptions.graphHacks & PPU_IGNORE_FIXEDCOLCHANGES)
1683                                                 snesMenuOptions.graphHacks &= ~PPU_IGNORE_FIXEDCOLCHANGES;
1684                                         else
1685                                                 snesMenuOptions.graphHacks |= PPU_IGNORE_FIXEDCOLCHANGES;                                       
1686                                         SNESHacksUpdateText(HACKS_MENU_FIXEDCOL);
1687                                         break;
1688                                 case HACKS_MENU_WINDOW:
1689                                         if (snesMenuOptions.graphHacks & PPU_IGNORE_WINDOW)
1690                                                 snesMenuOptions.graphHacks &= ~PPU_IGNORE_WINDOW;
1691                                         else
1692                                                 snesMenuOptions.graphHacks |= PPU_IGNORE_WINDOW;                                        
1693                                         SNESHacksUpdateText(HACKS_MENU_WINDOW);
1694                                         break;
1695                                 case HACKS_MENU_ADDSUB:
1696                                         if (snesMenuOptions.graphHacks & PPU_IGNORE_ADDSUB)
1697                                                 snesMenuOptions.graphHacks &= ~PPU_IGNORE_ADDSUB;
1698                                         else
1699                                                 snesMenuOptions.graphHacks |= PPU_IGNORE_ADDSUB;                                        
1700                                         SNESHacksUpdateText(HACKS_MENU_ADDSUB);
1701                                         break;
1702                                 case HACKS_MENU_OBJ:
1703                                         if (snesMenuOptions.graphHacks & GFX_IGNORE_OBJ)
1704                                                 snesMenuOptions.graphHacks &= ~GFX_IGNORE_OBJ;
1705                                         else
1706                                                 snesMenuOptions.graphHacks |= GFX_IGNORE_OBJ;                                   
1707                                         SNESHacksUpdateText(HACKS_MENU_OBJ);
1708                                         break;
1709                                 case HACKS_MENU_BG0:
1710                                         if (snesMenuOptions.graphHacks & GFX_IGNORE_BG0)
1711                                                 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG0;
1712                                         else
1713                                                 snesMenuOptions.graphHacks |= GFX_IGNORE_BG0;                                   
1714                                         SNESHacksUpdateText(HACKS_MENU_BG0);
1715                                         break;
1716                                 case HACKS_MENU_BG1:
1717                                         if (snesMenuOptions.graphHacks & GFX_IGNORE_BG1)
1718                                                 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG1;
1719                                         else
1720                                                 snesMenuOptions.graphHacks |= GFX_IGNORE_BG1;                                   
1721                                         SNESHacksUpdateText(HACKS_MENU_BG1);
1722                                         break;
1723                                 case HACKS_MENU_BG2:
1724                                         if (snesMenuOptions.graphHacks & GFX_IGNORE_BG2)
1725                                                 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG2;
1726                                         else
1727                                                 snesMenuOptions.graphHacks |= GFX_IGNORE_BG2;                                   
1728                                         SNESHacksUpdateText(HACKS_MENU_BG2);
1729                                         break;
1730                                 case HACKS_MENU_BG3:
1731                                         if (snesMenuOptions.graphHacks & GFX_IGNORE_BG3)
1732                                                 snesMenuOptions.graphHacks &= ~GFX_IGNORE_BG3;
1733                                         else
1734                                                 snesMenuOptions.graphHacks |= GFX_IGNORE_BG3;                                   
1735                                         SNESHacksUpdateText(HACKS_MENU_BG3);
1736                                         break;
1737                         }
1738                 }
1739                 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1740                 {
1741                         switch(menufocus)
1742                         {
1743                                 case HACKS_MENU_RETURN:
1744                                         menuExit=1;
1745                                         break;
1746                         }       
1747                 }
1748                 // Draw screen:
1749                 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
1750                 RenderMenu("SNES Advanced Hacks", menuCount,menuSmooth,menufocus);
1751                 MenuFlip();
1752        
1753         }
1754   
1755   return action;
1756 }
1757
1758 static
1759 void SNESOptionsUpdateText_All()
1760 {
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);
1784 #endif
1785         SNESOptionsUpdateText(SNES_MENU_AUTO_SAVE_SRAM);
1786         SNESOptionsUpdateText(SNES_MENU_ADVANCED_HACKS);
1787 }
1788
1789 static
1790 int SNESOptionsMenu(void)
1791 {
1792         int menuExit=0,menuCount=SNES_MENU_COUNT,menufocus=0,menuSmooth=0;
1793         int action=0;
1794         int subaction=0;
1795
1796         memset(&headerDone,0,sizeof(headerDone));
1797   
1798         //Update all items
1799         SNESOptionsUpdateText_All();
1800         
1801         while (!menuExit)
1802         {
1803                 InputUpdate(0);
1804
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
1808     
1809                 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1;
1810     
1811                 if (menufocus>menuCount-1)
1812                 {
1813                         menufocus=0;
1814                         menuSmooth=(menufocus<<8)-1;
1815                 }   
1816                 else if (menufocus<0) 
1817                 {
1818                         menufocus=menuCount-1;
1819                         menuSmooth=(menufocus<<8)-1;
1820                 }
1821
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])
1826                 {
1827                         switch(menufocus)
1828                         {
1829                                 case SNES_MENU_SOUND:
1830                                         snesMenuOptions.soundOn^=1;
1831                                         SNESOptionsUpdateText(SNES_MENU_SOUND);
1832                                         break;
1833                                 case SNES_MENU_SOUND_RATE:
1834                                         if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1835                                         {
1836                                                 if (!snesMenuOptions.stereo)
1837                                                         snesMenuOptions.stereo = 1;
1838                                                 else
1839                                                 {
1840                                                 snesMenuOptions.soundRate++;
1841                                                         snesMenuOptions.stereo = 0;
1842                                                 }
1843                                                 if(snesMenuOptions.soundRate>4) snesMenuOptions.soundRate=0;
1844                                         }
1845                                         else
1846                                         {
1847                                                 if (snesMenuOptions.stereo)
1848                                                         snesMenuOptions.stereo = 0;
1849                                                 else
1850                                                 {
1851                                                 snesMenuOptions.soundRate--;
1852                                                         snesMenuOptions.stereo = 1;
1853                                                 }
1854                                                 if(snesMenuOptions.soundRate>4) snesMenuOptions.soundRate=4;
1855                                         }
1856                                         SNESOptionsUpdateText(SNES_MENU_SOUND_RATE);
1857                                         break;
1858                                 case SNES_MENU_SOUND_VOL:
1859                                         if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1860                                         {
1861                                                 snesMenuOptions.volume+=1;
1862                                                 if(snesMenuOptions.volume>100) snesMenuOptions.volume=0;
1863                                         }
1864                                         else
1865                                         {
1866                                                 snesMenuOptions.volume-=1;
1867                                                 if(snesMenuOptions.volume>100) snesMenuOptions.volume=100;
1868                                         }
1869                                         SNESOptionsUpdateText(SNES_MENU_SOUND_VOL);
1870                                         break;
1871 #if defined(__GP2X__)
1872                                 case SNES_MENU_CPUSPEED:
1873                                         if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1874                                         {
1875                                                 snesMenuOptions.cpuSpeed++;
1876                                                 if(snesMenuOptions.cpuSpeed>40) snesMenuOptions.cpuSpeed=0;
1877                                         }
1878                                         else
1879                                         {
1880                                                 snesMenuOptions.cpuSpeed--;
1881                                                 if(snesMenuOptions.cpuSpeed>40) snesMenuOptions.cpuSpeed=0;
1882                                         }
1883                                         SNESOptionsUpdateText(SNES_MENU_CPUSPEED);
1884                                         break;
1885 #endif
1886                                 case SNES_MENU_FRAMESKIP:
1887                                         if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1888                                         {
1889                                                 snesMenuOptions.frameSkip++;
1890                                                 if(snesMenuOptions.frameSkip>6) snesMenuOptions.frameSkip=0;
1891                                         }
1892                                         else
1893                                         {
1894                                                 snesMenuOptions.frameSkip--;
1895                                                 if(snesMenuOptions.frameSkip>6) snesMenuOptions.frameSkip=6;
1896                                         }
1897                                         SNESOptionsUpdateText(SNES_MENU_FRAMESKIP);
1898                                         break;
1899                                 case SNES_MENU_REGION:
1900                                         if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1901                                         {
1902                                                 snesMenuOptions.region++;
1903                                                 if(snesMenuOptions.region>2) snesMenuOptions.region=0;
1904                                         }
1905                                         else
1906                                         {
1907                                                 snesMenuOptions.region--;
1908                                                 if(snesMenuOptions.region>2) snesMenuOptions.region=2;
1909                                         }
1910                                         SNESOptionsUpdateText(SNES_MENU_REGION);
1911                                         break;
1912                                 case SNES_MENU_FPS:
1913                                         snesMenuOptions.showFps^=1;
1914                                         SNESOptionsUpdateText(SNES_MENU_FPS);
1915                                         break;
1916 #if defined(__GP2X__)
1917                                 case SNES_MENU_GAMMA:
1918                                         if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT])
1919                                         {
1920                                                 snesMenuOptions.gamma++;
1921                                                 if(snesMenuOptions.gamma>100) snesMenuOptions.gamma=100;
1922                                         }
1923                                         else
1924                                         {
1925                                                 snesMenuOptions.gamma--;
1926                                                 if(snesMenuOptions.gamma<-100) snesMenuOptions.gamma=-100;
1927                                         }
1928                                         set_gamma(snesMenuOptions.gamma+100);
1929                                         SNESOptionsUpdateText(SNES_MENU_GAMMA);
1930                                         break;
1931                                 case SNES_MENU_ACTION_BUTTONS:
1932                                         snesMenuOptions.actionButtons^=1;
1933                                         SNESOptionsUpdateText(SNES_MENU_ACTION_BUTTONS);
1934                                         break;
1935 #endif
1936                                 case SNES_MENU_TRANSPARENCY:
1937                                         snesMenuOptions.transparency^=1;
1938                                         SNESOptionsUpdateText(SNES_MENU_TRANSPARENCY);
1939                                         break;
1940 #if defined(__GP2X__)
1941                                 case SNES_MENU_RENDER_MODE:
1942                                         snesMenuOptions.renderMode^=1;
1943                                         SNESOptionsUpdateText(SNES_MENU_RENDER_MODE);
1944                                         break;
1945 #endif
1946                                 case SNES_MENU_AUTO_SAVE_SRAM:
1947                                         snesMenuOptions.autoSram^=1;
1948                                         SNESOptionsUpdateText(SNES_MENU_AUTO_SAVE_SRAM);
1949                                         break;
1950 #if defined(__GP2X__)
1951                                 case SNES_MENU_RAM_SETTINGS:
1952                                         snesMenuOptions.ramSettings^=1;
1953                                         SNESOptionsUpdateText(SNES_MENU_RAM_SETTINGS);
1954                                         break;
1955                                 case SNES_MENU_MMU_HACK:
1956                                         snesMenuOptions.mmuHack^=1;
1957                                         SNESOptionsUpdateText(SNES_MENU_MMU_HACK);
1958                                         break;
1959 #endif
1960                         }
1961                 }
1962                 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
1963                 {
1964                         switch(menufocus)
1965                         {
1966                                 case SNES_MENU_ADVANCED_HACKS:
1967                                         memset(&headerDone,0,sizeof(headerDone));
1968                                         subaction = SNESHacksMenu();
1969                                         memset(&headerDone,0,sizeof(headerDone));
1970                                         SNESOptionsUpdateText_All();
1971                                         break;
1972                                 case SNES_MENU_LOAD_GLOBAL:
1973                                         LoadMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1974                                         SNESOptionsUpdateText_All();
1975                                         break;
1976                                 case SNES_MENU_SAVE_GLOBAL:
1977                                         SaveMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1978                                         break;
1979                                 case SNES_MENU_DELETE_GLOBAL:
1980                                         DeleteMenuOptions(snesOptionsDir,MENU_OPTIONS_FILENAME,MENU_OPTIONS_EXT,1);
1981                                         break;
1982                                 case SNES_MENU_LOAD_CURRENT:
1983                                         if(currentRomFilename[0]!=0)
1984                                         {
1985                                                 LoadMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1986                                                 SNESOptionsUpdateText_All();
1987                                         }
1988                                         break;
1989                                 case SNES_MENU_SAVE_CURRENT:
1990                                         if(currentRomFilename[0]!=0)
1991                                         {
1992                                                 SaveMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1);
1993                                         }
1994                                         break;
1995                                 case SNES_MENU_DELETE_CURRENT:
1996                                         if(currentRomFilename[0]!=0)
1997                                         {
1998                                                 DeleteMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT,1);
1999                                         }
2000                                         break;
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);
2004                                         break;
2005                                 case SNES_MENU_CLEAR_ROMDIR:
2006                                         DeleteMenuOptions(snesOptionsDir, DEFAULT_ROM_DIR_FILENAME, DEFAULT_ROM_DIR_EXT,1);
2007                                         strcpy(snesRomDir,currentWorkingDir);
2008                                         break;
2009                                 case SNES_MENU_RETURN:
2010                                         menuExit=1;
2011                                         break;
2012                         }       
2013                 }
2014                 // Draw screen:
2015                 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
2016                 RenderMenu("SNES Options", menuCount,menuSmooth,menufocus);
2017                 MenuFlip();
2018        
2019         }
2020   
2021   return action;
2022 }
2023
2024 static
2025 void MainMenuUpdateText(void)
2026 {
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");
2034 }
2035
2036
2037 int MainMenu(int prevaction)
2038 {
2039         int menuExit=0,menuCount=MAIN_MENU_COUNT,menufocus=0,menuSmooth=0;
2040         int action=prevaction;
2041         int subaction=0;
2042                         
2043         gp_setCpuspeed(MENU_CPU_SPEED);
2044         
2045         gp_initGraphics(16,currFB,snesMenuOptions.mmuHack);
2046         gp_clearFramebuffer16((unsigned short*)framebuffer16[currFB],0x0);
2047         MenuFlip();
2048         gp2x_video_RGB_setscaling(320,240);
2049         
2050         memset(&headerDone,0,sizeof(headerDone));
2051         MainMenuUpdateText();
2052         
2053         while (!menuExit)
2054         {
2055                 InputUpdate(0);
2056
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
2060     
2061                 if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) 
2062                 {
2063                         if(currentRomFilename[0]!=0)
2064                         {
2065                                 menuExit=1;
2066                         }
2067                 }
2068     
2069                 if (menufocus>menuCount-1)
2070                 {
2071                         menufocus=0;
2072                         menuSmooth=(menufocus<<8)-1;
2073                 }   
2074                 else if (menufocus<0) 
2075                 {
2076                         menufocus=menuCount-1;
2077                         menuSmooth=(menufocus<<8)-1;
2078                 }
2079
2080                 if (Inp.held[INP_BUTTON_MENU_SELECT]==1)
2081                 {
2082                         switch(menufocus)
2083                         {
2084                                 case MAIN_MENU_ROM_SELECT:
2085                                         memset(&headerDone,0,sizeof(headerDone));
2086                                         subaction=LoadRomMenu();
2087                                         memset(&headerDone,0,sizeof(headerDone));
2088                                         if(subaction)
2089                                         {
2090                                                 action=subaction;
2091                                                 menuExit=1;
2092                                         }
2093                                         MainMenuUpdateText();
2094                                         break;
2095
2096                                 case MAIN_MENU_MANAGE_SAVE_STATE:
2097                                         if(currentRomFilename[0]!=0)
2098                                         {
2099                                                 memset(&headerDone,0,sizeof(headerDone));
2100                                                 subaction=SaveStateMenu();
2101                                                 if (subaction==100)
2102                                                 {
2103                                                         menuExit=1;
2104                                                 }
2105                                                 memset(&headerDone,0,sizeof(headerDone));
2106                                         }
2107                                         MainMenuUpdateText();
2108                                         break;
2109                                 case MAIN_MENU_SAVE_SRAM:
2110                                         if(currentRomFilename[0]!=0)
2111                                         {
2112                                                 S9xSaveSRAM();
2113                                         }
2114                                         break;
2115                                 case MAIN_MENU_SNES_OPTIONS:
2116
2117                                         memset(&headerDone,0,sizeof(headerDone));
2118                                         subaction=SNESOptionsMenu();
2119                                         memset(&headerDone,0,sizeof(headerDone));
2120                                         MainMenuUpdateText();
2121                                         break;
2122                                 case MAIN_MENU_RESET_GAME       :
2123                                         if(currentRomFilename[0]!=0)
2124                                         {
2125                                                 switch(currentEmuMode)
2126                                                 {
2127                                                         case EMU_MODE_SNES:
2128                                                                 action=EVENT_RESET_SNES_ROM;
2129                                                                 menuExit=1;
2130                                                                 break;
2131                                                 }
2132                                         }
2133                                         break;
2134                                 case MAIN_MENU_RETURN:
2135                                         if(currentRomFilename[0]!=0)
2136                                         {
2137                                                 menuExit=1;
2138                                         }
2139                                         break;
2140                                 case MAIN_MENU_EXIT_APP:
2141                                         action=EVENT_EXIT_APP;
2142                                         menuExit=1;
2143                                         break;
2144                         }       
2145                 }
2146                 // Draw screen:
2147                 menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3;
2148                 RenderMenu("Main Menu", menuCount,menuSmooth,menufocus);
2149                 MenuFlip();
2150        
2151         }
2152         
2153   WaitForButtonsUp();
2154   
2155   return action;
2156 }
2157
2158
2159