From b547bda76671cf9c99973dd3faad97804949ced3 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 12 May 2007 23:45:22 +0000 Subject: [PATCH] menu and controls wip.. git-svn-id: file:///home/notaz/opt/svn/fceu@130 be3aeb3a-fb24-0410-a615-afba39da0efa --- Makefile.gp2x | 16 +- drivers/gp2x/gp2x-video.c | 6 +- drivers/gp2x/gp2x.c | 58 +++++--- drivers/gp2x/gp2x.h | 12 +- drivers/gp2x/input.c | 295 ++++++------------------------------- drivers/gp2x/main.c | 41 +++--- drivers/gp2x/main.h | 3 + drivers/gp2x/menu.c | 217 +++++++++++++++++++-------- drivers/gp2x/squidgehack.c | 35 +++-- fce.c | 1 - input.c | 10 -- input.h | 7 + 12 files changed, 300 insertions(+), 401 deletions(-) diff --git a/Makefile.gp2x b/Makefile.gp2x index a86f8c5..6b82e47 100644 --- a/Makefile.gp2x +++ b/Makefile.gp2x @@ -54,12 +54,22 @@ include Makefile.base ${B}main.o: ${B}main.c ${B}main.h ${B}usage.h ${B}input.c ${B}gp2x.o: ${B}gp2x.c ${B}gp2x.h ${B}throttle.o: ${B}throttle.c ${B}main.h ${B}throttle.h +${B}menu.o: ${B}rev.h ppu.o: ppu.c ppu.h -include Makefile.common +${B}rev.h: FORCE + @if [ -f $@ ]; then prevrev=`cat $@`; else prevrev="00"; fi; \ + if [ "`which svn`" != "" ]; then \ + rev=`svn update|tail -n 1|sed 's/.*\ \(.*\)\./\1/g'|sed "s/'//g"`; \ + fi; \ + if [ "$$rev" = "" ]; then rev="0"; fi; \ + if [ "$$rev" != "$$prevrev" ]; then \ + echo "$$rev" > $@; \ + fi + +.PHONY: FORCE -#x6502.o: x6502.c x6502.h ops.h fce.h sound.h -# $(CC) $(CFLAGS) -finline-limit=60000 -c $< -o $@ +include Makefile.common up: fceu cp -v fceu /mnt/gp2x/mnt/sd/emus/Gpfce_v02/gpfce diff --git a/drivers/gp2x/gp2x-video.c b/drivers/gp2x/gp2x-video.c index d74023a..6986df1 100644 --- a/drivers/gp2x/gp2x-video.c +++ b/drivers/gp2x/gp2x-video.c @@ -26,8 +26,6 @@ #include "minimal.h" #include "fonts.h" -extern int showfps; - static char fps_str[32]; static int framesEmulated, framesRendered; @@ -149,7 +147,7 @@ static INLINE void printFps(uint8 *screen) //*destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; //*destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; *destt++ = 0x3F3F3F3F; } - if (showfps) + if (Settings.showfps) { int sep; for (sep=1; sep < 5; sep++) @@ -163,7 +161,7 @@ static INLINE void printFps(uint8 *screen) } else { - if (showfps) + if (Settings.showfps) { gp2x_text(screen+32, 0, 0, fps_str, FPS_COLOR, 0); } diff --git a/drivers/gp2x/gp2x.c b/drivers/gp2x/gp2x.c index e7c3a0e..0ff378f 100644 --- a/drivers/gp2x/gp2x.c +++ b/drivers/gp2x/gp2x.c @@ -19,14 +19,13 @@ int CLImain(int argc, char *argv[]); //#define SOUND_RATE 44100 #define SOUND_RATE 22050 -#define GP2X_PORT_VERSION "0.4" DSETTINGS Settings; CFGSTRUCT DriverConfig[]={ + ACA(Settings.KeyBinds), + ACA(Settings.JoyBinds), + AC(Settings.turbo_rate_add), AC(Settings.sound), - ACA(Settings.joyBMap), - ACA(Settings.joyAMap), - ACA(Settings.joy), AC(Settings.showfps), AC(Settings.scaling), AC(Settings.frameskip), @@ -35,6 +34,7 @@ CFGSTRUCT DriverConfig[]={ AC(Settings.cpuclock), AC(Settings.mmuhack), AC(Settings.ramtimings), + AC(Settings.gamma), // TODO ENDCFGSTRUCT }; @@ -60,8 +60,6 @@ char *DriverUsage= static int docheckie[2]={0,0}; #endif ARGPSTRUCT DriverArgs[]={ - {"-joy1",0,&Settings.joy[0],0},{"-joy2",0,&Settings.joy[1],0}, - {"-joy3",0,&Settings.joy[2],0},{"-joy4",0,&Settings.joy[3],0}, {"-sound",0,&Settings.sound,0}, {"-showfps",0,&Settings.showfps,0}, {"-mmuhack",0,&Settings.mmuhack,0}, @@ -89,13 +87,22 @@ static void SetDefaults(void) Settings.cpuclock = 150; Settings.frameskip = -1; // auto Settings.mmuhack = 1; - Settings.sound=SOUND_RATE; + Settings.sound = SOUND_RATE; + // default controls, RLDU SEBA + Settings.KeyBinds[ 0] = 0x010; // GP2X_UP + Settings.KeyBinds[ 4] = 0x020; // GP2X_DOWN + Settings.KeyBinds[ 2] = 0x040; // GP2X_LEFT + 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[ 8] = 0x008; // GP2X_START + Settings.KeyBinds[ 9] = 0x004; // GP2X_SELECT } void DoDriverArgs(void) { - int x; - #ifdef NETWORK if(docheckie[0]) netplay=2; @@ -105,13 +112,6 @@ void DoDriverArgs(void) if(netplay) FCEUI_SetNetworkPlay(netplay); #endif - - for(x=0;x<4;x++) - if(!Settings.joy[x]) - { - memset(Settings.joyBMap[x],0,sizeof(Settings.joyBMap[0])); - memset(Settings.joyAMap[x],0,sizeof(Settings.joyAMap[0])); - } } int InitMouse(void) @@ -145,8 +145,9 @@ char *GetKeyboard(void) return NULL; } -extern int swapbuttons; // TODO: rm + char **g_argv; +int mmuhack_status = 0; // TODO: cleanup @@ -163,10 +164,6 @@ int main(int argc, char *argv[]) gp2x_init(); cpuctrl_init(); - // unscale the screen, in case this is bad. - gp2x_video_changemode(8); - gp2x_video_RGB_setscaling(0, 320, 240); - SetDefaults(); ret = CLImain(argc,argv); @@ -174,6 +171,9 @@ int main(int argc, char *argv[]) // unscale the screen, in case this is bad. gp2x_video_RGB_setscaling(0, 320, 240); + if (mmuhack_status > 0) + mmuunhack(); + cpuctrl_deinit(); gp2x_deinit(); @@ -181,14 +181,13 @@ int main(int argc, char *argv[]) } -int mmuhack_status = 0; - /* optional GP2X stuff to be done after config is loaded */ void gp2x_opt_setup(void) { if (Settings.mmuhack) { int ret = mmuhack(); - printf("squidge hack code finished and returned %i\n", ret); fflush(stdout); + printf("squidge hack code finished and returned %s\n", ret > 0 ? "ok" : "fail"); + fflush(stdout); mmuhack_status = ret; } if (Settings.ramtimings) { @@ -199,3 +198,14 @@ void gp2x_opt_setup(void) } } +void gp2x_cpuclock_update(void) +{ + static int prev_cpuclock = 200; + if (Settings.cpuclock != 0 && Settings.cpuclock != prev_cpuclock) + { + set_FCLK(Settings.cpuclock); + prev_cpuclock = Settings.cpuclock; + } +} + + diff --git a/drivers/gp2x/gp2x.h b/drivers/gp2x/gp2x.h index 799e0cb..86f9d66 100644 --- a/drivers/gp2x/gp2x.h +++ b/drivers/gp2x/gp2x.h @@ -1,9 +1,11 @@ +#define GP2X_PORT_VERSION "0.4" + typedef struct { - int sound; - int joy[4]; - int joyAMap[4][2]; - int joyBMap[4][4]; // gp2x specific + int KeyBinds[32]; + int JoyBinds[4][32]; + int turbo_rate_add; + int sound; int showfps; int scaling; // unscaled=0, hw_hor, hw_hor_vert, sw_hor int frameskip; // -1 ~ auto, >=0 ~ count @@ -12,9 +14,11 @@ typedef struct { int cpuclock; int mmuhack; int ramtimings; + int gamma; } DSETTINGS; extern DSETTINGS Settings; void gp2x_opt_setup(void); +void gp2x_cpuclock_update(void); diff --git a/drivers/gp2x/input.c b/drivers/gp2x/input.c index cd25e97..c6f9936 100644 --- a/drivers/gp2x/input.c +++ b/drivers/gp2x/input.c @@ -31,9 +31,7 @@ extern uint8 Exit; // exit emu loop -extern int swapbuttons; extern int scaled_display; -extern int FSkip_setting; @@ -64,12 +62,6 @@ char soundvolmeter[21]; int soundvolIndex=0; int L_count=0; int R_count=0; -extern int CurrentState; -int TurboFireOff=1; -int TurboFireTop=0; // 0 is none // 1 is A & X turbo // 2 is Y & B turbo -int TurboFireBottom=0; -int turbo_toggle_A=0; -int turbo_toggle_B=0; static void setsoundvol(int soundvolume) @@ -97,259 +89,60 @@ static void setsoundvol(int soundvolume) void FCEUD_UpdateInput(void) { - long lastpad2=lastpad; - unsigned long pad=gp2x_joystick_read(1); // TODO: USB joys and stuff - uint32 JS=0; - -#define down(b) (pad & GP2X_##b) -#define last_down(b) (lastpad & GP2X_##b) -#define L_down (pad & GP2X_L) -#define R_down (pad & GP2X_R) -#define last_L_down (lastpad & GP2X_L) -#define last_R_down (lastpad & GP2X_R) -#define shift ((pad & GP2X_PUSH) || ((pad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN))) -#define last_shift ((lastpad & GP2X_PUSH) || ((lastpad & (GP2X_VOL_UP|GP2X_VOL_DOWN)) == (GP2X_VOL_UP|GP2X_VOL_DOWN))) - - if (L_down && R_down && !(pad & GP2X_PUSH) && !(last_R_down && last_L_down)) - { - ResetNES(); - puts("Reset"); - goto no_pad; - } - - if (down(VOL_UP) && !down(VOL_DOWN)) - { - soundvol+=1; - if (soundvol >= 100) soundvol=100; - //FCEUI_SetSoundVolume(soundvol); - setsoundvol(soundvol); - } - else if (down(VOL_DOWN) && !down(VOL_UP)) - { - soundvol-=1; - if (soundvol < 0) soundvol=0; - //FCEUI_SetSoundVolume(soundvol); - setsoundvol(soundvol); - } - else if (down(VOL_DOWN) && down(VOL_UP)) - { - Exit = 1; - } - - if (shift) - { - // only if it's something else then last time, and not moving around the joystick - if (!(pad & (GP2X_UP|GP2X_DOWN|GP2X_LEFT|GP2X_RIGHT))) - { - if (down(SELECT)) - { - if (last_down(SELECT) && last_shift) + static int volpushed_frames = 0; + long lastpad2 = lastpad; + unsigned long keys = gp2x_joystick_read(0); + uint32 JS = 0; // RLDU SEBA + int i; + + #define down(b) (keys & GP2X_##b) + if ((down(VOL_DOWN) && down(VOL_UP)) || (keys & (GP2X_L|GP2X_L|GP2X_START)) == (GP2X_L|GP2X_L|GP2X_START)) { - // still pressed down from stretching from last one - goto no_pad; + Exit = 1; + JSreturn = 0; + return; } - scaled_display = !scaled_display; - - if (scaled_display) + else if (down(VOL_UP)) { - gp2x_video_RGB_setscaling(0, 256, 240); + /* wait for at least 10 updates, because user may be just trying to enter menu */ + if (volpushed_frames++ > 10) { + soundvol++; + if (soundvol > 100) soundvol=100; + //FCEUI_SetSoundVolume(soundvol); + setsoundvol(soundvol); + } } - else + else if (down(VOL_DOWN)) { - gp2x_video_RGB_setscaling(0, 320, 240); + if (volpushed_frames++ > 10) { + soundvol-=1; + if (soundvol < 0) soundvol=0; + //FCEUI_SetSoundVolume(soundvol); + setsoundvol(soundvol); + } + } + else + { + volpushed_frames = 0; } - goto no_pad; - } - else if (L_down && R_down) - { - FCEUI_CloseGame(); - puts("Quit"); - goto no_pad; - } - else if (R_down && !(last_R_down && last_shift)) - { - FCEUI_LoadState(); - goto no_pad; - } - else if (L_down && !(last_L_down && last_shift)) - { - FCEUI_SaveState(); - goto no_pad; - } - else if (down(A) && !(last_down(A) && last_shift)) - { - FSkip_setting--; - if (FSkip_setting < 0) { - FSkip_setting = -1; - FCEUI_DispMessage("Auto frameskip"); - } - else - FCEUI_DispMessage("Frameskip: %i", FSkip_setting); - goto no_pad; - } - else if (down(Y) && !(last_down(Y) && last_shift)) - { - FSkip_setting++; - if (FSkip_setting > 8) FSkip_setting = 8; - FCEUI_DispMessage("Frameskip: %i", FSkip_setting); - goto no_pad; - } - } - } - - // r is toggle savestate - if (R_down) - { - if (last_R_down) - { - R_count++; - if ((R_count & 31)== 31) - { - CurrentState=(CurrentState+1) % 10; - FCEUI_DispMessage("Now Using Save State %d", CurrentState); - } - } - } - else - { - R_count=0; - } - - // l is toggle turbo - if (L_down) - { - if (last_L_down) - { - L_count++; - if ((L_count & 31)== 31) - { - // 0 is none // 1 is Y & B turbo // 2 is X & A turbo - if ((!TurboFireTop) && (!TurboFireBottom)) - { - // was off - TurboFireTop=1; - TurboFireBottom=0; - if (swapbuttons) - { - FCEUI_DispMessage("Turbo A and Y"); - } - else - { - FCEUI_DispMessage("Turbo Y and B"); - } - } - else if (TurboFireTop) - { - TurboFireTop=0; - TurboFireBottom=1; - if (swapbuttons) - { - FCEUI_DispMessage("Turbo X and B"); - } - else - { - FCEUI_DispMessage("Turbo A and X"); - } - } - else - { - TurboFireTop=0; - TurboFireBottom=0; - FCEUI_DispMessage("Turbo Off"); - } - - } - } - } - else - { - L_count=0; - } - - //unsigned long padTmp=0; - // shift the bits in - // up - //padTmp=(pad & GP2X_UP) ; // 1 is 2^0, - JS |= ((pad & GP2X_UP) << (4-0)); // 0x10 is 2^4 - - //padTmp=(pad & GP2X_DOWN); // 0x10 is 2^4, - JS |= ((pad & GP2X_DOWN) << (5-4)); // 0x20 is 2^5 - - //padTmp=(pad & GP2X_LEFT); // 0x4 is 2^2, - JS |= ((pad & GP2X_LEFT) << (6-2)); // 0x40 is 2^6 - - //padTmp=(pad & GP2X_RIGHT); // 0x40 is 2^6, - JS |= ((pad & GP2X_RIGHT) << (7-6)); // 0x80 is 2^7 - - -#define A_down (pad & GP2X_A) -#define B_down (pad & GP2X_B) -#define X_down (pad & GP2X_X) -#define Y_down (pad & GP2X_Y) - - // should be 2 cycles held, 1 cycle release - turbo_toggle_A=(turbo_toggle_A+1) % 3; - turbo_toggle_B=(turbo_toggle_B+1) % 3; - - // 0 is none // 1 is Y & B turbo // 2 is X & A turbo - // B or X are both considered A - //padTmp=B_down >> 13; // 2^13, - - if (!(TurboFireTop && (!turbo_toggle_A))) - { - JS |= ((B_down >> 13) << 0); // 0x1 is 2^0 - } - // A or Y are both considered B - //padTmp=A_down >> 12; // 2^13, - if (!(TurboFireBottom && (!turbo_toggle_B))) - { - JS |= ((A_down >> 12) << 1); // 0x2 is 2^1 - } - - if (swapbuttons) - { - //padTmp=X_down >> 14; // 2^13, - if (!(TurboFireBottom && (!turbo_toggle_A))) - { -// JS |= ((X_down >> 14) << 0); // 0x1 is 2^0 - JS |= ((Y_down >> 15) << 0); // 0x1 is 2^0 - } - - //padTmp=Y_down >> 15; // 2^13, - if (!(TurboFireTop && (!turbo_toggle_B))) - { - JS |= ((X_down >> 14) << 1); // 0x2 is 2^1 - } - } - else - { - //padTmp=X_down >> 14; // 2^13, - if (!(TurboFireBottom && (!turbo_toggle_A))) - { - JS |= ((X_down >> 14) << 0); // 0x1 is 2^0 - } - - //padTmp=Y_down >> 15; // 2^13, - if (!(TurboFireTop && (!turbo_toggle_B))) - { - JS |= ((Y_down >> 15) << 1); // 0x2 is 2^1 - } - } - // select - //padTmp=(pad & GP2X_SELECT) >> 9; // 0x40 is 2^9, - JS |= (((pad & GP2X_SELECT) >> 9) << 2); // 0x4 is 2^2 + for (i = 0; i < 32; i++) + { + if (keys & (1 << i)) { + int acts = Settings.KeyBinds[i]; + if (!acts) continue; + JS |= acts & 0xff; + } + } - // start - //padTmp=(pad & GP2X_START) >> 8; // 2^8, - JS |= (((pad & GP2X_START) >> 8) << 3); // 0x8 is 2^3 - JSreturn = JS; - lastpad=pad; + JSreturn = JS; + lastpad=keys; - //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8); + //JSreturn=(JS&0xFF000000)|(JS&0xFF)|((JS&0xFF0000)>>8)|((JS&0xFF00)<<8); +#define pad keys // JSreturn=(JSreturn&0xFF000000)|(JSreturn&0xFF)|((JSreturn&0xFF0000)>>8)|((JSreturn&0xFF00)<<8); // TODO: make these bindable, use new interface @@ -370,10 +163,6 @@ void FCEUD_UpdateInput(void) } } return; - -no_pad: - JSreturn=0; - lastpad=pad; } diff --git a/drivers/gp2x/main.c b/drivers/gp2x/main.c index e9223f2..6a31f9d 100644 --- a/drivers/gp2x/main.c +++ b/drivers/gp2x/main.c @@ -1,7 +1,4 @@ /* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Ben Parnell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,11 +15,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* This file contains or coordinates all of the code necessary to compile - on a UNIX system that can use svgalib, such as FreeBSD and Linux. - This code is not guaranteed to compile on FreeBSD, though. -*/ - #include #include @@ -60,8 +52,6 @@ FCEUGI *fceugi = NULL; static int ntsccol=0,ntschue=-1,ntsctint=-1; int soundvol=70; int inited=0; -int swapbuttons=0; -int showfps=0; int srendlinev[2]={0,0}; int erendlinev[2]={239,239}; @@ -134,19 +124,23 @@ static CFGSTRUCT fceuconfig[]={ ENDCFGSTRUCT }; -static void SaveConfig(void) +void SaveConfig(const char *name) { char tdir[2048]; - sprintf(tdir,"%s"PSS"fceu.cfg",BaseDirectory); + if (name) + sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name); + else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory); DriverInterface(DES_GETNTSCTINT,&ntsctint); DriverInterface(DES_GETNTSCHUE,&ntschue); SaveFCEUConfig(tdir,fceuconfig); } -static void LoadConfig(void) +static void LoadConfig(const char *name) { char tdir[2048]; - sprintf(tdir,"%s"PSS"fceu.cfg",BaseDirectory); + if (name) + sprintf(tdir,"%s"PSS"cfg"PSS"%s.cfg",BaseDirectory,name); + else sprintf(tdir,"%s"PSS"fceu2.cfg",BaseDirectory); LoadFCEUConfig(tdir,fceuconfig); if(ntsctint>=0) DriverInterface(DES_SETNTSCTINT,&ntsctint); if(ntschue>=0) DriverInterface(DES_SETNTSCHUE,&ntschue); @@ -154,12 +148,12 @@ static void LoadConfig(void) static void CreateDirs(void) { - char *subs[5]={"fcs","snaps","gameinfo","sav","cheats"}; + char *subs[]={"fcs","snaps","gameinfo","sav","cheats","cfg"}; char tdir[2048]; int x; mkdir(BaseDirectory,S_IRWXU); - for(x=0;x<5;x++) + for(x=0;x= 0 && ((Settings.KeyBinds[i] >> 16) & 3) != player_idx) continue; if (strkeys[0]) { strcat(strkeys, " + "); strcat(strkeys, gp2xKeyNames[i]); break; } else strcpy(strkeys, gp2xKeyNames[i]); } @@ -609,9 +617,9 @@ static void draw_key_config(int curr_act, int is_p2) { for (i = 0; i < 32; i++) { - if (currentConfig.JoyBinds[joy][i] & (1 << curr_act)) + if (Settings.JoyBinds[joy][i] & action_mask) { - if (curr_act < 16 && (currentConfig.JoyBinds[joy][i] & (1 << 16)) != (is_p2 << 16)) continue; + if (player_idx >= 0 && ((Settings.KeyBinds[i] >> 16) & 3) != player_idx) continue; if (strkeys[0]) { strcat(strkeys, ", "); strcat(strkeys, usb_joy_key_name(joy + 1, i)); break; @@ -621,51 +629,121 @@ static void draw_key_config(int curr_act, int is_p2) } } - //memset(gp2x_screen, 0, 320*240); + return strkeys; +} + +static void unbind_action(int action) +{ + int i, u; + + for (i = 0; i < 32; i++) + Settings.KeyBinds[i] &= ~action; + for (u = 0; u < 4; u++) + for (i = 0; i < 32; i++) + Settings.JoyBinds[u][i] &= ~action; +} + +static int count_bound_keys(int action, int is_joy) +{ + int i, u, keys = 0; + + if (is_joy) + { + for (u = 0; u < 4; u++) + for (i = 0; i < 32; i++) + if (Settings.JoyBinds[u][i] & action) keys++; + } + else + { + for (i = 0; i < 32; i++) + if (Settings.KeyBinds[i] & action) keys++; + } + return keys; +} + +typedef struct { char *name; int mask; } bind_action_t; + +// b_turbo,a_turbo RLDU SEBA +static bind_action_t ctrl_actions[] = +{ + { "UP ", 0x010 }, + { "DOWN ", 0x020 }, + { "LEFT ", 0x040 }, + { "RIGHT ", 0x080 }, + { "A ", 0x001 }, + { "B ", 0x002 }, + { "A TURBO", 0x100 }, + { "B TURBO", 0x200 }, + { "START ", 0x008 }, + { "SELECT ", 0x004 }, +}; + +static void draw_key_config(const bind_action_t *opts, int opt_cnt, int player_idx, int sel) +{ + int x, y, tl_y = 40, i; + gp2x_fceu_copy_bg(); - gp2x_text_out15(60, 40, "Action: %s", actionNames[curr_act]); - gp2x_text_out15(60, 60, "Keys: %s", strkeys); + gp2x_text_out15(80, 20, "Player %i controls", player_idx + 1); + + x = 40; y = tl_y; + for (i = 0; i < opt_cnt; i++, y+=10) + gp2x_text_out15(x, y, "%s : %s", opts[i].name, action_binds(player_idx, opts[i].mask)); + + gp2x_text_out15(x, y, "Done"); + + // draw cursor + gp2x_text_out15(x - 16, tl_y + sel*10, ">"); - gp2x_text_out15(30, 180, "Use SELECT to change action"); - gp2x_text_out15(30, 190, "Press a key to bind/unbind"); - gp2x_text_out15(30, 200, "Select \"Done\" action and"); - gp2x_text_out15(30, 210, " press any key to finish"); + if (sel < 10) { + gp2x_text_out15(30, 190, "Press a button to bind/unbind"); + gp2x_text_out15(30, 200, "Use VOL+ to clear"); + gp2x_text_out15(30, 210, "To bind UP/DOWN, hold VOL-"); + gp2x_text_out15(30, 220, "Select \"Done\" to exit"); + } else { + gp2x_text_out15(30, 220, "Press B or X to exit"); + } gp2x_video_flip(); } -static void key_config_loop(int is_p2) +static void key_config_loop(const bind_action_t *opts, int opt_cnt, int player_idx) { - int curr_act = 0, joy = 0, i; + int joy = 0, sel = 0, menu_sel_max = opt_cnt, i; unsigned long inp = 0; for (;;) { - draw_key_config(curr_act, is_p2); - inp = wait_for_input_usbjoy(CONFIGURABLE_KEYS, &joy); + draw_key_config(opts, opt_cnt, player_idx, sel); + inp = wait_for_input_usbjoy(CONFIGURABLE_KEYS|GP2X_VOL_DOWN|GP2X_VOL_UP, &joy); // printf("got %08lX from joy %i\n", inp, joy); if (joy == 0) { - if (inp & GP2X_SELECT) { - curr_act++; - while (!actionNames[curr_act] && curr_act < 32) curr_act++; - if (curr_act > 31) curr_act = 0; + if (!(inp & GP2X_VOL_DOWN)) { + if(inp & GP2X_UP ) { sel--; if (sel < 0) sel = menu_sel_max; continue; } + if(inp & GP2X_DOWN) { sel++; if (sel > menu_sel_max) sel = 0; continue; } + } + if (sel >= opt_cnt) { + if (inp & (GP2X_B|GP2X_X)) break; + else continue; } + // if we are here, we want to bind/unbind something + if (inp & GP2X_VOL_UP) + unbind_action(opts[sel].mask); inp &= CONFIGURABLE_KEYS; - inp &= ~GP2X_SELECT; - } - if (curr_act == 31 && inp) break; - if (joy == 0) { for (i = 0; i < 32; i++) if (inp & (1 << i)) { - currentConfig.KeyBinds[i] ^= (1 << curr_act); - if (is_p2) currentConfig.KeyBinds[i] |= (1 << 16); // player 2 flag - else currentConfig.KeyBinds[i] &= ~(1 << 16); + if (count_bound_keys(opts[sel].mask, 0) >= 2) + Settings.KeyBinds[i] &= ~opts[sel].mask; // allow to unbind only + else Settings.KeyBinds[i] ^= opts[sel].mask; + Settings.KeyBinds[i] &= ~(3 << 16); + Settings.KeyBinds[i] |= player_idx << 16; } - } else { + } else if (sel < opt_cnt) { for (i = 0; i < 32; i++) if (inp & (1 << i)) { - currentConfig.JoyBinds[joy-1][i] ^= (1 << curr_act); - if (is_p2) currentConfig.JoyBinds[joy-1][i] |= (1 << 16); - else currentConfig.JoyBinds[joy-1][i] &= ~(1 << 16); + if (count_bound_keys(opts[sel].mask, 1) >= 1) // disallow combos for usbjoy + Settings.JoyBinds[joy-1][i] &= ~opts[sel].mask; + else Settings.JoyBinds[joy-1][i] ^= opts[sel].mask; + Settings.JoyBinds[joy-1][i] &= ~(3 << 16); + Settings.JoyBinds[joy-1][i] |= player_idx << 16; } } } @@ -677,10 +755,10 @@ static void draw_kc_sel(int menu_sel) char joyname[36]; y = tl_y; - //memset(gp2x_screen, 0, 320*240); gp2x_fceu_copy_bg(); gp2x_text_out15(tl_x, y, "Player 1"); gp2x_text_out15(tl_x, (y+=10), "Player 2"); + gp2x_text_out15(tl_x, (y+=10), "Emulator controls"); gp2x_text_out15(tl_x, (y+=10), "Done"); // draw cursor @@ -697,13 +775,12 @@ static void draw_kc_sel(int menu_sel) gp2x_text_out15(tl_x, (y+=10), "none"); } - gp2x_video_flip(); } static void kc_sel_loop(void) { - int menu_sel = 2, menu_sel_max = 2; + int menu_sel = 3, menu_sel_max = 3; unsigned long inp = 0; for(;;) @@ -714,15 +791,14 @@ static void kc_sel_loop(void) if(inp & GP2X_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; } if(inp & GP2X_B) { switch (menu_sel) { - case 0: key_config_loop(0); return; - case 1: key_config_loop(1); return; + case 0: key_config_loop(ctrl_actions, 10, 0); return; + case 1: key_config_loop(ctrl_actions, 8, 1); return; default: return; } } if(inp & GP2X_X) return; } } -#endif @@ -790,7 +866,7 @@ static void amenu_loop_options(void) static void draw_menu_options(int menu_sel) { int tl_x = 25, tl_y = 32, y; - char monostereo[8], strframeskip[8], *strscaling, *strssconfirm; + char /*monostereo[8],*/ strframeskip[8], *strscaling, *strssconfirm; //strcpy(monostereo, (currentConfig.PicoOpt&0x08)?"stereo":"mono"); if (Settings.frameskip < 0) @@ -813,12 +889,12 @@ static void draw_menu_options(int menu_sel) //memset(gp2x_screen, 0, 320*240); gp2x_fceu_copy_bg(); - gp2x_text_out15(tl_x, (y+=10), "Scaling: %s", strscaling); // 0 + gp2x_text_out15(tl_x, y, "Scaling: %s", strscaling); // 0 gp2x_text_out15(tl_x, (y+=10), "Show FPS %s", Settings.showfps?"ON":"OFF"); // 1 gp2x_text_out15(tl_x, (y+=10), "Frameskip %s", strframeskip); // 2 gp2x_text_out15(tl_x, (y+=10), "Enable sound %s", /*(currentConfig.EmuOpt &0x004)?"ON":*/"OFF"); // 3 gp2x_text_out15(tl_x, (y+=10), "Sound Quality: %5iHz %s", 0, "" /*currentConfig.PsndRate, monostereo*/); // 4 - gp2x_text_out15(tl_x, (y+=10), "Region: %s", + gp2x_text_out15(tl_x, (y+=10), "Region: %s", Settings.region_force == 2 ? "NTSC" : Settings.region_force == 1 ? "PAL" : "OFF"); // 5 gp2x_text_out15(tl_x, (y+=10), "Use SRAM savestates %s", "OFF"); gp2x_text_out15(tl_x, (y+=10), "Confirm savestate %s", strssconfirm); @@ -873,18 +949,20 @@ static int menu_loop_options(void) switch (menu_sel) { case 1: Settings.showfps = !Settings.showfps; break; //case 6: Settings. = !Settings.showfps; break; - //case 16: amenu_loop_options(); break; - case 17: // done (update and write) - //if (emu_WriteConfig(0)) strcpy(menuErrorMsg, "config saved"); - //else strcpy(menuErrorMsg, "failed to write config"); + //case 10: amenu_loop_options(); break; + case 11: // done (update and write) + gp2x_cpuclock_update(); + SaveConfig(NULL); return 1; - case 18: // done (update and write for current game) - //if (emu_WriteConfig(1)) strcpy(menuErrorMsg, "config saved"); - //else strcpy(menuErrorMsg, "failed to write config"); + case 12: // done (update and write for current game) + gp2x_cpuclock_update(); + if (lastLoadedGameName[0]) + SaveConfig(lastLoadedGameName); return 1; } } if(inp & (GP2X_X|GP2X_A)) { + gp2x_cpuclock_update(); return 0; // done (update, no write) } if(inp & (GP2X_LEFT|GP2X_RIGHT)) { // multi choise @@ -902,11 +980,11 @@ static int menu_loop_options(void) */ case 5: int_incdec(&Settings.region_force, (inp & GP2X_LEFT) ? -1 : 1, 0, 2); break; case 7: int_incdec(&Settings.sstate_confirm, (inp & GP2X_LEFT) ? -1 : 1, 0, 3); break; - //case 8: int_incdec(&Settings., (inp & GP2X_LEFT) ? -1 : 1, 0, 9); break; - case 14: + case 8: int_incdec(&CurrentState, (inp & GP2X_LEFT) ? -1 : 1, 0, 9); break; + case 9: while ((inp = gp2x_joystick_read(1)) & (GP2X_LEFT|GP2X_RIGHT)) { Settings.cpuclock += (inp & GP2X_LEFT) ? -1 : 1; - if (Settings.cpuclock < 1) Settings.cpuclock = 1; + if (Settings.cpuclock < 0) Settings.cpuclock = 0; // 0 ~ do not change draw_menu_options(menu_sel); usleep(50*1000); } @@ -920,8 +998,7 @@ static int menu_loop_options(void) static void draw_menu_credits(void) { - int tl_x = 15, tl_y = 70, y; - //memset(gp2x_screen, 0, 320*240); + //int tl_x = 15, tl_y = 70; gp2x_fceu_copy_bg(); // TODO @@ -934,7 +1011,7 @@ static void draw_menu_credits(void) static void draw_menu_root(int menu_sel) { - int tl_x = 70, tl_y = 70, y; + int tl_x = 30, tl_y = 128, y; gp2x_fceu_copy_bg(); y = tl_y; @@ -947,8 +1024,8 @@ static void draw_menu_root(int menu_sel) y += 30; } gp2x_text_out15(tl_x, (y+=10), "Load new ROM"); - gp2x_text_out15(tl_x, (y+=10), "Change options"); - gp2x_text_out15(tl_x, (y+=10), "Configure controls"); + gp2x_text_out15(tl_x, (y+=10), "Options"); + gp2x_text_out15(tl_x, (y+=10), "Controls"); gp2x_text_out15(tl_x, (y+=10), "Credits"); gp2x_text_out15(tl_x, (y+=10), "Exit"); // TODO @@ -958,14 +1035,20 @@ static void draw_menu_root(int menu_sel) // draw cursor gp2x_text_out15(tl_x - 16, tl_y + menu_sel*10, ">"); // error - if (menuErrorMsg[0]) gp2x_text_out15(5, 226, menuErrorMsg); + if (menuErrorMsg[0]) gp2x_text_out15(1, 230, menuErrorMsg); + else { + char vstr[16]; + sprintf(vstr, "v" GP2X_PORT_VERSION " r%i", GP2X_PORT_REV); + gp2x_text_out15(320-strlen(vstr)*8-1, 230, vstr); + } gp2x_video_flip(); } static int menu_loop_root(void) { - int ret, menu_sel = 4, menu_sel_max = 8, menu_sel_min = 4; + int ret, menu_sel_max = 8, menu_sel_min = 4; + static int menu_sel = 4; unsigned long inp = 0; char curr_path[PATH_MAX], *selfname; FILE *tstf; @@ -981,8 +1064,10 @@ static int menu_loop_root(void) getcwd(curr_path, PATH_MAX); } - if (fceugi) menu_sel = menu_sel_min = 0; + if (fceugi) menu_sel_min = 0; // TODO if (PicoPatches) menu_sel_max = 9; + if (menu_sel < menu_sel_min || menu_sel > menu_sel_max) + menu_sel = menu_sel_min; /* make sure action buttons are not pressed on entering menu */ draw_menu_root(menu_sel); @@ -1014,6 +1099,7 @@ static int menu_loop_root(void) if (fceugi) { /*if(savestate_menu_loop(0)) continue;*/ + FCEUI_SaveState(); return 0; } break; @@ -1021,11 +1107,14 @@ static int menu_loop_root(void) if (fceugi) { /*if(savestate_menu_loop(1)) continue;*/ + FCEUI_LoadState(); return 0; } break; case 3: // reset game if (fceugi) { + FCEU_DoSimpleCommand(FCEUNPCMD_RESET); + Exit = 0; return 0; } break; @@ -1041,7 +1130,7 @@ static int menu_loop_root(void) if (ret == 1) continue; // status update break; case 6: // controls - // TODO kc_sel_loop(); + kc_sel_loop(); break; case 7: // credits draw_menu_credits(); diff --git a/drivers/gp2x/squidgehack.c b/drivers/gp2x/squidgehack.c index f831bd4..67f21b0 100644 --- a/drivers/gp2x/squidgehack.c +++ b/drivers/gp2x/squidgehack.c @@ -12,25 +12,28 @@ extern char **g_argv; int mmuhack(void) { char kocmd[1024]; - int i, mmufd = open("/dev/mmuhack", O_RDWR); - - if(mmufd < 0) { - strcpy(kocmd, "/sbin/insmod "); - strncpy(kocmd+13, g_argv[0], 1023-13); - kocmd[1023] = 0; - for (i = strlen(kocmd); i > 0; i--) - if (kocmd[i] == '/') { kocmd[i] = 0; break; } - strcat(kocmd, "/mmuhack.o"); - - printf("Installing NK's kernel module for Squidge MMU Hack (%s)...\n", kocmd); - system(kocmd); - mmufd = open("/dev/mmuhack", O_RDWR); - } + int i, mmufd; + + /* some programs like some versions of gpSP use some weird version of mmuhack.o + * which doesn't seem to work. What's even worse they leave their mmuhack loaded on exit. + * So we must remove whatever may be left and always reload _our_ mmuhack.o */ + system("/sbin/rmmod mmuhack"); + + strcpy(kocmd, "/sbin/insmod "); + strncpy(kocmd+13, g_argv[0], 1023-13); + kocmd[1023] = 0; + for (i = strlen(kocmd); i > 0; i--) + if (kocmd[i] == '/') { kocmd[i] = 0; break; } + strcat(kocmd, "/mmuhack.o"); + + printf("Installing NK's kernel module for Squidge MMU Hack (%s)...\n", kocmd); + system(kocmd); + mmufd = open("/dev/mmuhack", O_RDWR); if(mmufd < 0) return 0; - + close(mmufd); return 1; -} +} /* Unload MMU Hack kernel module after closing all memory devices*/ diff --git a/fce.c b/fce.c index 38680f9..d83c5f5 100644 --- a/fce.c +++ b/fce.c @@ -562,7 +562,6 @@ void BGRender(uint8 *target) } #ifdef FRAMESKIP -int FSkip_setting=-1; // auto int FSkip=0; void FCEUI_FrameSkip(int x) { diff --git a/input.c b/input.c index 44432ae..b540f55 100644 --- a/input.c +++ b/input.c @@ -348,16 +348,6 @@ void FCEUI_SetInputFC(int type, void *ptr, int attrib) SetInputStuffFC(); } -// quick paste -#define FCEUNPCMD_RESET 0x01 -#define FCEUNPCMD_POWER 0x02 - -#define FCEUNPCMD_VSUNICOIN 0x07 -#define FCEUNPCMD_VSUNIDIP0 0x08 -#define FCEUNPCMD_FDSINSERT 0x18 -#define FCEUNPCMD_FDSSELECT 0x1A - - void FCEU_DoSimpleCommand(int cmd) { switch(cmd) diff --git a/input.h b/input.h index 3adc898..daaa304 100644 --- a/input.h +++ b/input.h @@ -22,6 +22,13 @@ void InitializeInput(void); extern void (*PStrobe[2])(void); extern void (*InputScanlineHook)(uint8 *buf, int line); +#define FCEUNPCMD_RESET 0x01 +#define FCEUNPCMD_POWER 0x02 + +#define FCEUNPCMD_VSUNICOIN 0x07 +#define FCEUNPCMD_VSUNIDIP0 0x08 +#define FCEUNPCMD_FDSINSERT 0x18 +#define FCEUNPCMD_FDSSELECT 0x1A void FCEU_DoSimpleCommand(int cmd); void FCEUI_FDSSelect(void); -- 2.39.5