more menu work, scalers, sound
authornotaz <notasas@gmail.com>
Sun, 13 May 2007 21:28:01 +0000 (21:28 +0000)
committernotaz <notasas@gmail.com>
Sun, 13 May 2007 21:28:01 +0000 (21:28 +0000)
git-svn-id: file:///home/notaz/opt/svn/fceu@131 be3aeb3a-fb24-0410-a615-afba39da0efa

16 files changed:
driver.h
drivers/gp2x/asmutils.h
drivers/gp2x/asmutils.s
drivers/gp2x/gp2x-sound.c
drivers/gp2x/gp2x-video.c
drivers/gp2x/gp2x.c
drivers/gp2x/gp2x.h
drivers/gp2x/input.c
drivers/gp2x/main.c
drivers/gp2x/menu.c
drivers/gp2x/minimal.c
drivers/gp2x/minimal.h
fce.c
fds.c
movie.c
svga.c

index 7e86dad..e240960 100644 (file)
--- a/driver.h
+++ b/driver.h
@@ -104,6 +104,7 @@ void FCEUI_SaveExtraDataUnderBase(int a);
 
 /* name=path and file to load.  returns 0 on failure, 1 on success */
 FCEUGI *FCEUI_LoadGame(char *name);
+extern int LoadGameLastError;
 
 /* allocates memory.  0 on failure, 1 on success. */
 int FCEUI_Initialize(void);
index 5f3d895..52f9ab8 100644 (file)
@@ -2,4 +2,5 @@ void flushcache(unsigned int beginning_addr, unsigned int end_addr, unsigned int
 void block_or(void *src, size_t n, int pat);\r
 void block_andor(void *src, size_t n, int andpat, int orpat);\r
 void spend_cycles(int c); // utility\r
+void soft_scale(void *dst, unsigned short *pal, int offs, int lines);\r
 \r
index 3db4e30..4a2e1a3 100644 (file)
@@ -66,6 +66,88 @@ spend_cycles:
     bx      lr
 
 
+.global soft_scale @ void *dst, unsigned short *pal, int offs, int lines
+
+soft_scale:
+    stmfd   sp!,{r4-r11,lr}
+    mov     lr, #0xff
+    mov     lr, lr, lsl #1
+    mov     r9, #0x3900        @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007
+    orr     r9, r9, #0x00e7
+
+    mov     r11,r3             @ r11= line counter
+    mov     r3, r1             @ r3 = pal base
+
+    mov     r12,#320
+    mul     r2, r12,r2
+    add     r4, r0, r2, lsl #1 @ r4 = dst_start
+    add     r5, r0, r2         @ r5 = src_start
+    mul     r12,r11,r12
+    add     r0, r4, r12,lsl #1 @ r0 = dst_end
+    add     r1, r5, r12        @ r1 = src_end
+
+soft_scale_loop:
+    sub     r1, r1, #64        @ skip borders
+    mov     r2, #256/8
+
+soft_scale_loop_line:
+    ldr     r12, [r1, #-8]!
+    ldr     r7,  [r1, #4]
+
+    and     r4, lr, r12,lsl #1
+    ldrh    r4, [r3, r4]
+    and     r5, lr, r12,lsr #7
+    ldrh    r5, [r3, r5]
+    and     r4, r4, r9, lsl #2
+    orr     r4, r4, r4, lsl #14       @ r4[31:16] = 1/4 pix_s 0
+    and     r5, r5, r9, lsl #2
+    sub     r6, r5, r5, lsr #2        @ r6 = 3/4 pix_s 1
+    add     r4, r4, r6, lsl #16       @ pix_d 0, 1
+    and     r6, lr, r12,lsr #15
+    ldrh    r6, [r3, r6]
+    and     r12,lr, r12,lsr #23
+    ldrh    r12,[r3, r12]
+    and     r6, r6, r9, lsl #2
+    add     r5, r5, r6
+    mov     r5, r5, lsr #1
+    sub     r6, r6, r6, lsr #2        @ r6 = 3/4 pix_s 2
+    orr     r5, r5, r6, lsl #16
+
+    and     r6, lr, r7, lsl #1
+    ldrh    r6, [r3, r6]
+    and     r12,r12,r9, lsl #2
+    add     r5, r5, r12,lsl #14       @ pix_d 2, 3
+    and     r6, r6, r9, lsl #2
+    orr     r6, r12,r6, lsl #16       @ pix_d 4, 5
+
+    and     r12,lr, r7, lsr #7
+    ldrh    r12,[r3, r12]
+    and     r10,lr, r7, lsr #15
+    ldrh    r10,[r3, r10]
+    and     r12,r12,r9, lsl #2
+    sub     r8, r12,r12,lsr #2        @ r8 = 3/4 pix_s 1
+    add     r8, r8, r6, lsr #18
+    and     r7, lr, r7, lsr #23
+    ldrh    r7, [r3, r7]
+    and     r10,r10,r9, lsl #2
+    orr     r8, r8, r10,lsl #15
+    add     r8, r8, r12,lsl #15       @ pix_d 6, 7
+    sub     r10,r10,r10,lsr #2        @ r10= 3/4 pix_s 2
+    and     r7, r7, r9, lsl #2
+    add     r10,r10,r7, lsr #2        @ += 1/4 pix_s 3
+    orr     r10,r10,r7, lsl #16       @ pix_d 8, 9
+
+    subs    r2, r2, #1
+
+    stmdb   r0!, {r4,r5,r6,r8,r10}
+    bne     soft_scale_loop_line
+
+    subs    r11,r11,#1
+    bne     soft_scale_loop
+
+    ldmfd   sp!,{r4-r11,lr}
+    bx      lr
+
 
 /* buggy and slow, probably because function call overhead
 @ renderer helper, based on bitbank's method
index 20af608..cb5e0d9 100644 (file)
@@ -37,12 +37,10 @@ void SilenceSound(int n)
        soundvol=0;
 }
 
-int InitSound(FCEUGI *gi)
+int InitSound(void)
 {
-       Settings.sound=22050;
-       FCEUI_Sound(Settings.sound);
+       FCEUI_Sound(Settings.sound_rate);
        gp2x_sound_volume(soundvol, soundvol);
-       printf("InitSound() sound_rate: %d\n", Settings.sound);
        return 1;
 }
 
index 6986df1..b1bf165 100644 (file)
 #include "gp2x.h"
 #include "minimal.h"
 #include "fonts.h"
+#include "asmutils.h"
 
 static char fps_str[32];
 static int framesEmulated, framesRendered;
 
 int gp2x_palette[256];
+unsigned short gp2x_palette16[256];
 
-int scaled_display=0;
 int paletterefresh;
 
 #define FPS_COLOR 1
@@ -101,9 +102,11 @@ void ToggleFS(void)
 }
 
 
+// 16: rrrr rggg gggb bbbb
 void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b)
 {
        gp2x_palette[index] = (r << 16) | (g << 8) | b;
+       gp2x_palette16[index] = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
        gp2x_video_setpalette(gp2x_palette, index + 1);
 
        paletterefresh = 1;
@@ -133,7 +136,7 @@ static INLINE void printFps(uint8 *screen)
                prevsec = tv_now.tv_sec;
        }
 
-       if (!scaled_display)
+       if (Settings.scaling == 0)
        {
                if (needfpsflip)
                {
@@ -163,7 +166,7 @@ static INLINE void printFps(uint8 *screen)
        {
                if (Settings.showfps)
                {
-                       gp2x_text(screen+32, 0, 0, fps_str, FPS_COLOR, 0);
+                       gp2x_text(screen+32, 0, 0, fps_str, FPS_COLOR, 0); // TODO: firstline
                }
        }
 }
@@ -178,6 +181,10 @@ void BlitScreen(uint8 *buf)
        framesRendered++;
 
        printFps(gp2x_screen);
+
+       if (Settings.scaling == 3)
+               soft_scale((char *)gp2x_screen + 32, gp2x_palette16, 0, 240);
+
        gp2x_video_flip();
        XBuf = gp2x_screen;
 }
index 0ff378f..0c48ad4 100644 (file)
@@ -25,7 +25,7 @@ CFGSTRUCT DriverConfig[]={
         ACA(Settings.KeyBinds),
        ACA(Settings.JoyBinds),
         AC(Settings.turbo_rate_add),
-        AC(Settings.sound),
+        AC(Settings.sound_rate),
        AC(Settings.showfps),
        AC(Settings.scaling),
        AC(Settings.frameskip),
@@ -60,7 +60,7 @@ char *DriverUsage=
 static int docheckie[2]={0,0};
 #endif
 ARGPSTRUCT DriverArgs[]={
-         {"-sound",0,&Settings.sound,0},
+         {"-sound",0,&Settings.sound_rate,0},
          {"-showfps",0,&Settings.showfps,0},
          {"-mmuhack",0,&Settings.mmuhack,0},
          {"-ramtimings",0,&Settings.ramtimings,0},
@@ -87,7 +87,9 @@ static void SetDefaults(void)
  Settings.cpuclock = 150;
  Settings.frameskip = -1; // auto
  Settings.mmuhack = 1;
- Settings.sound = SOUND_RATE;
+ Settings.sound_rate = SOUND_RATE;
+ Settings.turbo_rate_add = (8*2 << 24) / 60 + 1; // 8Hz turbofire
+ Settings.gamma = 100;
  // default controls, RLDU SEBA
  Settings.KeyBinds[ 0] = 0x010; // GP2X_UP
  Settings.KeyBinds[ 4] = 0x020; // GP2X_DOWN
@@ -95,8 +97,8 @@ static void SetDefaults(void)
  Settings.KeyBinds[ 6] = 0x080; // GP2X_RIGHT
  Settings.KeyBinds[13] = 0x001; // GP2X_B
  Settings.KeyBinds[14] = 0x002; // GP2X_X
- Settings.KeyBinds[15] = 0x100; // GP2X_Y
- Settings.KeyBinds[12] = 0x200; // GP2X_A
+ Settings.KeyBinds[12] = 0x100; // GP2X_A
+ Settings.KeyBinds[15] = 0x200; // GP2X_Y
  Settings.KeyBinds[ 8] = 0x008; // GP2X_START
  Settings.KeyBinds[ 9] = 0x004; // GP2X_SELECT
 }
@@ -174,6 +176,7 @@ int main(int argc, char *argv[])
        if (mmuhack_status > 0)
                mmuunhack();
 
+       set_gamma(100);
        cpuctrl_deinit();
         gp2x_deinit();
 
@@ -198,14 +201,20 @@ void gp2x_opt_setup(void)
        }
 }
 
-void gp2x_cpuclock_update(void)
+void gp2x_cpuclock_gamma_update(void)
 {
-       static int prev_cpuclock = 200;
+       static int prev_cpuclock = 200, prev_gamma = 100;
        if (Settings.cpuclock != 0 && Settings.cpuclock != prev_cpuclock)
        {
                set_FCLK(Settings.cpuclock);
                prev_cpuclock = Settings.cpuclock;
        }
+
+       if (Settings.gamma != 0 && Settings.gamma != prev_gamma)
+       {
+               set_gamma(Settings.gamma);
+               prev_gamma = Settings.gamma;
+       }
 }
 
 
index 86f9d66..3e31af3 100644 (file)
@@ -4,13 +4,13 @@ typedef struct {
        // gp2x specific
        int KeyBinds[32];
        int JoyBinds[4][32];
-       int turbo_rate_add;
-       int sound;
+       int turbo_rate_add;     // 8.24 int
+       int sound_rate;         // in Hz
        int showfps;
        int scaling;            // unscaled=0, hw_hor, hw_hor_vert, sw_hor
        int frameskip;          // -1 ~ auto, >=0 ~ count
        int sstate_confirm;
-       int region_force;       // 0 ~ off, 1 ~ PAL, 2 ~ NTSC
+       int region_force;       // 0 ~ off, 1 ~ NTSC, 2 ~ PAL
        int cpuclock;
        int mmuhack;
        int ramtimings;
@@ -20,5 +20,5 @@ typedef struct {
 extern DSETTINGS Settings;
 
 void gp2x_opt_setup(void);
-void gp2x_cpuclock_update(void);
+void gp2x_cpuclock_gamma_update(void);
 
index c6f9936..8345339 100644 (file)
@@ -31,9 +31,6 @@
 
 extern uint8 Exit; // exit emu loop
 
-extern int scaled_display;
-
-
 
 /* UsrInputType[] is user-specified.  InputType[] is current
        (game loading can override user settings)
@@ -55,13 +52,8 @@ static uint32 MouseData[3];
 static uint8 fkbkeys[0x48];
 unsigned long lastpad=0;
 
-extern void ResetNES(void);
-extern void CleanSurface(void);
-
 char soundvolmeter[21];
 int soundvolIndex=0;
-int L_count=0;
-int R_count=0;
 
 
 static void setsoundvol(int soundvolume)
@@ -90,6 +82,7 @@ static void setsoundvol(int soundvolume)
 void FCEUD_UpdateInput(void)
 {
        static int volpushed_frames = 0;
+       static int turbo_rate_cnt_a = 0, turbo_rate_cnt_b = 0;
        long lastpad2 = lastpad;
        unsigned long keys = gp2x_joystick_read(0);
        uint32 JS = 0; // RLDU SEBA
@@ -133,6 +126,14 @@ void FCEUD_UpdateInput(void)
                        int acts = Settings.KeyBinds[i];
                        if (!acts) continue;
                        JS |= acts & 0xff;
+                       if (acts & 0x100) {             // A turbo
+                               turbo_rate_cnt_a += Settings.turbo_rate_add;
+                               JS |= (turbo_rate_cnt_a >> 24) & 1;
+                       }
+                       if (acts & 0x200) {             // B turbo
+                               turbo_rate_cnt_b += Settings.turbo_rate_add;
+                               JS |= (turbo_rate_cnt_b >> 23) & 2;
+                       }
                }
        }
 
index 6a31f9d..96ef3f9 100644 (file)
@@ -119,7 +119,6 @@ static CFGSTRUCT fceuconfig[]={
        AC(eoptions),
        ACA(srendlinev),
        ACA(erendlinev),
-       ACA(lastLoadedGameName),
        ADDCFGSTRUCT(DriverConfig),
        ENDCFGSTRUCT
 };
@@ -146,6 +145,40 @@ static void LoadConfig(const char *name)
         if(ntschue>=0) DriverInterface(DES_SETNTSCHUE,&ntschue);
 }
 
+static void LoadLLGN(void)
+{
+ char tdir[2048];
+ FILE *f;
+ int len;
+ sprintf(tdir,"%s"PSS"last_rom.txt",BaseDirectory);
+ f=fopen(tdir, "r");
+ if(f)
+ {
+  len = fread(lastLoadedGameName, 1, sizeof(lastLoadedGameName)-1, f);
+  lastLoadedGameName[len] = 0;
+  fclose(f);
+ }
+}
+
+static void SaveLLGN(void)
+{
+ // save last loaded game name
+ if (lastLoadedGameName[0])
+ {
+  char tdir[2048];
+  FILE *f;
+  sprintf(tdir,"%s"PSS"last_rom.txt",BaseDirectory);
+  f=fopen(tdir, "w");
+  if(f)
+  {
+   fwrite(lastLoadedGameName, 1, strlen(lastLoadedGameName), f);
+   fclose(f);
+   sync();
+  }
+ }
+}
+
+
 static void CreateDirs(void)
 {
  char *subs[]={"fcs","snaps","gameinfo","sav","cheats","cfg"};
@@ -242,7 +275,7 @@ static int DoArgs(int argc, char *argv[])
          }
        }
        if(docheckie[0])
-        FCEUI_SetVidSystem(1);
+        Settings.region_force=2;
        if(docheckie[1])
         FCEUI_SetGameGenie(1);
         FCEUI_DisableSpriteLimitation(1);
@@ -328,7 +361,8 @@ int CLImain(int argc, char *argv[])
         LoadConfig(NULL);
         last_arg_parsed=DoArgs(argc-1,&argv[1]);
        gp2x_opt_setup();
-       gp2x_cpuclock_update();
+       gp2x_cpuclock_gamma_update();
+       LoadLLGN();
        if(cpalette)
         LoadCPalette();
        if(InitSound())
@@ -355,6 +389,8 @@ int CLImain(int argc, char *argv[])
          if (fceugi)
          {
           LoadConfig(lastLoadedGameName);
+          if (Settings.region_force)
+           FCEUI_SetVidSystem(Settings.region_force - 1);
           ParseGI(fceugi);
           //RefreshThrottleFPS();
           InitOtherInput();
@@ -370,7 +406,14 @@ int CLImain(int argc, char *argv[])
           }
          }
          else
-          strcpy(menuErrorMsg, "failed to load ROM");
+         {
+          switch(LoadGameLastError) {
+           default: strcpy(menuErrorMsg, "failed to load ROM"); break;
+           case  2: strcpy(menuErrorMsg, "Can't find a ROM for movie"); break;
+           case 10: strcpy(menuErrorMsg, "FDS BIOS ROM is missing, read docs"); break;
+           case 11: strcpy(menuErrorMsg, "Error reading auxillary FDS file"); break;
+          }
+         }
         }
          if(Exit || !fceugi)
          {
@@ -384,14 +427,20 @@ int CLImain(int argc, char *argv[])
          }
 
         gp2x_video_changemode(Settings.scaling == 3 ? 15 : 8);
-         gp2x_video_RGB_setscaling(0, 320, 240);
-        gp2x_start_sound(22050, 16, 0);
+        switch (Settings.scaling & 3) {
+                case 0: gp2x_video_RGB_setscaling(0, 320, 240); gp2x_video_set_offs(0); break;
+                case 1: gp2x_video_RGB_setscaling(0, 256, 240); gp2x_video_set_offs(32); break;
+                case 2: gp2x_video_RGB_setscaling(0, 256, 240); gp2x_video_set_offs(32); break; // TODO
+                case 3: gp2x_video_RGB_setscaling(0, 320, 240); gp2x_video_set_offs(32); break;
+        }
+        gp2x_start_sound(Settings.sound_rate, 16, 0);
         FCEUI_Emulate();
        }
 
        if (fceugi)
         CloseGame();
 
+       SaveLLGN();
        DriverKill();
         return 0;
 }
@@ -411,7 +460,7 @@ static int DriverInitialize(void)
 
 static void DriverKill(void)
 {
- SaveConfig(NULL);
+ // SaveConfig(NULL); // done explicitly in menu now
  SetSignals(SIG_IGN);
 
  if(inited&2)
index 6f0a9d5..12d6dc6 100644 (file)
@@ -30,9 +30,10 @@ static int GP2X_PORT_REV =
 ;\r
 \r
 extern char lastLoadedGameName[PATH_MAX];\r
-extern int  mmuhack_status;\r
-//extern int  state_slot; // TODO\r
+extern int mmuhack_status;\r
+extern int soundvol;\r
 extern uint8 Exit; // exit emu loop flag\r
+extern int InitSound(void);\r
 \r
 #define CONFIGURABLE_KEYS (GP2X_UP|GP2X_LEFT|GP2X_DOWN|GP2X_RIGHT|GP2X_START|GP2X_SELECT|GP2X_L|GP2X_R|GP2X_A|GP2X_B|GP2X_X|GP2X_Y|GP2X_PUSH)\r
 \r
@@ -663,27 +664,14 @@ static int count_bound_keys(int action, int is_joy)
 \r
 typedef struct { char *name; int mask; } bind_action_t;\r
 \r
-// b_turbo,a_turbo  RLDU SEBA\r
-static bind_action_t ctrl_actions[] =\r
-{\r
-       { "UP     ", 0x010 },\r
-       { "DOWN   ", 0x020 },\r
-       { "LEFT   ", 0x040 },\r
-       { "RIGHT  ", 0x080 },\r
-       { "A      ", 0x001 },\r
-       { "B      ", 0x002 },\r
-       { "A TURBO", 0x100 },\r
-       { "B TURBO", 0x200 },\r
-       { "START  ", 0x008 },\r
-       { "SELECT ", 0x004 },\r
-};\r
-\r
 static void draw_key_config(const bind_action_t *opts, int opt_cnt, int player_idx, int sel)\r
 {\r
        int x, y, tl_y = 40, i;\r
 \r
        gp2x_fceu_copy_bg();\r
-       gp2x_text_out15(80, 20, "Player %i controls", player_idx + 1);\r
+       if (player_idx >= 0)\r
+            gp2x_text_out15(80, 20, "Player %i controls", player_idx + 1);\r
+       else gp2x_text_out15(80, 20, "Emulator controls");\r
 \r
        x = 40; y = tl_y;\r
        for (i = 0; i < opt_cnt; i++, y+=10)\r
@@ -733,8 +721,10 @@ static void key_config_loop(const bind_action_t *opts, int opt_cnt, int player_i
                                        if (count_bound_keys(opts[sel].mask, 0) >= 2)\r
                                             Settings.KeyBinds[i] &= ~opts[sel].mask; // allow to unbind only\r
                                        else Settings.KeyBinds[i] ^=  opts[sel].mask;\r
-                                       Settings.KeyBinds[i] &= ~(3 << 16);\r
-                                       Settings.KeyBinds[i] |= player_idx << 16;\r
+                                       if (player_idx >= 0) {\r
+                                               Settings.KeyBinds[i] &= ~(3 << 16);\r
+                                               Settings.KeyBinds[i] |= player_idx << 16;\r
+                                       }\r
                                }\r
                } else if (sel < opt_cnt) {\r
                        for (i = 0; i < 32; i++)\r
@@ -742,8 +732,10 @@ static void key_config_loop(const bind_action_t *opts, int opt_cnt, int player_i
                                        if (count_bound_keys(opts[sel].mask, 1) >= 1) // disallow combos for usbjoy\r
                                             Settings.JoyBinds[joy-1][i] &= ~opts[sel].mask;\r
                                        else Settings.JoyBinds[joy-1][i] ^=  opts[sel].mask;\r
-                                       Settings.JoyBinds[joy-1][i] &= ~(3 << 16);\r
-                                       Settings.JoyBinds[joy-1][i] |= player_idx << 16;\r
+                                       if (player_idx >= 0) {\r
+                                               Settings.JoyBinds[joy-1][i] &= ~(3 << 16);\r
+                                               Settings.JoyBinds[joy-1][i] |= player_idx << 16;\r
+                                       }\r
                                }\r
                }\r
        }\r
@@ -778,6 +770,27 @@ static void draw_kc_sel(int menu_sel)
        gp2x_video_flip();\r
 }\r
 \r
+// b_turbo,a_turbo  RLDU SEBA\r
+static bind_action_t ctrl_actions[] =\r
+{\r
+       { "UP     ", 0x010 },\r
+       { "DOWN   ", 0x020 },\r
+       { "LEFT   ", 0x040 },\r
+       { "RIGHT  ", 0x080 },\r
+       { "A      ", 0x001 },\r
+       { "B      ", 0x002 },\r
+       { "A TURBO", 0x100 },\r
+       { "B TURBO", 0x200 },\r
+       { "START  ", 0x008 },\r
+       { "SELECT ", 0x004 },\r
+};\r
+\r
+static bind_action_t emuctrl_actions[] =\r
+{\r
+       { "Save State  ", 1<<31 },\r
+       { "Load State  ", 1<<30 },\r
+};\r
+\r
 static void kc_sel_loop(void)\r
 {\r
        int menu_sel = 3, menu_sel_max = 3;\r
@@ -793,6 +806,8 @@ static void kc_sel_loop(void)
                        switch (menu_sel) {\r
                                case 0: key_config_loop(ctrl_actions, 10, 0); return;\r
                                case 1: key_config_loop(ctrl_actions,  8, 1); return;\r
+                               case 2: key_config_loop(emuctrl_actions,\r
+                                               sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]), -1); return;\r
                                default: return;\r
                        }\r
                }\r
@@ -801,23 +816,16 @@ static void kc_sel_loop(void)
 }\r
 \r
 \r
+// --------- FCEU options ----------\r
 \r
-// --------- advanced options ----------\r
-#if 0\r
-static void draw_amenu_options(int menu_sel)\r
+static void draw_fcemenu_options(int menu_sel)\r
 {\r
        int tl_x = 25, tl_y = 60, y;\r
-       char *mms = mmuhack_status ? "active)  " : "inactive)";\r
 \r
        y = tl_y;\r
-       //memset(gp2x_screen, 0, 320*240);\r
        gp2x_fceu_copy_bg();\r
 \r
-       gp2x_text_out15(tl_x, y,       "Gamma correction           %i.%02i", currentConfig.gamma / 100, currentConfig.gamma%100); // 0\r
-       gp2x_text_out15(tl_x, (y+=10), "Don't save last used ROM   %s", (currentConfig.EmuOpt &0x020)?"ON":"OFF"); // 5\r
-       gp2x_text_out15(tl_x, (y+=10), "needs restart:");\r
-       gp2x_text_out15(tl_x, (y+=10), "craigix's RAM timings      %s", (currentConfig.EmuOpt &0x100)?"ON":"OFF"); // 7\r
-       gp2x_text_out15(tl_x, (y+=10), "squidgehack (now %s %s",   mms, (currentConfig.EmuOpt &0x010)?"ON":"OFF"); // 8\r
+       gp2x_text_out15(tl_x,  y,      "                           %s", "OFF"); // 0\r
        gp2x_text_out15(tl_x, (y+=10), "Done");\r
 \r
        // draw cursor\r
@@ -826,49 +834,41 @@ static void draw_amenu_options(int menu_sel)
        gp2x_video_flip();\r
 }\r
 \r
-static void amenu_loop_options(void)\r
+static void fcemenu_loop_options(void)\r
 {\r
-       int menu_sel = 0, menu_sel_max = 9;\r
+       int menu_sel = 0, menu_sel_max = 1;\r
        unsigned long inp = 0;\r
 \r
        for(;;)\r
        {\r
-               draw_amenu_options(menu_sel);\r
+               draw_fcemenu_options(menu_sel);\r
                inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT|GP2X_B|GP2X_X|GP2X_A);\r
                if(inp & GP2X_UP  ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }\r
                if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
                if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options\r
                        switch (menu_sel) {\r
-                               case  1: break;\r
-                               case  9: return;\r
+                               case  0: break;\r
+                               case  1: return;\r
                        }\r
                }\r
                if(inp & (GP2X_X|GP2X_A)) return;\r
                if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise\r
                        switch (menu_sel) {\r
                                case 0:\r
-                                       while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {\r
-                                               currentConfig.gamma += (inp & GP2X_LEFT) ? -1 : 1;\r
-                                               if (currentConfig.gamma <   1) currentConfig.gamma =   1;\r
-                                               if (currentConfig.gamma > 300) currentConfig.gamma = 300;\r
-                                               draw_amenu_options(menu_sel);\r
-                                               usleep(18*1000);\r
-                                       }\r
                                        break;\r
                        }\r
                }\r
        }\r
 }\r
-#endif\r
 \r
 // -------------- options --------------\r
 \r
 static void draw_menu_options(int menu_sel)\r
 {\r
        int tl_x = 25, tl_y = 32, y;\r
-       char /*monostereo[8],*/ strframeskip[8], *strscaling, *strssconfirm;\r
+       char strframeskip[8], *strscaling, *strssconfirm;\r
+       char *mms = mmuhack_status ? "active)  " : "inactive)";\r
 \r
-       //strcpy(monostereo, (currentConfig.PicoOpt&0x08)?"stereo":"mono");\r
        if (Settings.frameskip < 0)\r
             strcpy(strframeskip, "Auto");\r
        else sprintf(strframeskip, "%i", Settings.frameskip);\r
@@ -886,21 +886,24 @@ static void draw_menu_options(int menu_sel)
        }\r
 \r
        y = tl_y;\r
-       //memset(gp2x_screen, 0, 320*240);\r
        gp2x_fceu_copy_bg();\r
 \r
        gp2x_text_out15(tl_x,  y,      "Scaling:       %s", strscaling);                                // 0\r
        gp2x_text_out15(tl_x, (y+=10), "Show FPS                   %s", Settings.showfps?"ON":"OFF");   // 1\r
        gp2x_text_out15(tl_x, (y+=10), "Frameskip                  %s", strframeskip);                  // 2\r
-       gp2x_text_out15(tl_x, (y+=10), "Enable sound               %s", /*(currentConfig.EmuOpt &0x004)?"ON":*/"OFF"); // 3\r
-       gp2x_text_out15(tl_x, (y+=10), "Sound Quality:     %5iHz %s",   0, "" /*currentConfig.PsndRate, monostereo*/); // 4\r
-       gp2x_text_out15(tl_x, (y+=10), "Region:                    %s",\r
-               Settings.region_force == 2 ? "NTSC" : Settings.region_force == 1 ? "PAL" : "OFF");      // 5\r
+       gp2x_text_out15(tl_x, (y+=10), "Enable sound               %s", soundvol?"ON":"OFF");\r
+       gp2x_text_out15(tl_x, (y+=10), "Sound Rate:           %5iHz", Settings.sound_rate);             // 4\r
+       gp2x_text_out15(tl_x, (y+=10), "Force Region:              %s",\r
+               Settings.region_force == 2 ? "PAL" : Settings.region_force == 1 ? "NTSC" : "OFF");      // 5\r
        gp2x_text_out15(tl_x, (y+=10), "Use SRAM savestates        %s", "OFF");\r
-       gp2x_text_out15(tl_x, (y+=10), "Confirm savestate          %s", strssconfirm);\r
-       gp2x_text_out15(tl_x, (y+=10), "Save slot                  %i", 0/*state_slot*/);               // 8\r
-       gp2x_text_out15(tl_x, (y+=10), "GP2X CPU clock             %iMhz", Settings.cpuclock);\r
-       gp2x_text_out15(tl_x, (y+=10), "[advanced options]");                                           // 10\r
+       gp2x_text_out15(tl_x, (y+=10), "Turbo rate                 %iHz", (Settings.turbo_rate_add*60/2) >> 24);\r
+       gp2x_text_out15(tl_x, (y+=10), "Confirm savestate          %s", strssconfirm);                  // 8\r
+       gp2x_text_out15(tl_x, (y+=10), "Save slot                  %i", CurrentState);\r
+       gp2x_text_out15(tl_x, (y+=10), "Faster RAM timings         %s", Settings.ramtimings?"ON":"OFF");\r
+       gp2x_text_out15(tl_x, (y+=10), "squidgehack (now %s %s",   mms, Settings.mmuhack?"ON":"OFF");   // 11\r
+       gp2x_text_out15(tl_x, (y+=10), "Gamma correction           %i.%02i", Settings.gamma / 100, Settings.gamma%100);\r
+       gp2x_text_out15(tl_x, (y+=10), "GP2X CPU clock             %iMhz", Settings.cpuclock);          // 13\r
+       gp2x_text_out15(tl_x, (y+=10), "[FCE Ultra options]");\r
        gp2x_text_out15(tl_x, (y+=10), "Save cfg as default");\r
        if (fceugi)\r
                gp2x_text_out15(tl_x, (y+=10), "Save cfg for current game only");\r
@@ -911,7 +914,6 @@ static void draw_menu_options(int menu_sel)
        gp2x_video_flip();\r
 }\r
 \r
-/*\r
 static int sndrate_prevnext(int rate, int dir)\r
 {\r
        int i, rates[] = { 8000, 11025, 16000, 22050, 44100 };\r
@@ -924,7 +926,7 @@ static int sndrate_prevnext(int rate, int dir)
        if (i < 0) return dir ? 11025 : 8000;\r
        return rates[i];\r
 }\r
-*/\r
+\r
 static void int_incdec(int *p, int inc, int min, int max)\r
 {\r
        *p += inc;\r
@@ -932,9 +934,17 @@ static void int_incdec(int *p, int inc, int min, int max)
        else if (*p > max) *p = max;\r
 }\r
 \r
+static void config_commit(void)\r
+{\r
+       gp2x_cpuclock_gamma_update();\r
+       if (Settings.region_force)\r
+               FCEUI_SetVidSystem(Settings.region_force - 1);\r
+}\r
+\r
 static int menu_loop_options(void)\r
 {\r
-       int menu_sel = 0, menu_sel_max = 11;\r
+       static int menu_sel = 0;\r
+       int menu_sel_max = 15;\r
        unsigned long inp = 0;\r
 \r
        if (fceugi) menu_sel_max++;\r
@@ -947,41 +957,45 @@ static int menu_loop_options(void)
                if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }\r
                if((inp& GP2X_B)||(inp&GP2X_LEFT)||(inp&GP2X_RIGHT)) { // toggleable options\r
                        switch (menu_sel) {\r
-                               case  1: Settings.showfps = !Settings.showfps; break;\r
-                               //case  6: Settings. = !Settings.showfps; break;\r
-                               //case 10: amenu_loop_options();    break;\r
-                               case 11: // done (update and write)\r
-                                       gp2x_cpuclock_update();\r
+                               case  1: Settings.showfps    = !Settings.showfps; break;\r
+                               case  3: soundvol = soundvol ? 0 : 100; break;\r
+                               case 10: Settings.ramtimings = !Settings.ramtimings; break;\r
+                               case 11: Settings.mmuhack    = !Settings.mmuhack; break;\r
+                               case 14: fcemenu_loop_options(); break;\r
+                               case 15: // done (update and write)\r
+                                       config_commit();\r
                                        SaveConfig(NULL);\r
                                        return 1;\r
-                               case 12: // done (update and write for current game)\r
-                                       gp2x_cpuclock_update();\r
+                               case 16: // done (update and write for current game)\r
+                                       config_commit();\r
                                        if (lastLoadedGameName[0])\r
                                                SaveConfig(lastLoadedGameName);\r
                                        return 1;\r
                        }\r
                }\r
                if(inp & (GP2X_X|GP2X_A)) {\r
-                       gp2x_cpuclock_update();\r
+                       config_commit();\r
                        return 0;  // done (update, no write)\r
                }\r
                if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise\r
                        switch (menu_sel) {\r
                                case  0: int_incdec(&Settings.scaling,   (inp & GP2X_LEFT) ? -1 : 1,  0,  3); break;\r
                                case  2: int_incdec(&Settings.frameskip, (inp & GP2X_LEFT) ? -1 : 1, -1, 32); break;\r
-/*\r
                                case  4:\r
-                                       if ((inp & GP2X_RIGHT) && currentConfig.PsndRate == 44100 && !(currentConfig.PicoOpt&0x08)) {\r
-                                               currentConfig.PsndRate = 8000;  currentConfig.PicoOpt|= 0x08;\r
-                                       } else if ((inp & GP2X_LEFT) && currentConfig.PsndRate == 8000 && (currentConfig.PicoOpt&0x08)) {\r
-                                               currentConfig.PsndRate = 44100; currentConfig.PicoOpt&=~0x08;\r
-                                       } else currentConfig.PsndRate = sndrate_prevnext(currentConfig.PsndRate, inp & GP2X_RIGHT);\r
+                                       Settings.sound_rate = sndrate_prevnext(Settings.sound_rate, inp & GP2X_RIGHT);\r
+                                       InitSound();\r
                                        break;\r
-*/\r
                                case  5: int_incdec(&Settings.region_force,   (inp & GP2X_LEFT) ? -1 : 1, 0, 2); break;\r
-                               case  7: int_incdec(&Settings.sstate_confirm, (inp & GP2X_LEFT) ? -1 : 1, 0, 3); break;\r
-                               case  8: int_incdec(&CurrentState,            (inp & GP2X_LEFT) ? -1 : 1, 0, 9); break;\r
-                               case  9:\r
+                               case  7: {\r
+                                       int hz = Settings.turbo_rate_add*60/2 >> 24;\r
+                                       int_incdec(&hz, (inp & GP2X_LEFT) ? -1 : 1, 1, 30);\r
+                                       Settings.turbo_rate_add = (hz*2 << 24) / 60 + 1;\r
+                                       break;\r
+                               }\r
+                               case  8: int_incdec(&Settings.sstate_confirm, (inp & GP2X_LEFT) ? -1 : 1, 0, 3); break;\r
+                               case  9: int_incdec(&CurrentState,            (inp & GP2X_LEFT) ? -1 : 1, 0, 9); break;\r
+                               case 12: int_incdec(&Settings.gamma,          (inp & GP2X_LEFT) ? -1 : 1, 0, 300); break;\r
+                               case 13:\r
                                        while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) {\r
                                                Settings.cpuclock += (inp & GP2X_LEFT) ? -1 : 1;\r
                                                if (Settings.cpuclock < 0) Settings.cpuclock = 0; // 0 ~ do not change\r
@@ -1159,6 +1173,7 @@ static void menu_gfx_prepare(void)
 \r
        // switch bpp\r
        gp2x_video_changemode(16);\r
+       gp2x_video_set_offs(0);\r
        gp2x_video_RGB_setscaling(0, 320, 240);\r
        gp2x_video_flip();\r
 }\r
index ba4ffe0..9716e5b 100644 (file)
@@ -40,6 +40,7 @@ volatile unsigned short *gp2x_memregs;
 volatile unsigned long  *gp2x_memregl;\r
 static void *gp2x_screens[4];\r
 static int screensel = 0;\r
+static int gp2x_screen_offs = 0;\r
 //static\r
 int memdev = 0;\r
 static int sounddev = 0, mixerdev = 0;\r
@@ -57,16 +58,13 @@ static int gp2x_screenaddrs_use[4];
 static unsigned short gp2x_screenaddr_old[4];\r
 \r
 \r
-// hack to simplify thing for fceu\r
-static int scaling_enabled = 0;\r
-\r
 /* video stuff */\r
 void gp2x_video_flip(void)\r
 {\r
        unsigned short lsw, msw;\r
        int addr = gp2x_screenaddrs_use[screensel&3];\r
 \r
-       if (scaling_enabled) addr += 32;\r
+       addr += gp2x_screen_offs;\r
 \r
        // since we are using the mmu hack, we must flush the cache first\r
        // (the params are most likely wrong, but they seem to work somehow)\r
@@ -133,9 +131,6 @@ void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)
        int bpp = (gp2x_memregs[0x28DA>>1]>>9)&0x3;\r
        unsigned short scalw;\r
 \r
-       // fceu hack\r
-       scaling_enabled = (W == 320) ? 0 : 1;\r
-\r
        // set offset\r
        gp2x_screenaddrs_use[0] = gp2x_screenaddrs[0] + ln_offs * 320 * bpp;\r
        gp2x_screenaddrs_use[1] = gp2x_screenaddrs[1] + ln_offs * 320 * bpp;\r
@@ -163,6 +158,10 @@ void gp2x_video_RGB_setscaling(int ln_offs, int W, int H)
        gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0));\r
 }\r
 \r
+void gp2x_video_set_offs(int offs)\r
+{\r
+       gp2x_screen_offs = offs;\r
+}\r
 \r
 void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)\r
 {\r
index 37507f0..3b01cad 100644 (file)
@@ -12,6 +12,7 @@ void gp2x_video_changemode(int bpp);
 void gp2x_video_changemode2(int bpp);\r
 void gp2x_video_setpalette(int *pal, int len);\r
 void gp2x_video_RGB_setscaling(int ln_offs, int W, int H);\r
+void gp2x_video_set_offs(int offs);\r
 void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len);\r
 void gp2x_memcpy_all_buffers(void *data, int offset, int len);\r
 void gp2x_memset_all_buffers(int offset, int byte, int len);\r
diff --git a/fce.c b/fce.c
index d83c5f5..fb28572 100644 (file)
--- a/fce.c
+++ b/fce.c
@@ -1080,6 +1080,7 @@ void ResetGameLoaded(void)
 }
 
 char lastLoadedGameName [2048];
+int LoadGameLastError = 0;
 int UNIFLoad(const char *name, int fp);
 int iNESLoad(const char *name, int fp);
 int FDSLoad(const char *name, int fp);
@@ -1092,6 +1093,7 @@ FCEUGI *FCEUI_LoadGame(char *name)
         int fp;
 
         //Exit=1;
+       LoadGameLastError = 0;
         ResetGameLoaded();
 
        strncpy(name2, name, sizeof(name2));
@@ -1101,6 +1103,7 @@ FCEUGI *FCEUI_LoadGame(char *name)
        if(!fp)
         {
         FCEU_PrintError("Error opening \"%s\"!",name);
+        LoadGameLastError = 1;
         return 0;
        }
 
@@ -1117,14 +1120,13 @@ FCEUGI *FCEUI_LoadGame(char *name)
          fp=FCEU_fopen(name2,"rb");
          if (!fp) {
           printf("no ROM for movie\n");
+          LoadGameLastError = 2;
           return 0;
          }
          have_movie = 1;
         }
        }
 
-       strcpy(lastLoadedGameName, name2);
-
         GetFileBase(name2);
         if(iNESLoad(name2,fp))
          goto endlseq;
@@ -1137,6 +1139,8 @@ FCEUGI *FCEUI_LoadGame(char *name)
 
         FCEU_PrintError("An error occurred while loading the file.");
         FCEU_fclose(fp);
+       // format handlers may set LoadGameLastError themselves.
+       if (LoadGameLastError == 0) LoadGameLastError = 3;
         return 0;
 
         endlseq:
@@ -1164,6 +1168,9 @@ FCEUGI *FCEUI_LoadGame(char *name)
 
        if (have_movie)
                FCEUI_LoadMovie(name, 1);
+
+       strcpy(lastLoadedGameName, name2);
+
         return(&FCEUGameInfo);
 }
 
diff --git a/fds.c b/fds.c
index 41b3a5d..8e2fa60 100644 (file)
--- a/fds.c
+++ b/fds.c
@@ -819,6 +819,7 @@ int FDSLoad(const char *name, int fp)
   FCEU_PrintError("FDS BIOS ROM image missing!");\r
   FreeFDSMemory();\r
   free(fn);\r
+  LoadGameLastError = 10;\r
   return 0;\r
  }\r
 \r
@@ -829,6 +830,7 @@ int FDSLoad(const char *name, int fp)
   fclose(zp);\r
   FreeFDSMemory();\r
   FCEU_PrintError("Error reading FDS BIOS ROM image.");\r
+  LoadGameLastError = 10;\r
   return 0;\r
  }\r
 \r
@@ -853,6 +855,7 @@ int FDSLoad(const char *name, int fp)
    {\r
     FCEU_PrintError("Error reading auxillary FDS file.");\r
     free(fn);\r
+    LoadGameLastError = 11;\r
     return(0);\r
    }\r
    FCEU_fclose(tp);\r
diff --git a/movie.c b/movie.c
index 8e486b5..e44724b 100644 (file)
--- a/movie.c
+++ b/movie.c
@@ -431,7 +431,7 @@ strcpy(origname,fname);
   {
          // attempt to load previous version's format
          fclose(fp);
-         printf("trying movie v1\n");
+         printf("movie: trying movie v1\n");
          FCEUI_LoadMovie_v1(fname, _read_only);
          return;
   }
diff --git a/svga.c b/svga.c
index b040c27..00593fa 100644 (file)
--- a/svga.c
+++ b/svga.c
@@ -78,7 +78,8 @@ void FCEU_DispMessage(char *format, ...)
  va_end(ap);
 
  howlong=180;
- printf("%s\n", errmsg);
+ if (errmsg[0] != '|')
+  printf("%s\n", errmsg);
 }
 
 void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall)