From f37b3bee42130d11d0c6a9efff9b6d6f04dcd03e Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Sat, 2 May 2009 15:00:13 +0000 Subject: [PATCH] + added controller settings menu (preliminar, code is a little bit ugly) --- source/gen_input.c | 115 ++- source/gen_input.h | 1 - source/gx/config.c | 7 +- source/gx/config.h | 4 +- source/gx/gui/filesel.c | 2 +- source/gx/gui/menu.c | 1100 ++++++++++++++-------- source/gx/gui/menu.h | 52 +- source/gx/gx_input.c | 36 +- source/gx/gx_input.h | 1 + source/gx/gx_video.c | 11 +- source/gx/images/Button_icon_sm.png | Bin 6704 -> 4985 bytes source/gx/images/Button_icon_sm_over.png | Bin 6376 -> 4914 bytes source/gx/images/Frame_s3.png | Bin 4996 -> 4447 bytes source/gx/images/generic_point.png | Bin 2200 -> 2049 bytes source/loadrom.c | 8 - 15 files changed, 874 insertions(+), 463 deletions(-) diff --git a/source/gen_input.c b/source/gen_input.c index 2ee542d..cc9a980 100644 --- a/source/gen_input.c +++ b/source/gen_input.c @@ -603,7 +603,7 @@ void teamplayer_2_write (uint32 data) uint32 jcart_read(uint32 address) { - return (gamepad_read(5) | ((gamepad_read(6)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */ + return (gamepad_read(2) | ((gamepad_read(3)&0x3f) << 8)); /* fixes Micro Machines 2 (is it correct ?) */ } void jcart_write(uint32 address, uint32 data) @@ -630,67 +630,90 @@ void input_reset () input.pad[i] = 0; } - for (i=0; i<2; i++) + switch (input.system[0]) { - switch (input.system[i]) - { - case SYSTEM_GAMEPAD: + case SYSTEM_GAMEPAD: + if (input.max == MAX_INPUTS) return; + input.dev[0] = config.input[input.max].padtype; + input.max ++; + gamepad_reset(0); + break; + + case SYSTEM_MOUSE: + if (input.max == MAX_INPUTS) return; + input.dev[0] = DEVICE_MOUSE; + input.max ++; + mouse_reset(); + break; + + case SYSTEM_WAYPLAY: + for (j=0; j< 4; j++) + { if (input.max == MAX_INPUTS) return; - input.dev[i*4] = input.padtype[input.max]; + input.dev[j] = config.input[input.max].padtype; input.max ++; - gamepad_reset(i*4); - break; + gamepad_reset(j); + } + break; - case SYSTEM_MOUSE: + case SYSTEM_TEAMPLAYER: + for (j=0; j<4; j++) + { if (input.max == MAX_INPUTS) return; - input.dev[i*4] = DEVICE_MOUSE; + input.dev[j] = config.input[input.max].padtype; input.max ++; - mouse_reset(); - break; + } + teamplayer_reset(i); + break; + } - case SYSTEM_WAYPLAY: - for (j=i*4; j< i*4+4; j++) - { - if (input.max == MAX_INPUTS) return; - input.dev[j] = input.padtype[input.max]; - input.max ++; - gamepad_reset(j); - } - break; + switch (input.system[1]) + { + case SYSTEM_GAMEPAD: + if (input.max == MAX_INPUTS) return; + input.dev[4] = config.input[input.max].padtype; + input.max ++; + gamepad_reset(4); + break; - case SYSTEM_TEAMPLAYER: - for (j=i*4; j< i*4+4; j++) - { - if (input.max == MAX_INPUTS) return; - input.dev[j] = input.padtype[input.max]; - input.max ++; - } - teamplayer_reset(i); - break; + case SYSTEM_MOUSE: + if (input.max == MAX_INPUTS) return; + input.dev[4] = DEVICE_MOUSE; + input.max ++; + mouse_reset(); + break; - case SYSTEM_MENACER: + case SYSTEM_MENACER: + if (input.max == MAX_INPUTS) return; + input.dev[4] = DEVICE_LIGHTGUN; + lightgun_reset(0); + break; + + case SYSTEM_JUSTIFIER: + for (j=4; j<6; j++) + { if (input.max == MAX_INPUTS) return; - input.dev[i*4] = DEVICE_LIGHTGUN; - lightgun_reset(0); - break; + input.dev[j] = DEVICE_LIGHTGUN; + lightgun_reset(j - 4); + input.max ++; + } - case SYSTEM_JUSTIFIER: - for (j=i*4; j< i*4+2; j++) - { - if (input.max == MAX_INPUTS) return; - input.dev[j] = DEVICE_LIGHTGUN; - lightgun_reset(j - i*4); - input.max ++; - } - break; - } + case SYSTEM_TEAMPLAYER: + for (j=4; j<8; j++) + { + if (input.max == MAX_INPUTS) return; + input.dev[j] = config.input[input.max].padtype; + input.max ++; + } + teamplayer_reset(i); + break; } /* J-CART: add two gamepad inputs */ if (j_cart) { - input.dev[5] = input.padtype[2]; - input.dev[6] = input.padtype[3]; + input.dev[5] = config.input[2].padtype; + input.dev[6] = config.input[3].padtype; gamepad_reset(5); gamepad_reset(6); } diff --git a/source/gen_input.h b/source/gen_input.h index 47786dc..08a531c 100644 --- a/source/gen_input.h +++ b/source/gen_input.h @@ -62,7 +62,6 @@ typedef struct { uint8 dev[MAX_DEVICES]; /* Can be any of the DEVICE_* values */ uint32 pad[MAX_DEVICES]; /* Can be any of the INPUT_* bitmasks */ - uint8 padtype[MAX_DEVICES]; /* 3BUTTONS or 6BUTTONS gamepad */ uint8 system[2]; /* Can be any of the SYSTEM_* bitmasks */ uint8 max; /* maximum number of connected devices */ uint8 current; /* current PAD number (4WAYPLAY) */ diff --git a/source/gx/config.c b/source/gx/config.c index db78ca8..7b25237 100644 --- a/source/gx/config.c +++ b/source/gx/config.c @@ -90,7 +90,8 @@ void config_default(void) /* controllers options */ gx_input_SetDefault(); - config.gun_cursor = 1; + config.gun_cursor[0] = 1; + config.gun_cursor[1] = 1; config.invert_mouse = 0; /* menu options */ @@ -106,5 +107,9 @@ void config_default(void) /* restore saved configuration */ config_load(); + + input.system[0] = SYSTEM_GAMEPAD; + input.system[1] = SYSTEM_GAMEPAD; + io_reset(); } diff --git a/source/gx/config.h b/source/gx/config.h index 3ab5fdd..830c23a 100644 --- a/source/gx/config.h +++ b/source/gx/config.h @@ -49,11 +49,11 @@ typedef struct uint8 render; uint8 ntsc; uint8 bilinear; - uint8 gun_cursor; + uint8 gun_cursor[2]; uint8 invert_mouse; uint16 pad_keymap[4][MAX_KEYS]; uint32 wpad_keymap[4*3][MAX_KEYS]; - t_input_config input[MAX_DEVICES]; + t_input_config input[MAX_INPUTS]; int8 bg_color; float bgm_volume; float sfx_volume; diff --git a/source/gx/gui/filesel.c b/source/gx/gui/filesel.c index 1a3b4f7..86ecd9a 100644 --- a/source/gx/gui/filesel.c +++ b/source/gx/gui/filesel.c @@ -312,7 +312,7 @@ int FileSelector(unsigned char *buffer) /* draw wiimote pointer */ WPAD_Orientation(0,&orient); gxResetAngle(orient.roll); - gxDrawTexture(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,255); + gxDrawTexture(w_pointer, x, y, w_pointer->width, w_pointer->height,255); gxResetAngle(0.0); /* find selected item */ diff --git a/source/gx/gui/menu.c b/source/gx/gui/menu.c index 1fc9b58..08e636e 100644 --- a/source/gx/gui/menu.c +++ b/source/gx/gui/menu.c @@ -1,7 +1,7 @@ /**************************************************************************** * menu.c * - * Genesis Plus GX menu + * Genesis Plus GX menus * * code by Eke-Eke (march 2009) * @@ -88,6 +88,24 @@ static butn_data button_icon_data = {Button_icon_png,Button_icon_over_png} }; +static butn_data button_icon_sm_data = +{ + {NULL,NULL}, + {Button_icon_sm_png,Button_icon_sm_over_png} +}; + +static butn_data button_player_data = +{ + {NULL,NULL}, + {Ctrl_player_png,Ctrl_player_over_png} +}; + +static butn_data button_player_none_data = +{ + {NULL,NULL}, + {Ctrl_player_none_png,NULL} +}; + /*****************************************************************************/ /* Generic GUI items */ /*****************************************************************************/ @@ -130,6 +148,17 @@ static gui_image bg_misc[5] = {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255,{0,0},{0,0}} }; +static gui_image bg_ctrls[7] = +{ + {NULL,Bg_main_png,IMAGE_VISIBLE,356,144,348,288,255,{0,0},{0,0}}, + {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255,{0,0},{0,0}}, + {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255,{0,0},{0,0}}, + {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255,{0,0},{0,0}}, + {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255,{0,0},{0,0}}, + {NULL,Frame_s4_png,IMAGE_VISIBLE,38,72,316,168,128,{0,0},{0,0}}, + {NULL,Frame_s4_png,IMAGE_VISIBLE,38,242,308,168,128,{0,0},{0,0}}, +}; + static gui_image bg_list[6] = { {NULL,Bg_main_png,IMAGE_VISIBLE,356,144,348,288,255,{0,0},{0,0}}, @@ -144,7 +173,6 @@ static gui_image bg_list[6] = /* Menu Items description */ /*****************************************************************************/ -/* Main menu */ static gui_item items_main[9] = { {NULL,Main_quit_png ,"","",128, 84,52,80}, @@ -162,6 +190,20 @@ static gui_item items_main[9] = {NULL,Main_showinfo_png,"","",546,372,84,32} }; +static gui_item items_ctrls[10] = +{ + {NULL,NULL,"","" , 0, 0, 0, 0}, + {NULL,NULL,"","" , 0, 0, 0, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0}, + {NULL,NULL,"","Configure Player settings" ,304, 0, 24, 0} +}; + #ifdef HW_RVL static gui_item items_load[4] = { @@ -191,43 +233,43 @@ static gui_item items_options[5] = /* Audio options menu */ static gui_item items_audio[5] = { - {NULL,NULL,"PSG Volume: 2.50", "Adjust PSG output level", 0,0,0,0}, - {NULL,NULL,"FM Volume: 1.00", "Adjust FM output level", 0,0,0,0}, - {NULL,NULL,"Volume Boost: 1x", "Adjust general output level", 0,0,0,0}, - {NULL,NULL,"LowPass Filter: OFF","Enable/disable sound filtering", 0,0,0,0}, - {NULL,NULL,"HQ YM2612: LINEAR", "Enable/disable FM chip interpolation",0,0,0,0} + {NULL,NULL,"PSG Volume: 2.50", "Adjust PSG output level", 52,132,276,48}, + {NULL,NULL,"FM Volume: 1.00", "Adjust FM output level", 52,132,276,48}, + {NULL,NULL,"Volume Boost: 1x", "Adjust general output level", 52,132,276,48}, + {NULL,NULL,"LowPass Filter: OFF","Enable/disable sound filtering", 52,132,276,48}, + {NULL,NULL,"HQ YM2612: LINEAR", "Enable/disable FM chip interpolation",52,132,276,48} }; /* System options menu */ static gui_item items_system[4] = { - {NULL,NULL,"Console Region: AUTO","Select system region", 0,0,0,0}, - {NULL,NULL,"System Lockups: OFF", "Enable/disable original system lock-ups",0,0,0,0}, - {NULL,NULL,"System BIOS: OFF", "Enable/disable TMSS BIOS support", 0,0,0,0}, - {NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 0,0,0,0} + {NULL,NULL,"Console Region: AUTO","Select system region", 52,132,276,48}, + {NULL,NULL,"System Lockups: OFF", "Enable/disable original system lock-ups",52,132,276,48}, + {NULL,NULL,"System BIOS: OFF", "Enable/disable TMSS BIOS support", 52,132,276,48}, + {NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 52,132,276,48} }; /* Video options menu */ static gui_item items_video[8] = { - {NULL,NULL,"Aspect: STRETCHED", "Select display aspect ratio", 0,0,0,0}, - {NULL,NULL,"Display: PROGRESSIVE", "Select video mode type", 0,0,0,0}, - {NULL,NULL,"TV mode: 50/60Hz", "Select video refresh rate", 0,0,0,0}, - {NULL,NULL,"Bilinear Filter: OFF", "Enable/disable hardware filtering", 0,0,0,0}, - {NULL,NULL,"NTSC Filter: COMPOSITE","Enable/disable NTSC software filtering", 0,0,0,0}, - {NULL,NULL,"Borders: OFF", "Enable/disable original overscan emulation",0,0,0,0}, - {NULL,NULL,"DISPLAY POSITION", "Adjust display position", 0,0,0,0}, - {NULL,NULL,"DISPLAY SIZE", "Adjust display size", 0,0,0,0} + {NULL,NULL,"Aspect: STRETCHED", "Select display aspect ratio", 52,132,276,48}, + {NULL,NULL,"Display: PROGRESSIVE", "Select video mode type", 52,132,276,48}, + {NULL,NULL,"TV mode: 50/60Hz", "Select video refresh rate", 52,132,276,48}, + {NULL,NULL,"Bilinear Filter: OFF", "Enable/disable hardware filtering", 52,132,276,48}, + {NULL,NULL,"NTSC Filter: COMPOSITE","Enable/disable NTSC software filtering", 52,132,276,48}, + {NULL,NULL,"Borders: OFF", "Enable/disable original overscan emulation",52,132,276,48}, + {NULL,NULL,"DISPLAY POSITION", "Adjust display position", 52,132,276,48}, + {NULL,NULL,"DISPLAY SIZE", "Adjust display size", 52,132,276,48} }; /* Preferences menu */ static gui_item items_prefs[5] = { - {NULL,NULL,"Auto SRAM: OFF", "Enable/disable automatic SRAM", 0,0,0,0}, - {NULL,NULL,"Auto STATE: OFF", "Enable/disable automatic Savestate", 0,0,0,0}, - {NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 0,0,0,0}, - {NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 0,0,0,0}, - {NULL,NULL,"BG Color: DEFAULT", "Change background color", 0,0,0,0} + {NULL,NULL,"Auto SRAM: OFF", "Enable/disable automatic SRAM", 52,132,276,48}, + {NULL,NULL,"Auto STATE: OFF", "Enable/disable automatic Savestate", 52,132,276,48}, + {NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 52,132,276,48}, + {NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 52,132,276,48}, + {NULL,NULL,"BG Color: DEFAULT", "Change background color", 52,132,276,48} }; /*****************************************************************************/ @@ -235,59 +277,73 @@ static gui_item items_prefs[5] = /*****************************************************************************/ /* Generic Buttons for list menu */ -static gui_butn arrow_up = {&arrow_up_data,BUTTON_OVER_SFX,{0,0},14,76,360,32}; -static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,{0,0},14,368,360,32}; +static gui_butn arrow_up = {&arrow_up_data,BUTTON_OVER_SFX,{0,0,0,0},14,76,360,32}; +static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,{0,0,0,0},14,368,360,32}; /* Generic list menu */ static gui_butn buttons_list[4] = { - {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,{1,1},52,132,276,48}, - {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,{1,1},52,188,276,48}, - {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,{1,1},52,244,276,48}, - {&button_text_data,BUTTON_VISIBLE|BUTTON_OVER_SFX,{1,1},52,300,276,48} + {&button_text_data,BUTTON_VISIBLE|BUTTON_SHIFT|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},52,132,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_SHIFT|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},52,188,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_SHIFT|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},52,244,276,48}, + {&button_text_data,BUTTON_VISIBLE|BUTTON_SHIFT|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},52,300,276,48} }; /* Main menu */ static gui_butn buttons_main[9] = { - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3}, 80, 50,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3},246, 50,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3},412, 50,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,3}, 80,194,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX ,{3,3},246,194,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,2},412,194,148,132}, - {NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX ,{3,0}, 0,360, 88, 48}, - {NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,1},542,330, 88, 38}, - {NULL ,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0},542,370, 88, 48} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80, 50,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246, 50,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},412, 50,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,3,1,1}, 80,194,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{3,3,1,1},246,194,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,2,1,1},412,194,148,132}, + {NULL , BUTTON_OVER_SFX ,{3,0,1,1}, 0,360, 88, 48}, + {NULL , BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,1,1,1},542,330, 88, 38}, + {NULL , BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,1,0},542,370, 88, 48} }; +/* Controllers Menu */ +static gui_butn buttons_ctrls[10] = +{ + {&button_icon_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{0,1,0,2}, 60, 88,148,132}, + {&button_icon_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{1,0,0,5}, 60,258,148,132}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,1,2,0},250, 79, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,3,0},250,117, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,4,0},250,155, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,5,0},250,193, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,5,0},250,249, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,6,0},250,287, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,7,0},250,325, 84, 32}, + {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,8,0},250,363, 84, 32} +}; /* Load Game menu */ #ifdef HW_RVL static gui_butn buttons_load[4] = { - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2},246,102,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0}, 80,248,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0},246,248,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0},412,248,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,0,1},246,102,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,1,1}, 80,248,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,1,1},246,248,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,0},412,248,148,132} }; #else static gui_butn buttons_load[3] = { - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0}, 80,180,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0},246,180,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0},412,180,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,0,1}, 80,180,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,1},246,180,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,0},412,180,148,132} }; #endif /* Options menu */ static gui_butn buttons_options[5] = { - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3}, 80,120,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3},246,120,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2},412,120,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0},162,264,148,132}, - {&button_icon_data,BUTTON_VISIBLE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0},330,264,148,132} + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,1,1},412,120,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,1},162,264,148,132}, + {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,1,0},330,264,148,132} }; /*****************************************************************************/ @@ -308,6 +364,20 @@ static gui_menu menu_main = FALSE }; +/* Main menu */ +static gui_menu menu_ctrls = +{ + "Controller Settings", + 0,0, + 10,10,7, + items_ctrls, + buttons_ctrls, + bg_ctrls, + {NULL,NULL}, + {NULL,NULL}, + FALSE +}; + /* Load Game menu */ static gui_menu menu_load = { @@ -405,13 +475,21 @@ void GUI_InitMenu(gui_menu *menu) int i; gui_item *item; gui_butn *button; - gui_image *image; + gui_image *image,*previous = NULL; /* background elements */ for (i=0; imax_images; i++) { image = &menu->bg_images[i]; - image->texture = gxTextureOpenPNG(image->data,0); + if (previous && (previous->data == image->data)) + { + image->texture = previous->texture; + } + else + { + image->texture = gxTextureOpenPNG(image->data,0); + } + previous = image; } for (i=0; i<2; i++) @@ -553,7 +631,7 @@ void GUI_DrawMenu(gui_menu *menu) { if (button->data) gxDrawTexture(button->data->texture[1],button->x-4,button->y-4,button->w+8,button->h+8,255); if (item->data) gxDrawTexture(item->texture, item->x-4,item->y-4,item->w+8,item->h+8,255); - else FONT_writeCenter(item->text,18,button->x,button->x+button->w,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY); + else FONT_writeCenter(item->text,18,item->x,item->x+item->w,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY); /* update help comment */ if (menu->helpers[1]) strcpy(menu->helpers[1]->comment,item->comment); @@ -562,7 +640,7 @@ void GUI_DrawMenu(gui_menu *menu) { if (button->data) gxDrawTexture(button->data->texture[0],button->x,button->y,button->w, button->h,255); if (item->data) gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); - else FONT_writeCenter(item->text,16,button->x,button->x+button->w,button->y+(button->h - 16)/2+16,(GXColor)DARK_GREY); + else FONT_writeCenter(item->text,16,item->x,item->x+item->w,button->y+(button->h - 16)/2+16,(GXColor)DARK_GREY); } } } @@ -807,8 +885,10 @@ int GUI_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items) /* set initial vertical offset */ int yoffset = ywindow + window->height; + /* reset help comment */ + if (parent->helpers[1]) strcpy(parent->helpers[1]->comment,""); + /* slide in */ - parent->selected = -1; while (yoffset > 0) { /* draw parent menu */ @@ -883,7 +963,7 @@ int GUI_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items) /* draw wiimote pointer */ WPAD_Orientation(0,&orient); gxResetAngle(orient.roll); - gxDrawTexture(w_pointer,x-w_pointer->width/2,y-w_pointer->height/2,w_pointer->width,w_pointer->height,255); + gxDrawTexture(w_pointer,x,y,w_pointer->width,w_pointer->height,255); gxResetAngle(0.0); /* check for valid buttons */ @@ -897,6 +977,11 @@ int GUI_WindowPrompt(gui_menu *parent, char *title, char *items[], u8 nb_items) } } } + else + { + /* reinitialize selection */ + if (selected == -1) selected = 0; + } #endif /* update screen */ @@ -1008,7 +1093,7 @@ int GUI_RunMenu(gui_menu *menu) /* draw wiimote pointer */ WPAD_Orientation(0,&orient); gxResetAngle(orient.roll); - gxDrawTexture(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,255); + gxDrawTexture(w_pointer,x,y,w_pointer->width,w_pointer->height,255); gxResetAngle(0.0); /* check for valid buttons */ @@ -1016,7 +1101,7 @@ int GUI_RunMenu(gui_menu *menu) for (i=0; ibuttons[i]; - if ((button->state & BUTTON_VISIBLE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + if ((button->state & BUTTON_ACTIVE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) { selected = i; break; @@ -1054,12 +1139,34 @@ int GUI_RunMenu(gui_menu *menu) if (selected < max_buttons) { + button = &menu->buttons[selected]; if (p & PAD_BUTTON_UP) { - button = &menu->buttons[selected]; - if (button->shift[0]) + selected -= button->shift[0]; + if (selected < 0) { - selected -= button->shift[0]; + selected = 0; + if (menu->offset) menu->offset --; + } + } + else if (p & PAD_BUTTON_DOWN) + { + selected += button->shift[1]; + if (selected >= max_buttons) + { + selected = max_buttons - 1; + if ((menu->offset + selected < (max_items - 1))) menu->offset ++; + } + } + else if (p & PAD_BUTTON_LEFT) + { + if (button->state & BUTTON_SHIFT) + { + quit = -1; + } + else + { + selected -= button->shift[2]; if (selected < 0) { selected = 0; @@ -1067,12 +1174,15 @@ int GUI_RunMenu(gui_menu *menu) } } } - else if (p & PAD_BUTTON_DOWN) + else if (p & PAD_BUTTON_RIGHT) { - button = &menu->buttons[selected]; - if (button->shift[1]) + if (button->state & BUTTON_SHIFT) { - selected += button->shift[1]; + quit = 1; + } + else + { + selected += button->shift[3]; if (selected >= max_buttons) { selected = max_buttons - 1; @@ -1080,54 +1190,6 @@ int GUI_RunMenu(gui_menu *menu) } } } - else if (p & PAD_BUTTON_LEFT) - { - if (max_buttons == max_items) - { - selected --; - if (selected < 0) selected = 0; - } - else - { - quit = -1; - } - } - else if (p & PAD_BUTTON_RIGHT) - { - if (max_buttons == max_items) - { - selected ++; - if (selected >= max_buttons) selected = max_buttons - 1; - } - else - { - quit = 1; - } - } - else if (p & PAD_BUTTON_LEFT) - { - if (max_buttons == max_items) - { - selected --; - if (selected < 0) selected = 0; - } - else - { - quit = -1; - } - } - else if (p & PAD_BUTTON_RIGHT) - { - if (max_buttons == max_items) - { - selected ++; - if (selected >= max_buttons) selected = max_buttons - 1; - } - else - { - quit = 1; - } - } } if (p & PAD_BUTTON_A) @@ -1233,7 +1295,7 @@ static void GUI_SlideMenuTitle(gui_menu *m, int title_offset) /* draw wiimote pointer */ WPAD_Orientation(0,&orient); gxResetAngle(orient.roll); - gxDrawTexture(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,255); + gxDrawTexture(w_pointer,x,y,w_pointer->width,w_pointer->height,255); gxResetAngle(0.0); /* check for valid buttons */ @@ -1241,7 +1303,7 @@ static void GUI_SlideMenuTitle(gui_menu *m, int title_offset) for (i=0; imax_buttons; i++) { button = &m->buttons[i]; - if ((button->state & BUTTON_VISIBLE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) + if ((button->state & BUTTON_ACTIVE)&&(x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h))) { m->selected = i; break; @@ -1792,151 +1854,199 @@ static void videomenu () * ConfigureJoypads ****************************************************************************/ extern int old_system[2]; -static void inputsmenu(void) + +static void ctrl_raz(void) { - int ret, max_players; + gui_menu *m = &menu_ctrls; + + int i,max = 0; + for (i=0; ibuttons[i+2].data = &button_player_none_data; + m->buttons[i+2].state &= ~BUTTON_ACTIVE; + strcpy(m->items[i+2].text,""); + } + else + { + m->buttons[i+2].data = &button_player_data; + m->buttons[i+2].state |= BUTTON_ACTIVE; + sprintf(m->items[i+2].text,"%d",max + 1); + max++; + } + } +} + + +static void ctrlmenu(void) +{ + int ret,xoffset,player,selected,old; int i = 0; int quit = 0; - int prevmenu = menu; - char padmenu[8][25]; + s16 p; - int player = 0; #ifdef HW_RVL u32 exp; + int x,y; + struct orient_t orient; #endif - /* gui_item items_sys[7][2] = + gui_item *item; + u8 *special; + char msg[16]; + + /* System devices */ + gui_item items_sys[2][7] = { { - {NULL,Ctrl_none ,"","Port 1 - Unconnected",110,130,48,72}, - {NULL,Ctrl_gamepad ,"","Port 1 - Gamepad" , 87,117,96,84}, - {NULL,Ctrl_mouse ,"","Port 1 - Mouse" , 97,113,64,88}, - {NULL,Ctrl_menacer ,"","Port 1 - Menacer" , 94,113,80,88}, - {NULL,Ctrl_justifier ,"","Port 1 - Justifiers" , 88,117,80,84} - {NULL,Ctrl_teamplayer,"","Port 1 - Teamplayer" , 94,109,80,92}, - {NULL,Ctrl_4wayplay ,"","Port 1 - 4 Way Play" , 98,110,72,92} + {NULL,Ctrl_none_png ,"","Select Port 1 device",110,130,48,72}, + {NULL,Ctrl_gamepad_png ,"","Select Port 1 device", 87,117,96,84}, + {NULL,Ctrl_mouse_png ,"","Select Port 1 device", 97,113,64,88}, + {NULL,Ctrl_menacer_png ,"","Select Port 1 device", 94,113,80,88}, + {NULL,Ctrl_justifiers_png ,"","Select Port 1 device", 88,117,80,84}, + {NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,109,80,92}, + {NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,110,72,92} }, { - {NULL,Ctrl_none ,"","Port 2 - Unconnected",110,130,48,72}, - {NULL,Ctrl_gamepad ,"","Port 2 - Gamepad" , 87,117,96,84}, - {NULL,Ctrl_mouse ,"","Port 2 - Mouse" , 97,113,64,88}, - {NULL,Ctrl_menacer ,"","Port 2 - Menacer" , 94,113,80,88}, - {NULL,Ctrl_justifier ,"","Port 2 - Justifiers" , 88,117,80,84} - {NULL,Ctrl_teamplayer,"","Port 2 - Teamplayer" , 94,109,80,92}, - {NULL,Ctrl_4wayplay ,"","Port 2 - 4 Way Play" , 98,110,72,92} + {NULL,Ctrl_none_png ,"","Select Port 1 device",110,300,48,72}, + {NULL,Ctrl_gamepad_png ,"","Select Port 1 device", 87,287,96,84}, + {NULL,Ctrl_mouse_png ,"","Select Port 1 device", 97,283,64,88}, + {NULL,Ctrl_menacer_png ,"","Select Port 1 device", 94,283,80,88}, + {NULL,Ctrl_justifiers_png ,"","Select Port 1 device", 88,287,80,84}, + {NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,279,80,92}, + {NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,280,72,92} } }; -*/ - strcpy (menutitle, "Press B to return"); - menu = 0; + /* Player Configuration window */ + gui_image window = + { + NULL,Frame_s3_png,IMAGE_VISIBLE,400,134,292,248,128,{0,0},{0,0} + }; + + /* Player Configuration buttons */ + gui_butn buttons_config[3] = + { + {&button_icon_sm_data,BUTTON_OVER_SFX ,{0,1,0,0},436,168,160, 52}, + {&button_icon_sm_data,BUTTON_OVER_SFX ,{1,1,0,0},436,232,160, 52}, + {&button_icon_sm_data,BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,0,0},436,296,160, 52} + }; + + /* Player Configuration special items */ + gui_item items_special[3][2] = + { + { + /* Gamepad options */ + {NULL,Ctrl_pad3b_png,"Gamepad","Type",534,180,44,28}, + {NULL,Ctrl_pad6b_png,"Gamepad","Type",534,180,44,28} + }, + { + /* Mouse options */ + {NULL,ctrl_option_off_png,"Invert","Mouse",538,180,24,24}, + {NULL,ctrl_option_on_png ,"Invert","Mouse",538,180,24,24}, + }, + { + /* Gun options */ + {NULL,ctrl_option_off_png,"Show","Cursor",538,180,24,24}, + {NULL,ctrl_option_on_png ,"Show","Cursor",538,180,24,24}, + } + }; + + /* Player Configuration device items */ +#ifdef HW_RVL + gui_item items_device[5] = + { + {NULL,ctrl_option_off_png ,"Input","Device",538,244,24,24}, + {NULL,ctrl_gamecube_png ,"Input","Device",530,246,36,24}, + {NULL,ctrl_wiimote_png ,"Input","Device",526,250,40,12}, + {NULL,ctrl_nunchuk_png ,"Input","Device",532,242,32,32}, + {NULL,ctrl_classic_png ,"Input","Device",526,242,40,32}, + }; +#else + gui_item items_device[2] = + { + {NULL,ctrl_option_off_png ,"Input","Device",538,244,24,24}, + {NULL,ctrl_gamecube_png ,"Input","Device",530,246,36,24} + }; +#endif + + gui_item items_key = + { + NULL,Ctrl_config_png ,"Configure","Keys",536,306,32,32 + }; + + + gui_item *items_config[3] = + { + 0,items_device,&items_key + }; + + + gui_menu *m = &menu_ctrls; + + /* initialize menu (generic elements) */ + m->items[0].data = NULL; + m->items[1].data = NULL; + m->buttons[2].data = NULL; + m->buttons[3].data = NULL; + m->buttons[4].data = NULL; + m->buttons[5].data = NULL; + m->buttons[6].data = NULL; + m->buttons[7].data = NULL; + m->buttons[8].data = NULL; + m->buttons[9].data = NULL; + GUI_InitMenu(m); + + /* initialize custom buttons */ + button_player_data.texture[0] = gxTextureOpenPNG(button_player_data.image[0],0); + button_player_data.texture[1] = gxTextureOpenPNG(button_player_data.image[1],0); + button_player_none_data.texture[0] = gxTextureOpenPNG(button_player_none_data.image[0],0); + button_icon_sm_data.texture[0] = gxTextureOpenPNG(button_icon_sm_data.image[0],0); + button_icon_sm_data.texture[1] = gxTextureOpenPNG(button_icon_sm_data.image[1],0); + + /* intialize custom images */ + items_sys[1][0].texture = items_sys[0][0].texture = gxTextureOpenPNG(items_sys[0][0].data,0); + items_sys[1][1].texture = items_sys[0][1].texture = gxTextureOpenPNG(items_sys[0][1].data,0); + items_sys[1][2].texture = items_sys[0][2].texture = gxTextureOpenPNG(items_sys[0][2].data,0); + items_sys[1][3].texture = items_sys[0][3].texture = gxTextureOpenPNG(items_sys[0][3].data,0); + items_sys[1][4].texture = items_sys[0][4].texture = gxTextureOpenPNG(items_sys[0][4].data,0); + items_sys[1][5].texture = items_sys[0][5].texture = gxTextureOpenPNG(items_sys[0][5].data,0); + items_sys[1][6].texture = items_sys[0][6].texture = gxTextureOpenPNG(items_sys[0][6].data,0); + items_key.texture = gxTextureOpenPNG(items_key.data,0); +#ifdef HW_RVL + items_device[0].texture = gxTextureOpenPNG(items_device[0].data,0); + items_device[1].texture = gxTextureOpenPNG(items_device[1].data,0); + items_device[2].texture = gxTextureOpenPNG(items_device[2].data,0); + items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0); + items_device[4].texture = gxTextureOpenPNG(items_device[4].data,0); +#else + items_device[0].texture = gxTextureOpenPNG(items_device[0].data,0); + items_device[1].texture = gxTextureOpenPNG(items_device[1].data,0); +#endif + items_special[0][0].texture = gxTextureOpenPNG(items_special[0][0].data,0); + items_special[0][1].texture = gxTextureOpenPNG(items_special[0][1].data,0); + items_special[2][0].texture = items_special[1][0].texture = items_device[0].texture; + items_special[2][1].texture = items_special[1][1].texture = gxTextureOpenPNG(items_special[1][1].data,0); + + /* initialize custom window */ + window.texture = gxTextureOpenPNG(window.data,0); + + /* update menu layout */ + ctrl_raz(); + memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item)); + memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item)); + + GUI_SlideMenuTitle(m,strlen("Controller ")); + while (quit == 0) { - /* update max players */ - max_players = 0; - if (input.system[0] == SYSTEM_GAMEPAD) - { - sprintf (padmenu[0], "Port 1: GAMEPAD"); - max_players ++; - } - else if (input.system[0] == SYSTEM_MOUSE) - { - sprintf (padmenu[0], "Port 1: MOUSE"); - max_players ++; - } - else if (input.system[0] == SYSTEM_WAYPLAY) - { - sprintf (padmenu[0], "Port 1: 4-WAYPLAY"); - max_players += 4; - } - else if (input.system[0] == SYSTEM_TEAMPLAYER) - { - sprintf (padmenu[0], "Port 1: TEAMPLAYER"); - max_players += 4; - } - else - sprintf (padmenu[0], "Port 1: NONE"); - - if (input.system[1] == SYSTEM_GAMEPAD) - { - sprintf (padmenu[1], "Port 2: GAMEPAD"); - max_players ++; - } - else if (input.system[1] == SYSTEM_MOUSE) - { - sprintf (padmenu[1], "Port 2: MOUSE"); - max_players ++; - } - else if (input.system[1] == SYSTEM_WAYPLAY) - { - sprintf (padmenu[1], "Port 2: 4-WAYPLAY"); - } - else if (input.system[1] == SYSTEM_TEAMPLAYER) - { - sprintf (padmenu[1], "Port 2: TEAMPLAYER"); - max_players += 4; - } - else if (input.system[1] == SYSTEM_MENACER) - { - sprintf (padmenu[1], "Port 2: MENACER"); - max_players += 1; - } - else if (input.system[1] == SYSTEM_JUSTIFIER) - { - sprintf (padmenu[1], "Port 2: JUSTIFIERS"); - max_players += 2; - } - else - sprintf (padmenu[1], "Port 2: NONE"); - - /* JCART special case */ - if (j_cart) max_players +=2; - - /* reset current player nr */ - if (player >= max_players) - { - /* remove duplicate assigned inputs */ - if ((0!=player) && (config.input[0].device == config.input[player].device) && (config.input[0].port == config.input[player].port)) - { - config.input[0].device = -1; - config.input[0].port = i%4; - } - player = 0; - } - - sprintf (padmenu[2], "Gun Cursor: %s", config.gun_cursor ? " ON":"OFF"); - sprintf (padmenu[3], "Invert Mouse: %s", config.invert_mouse ? " ON":"OFF"); - sprintf (padmenu[4], "Set Player: %d%s", player + 1, (j_cart && (player > 1)) ? "-JCART" : ""); - - if (config.input[player].device == 0) - sprintf (padmenu[5], "Device: GAMECUBE %d", config.input[player].port + 1); -#ifdef HW_RVL - else if (config.input[player].device == 1) - sprintf (padmenu[5], "Device: WIIMOTE %d", config.input[player].port + 1); - else if (config.input[player].device == 2) - sprintf (padmenu[5], "Device: NUNCHUK %d", config.input[player].port + 1); - else if (config.input[player].device == 3) - sprintf (padmenu[5], "Device: CLASSIC %d", config.input[player].port + 1); -#endif - else - sprintf (padmenu[5], "Device: NONE"); - - /* when using wiimote, force to 3Buttons pad */ - if (config.input[player].device == 1) input.padtype[player] = DEVICE_3BUTTON; - sprintf (padmenu[6], "%s", (input.padtype[player] == DEVICE_3BUTTON) ? "Type: 3BUTTONS":"Type: 6BUTTONS"); - - sprintf (padmenu[7], "Configure Input"); - - ret = domenu (&padmenu[0], 8,0); + ret = GUI_RunMenu(m); switch (ret) { case 0: - if (j_cart) - { - WaitPrompt("JCART detected !"); - break; - } + if (j_cart) break; input.system[0] ++; if (input.system[0] == SYSTEM_MENACER) input.system[0] ++; if (input.system[0] == SYSTEM_JUSTIFIER) input.system[0] ++; @@ -1950,14 +2060,15 @@ static void inputsmenu(void) io_reset(); old_system[0] = input.system[0]; old_system[1] = input.system[1]; + + /* update menu layout */ + ctrl_raz(); + memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item)); + memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item)); break; case 1: - if (j_cart) - { - WaitPrompt("JCART detected !"); - break; - } + if (j_cart) break; input.system[1] ++; if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE)) input.system[1] ++; if (input.system[1] == SYSTEM_WAYPLAY) input.system[0] = SYSTEM_WAYPLAY; @@ -1969,154 +2080,379 @@ static void inputsmenu(void) io_reset(); old_system[0] = input.system[0]; old_system[1] = input.system[1]; + + /* update menu layout */ + ctrl_raz(); + memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item)); + memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item)); break; case 2: - config.gun_cursor ^= 1; - break; - case 3: - config.invert_mouse ^= 1; - break; - case 4: - /* remove duplicate assigned inputs */ - for (i=0; i<8; i++) - { - if ((i!=player) && (config.input[i].device == config.input[player].device) && (config.input[i].port == config.input[player].port)) - { - config.input[i].device = -1; - config.input[i].port = i%4; - } - } - player = (player + 1) % max_players; - break; - case 5: -#ifdef HW_RVL - if (config.input[player].device > 0) + case 6: + case 7: + case 8: + case 9: + + /* update player index */ + player = 0; + for (i=0; i<(ret-2); i++) { - config.input[player].port ++; + if (input.dev[i] != NO_DEVICE) player ++; + } + + /* get current player configuration */ + if (input.dev[ret-2] == DEVICE_LIGHTGUN) + { + items_config[0] = items_special[2]; + special = &config.gun_cursor[player % 3]; + } + else if (input.dev[ret-2] == DEVICE_MOUSE) + { + items_config[0] = items_special[1]; + special = &config.invert_mouse; } else { - config.input[player].device ++; - if (config.input[player].device == 1) config.input[player].port = 0; + items_config[0] = items_special[0]; + special = &config.input[player].padtype; } - if (config.input[player].device == 1) + /* shift player configuration window */ + xoffset = 640 - window.x; + while (xoffset > 0) { - exp = 4; - if (config.input[player].port<4) + GUI_DrawMenu(m); + gxDrawTexture(window.texture,window.x+xoffset,window.y,window.w,window.h,window.alpha); + gxDrawTexture(buttons_config[0].data->texture[0],buttons_config[0].x+xoffset,buttons_config[0].y,buttons_config[0].w,buttons_config[0].h,255); + gxDrawTexture(buttons_config[1].data->texture[0],buttons_config[1].x+xoffset,buttons_config[1].y,buttons_config[1].w,buttons_config[1].h,255); + gxDrawTexture(buttons_config[2].data->texture[0],buttons_config[2].x+xoffset,buttons_config[2].y,buttons_config[2].w,buttons_config[2].h,255); + item = &items_config[0][*special]; + gxDrawTexture(item->texture,item->x+xoffset,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[0].y+(buttons_config[0].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[0].y+(buttons_config[0].h - 32)/2+32,(GXColor)DARK_GREY); + item = &items_config[1][config.input[player].device + 1]; + gxDrawTexture(item->texture,item->x+xoffset,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[1].y+(buttons_config[1].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[1].y+(buttons_config[1].h - 32)/2+32,(GXColor)DARK_GREY); + if (config.input[player].device >= 0) { - WPAD_Probe(config.input[player].port,&exp); - if (exp == WPAD_EXP_NUNCHUK) exp = 4; + sprintf(msg,"%d",config.input[player].port); + FONT_write(msg,14,item->x+item->w+xoffset,item->y+item->h,strlen(msg),(GXColor)DARK_GREY); + } + item = items_config[2]; + gxDrawTexture(item->texture,item->x+xoffset,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[2].y+(buttons_config[2].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[2].y+(buttons_config[2].h - 32)/2+32,(GXColor)DARK_GREY); + gxSetScreen(); + + xoffset -= 20; + } + + /* wait for user input */ + ret = 0; + selected = -1; + while (!ret) + { + GUI_DrawMenu(m); + gxDrawTexture(window.texture,window.x,window.y,window.w,window.h,window.alpha); + for (i=0; i<3; i++) + { + if (i == selected) + gxDrawTexture(buttons_config[i].data->texture[1],buttons_config[i].x-4,buttons_config[i].y-4,buttons_config[i].w+8,buttons_config[0].h+8,255); + else + gxDrawTexture(buttons_config[i].data->texture[0],buttons_config[i].x,buttons_config[i].y,buttons_config[i].w,buttons_config[0].h,255); } - while ((config.input[player].port<4) && (exp == 4)) + item = &items_config[0][*special]; + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+4,item->x,buttons_config[0].y+(buttons_config[0].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+4,item->x,buttons_config[0].y+(buttons_config[0].h - 32)/2+32,(GXColor)DARK_GREY); + item = &items_config[1][config.input[player].device + 1]; + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+4,item->x,buttons_config[1].y+(buttons_config[1].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+4,item->x,buttons_config[1].y+(buttons_config[1].h - 32)/2+32,(GXColor)DARK_GREY); + if (config.input[player].device >= 0) { - config.input[player].port ++; - if (config.input[player].port<4) + sprintf(msg,"%d",config.input[player].port); + FONT_write(msg,14,item->x+item->w,item->y+item->h,strlen(msg),(GXColor)DARK_GREY); + } + item = items_config[2]; + gxDrawTexture(item->texture,item->x,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+4,item->x,buttons_config[2].y+(buttons_config[2].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+4,item->x,buttons_config[2].y+(buttons_config[2].h - 32)/2+32,(GXColor)DARK_GREY); + + old = selected; + p = m_input.keys; + + #ifdef HW_RVL + if (m_input.ir.valid) + { + /* get cursor position */ + x = m_input.ir.x; + y = m_input.ir.y; + + /* draw wiimote pointer */ + WPAD_Orientation(0,&orient); + gxResetAngle(orient.roll); + gxDrawTexture(w_pointer,x,y,w_pointer->width,w_pointer->height,255); + gxResetAngle(0.0); + + /* check for valid buttons */ + selected = -1; + for (i=0; i<3; i++) { - exp = 4; - WPAD_Probe(config.input[player].port,&exp); - if (exp == WPAD_EXP_NUNCHUK) exp = 4; + if ((x>=buttons_config[i].x)&&(x<=(buttons_config[i].x+buttons_config[i].w))&&(y>=buttons_config[i].y)&&(y<=(buttons_config[i].y+buttons_config[i].h))) + { + selected = i; + break; + } } } - - if (config.input[player].port >= 4) + else { - config.input[player].port = 0; - config.input[player].device = 2; + /* reinitialize selection */ + if (selected == -1) selected = 0; } - } - - if (config.input[player].device == 2) - { - exp = 4; - if (config.input[player].port<4) - { - WPAD_Probe(config.input[player].port,&exp); - } - - while ((config.input[player].port<4) && (exp != WPAD_EXP_NUNCHUK)) - { - config.input[player].port ++; - if (config.input[player].port<4) - { - exp = 4; - WPAD_Probe(config.input[player].port,&exp); - } - } - - if (config.input[player].port >= 4) - { - config.input[player].port = 0; - config.input[player].device = 3; - } - } - - if (config.input[player].device == 3) - { - exp = 4; - if (config.input[player].port<4) - { - WPAD_Probe(config.input[player].port,&exp); - } - - while ((config.input[player].port<4) && (exp != WPAD_EXP_CLASSIC)) - { - config.input[player].port ++; - if (config.input[player].port<4) - { - exp = 4; - WPAD_Probe(config.input[player].port,&exp); - } - } - - if (config.input[player].port >= 4) - { - config.input[player].port = player % 4; - config.input[player].device = 0; - } - } -#else - config.input[player].device = 0; #endif - break; - - case 6: - if (config.input[player].device == 1) break; - input.padtype[player] ^= 1; - io_reset(); + + /* update screen */ + gxSetScreen (); + + /* update selection */ + if (p&PAD_BUTTON_UP) + { + if (selected > 0) selected --; + } + else if (p&PAD_BUTTON_DOWN) + { + if (selected < 2) selected ++; + } + + /* sound fx */ + if (selected != old) + { + if (selected >= 0) + { + ASND_SetVoice(ASND_GetFirstUnusedVoice(),VOICE_MONO_16BIT,22050,0,(u8 *)button_over_pcm,button_over_pcm_size, + ((int)config.sfx_volume * 255) / 100,((int)config.sfx_volume * 255) / 100,NULL); + } + } + + if (p & PAD_BUTTON_A) + { + switch (selected) + { + case 0: /* special config */ + if ((config.input[player].device == 1) && (input.dev[ret-2] <= DEVICE_6BUTTON)) break; + *special ^= 1; + io_reset(); + break; + + case 1: + #ifdef HW_RVL + if (config.input[player].device > 0) + { + config.input[player].port ++; + } + else + { + config.input[player].device ++; + if (config.input[player].device == 1) config.input[player].port = 0; + } + + if (config.input[player].device == 1) + { + exp = 4; + if (config.input[player].port<4) + { + WPAD_Probe(config.input[player].port,&exp); + if (exp == WPAD_EXP_NUNCHUK) exp = 4; + } + + while ((config.input[player].port<4) && (exp == 4)) + { + config.input[player].port ++; + if (config.input[player].port<4) + { + exp = 4; + WPAD_Probe(config.input[player].port,&exp); + if (exp == WPAD_EXP_NUNCHUK) exp = 4; + } + } + + if (config.input[player].port >= 4) + { + config.input[player].port = 0; + config.input[player].device = 2; + } + } + + if (config.input[player].device == 2) + { + exp = 4; + if (config.input[player].port<4) + { + WPAD_Probe(config.input[player].port,&exp); + } + + while ((config.input[player].port<4) && (exp != WPAD_EXP_NUNCHUK)) + { + config.input[player].port ++; + if (config.input[player].port<4) + { + exp = 4; + WPAD_Probe(config.input[player].port,&exp); + } + } + + if (config.input[player].port >= 4) + { + config.input[player].port = 0; + config.input[player].device = 3; + } + } + + if (config.input[player].device == 3) + { + exp = 4; + if (config.input[player].port<4) + { + WPAD_Probe(config.input[player].port,&exp); + } + + while ((config.input[player].port<4) && (exp != WPAD_EXP_CLASSIC)) + { + config.input[player].port ++; + if (config.input[player].port<4) + { + exp = 4; + WPAD_Probe(config.input[player].port,&exp); + } + } + + if (config.input[player].port >= 4) + { + config.input[player].port = player % 4; + config.input[player].device = 0; + } + } + #else + config.input[player].device = 0; + #endif + /* remove duplicate assigned inputs */ + for (i=0; i<8; i++) + { + if ((i!=player) && (config.input[i].device == config.input[player].device) && (config.input[i].port == config.input[player].port)) + { + config.input[i].device = -1; + config.input[i].port = i%4; + } + } + + if (config.input[player].device == 1) config.input[player].padtype = DEVICE_3BUTTON; + break; + + case 2: + if (config.input[player].device < 0) break; + if (config.input[player].padtype == DEVICE_3BUTTON) /* 3-buttons */ + gx_input_Config(config.input[player].port, config.input[player].device, 4); + else if (config.input[player].device == 0) /* 6-buttons w/o MODE */ + gx_input_Config(config.input[player].port, 0, 7); + else /* 6-buttons */ + gx_input_Config(config.input[player].port, config.input[player].device, 8); + break; + } + } + else if (p & PAD_BUTTON_B) + { + ret = 1; + } + } + + /* shift player configuration window */ + xoffset = 0; ; + while (xoffset < 640 - window.x) + { + GUI_DrawMenu(m); + gxDrawTexture(window.texture,window.x+xoffset,window.y,window.w,window.h,window.alpha); + gxDrawTexture(buttons_config[0].data->texture[0],buttons_config[0].x+xoffset,buttons_config[0].y,buttons_config[0].w,buttons_config[0].h,255); + gxDrawTexture(buttons_config[1].data->texture[0],buttons_config[1].x+xoffset,buttons_config[1].y,buttons_config[1].w,buttons_config[1].h,255); + gxDrawTexture(buttons_config[2].data->texture[0],buttons_config[2].x+xoffset,buttons_config[2].y,buttons_config[2].w,buttons_config[2].h,255); + item = &items_config[0][*special]; + gxDrawTexture(item->texture,item->x+xoffset,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[0].y+(buttons_config[0].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[0].y+(buttons_config[0].h - 32)/2+32,(GXColor)DARK_GREY); + item = &items_config[1][config.input[player].device + 1]; + gxDrawTexture(item->texture,item->x+xoffset,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[1].y+(buttons_config[1].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[1].y+(buttons_config[1].h - 32)/2+32,(GXColor)DARK_GREY); + if (config.input[player].device >= 0) + { + sprintf(msg,"%d",config.input[player].port); + FONT_write(msg,14,item->x+item->w+xoffset,item->y+item->h,strlen(msg),(GXColor)DARK_GREY); + } + item = items_config[2]; + gxDrawTexture(item->texture,item->x+xoffset,item->y,item->w,item->h,255); + FONT_writeCenter(item->text,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[2].y+(buttons_config[2].h - 32)/2+16,(GXColor)DARK_GREY); + FONT_writeCenter(item->comment,16,buttons_config[0].x+xoffset+4,item->x+xoffset,buttons_config[2].y+(buttons_config[2].h - 32)/2+32,(GXColor)DARK_GREY); + gxSetScreen(); + + xoffset += 20; + } + break; - case 7: - if (config.input[player].device < 0) break; - if (input.padtype[player] == DEVICE_3BUTTON) /* 3-buttons */ - gx_input_Config(config.input[player].port, config.input[player].device, 4); - else if (config.input[player].device == 0) /* 6-buttons w/o MODE */ - gx_input_Config(config.input[player].port, 0, 7); - else /* 6-buttons */ - gx_input_Config(config.input[player].port, config.input[player].device, 8); - break; case -1: - /* remove duplicate assigned inputs */ - for (i=0; i<8; i++) - { - if ((i!=player) && (config.input[i].device == config.input[player].device) && (config.input[i].port == config.input[player].port)) - { - config.input[i].device = -1; - config.input[i].port = i%4; - } - } quit = 1; break; } } - menu = prevmenu; + m->items[0].texture = NULL; + m->items[1].texture = NULL; + m->buttons[2].data = NULL; + m->buttons[3].data = NULL; + m->buttons[4].data = NULL; + m->buttons[5].data = NULL; + m->buttons[6].data = NULL; + m->buttons[7].data = NULL; + m->buttons[8].data = NULL; + m->buttons[9].data = NULL; + GUI_DeleteMenu(m); + + gxTextureClose(&button_player_data.texture[0]); + gxTextureClose(&button_player_data.texture[1]); + gxTextureClose(&button_player_none_data.texture[0]); + gxTextureClose(&button_icon_sm_data.texture[0]); + gxTextureClose(&button_icon_sm_data.texture[1]); + + gxTextureClose(&items_sys[0][0].texture); + gxTextureClose(&items_sys[0][1].texture); + gxTextureClose(&items_sys[0][2].texture); + gxTextureClose(&items_sys[0][3].texture); + gxTextureClose(&items_sys[0][4].texture); + gxTextureClose(&items_sys[0][5].texture); + gxTextureClose(&items_sys[0][6].texture); + gxTextureClose(&items_key.texture); +#ifdef HW_RVL + gxTextureClose(&items_device[0].texture); + gxTextureClose(&items_device[1].texture); + gxTextureClose(&items_device[2].texture); + gxTextureClose(&items_device[3].texture); + gxTextureClose(&items_device[4].texture); +#else + gxTextureClose(&items_device[0].texture); + gxTextureClose(&items_device[1].texture); +#endif + gxTextureClose(&items_special[0][0].texture); + gxTextureClose(&items_special[0][1].texture); + gxTextureClose(&items_special[1][1].texture); + + gxTextureClose(&window.texture); } /**************************************************************************** @@ -2145,7 +2481,7 @@ static void optionmenu(void) soundmenu(); break; case 3: - inputsmenu(); + ctrlmenu(); break; case 4: prefmenu(); @@ -2435,6 +2771,7 @@ static void showrominfo () * Main Menu * ****************************************************************************/ +static int rom_loaded = 0; void MainMenu (void) { int ret, quit = 0; @@ -2466,28 +2803,22 @@ void MainMenu (void) gui_menu *m = &menu_main; - /* check if a game is running */ - if (genromsize) + if (!rom_loaded) { - m->screenshot = 1; - m->max_items = 9; - m->max_buttons = 9; - m->buttons[3].state |= BUTTON_SELECT_SFX; - m->buttons[5].state |= BUTTON_SELECT_SFX; - m->buttons[3].shift[1] = 3; - m->buttons[4].shift[1] = 3; - m->buttons[5].shift[1] = 2; - } - else - { - m->screenshot = 0; - m->max_items = 6; - m->max_buttons = 6; - m->buttons[3].state &= ~BUTTON_SELECT_SFX; - m->buttons[5].state &= ~BUTTON_SELECT_SFX; - m->buttons[3].shift[1] = 0; - m->buttons[4].shift[1] = 0; - m->buttons[5].shift[1] = 0; + /* check if a game is running */ + if (genromsize) + { + m->screenshot = 1; + m->buttons[3].state |= BUTTON_SELECT_SFX; + m->buttons[5].state |= BUTTON_SELECT_SFX; + m->buttons[6].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[7].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[8].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE); + m->buttons[3].shift[1] = 3; + m->buttons[4].shift[1] = 3; + m->buttons[5].shift[1] = 2; + rom_loaded = 1; + } } GUI_DrawMenuFX(m,10,0); @@ -2516,7 +2847,8 @@ void MainMenu (void) switch (GUI_WindowPrompt(m, VERSION, items,3)) { case 1: - GUI_FadeMenu(m,1,1); + GUI_FadeMenu(m,1 + ,1); #ifdef HW_RVL gxTextureClose(&w_pointer); #endif diff --git a/source/gx/gui/menu.h b/source/gx/gui/menu.h index 6de960d..634a9e2 100644 --- a/source/gx/gui/menu.h +++ b/source/gx/gui/menu.h @@ -33,6 +33,8 @@ /* GUI Buttons state */ /*****************************************************************************/ #define BUTTON_VISIBLE 0x01 +#define BUTTON_SHIFT 0x02 +#define BUTTON_ACTIVE 0x04 #define BUTTON_OVER_SFX 0x10 #define BUTTON_SELECT_SFX 0x20 @@ -49,35 +51,34 @@ /* GUI png data */ /*****************************************************************************/ +/* Generic backgrounds */ extern const u8 Bg_intro_c1_png[]; extern const u8 Bg_intro_c2_png[]; extern const u8 Bg_intro_c3_png[]; extern const u8 Bg_intro_c4_png[]; extern const u8 Bg_main_png[]; extern const u8 Bg_overlay_png[]; - -extern const u8 Main_logo_png[]; - extern const u8 Banner_main_png[]; extern const u8 Banner_bottom_png[]; extern const u8 Banner_top_png[]; +extern const u8 Main_logo_png[]; +/* Generic frames */ extern const u8 Frame_s1_png[]; extern const u8 Frame_s2_png[]; extern const u8 Frame_s3_png[]; +extern const u8 Frame_s4_png[]; extern const u8 Frame_s1_title_png[]; -extern const u8 Frame_s3_title_png[]; +/* ROM Browser */ extern const u8 Overlay_bar_png[]; - extern const u8 Browser_dir_png[]; - extern const u8 Star_full_png[]; extern const u8 Star_empty_png[]; - extern const u8 Snap_empty_png[]; extern const u8 Snap_frame_png[]; +/* Main menu */ extern const u8 Main_load_png[]; extern const u8 Main_options_png[]; extern const u8 Main_quit_png[]; @@ -92,12 +93,14 @@ extern const u8 Main_play_wii_png[]; extern const u8 Main_play_gcn_png[]; #endif +/* Options menu */ extern const u8 Option_menu_png[]; extern const u8 Option_ctrl_png[]; extern const u8 Option_sound_png[]; extern const u8 Option_video_png[]; extern const u8 Option_system_png[]; +/* Load ROM menu */ extern const u8 Load_recent_png[]; extern const u8 Load_sd_png[]; extern const u8 Load_dvd_png[]; @@ -105,16 +108,44 @@ extern const u8 Load_dvd_png[]; extern const u8 Load_usb_png[]; #endif +/* Generic Buttons */ extern const u8 Button_text_png[]; extern const u8 Button_text_over_png[]; extern const u8 Button_icon_png[]; extern const u8 Button_icon_over_png[]; +extern const u8 Button_icon_sm_png[]; +extern const u8 Button_icon_sm_over_png[]; extern const u8 Button_up_png[]; extern const u8 Button_down_png[]; extern const u8 Button_up_over_png[]; extern const u8 Button_down_over_png[]; +/* Controller Settings */ +extern const u8 Ctrl_4wayplay_png[]; +extern const u8 Ctrl_gamepad_png[]; +extern const u8 Ctrl_justifiers_png[]; +extern const u8 Ctrl_menacer_png[]; +extern const u8 Ctrl_mouse_png[]; +extern const u8 Ctrl_none_png[]; +extern const u8 Ctrl_teamplayer_png[]; +extern const u8 Ctrl_pad3b_png[]; +extern const u8 Ctrl_pad6b_png[]; +extern const u8 Ctrl_config_png[]; +extern const u8 Ctrl_player_png[]; +extern const u8 Ctrl_player_over_png[]; +extern const u8 Ctrl_player_none_png[]; +extern const u8 ctrl_option_off_png[]; +extern const u8 ctrl_option_on_png[]; +extern const u8 ctrl_gamecube_png[]; #ifdef HW_RVL +extern const u8 ctrl_classic_png[]; +extern const u8 ctrl_nunchuk_png[]; +extern const u8 ctrl_wiimote_png[]; +#endif + +/* Generic images*/ +#ifdef HW_RVL +extern const u8 generic_point_png[]; extern const u8 Key_A_wii_png[]; extern const u8 Key_B_wii_png[]; #else @@ -122,10 +153,7 @@ extern const u8 Key_A_gcn_png[]; extern const u8 Key_B_gcn_png[]; #endif -#ifdef HW_RVL -extern const u8 generic_point_png[]; -#endif - +/* Generic sounds */ extern const u8 button_select_pcm[]; extern const u32 button_select_pcm_size; extern const u8 button_over_pcm[]; @@ -170,7 +198,7 @@ typedef struct { butn_data *data; /* pointer to button image/texture data */ u8 state; /* button state (ACTIVE,VISIBLE,SELECTED...) */ - u8 shift[2]; /* up & down direction offsets */ + u8 shift[4]; /* direction offsets */ u16 x; /* button image X position (upper left corner) */ u16 y; /* button image Y position (upper left corner) */ u16 w; /* button image pixels width */ diff --git a/source/gx/gx_input.c b/source/gx/gx_input.c index f9d6bb2..9cda8ae 100644 --- a/source/gx/gx_input.c +++ b/source/gx/gx_input.c @@ -94,6 +94,13 @@ static void pad_config(int chan, int max_keys) { sprintf(msg, "PAD #%d is not connected !", chan+1); WaitPrompt(msg); + + /* remove any pending keys */ + while (PAD_ButtonsHeld(chan)) + { + VIDEO_WaitVSync(); + PAD_ScanPads(); + } return; } @@ -141,6 +148,13 @@ static void pad_config(int chan, int max_keys) if (key !=0xff) config.pad_keymap[chan][i] = key; } + /* remove any pending keys */ + while (PAD_ButtonsHeld(chan)) + { + VIDEO_WaitVSync(); + PAD_ScanPads(); + } + /* restore inputs update callback */ VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu); VIDEO_Flush(); @@ -321,6 +335,14 @@ static void wpad_config(u8 chan, u8 exp, u8 max_keys) if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1); if (exp == WPAD_EXP_CLASSIC) sprintf(msg, "CLASSIC #%d is not connected !", chan+1); WaitPrompt(msg); + + /* remove any pending buttons */ + while (WPAD_ButtonsHeld(chan)) + { + WPAD_ScanPads(); + VIDEO_WaitVSync(); + } + return; } @@ -404,6 +426,13 @@ static void wpad_config(u8 chan, u8 exp, u8 max_keys) if (key != 0xff) config.wpad_keymap[exp + (chan * 3)][i] = key; } + /* remove any pending buttons */ + while (WPAD_ButtonsHeld(chan)) + { + WPAD_ScanPads(); + VIDEO_WaitVSync(); + } + /* restore inputs update callback */ VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu); VIDEO_Flush(); @@ -637,8 +666,9 @@ void gx_input_SetDefault(void) for (i=0; i0000q2nGNE01Y@Zc#$D!e>E>K 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 ee(Q7=;{O0zMvY5#{@?Zh00005*L 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 diff --git a/source/gx/images/Frame_s3.png b/source/gx/images/Frame_s3.png index b9b057e4a2cddc7e48f9555fc53ba6192b920fad..c12f11c9ddfd5214fc7b39cc9c7e5926fa59a0c8 100644 GIT binary patch delta 3624 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 diff --git a/source/gx/images/generic_point.png b/source/gx/images/generic_point.png index eb79fbd4202cb14c5a95ed1f96851338d006361c..7c3432b11ad090f1c21e29339103453c305cdaad 100644 GIT binary patch literal 2049 zcmV+c2>$npP)$K}&#&jZm`t_Ob8Ynd2XG=kC4x-o3khEQx>gn@rxDGiT;}@0po1X9lLmmw=an ze*)Kl^S~gmU>bd!f`~*V3oXD807)tD0Bi0wL6xC506YUQZ{9q%Zrw_;Smf;4vkVUp zJDp3w=YfCEG{LE`3>XDu_3G7f;lc%R@O@tf1_t7u+&`1#9Kork_?v*Vw6w^{lP9GS zHg4SL2>u0Vy;lUi6rG0vy1KgP>FH^xuxZmK_je&McP0tOkw!2N(AL(5=QUPoZ*O;h zbJz`aPmo4XfXsDZjEU<`y{el;8o~b?d_?eW@e#qh#Y_+spgIHNG(>&|#%Kqg1#SUv z1FrzrXJA}lW(c+dJ7e{Cfo}sp#|H8HvFCcNnZfUxpi+vZOP4Y}KF*aZR{%Z^{1kW$ zSPDFd_3kO)Mc{8AX8fktpzr$>i$#WphB$Zb9OuuUr(7;mEEd6j_)ee)=mH)Fz6HD< z$~&=X+D2e`mYp;YPI+|IYBiQDS;FScn5$WjYNXyOz7z3Vw^mJ=BHV=H&DK>+AK2NDsqN}SbkqK?vwv9b|_5iS9 z!v@ObGDnXdW!J7iWQJV6j7%v$d>Wvyua7fl&QLCw*}Z!=K@g-893LO2QmHg-t5hnCkB`^MecxwvbhM5j zz?wDD1#wPXo(CRx3I`4xpin481hTMx{d!8J5=td6hDs^=`}f$M5q*qU9kg9qMqy%@29LY0Y)mln(-f)e^X2qdgqxi%1(P#)iC_B)bj zBuhi6YbQ!YQ=UrDc_=WpuX|V08iK&ey_gpbwjOt^=Neqa)K!z;Xut~>a@q_{cu-s? zgCWPAaT`>%2)+R=pcCd?-I)d*H?Nb_b@*A6m#Z-4upIOH<-}x@$ zwNUeQM8f`<*!GJN@!~oO8jY<3qQV(VVHgqA#)gx?KyA!t>9Uoq{?tlt-45c<9N9LT z*hnfQs7>Ri$_WoDi8g~lF*@cmI%ZIk^~Tv4q7*74$w;(&iojU=*#yPzTx0Co5>Y5M zu{PAC0c?BypdtzvG~(?d3IvoVHcE$TInjv8XRbj7aQX5@JFEwRPZ;(gJwi1p*Ga8h zi-!Q0F8#wPCZ^0Iyu%*<-ESB=ewukj`_va0!4JqRLC{zy2qd%34?qWkCyIH+7KVfO$%;Wz1=+lr?^i$RMaFcSU7iw)uuwMWI!uq`k)WCcd> za?n{SaBBEXp6cDs*x0D!^g^7V3Q0bTy%tiMzknbA?6-WjXAReG+@a>n^iPLrqL5Q8 zoZrToGk@f(U-=^M--w*{Jz$TBMDf7Qw+DP5=m#iuF5tyOzo%#I!(97Mm711`MKiGn zCVETC|2V=vg@R(?+;+~r@n`zJ{8*ga^Vmz9iO0nFP@$EE?7kQm#^`O#h>JZ z+hh3kS^9@YF7Hw7Xyae+UgpW|kMiF2tFEaGd>sfN8MNb*7XaS?4gtJ({VLDxf7&W} z9=?V^hlxWI#n+JcKs-HU+c{I5m z1(-9tjhi>F@x+$ZjEvj{cmwzXlb-L=Jm^pbUIM6AtBj6}AjZQOFh=T25SB*rcwK`S zkI|74s?~_kOOwe>M%vrVO|UmK!N%4=i%l-;vgdFT8f4s7*JUe$Cfq|4H^G}(NpAUCJgn0-&|eJAZwPwT~>LB{yqY$%@EC8t>`= zIR<aPrt&XzeHLWFak8Sp@tE_}Bx*5*xQ{ fQ{!kBL5KeV*-$5Ne9HE700000NkvXXu0mjfr83Bv literal 2200 zcmb`J`6CmI1IEY8vN0xij+UG&;&p3|F*j?jGUc{R%~8h6v0P(`EGb9h>kcu=ZSE=O z>&lgpQoSJxQ^Lx(@Bi@q;dwrvADr< z#K{;X{HY?f6TL8$K#}do2VHnl5aaV=TSLJc^qdQ6L^A@tv-!4-x$GiI_kS}>Cg z?YX&!3X;&`aRdm8_3%Cazsq7?neqpx;QSvx%xT4S(FQ28Ujik#qTzm@skCvDf3<%o zMLO&Lt)$Qx03DfKo>kZw$gQJFOHNSd9Vs_Hyy|^{8-W=ZNZnU30o&Y{tKTz9y(PXa zb=f>t!}mlIjx_Wb zh+^@#NoUxysbSQHw451PEF0OO*kerLVyM(xu6zfex(EE42N!eY}8O%g)@MyG$ZeSy{P+$zHoe@u(nQVq=g%9RQq&B>rGEj&p+XC zCHYMA#jg5_=$Mvh9M%4{gm6n#CZK+I3~~24<#n0f?nt&FfHj(@b11J9JcYs&2+3S7_jjl3h1esIh3eDdbshGn+>0uN9q*&OhQJ9+iDK>KmQn&sTW)lt{vzyZ_9W~{6{^5YVXvviK%;E@e0!@^NTunWo}QK z$D(@DoU(|Q!u$@GAduH^&}ie`l=Ln}NVSN`FcEOz*q^Q^XCu-#yb_BL!N|{o4TffR zqbNmqPf+$4JVCalZwyDRk2K~pC{gDXa^{MgOD4+u}CN@DX!^x`yrqMT;4DcPgmto1t9 z1URTk{>{ZYgsiezr}W%s0<2aoYYY}+_@^SVrlhZ=xnD{aS$gssb6Xon>w@zwM_TD4 zPM6-RS({0dU-7m*OIQzRnrul}HumKA%4Ed&e*4Tg+!o^rdu?;+(lNy4Zm_WYzQWGH z)xpJ#1k=0bf%D5~kB7RV!I?dLw|=J~>HMtNHU6wdRg8N^S{ zurjj>v@HZNq4n5dUz~F&K6xbPFBL+&>AiH282O=HSXV|^7Ori;H?duLhmK7`)LHH` zrz2UQZv^$73PkO=QM%grkPLr}CmQ+nCof%ex%uxL%MEMdYVL!)@L%gV53DPAbF&d9 zjD{&BResteHvul&$}n-oOj+Xv_KlLV5m3I}IIu+Y;#M^&R2DXF`MHz>e*$(TXY=FSqCe*tID#sG=)seI~`kdJntw{XN&Y3T6ILyRA?%9YLQ%aP<74 zV>acAj*+IBU$l5agLCBP1$y&*&=&jjV4A|9g4>ISi!Biz^-D%6zi9@*qNYz}h&qlj zOaE>8#PW=z1((_yMhsPOo2!WzJ$>^dVfNsZeOo?f;7z1r7P9;tB(r!U$Xw7oDCoQ# zVP7cJyW9GoBiO$%&F`uYju