ABC turbo
authornotaz <notasas@gmail.com>
Wed, 16 Jul 2008 12:50:33 +0000 (12:50 +0000)
committernotaz <notasas@gmail.com>
Wed, 16 Jul 2008 12:50:33 +0000 (12:50 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@553 be3aeb3a-fb24-0410-a615-afba39da0efa

13 files changed:
base_readme.txt
common/config.c
common/emu.c
common/emu.h
common/menu.c
common/menu.h
gp2x/emu.c
gp2x/gp2x.c
gp2x/menu.c
gp2x/version.h
psp/emu.c
psp/menu.c
psp/version.h

index d59baa7..d0f074b 100644 (file)
@@ -245,10 +245,6 @@ This option causes PicoDrive to use ARM940T core (GP2X's second CPU) for sound
 (i.e. to generate YM2612 samples) to improve performance noticeably.\r
 #endif\r
 \r
-@@0. "6 button pad"\r
-If you enable this, games will think that 6 button gamepad is connected. If you\r
-go and reconfigure your keys, you will be able to bind X,Y,Z and mode actions.\r
-\r
 @@0. "Region"\r
 This option lets you force the game to think it is running on machine from the\r
 specified region, or just to set autodetection order. Also affects Sega/Mega CD.\r
@@ -473,7 +469,10 @@ the right Giz ones, which are assigned to them. If you bind 2 different Giz butt
 the right PSP ones, which are assigned to them. If you bind 2 different PSP buttons\r
 #endif\r
 to the same action, you will get a combo (which means that you will have to press\r
-both buttons for that action to happen.\r
+both buttons for that action to happen).\r
+\r
+There is also option to enable 6 button pad (will allow you to configure XYZ\r
+keys), and an option to set turbo rate (in Hz) for turbo buttons.\r
 \r
 \r
 Cheat support\r
@@ -646,12 +645,13 @@ Additional thanks
 \r
 Changelog\r
 ---------\r
-1.50a\r
+1.51\r
   * Improved bin_to_cso_mp3 tool, it should no longer complain about\r
     missing lame.exe even if it's in working dir.\r
   * Fixed a regression from 1.50, which caused slowdowns in Final Fight.\r
   * Fixed some regressions from 1.50 related to sprite limit and palette\r
     handling (caused graphical glitches in some games).\r
+  + Added ABC turbo actions to key config.\r
   * Some other minor adjustments.\r
 \r
 1.50\r
index 3959706..55b1eae 100644 (file)
@@ -20,9 +20,11 @@ static char *mystrip(char *str);
 extern menu_entry opt_entries[];
 extern menu_entry opt2_entries[];
 extern menu_entry cdopt_entries[];
+extern menu_entry ctrlopt_entries[];
 extern const int opt_entry_count;
 extern const int opt2_entry_count;
 extern const int cdopt_entry_count;
+extern const int ctrlopt_entry_count;
 #ifdef PSP
 extern menu_entry opt3_entries[];
 extern const int opt3_entry_count;
@@ -33,6 +35,7 @@ static menu_entry *cfg_opts[] =
        opt_entries,
        opt2_entries,
        cdopt_entries,
+       ctrlopt_entries,
 #ifdef PSP
        opt3_entries,
 #endif
@@ -43,6 +46,7 @@ static const int *cfg_opt_counts[] =
        &opt_entry_count,
        &opt2_entry_count,
        &cdopt_entry_count,
+       &ctrlopt_entry_count,
 #ifdef PSP
        &opt3_entry_count,
 #endif
@@ -277,6 +281,9 @@ static int default_var(const menu_entry *me)
                case MA_CDOPT_LEDS:
                        return defaultConfig.EmuOpt;
 
+               case MA_CTRL_TURBO_RATE:
+                       return defaultConfig.turbo_rate;
+
                case MA_OPT_SAVE_SLOT:
                default:
                        return 0;
@@ -370,7 +377,7 @@ write:
                                if (!no_defaults || ((*(int *)me->var ^ default_var(me)) & me->mask))
                                        fprintf(fn, "%s = %i" NL, me->name, (*(int *)me->var & me->mask) ? 1 : 0);
                        } else if (me->beh == MB_RANGE) {
-                               if (!no_defaults || ((*(int *)me->var ^ default_var(me)) & me->mask))
+                               if (!no_defaults || (*(int *)me->var ^ default_var(me)))
                                        fprintf(fn, "%s = %i" NL, me->name, *(int *)me->var);
                        }
                }
index c482673..5b69357 100644 (file)
@@ -1026,6 +1026,27 @@ void emu_RunEventsPico(unsigned int events)
        }\r
 }\r
 \r
-\r
-\r
+void emu_DoTurbo(int *pad, int acts)\r
+{\r
+       static int turbo_pad = 0;\r
+       static unsigned char turbo_cnt[3] = { 0, 0, 0 };\r
+       int inc = currentConfig.turbo_rate * 2;\r
+\r
+       if (acts & 0x1000) {\r
+               turbo_cnt[0] += inc;\r
+               if (turbo_cnt[0] >= 60)\r
+                       turbo_pad ^= 0x10, turbo_cnt[0] = 0;\r
+       }\r
+       if (acts & 0x2000) {\r
+               turbo_cnt[1] += inc;\r
+               if (turbo_cnt[1] >= 60)\r
+                       turbo_pad ^= 0x20, turbo_cnt[1] = 0;\r
+       }\r
+       if (acts & 0x4000) {\r
+               turbo_cnt[2] += inc;\r
+               if (turbo_cnt[2] >= 60)\r
+                       turbo_pad ^= 0x40, turbo_cnt[2] = 0;\r
+       }\r
+       *pad |= turbo_pad & (acts >> 8);\r
+}\r
 \r
index ac75dd0..9ba0219 100644 (file)
@@ -25,6 +25,7 @@ typedef struct {
        float scale; // psp: screen scale
        float hscale32, hscale40; // psp: horizontal scale
        int gamma2;  // psp: black level
+       int turbo_rate;
 } currentConfig_t;
 
 extern currentConfig_t currentConfig, defaultConfig;
@@ -56,6 +57,7 @@ void  emu_findKeyBindCombos(void);
 void  emu_forcedFrame(int opts);
 void  emu_changeFastForward(int set_on);
 void  emu_RunEventsPico(unsigned int events);
+void  emu_DoTurbo(int *pad, int acts);
 
 extern const char * const keyNames[];
 void  emu_prepareDefaultConfig(void);
index b3dc27a..7a97fc3 100644 (file)
 char menuErrorMsg[64] = { 0, };\r
 \r
 // PicoPad[] format: MXYZ SACB RLDU\r
-me_bind_action me_ctrl_actions[12] =\r
+me_bind_action me_ctrl_actions[15] =\r
 {\r
-       { "UP     ", 0x001 },\r
-       { "DOWN   ", 0x002 },\r
-       { "LEFT   ", 0x004 },\r
-       { "RIGHT  ", 0x008 },\r
-       { "A      ", 0x040 },\r
-       { "B      ", 0x010 },\r
-       { "C      ", 0x020 },\r
-       { "START  ", 0x080 },\r
-       { "MODE   ", 0x800 },\r
-       { "X      ", 0x400 },\r
-       { "Y      ", 0x200 },\r
-       { "Z      ", 0x100 }\r
+       { "UP     ", 0x0001 },\r
+       { "DOWN   ", 0x0002 },\r
+       { "LEFT   ", 0x0004 },\r
+       { "RIGHT  ", 0x0008 },\r
+       { "A      ", 0x0040 },\r
+       { "B      ", 0x0010 },\r
+       { "C      ", 0x0020 },\r
+       { "A turbo", 0x4000 },\r
+       { "B turbo", 0x1000 },\r
+       { "C turbo", 0x2000 },\r
+       { "START  ", 0x0080 },\r
+       { "MODE   ", 0x0800 },\r
+       { "X      ", 0x0400 },\r
+       { "Y      ", 0x0200 },\r
+       { "Z      ", 0x0100 }\r
 };\r
 \r
 \r
index 4c20b55..7a4213d 100644 (file)
@@ -91,6 +91,11 @@ typedef enum
        MA_CDOPT_SCALEROT_CHIP,
        MA_CDOPT_BETTER_SYNC,
        MA_CDOPT_DONE,
+       MA_CTRL_PLAYER1,
+       MA_CTRL_PLAYER2,
+       MA_CTRL_EMU,
+       MA_CTRL_TURBO_RATE,
+       MA_CTRL_DONE,
 } menu_id;
 
 typedef struct
@@ -112,7 +117,7 @@ typedef struct
        int mask;
 } me_bind_action;
 
-extern me_bind_action me_ctrl_actions[12];
+extern me_bind_action me_ctrl_actions[15];
 extern me_bind_action emuctrl_actions[];       // platform code
 
 
index 570b0fc..9afa61b 100644 (file)
@@ -164,6 +164,7 @@ void emu_prepareDefaultConfig(void)
        defaultConfig.KeyBinds[22] = 1<<30; // vol down\r
        defaultConfig.gamma = 100;\r
        defaultConfig.scaling = 0;\r
+       defaultConfig.turbo_rate = 15;\r
 }\r
 \r
 void emu_setDefaultConfig(void)\r
@@ -436,33 +437,19 @@ static void emu_msg_tray_open(void)
 \r
 static void RunEventsPico(unsigned int events, unsigned int gp2x_keys)\r
 {\r
-       int ret, px, py;\r
+       int ret, px, py, lim_x;\r
        static int pdown_frames = 0;\r
 \r
        emu_RunEventsPico(events);\r
 \r
-       if (pico_inp_mode != 0)\r
-       {\r
-               PicoPad[0] &= ~0x0f; // release UDLR\r
-               if (gp2x_keys & GP2X_UP)   { pico_pen_y--; if (pico_pen_y < 8) pico_pen_y = 8; }\r
-               if (gp2x_keys & GP2X_DOWN) { pico_pen_y++; if (pico_pen_y > 224-PICO_PEN_ADJUST_Y) pico_pen_y = 224-PICO_PEN_ADJUST_Y; }\r
-               if (gp2x_keys & GP2X_LEFT) { pico_pen_x--; if (pico_pen_x < 0) pico_pen_x = 0; }\r
-               if (gp2x_keys & GP2X_RIGHT) {\r
-                       int lim = (Pico.video.reg[12]&1) ? 319 : 255;\r
-                       pico_pen_x++;\r
-                       if (pico_pen_x > lim-PICO_PEN_ADJUST_X)\r
-                               pico_pen_x = lim-PICO_PEN_ADJUST_X;\r
-               }\r
-               PicoPicohw.pen_pos[0] = pico_pen_x;\r
-               if (!(Pico.video.reg[12]&1)) PicoPicohw.pen_pos[0] += pico_pen_x/4;\r
-               PicoPicohw.pen_pos[0] += 0x3c;\r
-               PicoPicohw.pen_pos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);\r
-       }\r
+       if (pico_inp_mode == 0) return;\r
 \r
        // for F200\r
        ret = gp2x_touchpad_read(&px, &py);\r
-       if (ret >= 0) {\r
-               if (ret > 5000) {\r
+       if (ret >= 0)\r
+       {\r
+               if (ret > 35000)\r
+               {\r
                        if (pdown_frames++ > 5)\r
                                PicoPad[0] |= 0x20;\r
 \r
@@ -476,11 +463,28 @@ static void RunEventsPico(unsigned int events, unsigned int gp2x_keys)
                        if (pico_pen_y > 224) pico_pen_y = 224;\r
                }\r
                else\r
-                       pdown_frames= 0;\r
+                       pdown_frames = 0;\r
 \r
                //if (ret == 0)\r
                //      PicoPicohw.pen_pos[0] = PicoPicohw.pen_pos[1] = 0x8000;\r
        }\r
+\r
+       PicoPad[0] &= ~0x0f; // release UDLR\r
+       if (gp2x_keys & GP2X_UP)    pico_pen_y--;\r
+       if (gp2x_keys & GP2X_DOWN)  pico_pen_y++;\r
+       if (gp2x_keys & GP2X_LEFT)  pico_pen_x--;\r
+       if (gp2x_keys & GP2X_RIGHT) pico_pen_x++;\r
+\r
+       lim_x = (Pico.video.reg[12]&1) ? 319 : 255;\r
+       if (pico_pen_y < 8) pico_pen_y = 8;\r
+       if (pico_pen_y > 224-PICO_PEN_ADJUST_Y) pico_pen_y = 224-PICO_PEN_ADJUST_Y;\r
+       if (pico_pen_x < 0) pico_pen_x = 0;\r
+       if (pico_pen_x > lim_x-PICO_PEN_ADJUST_X) pico_pen_x = lim_x-PICO_PEN_ADJUST_X;\r
+\r
+       PicoPicohw.pen_pos[0] = pico_pen_x;\r
+       if (!(Pico.video.reg[12]&1)) PicoPicohw.pen_pos[0] += pico_pen_x/4;\r
+       PicoPicohw.pen_pos[0] += 0x3c;\r
+       PicoPicohw.pen_pos[1] = pico_inp_mode == 1 ? (0x2f8 + pico_pen_y) : (0x1fc + pico_pen_y);\r
 }\r
 \r
 static void update_volume(int has_changed, int is_up)\r
@@ -639,8 +643,11 @@ static void updateKeys(void)
                }\r
        }\r
 \r
-       PicoPad[0] = (unsigned short) allActions[0];\r
-       PicoPad[1] = (unsigned short) allActions[1];\r
+       PicoPad[0] = allActions[0] & 0xfff;\r
+       PicoPad[1] = allActions[1] & 0xfff;\r
+\r
+       if (allActions[0] & 0x7000) emu_DoTurbo(&PicoPad[0], allActions[0]);\r
+       if (allActions[1] & 0x7000) emu_DoTurbo(&PicoPad[1], allActions[1]);\r
 \r
        events = (allActions[0] | allActions[1]) >> 16;\r
 \r
index 78e8561..80b0486 100644 (file)
@@ -231,6 +231,7 @@ typedef struct ucb1x00_ts_event
 int gp2x_touchpad_read(int *x, int *y)\r
 {\r
        UCB1X00_TS_EVENT event;\r
+       static int zero_seen = 0;\r
        int retval;\r
 \r
        if (touchdev < 0) return -1;\r
@@ -240,12 +241,14 @@ int gp2x_touchpad_read(int *x, int *y)
                printf("touch read failed %i %i\n", retval, errno);\r
                return -1;\r
        }\r
+       // this is to ignore the messed-up 4.1.x driver\r
+       if (retval == 0) zero_seen = 1;\r
 \r
        if (x) *x = (event.x * touchcal[0] + touchcal[2]) >> 16;\r
        if (y) *y = (event.y * touchcal[4] + touchcal[5]) >> 16;\r
        // printf("read %i %i %i\n", event.pressure, *x, *y);\r
 \r
-       return event.pressure;\r
+       return zero_seen ? event.pressure : 0;\r
 }\r
 \r
 \r
index 9bc880a..1dc829a 100644 (file)
@@ -712,14 +712,14 @@ static int count_bound_keys(int action, int pl_idx, int joy)
 \r
 static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, int sel)\r
 {\r
-       int x, y, tl_y = 40, i;\r
+       int x, y, tl_y = 30, i;\r
 \r
        gp2x_pd_clone_buffer2();\r
        if (player_idx >= 0) {\r
-               text_out16(80, 20, "Player %i controls", player_idx + 1);\r
+               text_out16(80, 10, "Player %i controls", player_idx + 1);\r
                x = 80;\r
        } else {\r
-               text_out16(80, 20, "Emulator controls");\r
+               text_out16(80, 10, "Emulator controls");\r
                x = 40;\r
        }\r
 \r
@@ -732,14 +732,14 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_
        text_out16(x, y, "Done");\r
 \r
        if (sel < opt_cnt) {\r
-               text_out16(30, 180, "Press a button to bind/unbind");\r
-               text_out16(30, 190, "Use SELECT to clear");\r
-               text_out16(30, 200, "To bind UP/DOWN, hold SELECT");\r
-               text_out16(30, 210, "Select \"Done\" to exit");\r
+               text_out16(30, 195, "Press a button to bind/unbind");\r
+               text_out16(30, 205, "Use SELECT to clear");\r
+               text_out16(30, 215, "To bind UP/DOWN, hold SELECT");\r
+               text_out16(30, 225, "Select \"Done\" to exit");\r
        } else {\r
-               text_out16(30, 190, "Use Options -> Save cfg");\r
-               text_out16(30, 200, "to save controls");\r
-               text_out16(30, 210, "Press B or X to exit");\r
+               text_out16(30, 205, "Use Options -> Save cfg");\r
+               text_out16(30, 215, "to save controls");\r
+               text_out16(30, 225, "Press B or X to exit");\r
        }\r
        menu_flip();\r
 }\r
@@ -800,6 +800,21 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_
        }\r
 }\r
 \r
+\r
+menu_entry ctrlopt_entries[] =\r
+{\r
+       { "Player 1",                  MB_NONE,  MA_CTRL_PLAYER1,       NULL, 0, 0, 0, 1, 0 },\r
+       { "Player 2",                  MB_NONE,  MA_CTRL_PLAYER2,       NULL, 0, 0, 0, 1, 0 },\r
+       { "Emulator controls",         MB_NONE,  MA_CTRL_EMU,           NULL, 0, 0, 0, 1, 0 },\r
+       { "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &PicoOpt, 0x020, 0, 0, 1, 1 },\r
+       { "Turbo rate",                MB_RANGE, MA_CTRL_TURBO_RATE,   &currentConfig.turbo_rate, 0, 1, 30, 1, 1 },\r
+       { "Done",                      MB_NONE,  MA_CTRL_DONE,          NULL, 0, 0, 0, 1, 0 },\r
+};\r
+\r
+#define CTRLOPT_ENTRY_COUNT (sizeof(ctrlopt_entries) / sizeof(ctrlopt_entries[0]))\r
+const int ctrlopt_entry_count = CTRLOPT_ENTRY_COUNT;\r
+\r
+\r
 static void draw_kc_sel(int menu_sel)\r
 {\r
        int tl_x = 25+40, tl_y = 60, y, i;\r
@@ -809,13 +824,10 @@ static void draw_kc_sel(int menu_sel)
        gp2x_pd_clone_buffer2();\r
        menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 138);\r
 \r
-       text_out16(tl_x, y,       "Player 1");\r
-       text_out16(tl_x, (y+=10), "Player 2");\r
-       text_out16(tl_x, (y+=10), "Emulator controls");\r
-       text_out16(tl_x, (y+=10), "Done");\r
+       me_draw(ctrlopt_entries, ctrlopt_entry_count, tl_x, tl_y, NULL, NULL);\r
 \r
        tl_x = 25;\r
-       text_out16(tl_x, (y=110), "USB joys detected:");\r
+       text_out16(tl_x, (y=130), "USB joys detected:");\r
        if (num_of_joys > 0) {\r
                for (i = 0; i < num_of_joys; i++) {\r
                        strncpy(joyname, joy_name(joys[i]), 33); joyname[33] = 0;\r
@@ -852,23 +864,27 @@ me_bind_action emuctrl_actions[] =
 \r
 static void kc_sel_loop(void)\r
 {\r
-       int menu_sel = 3, menu_sel_max = 3;\r
+       int menu_sel = 5, menu_sel_max = 5;\r
        unsigned long inp = 0;\r
-       int is_6button = PicoOpt & POPT_6BTN_PAD;\r
+       menu_id selected_id;\r
 \r
        while (1)\r
        {\r
                draw_kc_sel(menu_sel);\r
-               inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X);\r
+               inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_RIGHT|GP2X_LEFT|GP2X_B|GP2X_X);\r
+               selected_id = me_index2id(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, menu_sel);\r
+               if (inp & (GP2X_LEFT|GP2X_RIGHT)) // multi choise\r
+                       me_process(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, selected_id, (inp&GP2X_RIGHT) ? 1 : 0);\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) {\r
-                       switch (menu_sel) {\r
-                               case 0: key_config_loop(me_ctrl_actions, is_6button ? 12 : 8, 0); return;\r
-                               case 1: key_config_loop(me_ctrl_actions, is_6button ? 12 : 8, 1); return;\r
-                               case 2: key_config_loop(emuctrl_actions,\r
-                                               sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]) - 1, -1); return;\r
-                               case 3: if (!rom_loaded) emu_WriteConfig(0); return;\r
+                       int is_6button = PicoOpt & POPT_6BTN_PAD;\r
+                       switch (selected_id) {\r
+                               case MA_CTRL_PLAYER1: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 0); return;\r
+                               case MA_CTRL_PLAYER2: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 1); return;\r
+                               case MA_CTRL_EMU:     key_config_loop(emuctrl_actions,\r
+                                                       sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]) - 1, -1); return;\r
+                               case MA_CTRL_DONE:    if (!rom_loaded) emu_WriteConfig(0); return;\r
                                default: return;\r
                        }\r
                }\r
@@ -1126,7 +1142,6 @@ menu_entry opt_entries[] =
        { "Enable sound",              MB_ONOFF, MA_OPT_ENABLE_SOUND,  &currentConfig.EmuOpt,  0x004, 0, 0, 1, 1 },\r
        { NULL,                        MB_NONE,  MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },\r
        { "Use ARM940 core for sound", MB_ONOFF, MA_OPT_ARM940_SOUND,  &PicoOpt, 0x200, 0, 0, 1, 1 },\r
-       { "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &PicoOpt, 0x020, 0, 0, 1, 1 },\r
        { NULL,                        MB_NONE,  MA_OPT_REGION,        NULL, 0, 0, 0, 1, 1 },\r
        { "Use SRAM/BRAM savestates",  MB_ONOFF, MA_OPT_SRAM_STATES,   &currentConfig.EmuOpt,  0x001, 0, 0, 1, 1 },\r
        { NULL,                        MB_NONE,  MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1, 1 },\r
index 076e6d8..d9dd3d3 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.50a"\r
+#define VERSION "1.51"\r
 \r
index e099d58..d6bc20c 100644 (file)
--- a/psp/emu.c
+++ b/psp/emu.c
@@ -151,6 +151,7 @@ void emu_prepareDefaultConfig(void)
        defaultConfig.scale = 1.20;    // fullscreen
        defaultConfig.hscale40 = 1.25;
        defaultConfig.hscale32 = 1.56;
+       defaultConfig.turbo_rate = 15;
 }
 
 void emu_setDefaultConfig(void)
@@ -862,8 +863,11 @@ static void updateKeys(void)
                }
        }
 
-       PicoPad[0] = (unsigned short) allActions[0];
-       PicoPad[1] = (unsigned short) allActions[1];
+       PicoPad[0] = allActions[0] & 0xfff;
+       PicoPad[1] = allActions[1] & 0xfff;
+
+       if (allActions[0] & 0x7000) emu_DoTurbo(&PicoPad[0], allActions[0]);
+       if (allActions[1] & 0x7000) emu_DoTurbo(&PicoPad[1], allActions[1]);
 
        events = (allActions[0] | allActions[1]) >> 16;
 
index 86b1022..20c3460 100644 (file)
@@ -672,14 +672,14 @@ static int count_bound_keys(int action, int pl_idx)
 
 static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_idx, int sel)
 {
-       int x, y, tl_y = 16+40, i;
+       int x, y, tl_y = 16+20, i;
 
        menu_draw_begin();
        if (player_idx >= 0) {
-               text_out16(80+80, 16+20, "Player %i controls", player_idx + 1);
+               text_out16(80+80, 16, "Player %i controls", player_idx + 1);
                x = 80+80;
        } else {
-               text_out16(80+80, 16+20, "Emulator controls");
+               text_out16(80+80, 16, "Emulator controls");
                x = 80+40;
        }
 
@@ -692,14 +692,14 @@ static void draw_key_config(const me_bind_action *opts, int opt_cnt, int player_
        text_out16(x, y, "Done");
 
        if (sel < opt_cnt) {
-               text_out16(80+30, 220, "Press a button to bind/unbind");
-               text_out16(80+30, 230, "Use SELECT to clear");
-               text_out16(80+30, 240, "To bind UP/DOWN, hold SELECT");
-               text_out16(80+30, 250, "Select \"Done\" to exit");
+               text_out16(80+30, 225, "Press a button to bind/unbind");
+               text_out16(80+30, 235, "Use SELECT to clear");
+               text_out16(80+30, 245, "To bind UP/DOWN, hold SELECT");
+               text_out16(80+30, 255, "Select \"Done\" to exit");
        } else {
-               text_out16(80+30, 230, "Use Options -> Save cfg");
-               text_out16(80+30, 240, "to save controls");
-               text_out16(80+30, 250, "Press X or O to exit");
+               text_out16(80+30, 235, "Use Options -> Save cfg");
+               text_out16(80+30, 245, "to save controls");
+               text_out16(80+30, 255, "Press X or O to exit");
        }
        menu_draw_end();
 }
@@ -741,6 +741,19 @@ static void key_config_loop(const me_bind_action *opts, int opt_cnt, int player_
        }
 }
 
+menu_entry ctrlopt_entries[] =
+{
+       { "Player 1",                  MB_NONE,  MA_CTRL_PLAYER1,       NULL, 0, 0, 0, 1, 0 },
+       { "Player 2",                  MB_NONE,  MA_CTRL_PLAYER2,       NULL, 0, 0, 0, 1, 0 },
+       { "Emulator controls",         MB_NONE,  MA_CTRL_EMU,           NULL, 0, 0, 0, 1, 0 },
+       { "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &PicoOpt, 0x020, 0, 0, 1, 1 },
+       { "Turbo rate",                MB_RANGE, MA_CTRL_TURBO_RATE,   &currentConfig.turbo_rate, 0, 1, 30, 1, 1 },
+       { "Done",                      MB_NONE,  MA_CTRL_DONE,          NULL, 0, 0, 0, 1, 0 },
+};
+
+#define CTRLOPT_ENTRY_COUNT (sizeof(ctrlopt_entries) / sizeof(ctrlopt_entries[0]))
+const int ctrlopt_entry_count = CTRLOPT_ENTRY_COUNT;
+
 static void draw_kc_sel(int menu_sel)
 {
        int tl_x = 80+25+40, tl_y = 16+60, y;
@@ -749,10 +762,7 @@ static void draw_kc_sel(int menu_sel)
        menu_draw_begin();
        menu_draw_selection(tl_x - 16, tl_y + menu_sel*10, 138);
 
-       text_out16(tl_x, y,       "Player 1");
-       text_out16(tl_x, (y+=10), "Player 2");
-       text_out16(tl_x, (y+=10), "Emulator controls");
-       text_out16(tl_x, (y+=10), "Done");
+       me_draw(ctrlopt_entries, ctrlopt_entry_count, tl_x, tl_y, NULL, NULL);
 
        menu_draw_end();
 }
@@ -779,21 +789,25 @@ static void kc_sel_loop(void)
 {
        int menu_sel = 3, menu_sel_max = 3;
        unsigned long inp = 0;
-       int is_6button = PicoOpt & POPT_6BTN_PAD;
+       menu_id selected_id;
 
        while (1)
        {
                draw_kc_sel(menu_sel);
-               inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_X|BTN_CIRCLE, 0);
+               inp = wait_for_input(BTN_UP|BTN_DOWN|BTN_LEFT|BTN_RIGHT|BTN_X|BTN_CIRCLE, 0);
+               selected_id = me_index2id(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, menu_sel);
+               if (inp & (BTN_LEFT|BTN_RIGHT)) // multi choise
+                       me_process(ctrlopt_entries, CTRLOPT_ENTRY_COUNT, selected_id, (inp&BTN_RIGHT) ? 1 : 0);
                if (inp & BTN_UP  ) { menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max; }
                if (inp & BTN_DOWN) { menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0; }
                if (inp & BTN_CIRCLE) {
-                       switch (menu_sel) {
-                               case 0: key_config_loop(me_ctrl_actions, is_6button ? 12 : 8, 0); return;
-                               case 1: key_config_loop(me_ctrl_actions, is_6button ? 12 : 8, 1); return;
-                               case 2: key_config_loop(emuctrl_actions,
-                                               sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]) - 1, -1); return;
-                               case 3: if (!rom_loaded) emu_WriteConfig(0); return;
+                       int is_6button = PicoOpt & POPT_6BTN_PAD;
+                       switch (selected_id) {
+                               case MA_CTRL_PLAYER1: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 0); return;
+                               case MA_CTRL_PLAYER2: key_config_loop(me_ctrl_actions, is_6button ? 15 : 11, 1); return;
+                               case MA_CTRL_EMU:     key_config_loop(emuctrl_actions,
+                                                       sizeof(emuctrl_actions)/sizeof(emuctrl_actions[0]) - 1, -1); return;
+                               case MA_CTRL_DONE:    if (!rom_loaded) emu_WriteConfig(0); return;
                                default: return;
                        }
                }
@@ -1205,12 +1219,11 @@ static void amenu_loop_options(void)
 menu_entry opt_entries[] =
 {
        { NULL,                        MB_NONE,  MA_OPT_RENDERER,      NULL, 0, 0, 0, 1, 1 },
-       { "Accurate sprites",          MB_ONOFF, MA_OPT_ACC_SPRITES,   &PicoOpt, 0x0080, 0, 0, 0, 1 },
+       { "Accurate sprites",          MB_ONOFF, MA_OPT_ACC_SPRITES,   &PicoOpt, 0x080, 0, 0, 0, 1 },
        { "Show FPS",                  MB_ONOFF, MA_OPT_SHOW_FPS,      &currentConfig.EmuOpt,  0x0002,  0,  0, 1, 1 },
        { NULL,                        MB_RANGE, MA_OPT_FRAMESKIP,     &currentConfig.Frameskip,    0, -1, 16, 1, 1 },
        { "Enable sound",              MB_ONOFF, MA_OPT_ENABLE_SOUND,  &currentConfig.EmuOpt,  0x0004,  0,  0, 1, 1 },
        { NULL,                        MB_NONE,  MA_OPT_SOUND_QUALITY, NULL, 0, 0, 0, 1, 1 },
-       { "6 button pad",              MB_ONOFF, MA_OPT_6BUTTON_PAD,   &PicoOpt, 0x0020, 0, 0, 1, 1 },
        { NULL,                        MB_NONE,  MA_OPT_REGION,        NULL, 0, 0, 0, 1, 1 },
        { "Use SRAM/BRAM savestates",  MB_ONOFF, MA_OPT_SRAM_STATES,   &currentConfig.EmuOpt,  0x0001, 0, 0, 1, 1 },
        { NULL,                        MB_NONE,  MA_OPT_CONFIRM_STATES,NULL, 0, 0, 0, 1, 1 },
index 076e6d8..d9dd3d3 100644 (file)
@@ -1,2 +1,2 @@
-#define VERSION "1.50a"\r
+#define VERSION "1.51"\r
 \r