1 /****************************************************************************
2 * menu.c
3 *
4 * Genesis Plus GX menu
5 *
6 * Copyright Eke-Eke (2009-2019)
7 *
8 * Redistribution and use of this code or any derivative works are permitted
9 * provided that the following conditions are met:
10 *
11 * - Redistributions may not be sold, nor may they be used in a commercial
12 * product or activity.
13 *
14 * - Redistributions that are modified from the original source must include the
15 * complete source code, including the source code for all components used by a
16 * binary built from the modified sources. However, as a special exception, the
17 * source code distributed need not include anything that is normally distributed
18 * (in either source or binary form) with the major components (compiler, kernel,
19 * and so on) of the operating system on which the executable runs, unless that
20 * component itself accompanies the executable.
21 *
22 * - Redistributions must reproduce the above copyright notice, this list of
23 * conditions and the following disclaimer in the documentation and/or other
24 * materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 ****************************************************************************************/
39
40 #include "shared.h"
41 #include "font.h"
42 #include "gui.h"
43 #include "filesel.h"
44 #include "cheats.h"
45 #include "file_load.h"
46 #include "file_slot.h"
47
48 #ifdef HW_RVL
49 #include <ogc/usbmouse.h>
50 #include "wiidrc.h"
51 #endif
52
53 #include <ogc/lwp_threads.h>
54 #include <ogc/lwp_watchdog.h>
55
56 /* Credits */
57 extern const u8 Bg_credits_png[];
58
59 /* Main menu */
60 extern const u8 Main_load_png[];
61 extern const u8 Main_options_png[];
62 extern const u8 Main_quit_png[];
63 extern const u8 Main_file_png[];
64 extern const u8 Main_reset_png[];
65 extern const u8 Main_cheats_png[];
66 extern const u8 Main_showinfo_png[];
67 extern const u8 Main_takeshot_png[];
68 #ifdef HW_RVL
69 extern const u8 Main_play_wii_png[];
70 #else
71 extern const u8 Main_play_gcn_png[];
72 #endif
73
74 /* Options menu */
75 extern const u8 Option_menu_png[];
76 extern const u8 Option_ctrl_png[];
77 extern const u8 Option_sound_png[];
78 extern const u8 Option_video_png[];
79 extern const u8 Option_system_png[];
80
81 /* Load ROM menu */
82 extern const u8 Load_recent_png[];
83 extern const u8 Load_md_png[];
84 extern const u8 Load_ms_png[];
85 extern const u8 Load_gg_png[];
86 extern const u8 Load_sg_png[];
87 extern const u8 Load_cd_png[];
88
89 /* Save Manager menu */
90 extern const u8 Button_load_png[];
91 extern const u8 Button_load_over_png[];
92 extern const u8 Button_save_png[];
93 extern const u8 Button_save_over_png[];
94 extern const u8 Button_special_png[];
95 extern const u8 Button_special_over_png[];
96 extern const u8 Button_delete_png[];
97 extern const u8 Button_delete_over_png[];
98
99 /* Controller Settings */
100 extern const u8 Ctrl_4wayplay_png[];
101 extern const u8 Ctrl_gamepad_png[];
102 extern const u8 Ctrl_justifiers_png[];
103 extern const u8 Ctrl_menacer_png[];
104 extern const u8 Ctrl_mouse_png[];
105 extern const u8 Ctrl_xe_1ap_png[];
106 extern const u8 Ctrl_activator_png[];
107 extern const u8 Ctrl_lightphaser_png[];
108 extern const u8 Ctrl_paddle_png[];
109 extern const u8 Ctrl_sportspad_png[];
110 extern const u8 Ctrl_none_png[];
111 extern const u8 Ctrl_teamplayer_png[];
112 extern const u8 Ctrl_mastertap_png[];
113 extern const u8 Ctrl_graphic_board_png[];
114 extern const u8 Ctrl_pad_auto_png[];
115 extern const u8 Ctrl_pad2b_png[];
116 extern const u8 Ctrl_pad3b_png[];
117 extern const u8 Ctrl_pad6b_png[];
118 extern const u8 Ctrl_config_png[];
119 extern const u8 ctrl_option_off_png[];
120 extern const u8 ctrl_option_on_png[];
121 extern const u8 ctrl_gamecube_png[];
122 #ifdef HW_RVL
123 extern const u8 ctrl_classic_png[];
124 extern const u8 ctrl_nunchuk_png[];
125 extern const u8 ctrl_wiimote_png[];
126 extern const u8 ctrl_wiiu_png[];
127 #endif
128
129 /* Generic images */
130 extern const u8 Button_sm_blue_png[];
131 extern const u8 Button_sm_grey_png[];
132 extern const u8 Button_sm_yellow_png[];
133
134 /* Exit callback */
135 void (*reload)(void);
136
137
138 /*****************************************************************************/
139 /* Specific Menu Callbacks */
140 /*****************************************************************************/
141 static void ctrlmenu_cb(void);
142 static void savemenu_cb(void);
143 static void mainmenu_cb(void);
144
145 /*****************************************************************************/
146 /* Generic Buttons data */
147 /*****************************************************************************/
148 static butn_data arrow_up_data =
149 {
150 {NULL,NULL},
151 {Button_up_png,Button_up_over_png}
152 };
153
154 static butn_data arrow_down_data =
155 {
156 {NULL,NULL},
157 {Button_down_png,Button_down_over_png}
158 };
159
160 static butn_data button_text_data =
161 {
162 {NULL,NULL},
163 {Button_text_png,Button_text_over_png}
164 };
165
166 static butn_data button_icon_data =
167 {
168 {NULL,NULL},
169 {Button_icon_png,Button_icon_over_png}
170 };
171
172 static butn_data button_icon_sm_data =
173 {
174 {NULL,NULL},
175 {Button_icon_sm_png,Button_icon_sm_over_png}
176 };
177
178 static butn_data button_player_data =
179 {
180 {NULL,NULL},
181 {Button_sm_blue_png,Button_sm_yellow_png}
182 };
183
184 static butn_data button_player_none_data =
185 {
186 {NULL,NULL},
187 {Button_sm_grey_png,NULL}
188 };
189
190 static butn_data button_load_data =
191 {
192 {NULL,NULL},
193 {Button_load_png,Button_load_over_png}
194 };
195
196 static butn_data button_save_data =
197 {
198 {NULL,NULL},
199 {Button_save_png,Button_save_over_png}
200 };
201
202 static butn_data button_special_data =
203 {
204 {NULL,NULL},
205 {Button_special_png,Button_special_over_png}
206 };
207
208 static butn_data button_delete_data =
209 {
210 {NULL,NULL},
211 {Button_delete_png,Button_delete_over_png}
212 };
213
214 /*****************************************************************************/
215 /* Generic GUI items */
216 /*****************************************************************************/
217 static gui_item action_cancel =
218 {
219 NULL,Key_B_png,"","Back",10,422,28,28
220 };
221
222 static gui_item action_select =
223 {
224 NULL,Key_A_png,"","",602,422,28,28
225 };
226
227 /*****************************************************************************/
228 /* GUI backgrounds images */
229 /*****************************************************************************/
230 static gui_image bg_main[] =
231 {
232 {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
233 {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
234 {NULL,Banner_main_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,340,640,140,255},
235 {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,202,362,232,56,255}
236 };
237
238 static gui_image bg_misc[] =
239 {
240 {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
241 {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
242 {NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255},
243 {NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255},
244 {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,466,40,152,44,255}
245 };
246
247 static gui_image bg_ctrls[] =
248 {
249 {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
250 {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
251 {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
252 {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
253 {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
254 {NULL,Frame_s2_png,IMAGE_VISIBLE,38,72,316,168,128},
255 {NULL,Frame_s2_png,IMAGE_VISIBLE,38,242,316,168,128},
256 {NULL,Frame_s3_png,IMAGE_SLIDE_RIGHT,400,134,292,248,128}
257 };
258
259 static gui_image bg_list[] =
260 {
261 {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
262 {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
263 {NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
264 {NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
265 {NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
266 {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,76}
267 };
268
269 static gui_image bg_saves[] =
270 {
271 {NULL,NULL,0,0,0,0,0,255},
272 {NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
273 {NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
274 {NULL,Banner_top_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,0,0,640,108,255},
275 {NULL,Banner_bottom_png,IMAGE_VISIBLE|IMAGE_SLIDE_BOTTOM,0,380,640,100,255},
276 {NULL,Main_logo_png,IMAGE_VISIBLE|IMAGE_SLIDE_TOP,466,40,152,44,255},
277 {NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,76},
278 {NULL,Frame_s1_png,IMAGE_SLIDE_RIGHT,468,108,372,296,76}
279 };
280
281 /*****************************************************************************/
282 /* Menu Items description */
283 /*****************************************************************************/
284
285 /* Main menu */
286 static gui_item items_main[] =
287 {
288 {NULL,Main_load_png ,"","",114,162,80,92},
289 {NULL,Main_options_png ,"","",290,166,60,88},
290 {NULL,Main_quit_png ,"","",460,170,52,84},
291 {NULL,Main_file_png ,"","",114,216,80,92},
292 {NULL,Main_reset_png ,"","",294,227,52,80},
293 {NULL,Main_cheats_png ,"","",454,218,64,92},
294 {NULL,NULL ,"","", 10,334,84,32},
295 #ifdef HW_RVL
296 {NULL,Main_play_wii_png,"","", 10,372,84,32},
297 #else
298 {NULL,Main_play_gcn_png,"","", 10,372,84,32},
299 #endif
300 {NULL,Main_takeshot_png,"","",546,334,84,32},
301 {NULL,Main_showinfo_png,"","",546,372,84,32}
302 };
303
304 /* Controllers menu */
305 static gui_item items_ctrls[] =
306 {
307 {NULL,NULL,"","", 0, 0, 0, 0},
308 {NULL,NULL,"","", 0, 0, 0, 0},
309 {NULL,NULL,"","",305, 0, 24, 0},
310 {NULL,NULL,"","",305, 0, 24, 0},
311 {NULL,NULL,"","",305, 0, 24, 0},
312 {NULL,NULL,"","",305, 0, 24, 0},
313 {NULL,NULL,"","",305, 0, 24, 0},
314 {NULL,NULL,"","",305, 0, 24, 0},
315 {NULL,NULL,"","",305, 0, 24, 0},
316 {NULL,NULL,"","",305, 0, 24, 0},
317 {NULL,NULL,"","", 0, 0, 0, 0},
318 {NULL,NULL,"","", 0, 0, 0, 0},
319 {NULL,Ctrl_config_png,"Keys\nConfig","Configure Controller Keys",530,306,32,32}
320 };
321
322 /* Load menu */
323 static gui_item items_load[] =
324 {
325 {NULL,Load_recent_png,"","Load recently played games", 119,144,72, 92},
326 {NULL,Load_md_png, "","Load Mega Drive/Genesis games", 278,141,84, 92},
327 {NULL,Load_cd_png, "","Load Sega/Mega CD games", 454,141,64, 92},
328 {NULL,Load_ms_png, "","Load Master System games", 114,284,84, 96},
329 {NULL,Load_gg_png, "","Load Game Gear games", 278,283,84,100},
330 {NULL,Load_sg_png, "","Load SG-1000 games", 454,281,64, 96}
331 };
332
333 /* Option menu */
334 static gui_item items_options[] =
335 {
336 {NULL,Option_system_png,"","System settings", 114,142,80,92},
337 {NULL,Option_video_png, "","Video settings", 288,150,64,84},
338 {NULL,Option_sound_png, "","Audio settings", 464,154,44,80},
339 {NULL,Option_ctrl_png, "","Controllers settings", 192,286,88,92},
340 {NULL,Option_menu_png, "","Menu settings", 370,286,60,92}
341 };
342
343 /* Audio options */
344 static gui_item items_audio[] =
345 {
346 {NULL,NULL,"Master System FM: AUTO", "Enable/Disable YM2413 chip", 56,132,276,48},
347 {NULL,NULL,"YM2612 Type: DISCRETE", "Select YM2612 chip model", 56,132,276,48},
348 {NULL,NULL,"High-Quality FM: ON", "Enable/Disable YM2612/YM2413 high-quality resampling", 56,132,276,48},
349 {NULL,NULL,"High-Quality PSG: ON", "Enable/Disable SN76489 high-quality resampling", 56,132,276,48},
350 {NULL,NULL,"FM Volume: 1.00", "Adjust YM2612/YM2413 audio balance", 56,132,276,48},
351 {NULL,NULL,"PSG Volume: 2.50", "Adjust SN76489 audio balance", 56,132,276,48},
352 {NULL,NULL,"Audio Output: STEREO", "Select audio mixing output type", 56,132,276,48},
353 {NULL,NULL,"Filtering: 3-BAND EQ", "Select audio filtering type", 56,132,276,48},
354 {NULL,NULL,"Low Gain: 1.00", "Adjust EQ Low Band Gain", 56,132,276,48},
355 {NULL,NULL,"Mid Gain: 1.00", "Adjust EQ Mid Band Gain", 56,132,276,48},
356 {NULL,NULL,"High Gain: 1.00", "Adjust EQ High Band Gain", 56,132,276,48},
357 {NULL,NULL,"Low Freq: 200 Hz", "Adjust EQ Lowest Frequency", 56,132,276,48},
358 {NULL,NULL,"High Freq: 20000 Hz", "Adjust EQ Highest Frequency", 56,132,276,48}
359 };
360
361 /* System ROM paths */
362 static gui_item items_rompaths[] =
363 {
364 {NULL,NULL,"CD BIOS (USA): NOT FOUND", "Select Sega CD (USA) BIOS", 56,132,276,48},
365 {NULL,NULL,"CD BIOS (PAL): NOT FOUND", "Select Mega CD (PAL) BIOS", 56,132,276,48},
366 {NULL,NULL,"CD BIOS (JAP): NOT FOUND", "Select Mega CD (JAP) BIOS", 56,132,276,48},
367 {NULL,NULL,"MD BIOS (TMSS): NOT FOUND", "Select Mega Drive / Genesis BootROM", 56,132,276,48},
368 {NULL,NULL,"MS BIOS (USA): NOT FOUND", "Select Master System (USA) BootROM", 56,132,276,48},
369 {NULL,NULL,"MS BIOS (PAL): NOT FOUND", "Select Master System (PAL) BootROM", 56,132,276,48},
370 {NULL,NULL,"MS BIOS (JAP): NOT FOUND", "Select Master System (JAP) BootROM", 56,132,276,48},
371 {NULL,NULL,"Game Gear BIOS: NOT FOUND", "Select Game Gear BootROM", 56,132,276,48},
372 {NULL,NULL,"Game Genie: NOT FOUND", "Select Game Genie ROM", 56,132,276,48},
373 {NULL,NULL,"Action Replay: NOT FOUND", "Select Action Replay (Pro) ROM", 56,132,276,48},
374 {NULL,NULL,"S&K (2MB ROM): NOT FOUND", "Select Sonic & Knuckle main ROM", 56,132,276,48},
375 {NULL,NULL,"S2&K (256K ROM): NOT FOUND","Select Sonic 2 & Knuckle upmem ROM", 56,132,276,48},
376 };
377
378 /* System options */
379 static gui_item items_system[] =
380 {
381 {NULL,NULL,"Console Hardware: AUTO", "Select system hardware model", 56,132,276,48},
382 {NULL,NULL,"Console Region: AUTO", "Select system region", 56,132,276,48},
383 {NULL,NULL,"VDP Mode: AUTO", "Select VDP mode", 56,132,276,48},
384 {NULL,NULL,"System Clock: AUTO", "Select system clock frequency", 56,132,276,48},
385 {NULL,NULL,"System Boot: BIOS&CART", "Select system booting method", 56,132,276,48},
386 {NULL,NULL,"System Lockups: ON", "Enable/Disable original system lock-ups", 56,132,276,48},
387 {NULL,NULL,"68k Address Error: ON", "Enable/Disable 68k address error exceptions", 56,132,276,48},
388 {NULL,NULL,"Lock-on: OFF", "Select Lock-On cartridge type", 56,132,276,48},
389 {NULL,NULL,"Cartridge Swap: OFF", "Enable/Disable cartridge hot swap", 56,132,276,48},
390 {NULL,NULL,"BIOS & Lock-On ROM paths","Configure BIOS & Lock-On ROM paths", 56,132,276,48},
391 {NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 56,132,276,48}
392 };
393
394 /* Video options */
395 static gui_item items_video[] =
396 {
397 {NULL,NULL,"Display: PROGRESSIVE", "Select video mode", 56,132,276,48},
398 {NULL,NULL,"TV mode: 50/60HZ", "Select video refresh rate", 56,132,276,48},
399 {NULL,NULL,"VSYNC: AUTO", "Enable/Disable sync with video hardware", 56,132,276,48},
400 {NULL,NULL,"Bilinear Filter: OFF", "Enable/Disable GX hardware texture filtering", 56,132,276,48},
401 {NULL,NULL,"Deflickering Filter: AUTO", "Enable/Disable GX hardware framebuffer filtering", 56,132,276,48},
402 #ifdef HW_RVL
403 {NULL,NULL,"Trap Filter: ON", "Enable/Disable VI hardware composite out filtering",56,132,276,48},
404 {NULL,NULL,"Gamma Correction: 1.0", "Adjust VI hardware gamma correction", 56,132,276,48},
405 #endif
406 {NULL,NULL,"LCD Ghosting Filter: OFF", "Enable/Disable software LCD image persistence", 56,132,276,48},
407 {NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/Disable software NTSC filtering", 56,132,276,48},
408 {NULL,NULL,"NTSC Sharpness: 0.0", "Adjust edge contrast enhancement/blurring", 56,132,276,48},
409 {NULL,NULL,"NTSC Resolution: 0.0", "Adjust image resolution", 56,132,276,48},
410 {NULL,NULL,"NTSC Artifacts: 0.0", "Adjust artifacts caused by color changes", 56,132,276,48},
411 {NULL,NULL,"NTSC Color Bleed: 0.0", "Adjust color resolution reduction", 56,132,276,48},
412 {NULL,NULL,"NTSC Color Fringing: 0.0", "Adjust artifacts caused by brightness changes", 56,132,276,48},
413 {NULL,NULL,"Borders: OFF", "Enable/Disable overscan emulation", 56,132,276,48},
414 {NULL,NULL,"GG screen: ORIGINAL", "Enable/Disable Game Gear extended screen", 56,132,276,48},
415 {NULL,NULL,"Aspect: ORIGINAL (4:3)", "Select display aspect ratio", 56,132,276,48},
416 {NULL,NULL,"Screen Position (+0,+0)", "Adjust display position", 56,132,276,48},
417 {NULL,NULL,"Screen Scaling (+0,+0)", "Adjust display scaling", 56,132,276,48}
418 };
419
420 /* Menu options */
421 static gui_item items_prefs[] =
422 {
423 {NULL,NULL,"Auto ROM Load: OFF", "Enable/Disable automatic ROM loading on startup", 56,132,276,48},
424 {NULL,NULL,"Auto Cheats: OFF", "Enable/Disable automatic cheats activation", 56,132,276,48},
425 {NULL,NULL,"Auto Saves: OFF", "Enable/Disable automatic saves", 56,132,276,48},
426 {NULL,NULL,"ROM Load Device: SD", "Configure default device for ROM files", 56,132,276,48},
427 {NULL,NULL,"Saves Device: FAT", "Configure default device for Save files", 56,132,276,48},
428 {NULL,NULL,"SFX Volume: 100", "Adjust sound effects volume", 56,132,276,48},
429 {NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 56,132,276,48},
430 {NULL,NULL,"BG Overlay: ON", "Enable/Disable background overlay", 56,132,276,48},
431 {NULL,NULL,"Screen Width: 658", "Adjust menu screen width in pixels", 56,132,276,48},
432 {NULL,NULL,"Show CD Leds: OFF", "Enable/Disable CD leds display", 56,132,276,48},
433 {NULL,NULL,"Show FPS: OFF", "Enable/Disable FPS counter", 56,132,276,48},
434 #ifdef HW_RVL
435 {NULL,NULL,"Wiimote Timeout: OFF","Enable/Disable Wii remote automatic shutdown", 56,132,276,48},
436 {NULL,NULL,"Wiimote Calibration: AUTO","Calibrate Wii remote pointer", 56,132,276,48},
437 #endif
438 };
439
440 /* Save Manager */
441 static gui_item items_saves[] =
442 {
443 {NULL,NULL,"","" ,0,0,0,0},
444 {NULL,NULL,"","" ,0,0,0,0},
445 {NULL,NULL,"","" ,0,0,0,0},
446 {NULL,NULL,"","" ,0,0,0,0},
447 {NULL,NULL,"","" ,0,0,0,0},
448 {NULL,NULL,"","Load file" ,0,0,0,0},
449 {NULL,NULL,"","Set as default file",0,0,0,0},
450 {NULL,NULL,"","Delete file" ,0,0,0,0},
451 {NULL,NULL,"","Save file" ,0,0,0,0}
452 };
453
454 /*****************************************************************************/
455 /* Menu Buttons description */
456 /*****************************************************************************/
457
458 /* Generic Buttons for list menu */
459 static gui_butn arrow_up = {&arrow_up_data,BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,76,360,32};
460 static gui_butn arrow_down = {&arrow_down_data,BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,368,360,32};
461
462 /* Generic list menu */
463 static gui_butn buttons_list[] =
464 {
465 {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,132,276,48},
466 {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,188,276,48},
467 {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,244,276,48},
468 {&button_text_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0},56,300,276,48}
469 };
470
471 /* Main menu */
472 static gui_butn buttons_main[] =
473 {
474 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,0,1}, 80,140,148,132},
475 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,1},246,140,148,132},
476 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,0,1,0},412,140,148,132},
477 {&button_icon_data, BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,4,0,1}, 80,194,148,132},
478 {&button_icon_data, BUTTON_OVER_SFX ,{3,4,1,1},246,194,148,132},
479 {&button_icon_data, BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,3,1,0},412,194,148,132},
480 {NULL , BUTTON_OVER_SFX ,{3,1,0,2}, 10,334, 84, 32},
481 {NULL , BUTTON_OVER_SFX ,{4,0,0,2}, 10,372, 84, 32},
482 {NULL , BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,1,1,0},546,334, 84, 32},
483 {NULL , BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,2,0},546,372, 84, 32}
484 };
485
486 /* Controllers Menu */
487 static gui_butn buttons_ctrls[] =
488 {
489 {&button_icon_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{0,1,0,2}, 60, 88,148,132},
490 {&button_icon_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX ,{1,0,0,5}, 60,258,148,132},
491 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,1,2,0},250, 79, 84, 32},
492 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,3,0},250,117, 84, 32},
493 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,4,0},250,155, 84, 32},
494 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,5,0},250,193, 84, 32},
495 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,5,0},250,249, 84, 32},
496 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,6,0},250,287, 84, 32},
497 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,1,7,0},250,325, 84, 32},
498 {NULL ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{1,0,8,0},250,363, 84, 32},
499 {&button_icon_sm_data ,BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX ,{0,1,1,0},436,168,160, 52},
500 {&button_icon_sm_data ,BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX ,{1,1,0,0},436,232,160, 52},
501 {&button_icon_sm_data ,BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX|BUTTON_SELECT_SFX ,{1,0,0,0},436,296,160, 52}
502 };
503
504 /* Load Game menu */
505 static gui_butn buttons_load[] =
506 {
507 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80,120,148,132},
508 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246,120,148,132},
509 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,0},412,120,148,132},
510 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,0,1}, 80,264,148,132},
511 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,1},246,264,148,132},
512 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,0},412,264,148,132}
513 };
514
515 /* Options menu */
516 static gui_butn buttons_options[] =
517 {
518 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,0,1}, 80,120,148,132},
519 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,3,1,1},246,120,148,132},
520 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{0,2,1,1},412,120,148,132},
521 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{3,0,1,1},162,264,148,132},
522 {&button_icon_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX|BUTTON_SELECT_SFX,{2,0,1,0},330,264,148,132}
523 };
524
525 /* Save Manager Menu */
526 static gui_butn buttons_saves[] =
527 {
528 {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,1,0,0}, 56,102,276,48},
529 {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0}, 56,158,276,48},
530 {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0}, 56,214,276,48},
531 {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,1,0,0}, 56,270,276,48},
532 {&button_text_data ,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{1,0,0,0}, 56,326,276,48},
533 {&button_load_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{0,1,0,0},530,130, 56,56},
534 {&button_special_data,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{1,1,0,0},530,196, 56,56},
535 {&button_delete_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{1,1,0,0},530,262, 56,56},
536 {&button_save_data ,BUTTON_ACTIVE|BUTTON_SLIDE_RIGHT|BUTTON_OVER_SFX,{1,0,0,0},530,328, 56,56}
537 };
538
539 /*****************************************************************************/
540 /* Menu descriptions */
541 /*****************************************************************************/
542
543 /* Main menu */
544 static gui_menu menu_main =
545 {
546 "",
547 0,0,
548 10,10,4,0,
549 items_main,
550 buttons_main,
551 bg_main,
552 {NULL,NULL},
553 {NULL,NULL},
554 NULL
555 };
556
557 /* Main menu */
558 gui_menu menu_ctrls =
559 {
560 "Controller Settings",
561 0,0,
562 13,13,8,0,
563 items_ctrls,
564 buttons_ctrls,
565 bg_ctrls,
566 {&action_cancel, &action_select},
567 {NULL,NULL},
568 ctrlmenu_cb
569 };
570
571 /* Load Game menu */
572 static gui_menu menu_load =
573 {
574 "Load Game",
575 0,0,
576 6,6,5,0,
577 items_load,
578 buttons_load,
579 bg_misc,
580 {&action_cancel, &action_select},
581 {NULL,NULL},
582 NULL
583 };
584
585 /* Options menu */
586 static gui_menu menu_options =
587 {
588 "Settings",
589 0,0,
590 5,5,5,0,
591 items_options,
592 buttons_options,
593 bg_misc,
594 {&action_cancel, &action_select},
595 {NULL,NULL},
596 NULL
597 };
598
599 /* System ROM Path submenu */
600 static gui_menu menu_rompaths =
601 {
602 "System ROM Paths",
603 0,0,
604 12,4,6,0,
605 items_rompaths,
606 buttons_list,
607 bg_list,
608 {&action_cancel, &action_select},
609 {&arrow_up,&arrow_down},
610 NULL
611 };
612
613 /* System Options menu */
614 static gui_menu menu_system =
615 {
616 "System Settings",
617 0,0,
618 0,4,6,0,
619 items_system,
620 buttons_list,
621 bg_list,
622 {&action_cancel, &action_select},
623 {&arrow_up,&arrow_down},
624 NULL
625 };
626
627 /* Video Options menu */
628 static gui_menu menu_video =
629 {
630 "Video Settings",
631 0,0,
632 0,4,6,0,
633 items_video,
634 buttons_list,
635 bg_list,
636 {&action_cancel, &action_select},
637 {&arrow_up,&arrow_down},
638 NULL
639 };
640
641 /* Sound Options menu */
642 static gui_menu menu_audio =
643 {
644 "Audio Settings",
645 0,0,
646 0,4,6,0,
647 items_audio,
648 buttons_list,
649 bg_list,
650 {&action_cancel, &action_select},
651 {&arrow_up,&arrow_down},
652 NULL
653 };
654
655 /* Sound Options menu */
656 static gui_menu menu_prefs =
657 {
658 "Menu Settings",
659 0,0,
660 0,4,6,0,
661 items_prefs,
662 buttons_list,
663 bg_list,
664 {&action_cancel, &action_select},
665 {&arrow_up,&arrow_down},
666 NULL
667 };
668
669
670 /* Save Manager menu */
671 static gui_menu menu_saves =
672 {
673 "Save Manager",
674 0,0,
675 9,9,8,0,
676 items_saves,
677 buttons_saves,
678 bg_saves,
679 {&action_cancel, &action_select},
680 {NULL,NULL},
681 savemenu_cb
682 };
683
684 /****************************************************************************
685 * GUI Settings menu
686 *
687 ****************************************************************************/
update_screen_w(void)688 static void update_screen_w(void)
689 {
690 vmode->viWidth = config.screen_w;
691 vmode->viXOrigin = (VI_MAX_WIDTH_NTSC -config.screen_w)/2;
692 VIDEO_Configure(vmode);
693 VIDEO_Flush();
694 }
695
update_bgm(void)696 static void update_bgm(void)
697 {
698 SetVolumeOgg(((int)config.bgm_volume * 255) / 100);
699 }
700
prefmenu()701 static void prefmenu ()
702 {
703 int ret, quit = 0;
704 gui_menu *m = &menu_prefs;
705 gui_item *items = m->items;
706
707 sprintf (items[0].text, "Auto ROM Load: %s", config.autoload ? "ON":"OFF");
708 sprintf (items[1].text, "Auto Cheats: %s", config.autocheat ? "ON":"OFF");
709 if (config.s_auto == 3) sprintf (items[2].text, "Auto Saves: ALL");
710 else if (config.s_auto == 2) sprintf (items[2].text, "Auto Saves: STATE ONLY");
711 else if (config.s_auto == 1) sprintf (items[2].text, "Auto Saves: SRAM ONLY");
712 else sprintf (items[2].text, "Auto Saves: NONE");
713 #ifdef HW_RVL
714 if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: USB");
715 else if (config.l_device == 2) sprintf (items[3].text, "ROM Load Device: DVD");
716 #else
717 if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: DVD");
718 #endif
719 else sprintf (items[3].text, "ROM Load Device: SD");
720 if (config.s_device == 1) sprintf (items[4].text, "Saves Device: MCARD A");
721 else if (config.s_device == 2) sprintf (items[4].text, "Saves Device: MCARD B");
722 else sprintf (items[4].text, "Saves Device: FAT");
723 sprintf (items[5].text, "SFX Volume: %1.1f", config.sfx_volume);
724 sprintf (items[6].text, "BGM Volume: %1.1f", config.bgm_volume);
725 sprintf (items[7].text, "BG Overlay: %s", config.bg_overlay ? "ON":"OFF");
726 sprintf (items[8].text, "Screen Width: %d", config.screen_w);
727 sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF");
728 sprintf (items[10].text, "Show FPS: %s", config.fps ? "ON":"OFF");
729 #ifdef HW_RVL
730 sprintf (items[11].text, "Wiimote Timeout: %s", config.autosleep ? "5 MIN":"30 MIN");
731 sprintf (items[12].text, "Wiimote Calibration: %s", ((config.calx * config.caly) != 0) ? "MANUAL":"AUTO");
732 sprintf (items[12].comment, "%s", ((config.calx * config.caly) != 0) ? "Reset default Wii remote pointer calibration":"Calibrate Wii remote pointer");
733 m->max_items = 13;
734 #else
735 m->max_items = 11;
736 #endif
737
738 GUI_InitMenu(m);
739 GUI_SlideMenuTitle(m,strlen("Menu "));
740
741 while (quit == 0)
742 {
743 ret = GUI_RunMenu(m);
744
745 switch (ret)
746 {
747 case 0: /* Auto load last ROM file on startup */
748 config.autoload ^= 1;
749 sprintf (items[0].text, "Auto ROM Load: %s", config.autoload ? "ON":"OFF");
750 break;
751
752 case 1: /* Cheats automatic activation */
753 config.autocheat ^= 1;
754 sprintf (items[1].text, "Auto Cheats: %s", config.autocheat ? "ON":"OFF");
755 break;
756
757 case 2: /*** Auto load/save STATE & SRAM files ***/
758 config.s_auto = (config.s_auto + 1) % 4;
759 if (config.s_auto == 3) sprintf (items[2].text, "Auto Saves: ALL");
760 else if (config.s_auto == 2) sprintf (items[2].text, "Auto Saves: STATE ONLY");
761 else if (config.s_auto == 1) sprintf (items[2].text, "Auto Saves: SRAM ONLY");
762 else sprintf (items[2].text, "Auto Saves: NONE");
763 break;
764
765 case 3: /*** Default ROM device ***/
766 #ifdef HW_RVL
767 config.l_device = (config.l_device + 1) % 3;
768 if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: USB");
769 else if (config.l_device == 2) sprintf (items[3].text, "ROM Load Device: DVD");
770 #else
771 config.l_device ^= 1;
772 if (config.l_device == 1) sprintf (items[3].text, "ROM Load Device: DVD");
773 #endif
774 else sprintf (items[3].text, "ROM Load Device: SD");
775 break;
776
777 case 4: /*** Default saves device ***/
778 config.s_device = (config.s_device + 1) % 3;
779 if (config.s_device == 1) sprintf (items[4].text, "Saves Device: MCARD A");
780 else if (config.s_device == 2) sprintf (items[4].text, "Saves Device: MCARD B");
781 else sprintf (items[4].text, "Saves Device: FAT");
782 break;
783
784 case 5: /*** Sound effects volume ***/
785 GUI_OptionBox(m,0,"SFX Volume",(void *)&config.sfx_volume,10.0,0.0,100.0,0);
786 sprintf (items[5].text, "SFX Volume: %1.1f", config.sfx_volume);
787 break;
788
789 case 6: /*** Background music volume ***/
790 GUI_OptionBox(m,update_bgm,"BGM Volume",(void *)&config.bgm_volume,10.0,0.0,100.0,0);
791 sprintf (items[6].text, "BGM Volume: %1.1f", config.bgm_volume);
792 break;
793
794 case 7: /*** Background overlay ***/
795 config.bg_overlay ^= 1;
796 if (config.bg_overlay)
797 {
798 bg_main[1].state |= IMAGE_VISIBLE;
799 bg_misc[1].state |= IMAGE_VISIBLE;
800 bg_ctrls[1].state |= IMAGE_VISIBLE;
801 bg_list[1].state |= IMAGE_VISIBLE;
802 bg_saves[2].state |= IMAGE_VISIBLE;
803 sprintf (items[7].text, "BG Overlay: ON");
804 }
805 else
806 {
807 bg_main[1].state &= ~IMAGE_VISIBLE;
808 bg_misc[1].state &= ~IMAGE_VISIBLE;
809 bg_ctrls[1].state &= ~IMAGE_VISIBLE;
810 bg_list[1].state &= ~IMAGE_VISIBLE;
811 bg_saves[2].state &= ~IMAGE_VISIBLE;
812 sprintf (items[7].text, "BG Overlay: OFF");
813 }
814 break;
815
816 case 8: /*** Screen Width ***/
817 GUI_OptionBox(m,update_screen_w,"Screen Width",(void *)&config.screen_w,2,640,VI_MAX_WIDTH_NTSC,1);
818 sprintf (items[8].text, "Screen Width: %d", config.screen_w);
819 break;
820
821 case 9: /*** CD LEDS ***/
822 config.cd_leds ^= 1;
823 sprintf (items[9].text, "Show CD Leds: %s", config.cd_leds ? "ON":"OFF");
824 break;
825
826 case 10: /*** FPS counter ***/
827 config.fps ^= 1;
828 sprintf (items[10].text, "Show FPS: %s", config.fps ? "ON":"OFF");
829 break;
830
831 #ifdef HW_RVL
832 case 11: /*** Wii remote auto switch-off ***/
833 config.autosleep ^= 1;
834 sprintf (items[11].text, "Wiimote Timeout: %s", config.autosleep ? "5min":"30min");
835 WPAD_SetIdleTimeout(config.autosleep ? 300 : 1800);
836 break;
837
838 case 12: /*** Wii remote pointer calibration ***/
839 if ((config.calx * config.caly) == 0)
840 {
841 if (GUI_WaitConfirm("Pointer Calibration","Aim center of TV screen"))
842 {
843 sprintf (items[12].text, "Wiimote Calibration: MANUAL");
844 sprintf (items[12].comment, "Reset default Wii remote pointer calibration");
845 config.calx = 320 - m_input.ir.x;
846 config.caly = 240 - m_input.ir.y;
847 m_input.ir.x = 320;
848 m_input.ir.y = 240;
849 }
850 }
851 else
852 {
853 sprintf (items[12].text, "Wiimote Calibration: AUTO");
854 sprintf (items[12].comment, "Calibrate Wii remote pointer");
855 config.calx = config.caly = 0;
856 }
857 break;
858 #endif
859
860 case -1:
861 quit = 1;
862 break;
863 }
864 }
865
866 /* stop DVD drive when not in use */
867 if (config.l_device != 2)
868 {
869 #ifdef HW_RVL
870 DI_StopMotor();
871 #else
872 vu32* const dvd = (u32*)0xCC006000;
873 dvd[0] = 0x2e;
874 dvd[1] = 0;
875 dvd[2] = 0xe3000000;
876 dvd[3] = 0;
877 dvd[4] = 0;
878 dvd[5] = 0;
879 dvd[6] = 0;
880 dvd[7] = 1;
881 while (dvd[7] & 1);
882 #endif
883 }
884
885 GUI_DeleteMenu(m);
886 }
887
888 /****************************************************************************
889 * Audio Settings menu
890 *
891 ****************************************************************************/
soundmenu()892 static void soundmenu ()
893 {
894 int ret, quit = 0;
895 float fm_volume = (float)config.fm_preamp/100.0;
896 float psg_volume = (float)config.psg_preamp/100.0;
897 gui_menu *m = &menu_audio;
898 gui_item *items = m->items;
899
900 if (config.ym2413 == 0) sprintf (items[0].text, "Master System FM: OFF");
901 else if (config.ym2413 == 1) sprintf (items[0].text, "Master System FM: ON");
902 else sprintf (items[0].text, "Master System FM: AUTO");
903
904 if (config.ym2612 == YM2612_DISCRETE) sprintf (items[1].text, "YM2612 Type: DISCRETE");
905 else if (config.ym2612 == YM2612_INTEGRATED) sprintf (items[1].text, "YM2612 Type: ASIC");
906 else sprintf (items[1].text, "YM2612 Type: ENHANCED");
907
908 sprintf (items[2].text, "High-Quality FM: %s", config.hq_fm ? "ON":"OFF");
909 sprintf (items[3].text, "High-Quality PSG: %s", config.hq_psg? "ON":"OFF");
910
911 sprintf (items[4].text, "FM Volume: %1.2f", fm_volume);
912 sprintf (items[5].text, "PSG Volume: %1.2f", psg_volume);
913
914 sprintf (items[6].text, "Audio Output: %s", config.mono ? "MONO":"STEREO");
915
916 if (config.filter == 2)
917 {
918 float lg = (float)config.lg/100.0;
919 float mg = (float)config.mg/100.0;
920 float hg = (float)config.hg/100.0;
921
922 sprintf(items[7].text, "Filtering: 3-BAND EQ");
923 sprintf(items[8].text, "Low Gain: %1.2f", lg);
924 strcpy(items[8].comment, "Adjust EQ Low Band Gain");
925 sprintf(items[9].text, "Middle Gain: %1.2f", mg);
926 sprintf(items[10].text, "High Gain: %1.2f", hg);
927 sprintf(items[11].text, "Low Freq: %d", config.low_freq);
928 sprintf(items[12].text, "High Freq: %d", config.high_freq);
929 m->max_items = 13;
930 }
931 else if (config.filter == 1)
932 {
933 int16 lp_range = (config.lp_range * 100 + 0xffff) / 0x10000;
934 sprintf (items[7].text, "Filtering: LOW-PASS");
935 sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range);
936 strcpy (items[8].comment, "Adjust Low Pass filter");
937 m->max_items = 9;
938 }
939 else
940 {
941 sprintf (items[7].text, "Filtering: OFF");
942 m->max_items = 8;
943 }
944
945 GUI_InitMenu(m);
946 GUI_SlideMenuTitle(m,strlen("Audio "));
947
948 while (quit == 0)
949 {
950 ret = GUI_RunMenu(m);
951
952 switch (ret)
953 {
954 case 0:
955 {
956 config.ym2413++;
957 if (config.ym2413 > 2) config.ym2413 = 0;
958 if (config.ym2413 == 0) sprintf (items[0].text, "Master System FM: OFF");
959 else if (config.ym2413 == 1) sprintf (items[0].text, "Master System FM: ON");
960 else sprintf (items[0].text, "Master System FM: AUTO");
961
962 /* Automatic detection */
963 if ((config.ym2413 & 2) && system_hw && ((system_hw & SYSTEM_PBC) != SYSTEM_MD))
964 {
965 /* detect if game is using YM2413 */
966 sms_cart_init();
967
968 /* restore SRAM */
969 slot_autoload(0,config.s_device);
970 }
971 break;
972 }
973
974 case 1:
975 {
976 config.ym2612++;
977 if (config.ym2612 > YM2612_ENHANCED) config.ym2612 = YM2612_DISCRETE;
978 if (config.ym2612 == YM2612_DISCRETE) sprintf (items[1].text, "YM2612 Type: DISCRETE");
979 else if (config.ym2612 == YM2612_INTEGRATED) sprintf (items[1].text, "YM2612 Type: ASIC");
980 else sprintf (items[1].text, "YM2612 Type: ENHANCED");
981 YM2612Config(config.ym2612);
982 break;
983 }
984
985 case 2:
986 {
987 config.hq_fm ^= 1;
988 sprintf (items[2].text, "High-Quality FM: %s", config.hq_fm ? "ON":"OFF");
989 break;
990 }
991
992 case 3:
993 {
994 config.hq_psg ^= 1;
995 sprintf (items[3].text, "High-Quality PSG: %s", config.hq_psg ? "ON":"OFF");
996 break;
997 }
998
999 case 4:
1000 {
1001 GUI_OptionBox(m,0,"FM Volume",(void *)&fm_volume,0.01,0.0,5.0,0);
1002 sprintf (items[4].text, "FM Volume: %1.2f", fm_volume);
1003 config.fm_preamp = (int)(fm_volume * 100.0 + 0.5);
1004 break;
1005 }
1006
1007 case 5:
1008 {
1009 GUI_OptionBox(m,0,"PSG Volume",(void *)&psg_volume,0.01,0.0,5.0,0);
1010 sprintf (items[5].text, "PSG Volume: %1.2f", psg_volume);
1011 config.psg_preamp = (int)(psg_volume * 100.0 + 0.5);
1012 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
1013 {
1014 psg_config(0, config.psg_preamp, 0xff);
1015 }
1016 else
1017 {
1018 psg_config(0, config.psg_preamp, io_reg[6]);
1019 }
1020 break;
1021 }
1022
1023 case 6:
1024 {
1025 config.mono ^= 1;
1026 sprintf (items[6].text, "Audio Out: %s", config.mono ? "MONO":"STEREO");
1027 break;
1028 }
1029
1030 case 7:
1031 {
1032 config.filter = (config.filter + 1) % 3;
1033 if (config.filter == 2)
1034 {
1035 float lg = (float)config.lg/100.0;
1036 sprintf (items[7].text, "Filtering: 3-BAND EQ");
1037 sprintf (items[8].text, "Low Gain: %1.2f", lg);
1038 strcpy (items[8].comment, "Adjust EQ Low Band Gain");
1039 m->max_items = 13;
1040 audio_set_equalizer();
1041 }
1042 else if (config.filter == 1)
1043 {
1044 int lp_range = (config.lp_range * 100 + 0xffff) / 0x10000;
1045 sprintf (items[7].text, "Filtering: LOW-PASS");
1046 sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range);
1047 strcpy (items[8].comment, "Adjust Low Pass filter");
1048 m->max_items = 9;
1049 }
1050 else
1051 {
1052 sprintf (items[7].text, "Filtering: OFF");
1053 m->max_items = 8;
1054 }
1055
1056 while ((m->offset + 4) > m->max_items)
1057 {
1058 m->offset--;
1059 m->selected++;
1060 }
1061 break;
1062 }
1063
1064 case 8:
1065 {
1066 if (config.filter == 1)
1067 {
1068 int16 lp_range = (config.lp_range * 100 + 0xffff) / 0x10000;
1069 GUI_OptionBox(m,0,"Low-Pass Rate (%)",(void *)&lp_range,1,0,100,1);
1070 sprintf (items[8].text, "Low-Pass Rate: %d %%", lp_range);
1071 config.lp_range = (lp_range * 0x10000) / 100;
1072 }
1073 else
1074 {
1075 float lg = (float)config.lg/100.0;
1076 GUI_OptionBox(m,0,"Low Gain",(void *)&lg,0.01,0.0,2.0,0);
1077 sprintf (items[8].text, "Low Gain: %1.2f", lg);
1078 config.lg = (int)(lg * 100.0);
1079 audio_set_equalizer();
1080 }
1081 break;
1082 }
1083
1084 case 9:
1085 {
1086 float mg = (float)config.mg/100.0;
1087 GUI_OptionBox(m,0,"Middle Gain",(void *)&mg,0.01,0.0,2.0,0);
1088 sprintf (items[9].text, "Middle Gain: %1.2f", mg);
1089 config.mg = (int)(mg * 100.0);
1090 audio_set_equalizer();
1091 break;
1092 }
1093
1094 case 10:
1095 {
1096 float hg = (float)config.hg/100.0;
1097 GUI_OptionBox(m,0,"High Gain",(void *)&hg,0.01,0.0,2.0,0);
1098 sprintf (items[10].text, "High Gain: %1.2f", hg);
1099 config.hg = (int)(hg * 100.0);
1100 audio_set_equalizer();
1101 break;
1102 }
1103
1104 case 11:
1105 {
1106 GUI_OptionBox(m,0,"Low Frequency",(void *)&config.low_freq,10,0,config.high_freq,1);
1107 sprintf (items[11].text, "Low Freq: %d", config.low_freq);
1108 audio_set_equalizer();
1109 break;
1110 }
1111
1112 case 12:
1113 {
1114 GUI_OptionBox(m,0,"High Frequency",(void *)&config.high_freq,100,config.low_freq,30000,1);
1115 sprintf (items[12].text, "High Freq: %d", config.high_freq);
1116 audio_set_equalizer();
1117 break;
1118 }
1119
1120 case -1:
1121 {
1122 quit = 1;
1123 break;
1124 }
1125 }
1126 }
1127
1128 GUI_DeleteMenu(m);
1129 }
1130
1131 /****************************************************************************
1132 * System ROM paths menu
1133 *
1134 ****************************************************************************/
1135
rompathmenu()1136 static void rompathmenu ()
1137 {
1138 FILE *f;
1139 int i, ret;
1140 gui_menu *m = &menu_rompaths;
1141 gui_item *items = m->items;
1142
1143 for (i=0; i<12; i++)
1144 {
1145 f = fopen(config.sys_rom[i],"rb");
1146 if (f)
1147 {
1148 strcpy(strstr(items[i].text,":") + 2, "FOUND");
1149 fclose(f);
1150 }
1151 else
1152 {
1153 strcpy(strstr(items[i].text,":") + 2, "NOT FOUND");
1154 }
1155 }
1156
1157 GUI_InitMenu(m);
1158
1159 while (1)
1160 {
1161 ret = GUI_RunMenu(m);
1162
1163 if (ret < 0)
1164 {
1165 GUI_DeleteMenu(m);
1166 return;
1167 }
1168
1169 /* Initialize System ROM browser */
1170 if (OpenDirectory(config.l_device, ret + FILETYPE_MAX))
1171 {
1172 /* Get current System ROM path */
1173 char *dir = GetCurrentDirectory();
1174
1175 /* Open System ROM browser */
1176 GUI_DeleteMenu(m);
1177 i = FileSelector(ret + FILETYPE_MAX);
1178
1179 /* System ROM selected ? */
1180 if (i >= 0)
1181 {
1182 /* full System ROM pathname */
1183 sprintf(config.sys_rom[ret],"%s%s",dir,filelist[i].filename);
1184
1185 /* mark System ROM as found */
1186 strcpy(strstr(items[ret].text,":") + 2, "FOUND");
1187
1188 /* BOOT ROM special cases */
1189 switch (ret)
1190 {
1191 case 0:
1192 case 1:
1193 case 2:
1194 {
1195 /* force CD BOOT ROM reloading */
1196 system_bios &= ~0x10;
1197 break;
1198 }
1199
1200 case 3:
1201 {
1202 /* Genesis BOOT ROM must be reloaded */
1203 if (load_archive(MD_BIOS, boot_rom, 0x800, NULL) > 0)
1204 {
1205 /* check if BOOT ROM header is valid */
1206 if (!memcmp((char *)(boot_rom + 0x120),"GENESIS OS", 10))
1207 {
1208 /* mark Genesis BOOT ROM as loaded */
1209 system_bios |= SYSTEM_MD;
1210 }
1211 else
1212 {
1213 /* mark Genesis BOOT ROM as unloaded */
1214 system_bios &= ~SYSTEM_MD;
1215 }
1216 }
1217 break;
1218 }
1219
1220 case 4:
1221 case 5:
1222 case 6:
1223 {
1224 /* force Master System BOOT ROM reloading */
1225 system_bios &= ~SYSTEM_SMS;
1226 break;
1227 }
1228
1229 case 7:
1230 {
1231 /* force Game Gear BOOT ROM reloading */
1232 system_bios &= ~SYSTEM_GG;
1233 break;
1234 }
1235
1236 default:
1237 {
1238 /* not a BOOT ROM */
1239 break;
1240 }
1241 }
1242 }
1243
1244 free(dir);
1245 GUI_InitMenu(m);
1246 }
1247 }
1248 }
1249
1250 /****************************************************************************
1251 * System Settings menu
1252 *
1253 ****************************************************************************/
1254 static const uint16 vc_table[4][2] =
1255 {
1256 /* NTSC, PAL */
1257 {0xDA , 0xF2}, /* Mode 4 (192 lines) */
1258 {0xEA , 0x102}, /* Mode 5 (224 lines) */
1259 {0xDA , 0xF2}, /* Mode 4 (192 lines) */
1260 {0x106, 0x10A} /* Mode 5 (240 lines) */
1261 };
1262
systemmenu()1263 static void systemmenu ()
1264 {
1265 int ret, quit = 0;
1266 int reinit = 0;
1267 gui_menu *m = &menu_system;
1268 gui_item *items = m->items;
1269
1270 if (config.system == 0)
1271 sprintf (items[0].text, "Console Type: AUTO");
1272 else if (config.system == SYSTEM_SG)
1273 sprintf (items[0].text, "Console Type: SG-1000");
1274 else if (config.system == SYSTEM_SGII)
1275 sprintf (items[0].text, "Console Type: SG-1000 II");
1276 else if (config.system == SYSTEM_MARKIII)
1277 sprintf (items[0].text, "Console Type: MARK-III");
1278 else if (config.system == SYSTEM_SMS)
1279 sprintf (items[0].text, "Console Type: SMS");
1280 else if (config.system == SYSTEM_SMS2)
1281 sprintf (items[0].text, "Console Type: SMS II");
1282 else if (config.system == SYSTEM_GG)
1283 sprintf (items[0].text, "Console Type: GG");
1284 else if (config.system == SYSTEM_MD)
1285 sprintf (items[0].text, "Console Type: MD");
1286
1287 if (config.region_detect == 0)
1288 sprintf (items[1].text, "Console Region: AUTO");
1289 else if (config.region_detect == 1)
1290 sprintf (items[1].text, "Console Region: USA");
1291 else if (config.region_detect == 2)
1292 sprintf (items[1].text, "Console Region: PAL");
1293 else if (config.region_detect == 3)
1294 sprintf (items[1].text, "Console Region: JAP");
1295
1296 if (config.vdp_mode == 0)
1297 sprintf (items[2].text, "VDP Mode: AUTO");
1298 else if (config.vdp_mode == 1)
1299 sprintf (items[2].text, "VDP Mode: NTSC");
1300 else if (config.vdp_mode == 2)
1301 sprintf (items[2].text, "VDP Mode: PAL");
1302
1303 if (config.master_clock == 0)
1304 sprintf (items[3].text, "System Clock: AUTO");
1305 else if (config.master_clock == 1)
1306 sprintf (items[3].text, "System Clock: NTSC");
1307 else if (config.master_clock == 2)
1308 sprintf (items[3].text, "System Clock: PAL");
1309
1310 sprintf (items[4].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART" : "BIOS ONLY") : "CART");
1311 sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
1312 sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
1313
1314 if (config.lock_on == TYPE_GG)
1315 sprintf (items[7].text, "Lock-On: GAME GENIE");
1316 else if (config.lock_on == TYPE_AR)
1317 sprintf (items[7].text, "Lock-On: ACTION REPLAY");
1318 else if (config.lock_on == TYPE_SK)
1319 sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES");
1320 else
1321 sprintf (items[7].text, "Lock-On: OFF");
1322
1323 sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF");
1324
1325 if (svp)
1326 {
1327 sprintf (items[10].text, "SVP Cycles: %d", SVP_cycles);
1328 m->max_items = 11;
1329 }
1330 else
1331 {
1332 m->max_items = 10;
1333 }
1334
1335 GUI_InitMenu(m);
1336 GUI_SlideMenuTitle(m,strlen("System "));
1337
1338 while (quit == 0)
1339 {
1340 ret = GUI_RunMenu(m);
1341
1342 switch (ret)
1343 {
1344 case 0: /*** Force System Hardware ***/
1345 {
1346 if (config.system == SYSTEM_MD)
1347 {
1348 config.system = 0;
1349 sprintf (items[0].text, "Console Type: AUTO");
1350
1351 /* Default system hardware (auto) */
1352 if (system_hw) system_hw = romtype;
1353 }
1354 else if (config.system == 0)
1355 {
1356 config.system = SYSTEM_SG;
1357 sprintf (items[0].text, "Console Type: SG-1000");
1358 if (system_hw) system_hw = SYSTEM_SG;
1359 }
1360 else if (config.system == SYSTEM_SG)
1361 {
1362 config.system = SYSTEM_SGII;
1363 sprintf (items[0].text, "Console Type: SG-1000 II");
1364 if (system_hw) system_hw = SYSTEM_SGII;
1365 }
1366 else if (config.system == SYSTEM_SGII)
1367 {
1368 config.system = SYSTEM_MARKIII;
1369 sprintf (items[0].text, "Console Type: MARK-III");
1370 if (system_hw) system_hw = SYSTEM_MARKIII;
1371 }
1372 else if (config.system == SYSTEM_MARKIII)
1373 {
1374 config.system = SYSTEM_SMS;
1375 sprintf (items[0].text, "Console Type: SMS");
1376 if (system_hw) system_hw = SYSTEM_SMS;
1377 }
1378 else if (config.system == SYSTEM_SMS)
1379 {
1380 config.system = SYSTEM_SMS2;
1381 sprintf (items[0].text, "Console Type: SMS II");
1382 if (system_hw) system_hw = SYSTEM_SMS2;
1383 }
1384 else if (config.system == SYSTEM_SMS2)
1385 {
1386 config.system = SYSTEM_GG;
1387 sprintf (items[0].text, "Console Type: GG");
1388
1389 if (romtype == SYSTEM_GG)
1390 {
1391 /* Game Gear mode */
1392 if (system_hw) system_hw = SYSTEM_GG;
1393 }
1394 else
1395 {
1396 /* Game Gear in MS compatibility mode */
1397 if (system_hw) system_hw = SYSTEM_GGMS;
1398 }
1399 }
1400 else if (config.system == SYSTEM_GG)
1401 {
1402 config.system = SYSTEM_MD;
1403 sprintf (items[0].text, "Console Type: MD");
1404
1405 if (romtype & SYSTEM_MD)
1406 {
1407 /* Default mode */
1408 if (system_hw) system_hw = romtype;
1409 }
1410 else
1411 {
1412 /* Mega Drive in MS compatibility mode */
1413 if (system_hw) system_hw = SYSTEM_PBC;
1414 }
1415 }
1416
1417 if (system_hw)
1418 {
1419 /* restore previous input settings */
1420 if (old_system[0] != -1)
1421 {
1422 input.system[0] = old_system[0];
1423 }
1424 if (old_system[1] != -1)
1425 {
1426 input.system[1] = old_system[1];
1427 }
1428
1429 /* reinitialize audio streams */
1430 audio_init(snd.sample_rate, snd.frame_rate);
1431
1432 /* force hard reset */
1433 system_init();
1434 system_reset();
1435
1436 /* restore SRAM */
1437 slot_autoload(0,config.s_device);
1438 }
1439
1440 break;
1441 }
1442
1443 case 1: /*** Force Region ***/
1444 {
1445 config.region_detect = (config.region_detect + 1) % 4;
1446 if (config.region_detect == 0)
1447 sprintf (items[1].text, "Console Region: AUTO");
1448 else if (config.region_detect == 1)
1449 sprintf (items[1].text, "Console Region: USA");
1450 else if (config.region_detect == 2)
1451 sprintf (items[1].text, "Console Region: PAL");
1452 else if (config.region_detect == 3)
1453 sprintf (items[1].text, "Console Region: JAP");
1454
1455 /* force system reinitialization + region BIOS */
1456 reinit = 2;
1457 break;
1458 }
1459
1460 case 2: /*** Force VDP mode ***/
1461 {
1462 config.vdp_mode = (config.vdp_mode + 1) % 3;
1463 if (config.vdp_mode == 0)
1464 sprintf (items[2].text, "VDP Mode: AUTO");
1465 else if (config.vdp_mode == 1)
1466 sprintf (items[2].text, "VDP Mode: NTSC");
1467 else if (config.vdp_mode == 2)
1468 sprintf (items[2].text, "VDP Mode: PAL");
1469
1470 /* force system reinitialization */
1471 reinit = 1;
1472 break;
1473 }
1474
1475 case 3: /*** Force Master Clock ***/
1476 {
1477 config.master_clock = (config.master_clock + 1) % 3;
1478 if (config.master_clock == 0)
1479 sprintf (items[3].text, "System Clock: AUTO");
1480 else if (config.master_clock == 1)
1481 sprintf (items[3].text, "System Clock: NTSC");
1482 else if (config.master_clock == 2)
1483 sprintf (items[3].text, "System Clock: PAL");
1484
1485 /* force system reinitialization */
1486 reinit = 1;
1487 break;
1488 }
1489
1490 case 4: /*** BIOS support ***/
1491 {
1492 if (config.bios == 0) config.bios = 3;
1493 else if (config.bios == 3) config.bios = 1;
1494 else config.bios = 0;
1495 sprintf (items[4].text, "System Boot: %s", (config.bios & 1) ? ((config.bios & 2) ? "BIOS&CART " : "BIOS ONLY") : "CART");
1496 if ((system_hw == SYSTEM_MD) || (system_hw & SYSTEM_GG) || (system_hw & SYSTEM_SMS))
1497 {
1498 /* force hard reset */
1499 system_init();
1500 system_reset();
1501
1502 /* restore SRAM */
1503 slot_autoload(0,config.s_device);
1504 }
1505 break;
1506 }
1507
1508 case 5: /*** force DTACK ***/
1509 {
1510 config.force_dtack ^= 1;
1511 sprintf (items[5].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
1512 break;
1513 }
1514
1515 case 6: /*** 68k Address Error ***/
1516 {
1517 config.addr_error ^= 1;
1518 m68k.aerr_enabled = config.addr_error;
1519 sprintf (items[6].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
1520 break;
1521 }
1522
1523 case 7: /*** Cart Lock-On ***/
1524 {
1525 config.lock_on = (config.lock_on + 1) % (TYPE_SK + 1);
1526 if (config.lock_on == TYPE_GG)
1527 sprintf (items[7].text, "Lock-On: GAME GENIE");
1528 else if (config.lock_on == TYPE_AR)
1529 sprintf (items[7].text, "Lock-On: ACTION REPLAY");
1530 else if (config.lock_on == TYPE_SK)
1531 sprintf (items[7].text, "Lock-On: SONIC&KNUCKLES");
1532 else
1533 sprintf (items[7].text, "Lock-On: OFF");
1534
1535 if ((system_hw == SYSTEM_MD) || (system_hw == SYSTEM_PICO))
1536 {
1537 /* force hard reset */
1538 system_init();
1539 system_reset();
1540
1541 /* restore SRAM */
1542 slot_autoload(0,config.s_device);
1543
1544 /* Action Replay switch */
1545 if (areplay_get_status() < 0)
1546 {
1547 menu_main.buttons[6].state &= ~(BUTTON_VISIBLE | BUTTON_ACTIVE);
1548 menu_main.items[6].data = NULL;
1549 menu_main.cb = NULL;
1550 menu_main.buttons[3].shift[1] = 4;
1551 menu_main.buttons[7].shift[0] = 4;
1552 menu_main.buttons[8].shift[2] = 1;
1553 }
1554 else
1555 {
1556 menu_main.buttons[6].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
1557 menu_main.items[6].data = Button_sm_grey_png;
1558 menu_main.cb = mainmenu_cb;
1559 menu_main.buttons[3].shift[1] = 3;
1560 menu_main.buttons[7].shift[0] = 1;
1561 menu_main.buttons[8].shift[2] = 2;
1562 }
1563 }
1564 break;
1565 }
1566
1567 case 8: /*** Cartridge Hot Swap ***/
1568 {
1569 config.hot_swap ^= 1;
1570 sprintf (items[8].text, "Cartridge Swap: %s", (config.hot_swap & 1) ? "ON":"OFF");
1571 break;
1572 }
1573
1574 case 9: /*** System ROM paths ***/
1575 {
1576 GUI_DeleteMenu(m);
1577 rompathmenu();
1578 GUI_InitMenu(m);
1579 break;
1580 }
1581
1582 case 10: /*** SVP cycles per line ***/
1583 {
1584 GUI_OptionBox(m,0,"SVP Cycles",(void *)&SVP_cycles,1,1,1500,1);
1585 sprintf (items[10].text, "SVP Cycles: %d", SVP_cycles);
1586 break;
1587 }
1588
1589 case -1:
1590 {
1591 quit = 1;
1592 break;
1593 }
1594 }
1595 }
1596
1597 if (reinit && system_hw)
1598 {
1599 /* reinitialize console region */
1600 get_region(NULL);
1601
1602 /* framerate might have changed, reinitialize audio timings */
1603 audio_init(snd.sample_rate, get_framerate());
1604
1605 /* system with region BIOS should be reinitialized if region code has changed */
1606 if ((reinit & 2) && ((system_hw == SYSTEM_MCD) || ((system_hw & SYSTEM_SMS) && (config.bios & 1))))
1607 {
1608 system_init();
1609 system_reset();
1610
1611 /* restore SRAM */
1612 slot_autoload(0,config.s_device);
1613 }
1614 else
1615 {
1616 /* reinitialize I/O region register */
1617 if (system_hw == SYSTEM_MD)
1618 {
1619 io_reg[0x00] = 0x20 | region_code | (config.bios & 1);
1620 }
1621 else if (system_hw == SYSTEM_MCD)
1622 {
1623 io_reg[0x00] = region_code | (config.bios & 1);
1624 }
1625 else
1626 {
1627 io_reg[0x00] = 0x80 | (region_code >> 1);
1628 }
1629
1630 /* reinitialize VDP timings */
1631 lines_per_frame = vdp_pal ? 313 : 262;
1632
1633 /* reinitialize NTSC/PAL mode in VDP status */
1634 if (system_hw & SYSTEM_MD)
1635 {
1636 status = (status & ~1) | vdp_pal;
1637 }
1638
1639 /* reinitialize VC max value */
1640 switch (bitmap.viewport.h)
1641 {
1642 case 192:
1643 vc_max = vc_table[0][vdp_pal];
1644 break;
1645 case 224:
1646 vc_max = vc_table[1][vdp_pal];
1647 break;
1648 case 240:
1649 vc_max = vc_table[3][vdp_pal];
1650 break;
1651 }
1652 }
1653 }
1654
1655 GUI_DeleteMenu(m);
1656 }
1657
1658 /****************************************************************************
1659 * Video Settings menu
1660 *
1661 ****************************************************************************/
1662 #ifdef HW_RVL
1663 #define VI_OFFSET 7
update_gamma(void)1664 static void update_gamma(void)
1665 {
1666 VIDEO_SetGamma((int)(config.gamma * 10.0));
1667 VIDEO_Flush();
1668 }
1669 #else
1670 #define VI_OFFSET 5
1671 #endif
1672
videomenu()1673 static void videomenu ()
1674 {
1675 u16 state[2];
1676 int ret, quit = 0;
1677 int reinit = 0;
1678 gui_menu *m = &menu_video;
1679 gui_item *items = m->items;
1680 int ntsc_offset = 0;
1681
1682 if (config.render == 1)
1683 sprintf (items[0].text,"Display: INTERLACED");
1684 else if (config.render == 2)
1685 sprintf (items[0].text, "Display: PROGRESSIVE");
1686 else
1687 sprintf (items[0].text, "Display: ORIGINAL");
1688
1689 if (config.tv_mode == 0)
1690 sprintf (items[1].text, "TV Mode: 60HZ");
1691 else if (config.tv_mode == 1)
1692 sprintf (items[1].text, "TV Mode: 50HZ");
1693 else
1694 sprintf (items[1].text, "TV Mode: 50/60HZ");
1695
1696 if (config.vsync)
1697 sprintf (items[2].text, "VSYNC: AUTO");
1698 else
1699 sprintf (items[2].text, "VSYNC: OFF");
1700
1701 sprintf (items[3].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
1702 sprintf (items[4].text, "Deflickering Filter: %s", config.vfilter ? "AUTO" : "OFF");
1703
1704 #ifdef HW_RVL
1705 sprintf (items[5].text, "Trap Filter: %s", config.trap ? " ON" : "OFF");
1706 sprintf (items[6].text, "Gamma Correction: %1.1f", config.gamma);
1707 #endif
1708
1709 if (config.lcd > 0)
1710 {
1711 int ratio = ((config.lcd * 100) + 254) / 255;
1712 sprintf (items[VI_OFFSET].text, "LCD Ghosting Filter: %d%%", ratio);
1713 }
1714 else
1715 {
1716 sprintf (items[VI_OFFSET].text, "LCD Ghosting Filter: OFF");
1717 }
1718
1719 if (config.ntsc == 1)
1720 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: COMPOSITE");
1721 else if (config.ntsc == 2)
1722 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: S-VIDEO");
1723 else if (config.ntsc == 3)
1724 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: RGB");
1725 else if (config.ntsc == 4)
1726 {
1727 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: MANUAL");
1728 sprintf(items[VI_OFFSET+2].text, "NTSC Sharpness: %1.2f", config.ntsc_sharpness);
1729 sprintf(items[VI_OFFSET+3].text, "NTSC Resolution: %1.2f", config.ntsc_resolution);
1730 sprintf(items[VI_OFFSET+4].text, "NTSC Artifacts: %1.2f", config.ntsc_artifacts);
1731 sprintf(items[VI_OFFSET+5].text, "NTSC Color Bleed: %1.2f", config.ntsc_bleed);
1732 sprintf(items[VI_OFFSET+6].text, "NTSC Color Fringing: %1.2f", config.ntsc_fringing);
1733 strcpy(items[VI_OFFSET+2].comment, "Adjust edge contrast enhancement/blurring");
1734 strcpy(items[VI_OFFSET+3].comment, "Adjust image resolution");
1735 strcpy(items[VI_OFFSET+4].comment, "Adjust artifacts caused by color changes");
1736 strcpy(items[VI_OFFSET+5].comment, "Adjust color resolution reduction");
1737 strcpy(items[VI_OFFSET+6].comment, "Adjust artifacts caused by brightness changes");
1738 ntsc_offset = 5;
1739 }
1740 else
1741 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: OFF");
1742
1743 strcpy(items[VI_OFFSET+2+ntsc_offset].comment, "Enable/Disable overscan emulation");
1744 strcpy(items[VI_OFFSET+3+ntsc_offset].comment, "Enable/Disable Game Gear extended screen");
1745 strcpy(items[VI_OFFSET+4+ntsc_offset].comment, "Select display aspect ratio");
1746 strcpy(items[VI_OFFSET+5+ntsc_offset].comment, "Adjust display position");
1747 strcpy(items[VI_OFFSET+6+ntsc_offset].comment, "Adjust display scaling");
1748
1749 if (config.overscan == 3)
1750 sprintf (items[VI_OFFSET+2+ntsc_offset].text, "Borders: FULL");
1751 else if (config.overscan == 2)
1752 sprintf (items[VI_OFFSET+2+ntsc_offset].text, "Borders: H ONLY");
1753 else if (config.overscan == 1)
1754 sprintf (items[VI_OFFSET+2+ntsc_offset].text, "Borders: V ONLY");
1755 else
1756 sprintf (items[VI_OFFSET+2+ntsc_offset].text, "Borders: NONE");
1757
1758 sprintf(items[VI_OFFSET+3+ntsc_offset].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL");
1759
1760 if (config.aspect == 1)
1761 sprintf (items[VI_OFFSET+4+ntsc_offset].text,"Aspect: ORIGINAL (4:3)");
1762 else if (config.aspect == 2)
1763 sprintf (items[VI_OFFSET+4+ntsc_offset].text, "Aspect: ORIGINAL (16:9)");
1764 else
1765 {
1766 sprintf (items[VI_OFFSET+4+ntsc_offset].text, "Aspect: SCALED");
1767 }
1768
1769 sprintf (items[VI_OFFSET+5+ntsc_offset].text, "Screen Position: (%s%02d,%s%02d)",
1770 (config.xshift < 0) ? "":"+", config.xshift,
1771 (config.yshift < 0) ? "":"+", config.yshift);
1772
1773 sprintf (items[VI_OFFSET+6+ntsc_offset].text, "Screen Scaling: (%s%02d,%s%02d)",
1774 (config.xscale < 0) ? "":"+", config.xscale,
1775 (config.yscale < 0) ? "":"+", config.yscale);
1776
1777 m->max_items = VI_OFFSET + 6 + ntsc_offset + (config.aspect == 0);
1778
1779 GUI_InitMenu(m);
1780 GUI_SlideMenuTitle(m,strlen("Video "));
1781
1782 while (quit == 0)
1783 {
1784 ret = GUI_RunMenu(m);
1785
1786 if (ret > (VI_OFFSET + 1))
1787 {
1788 ret += (5 - ntsc_offset);
1789 }
1790
1791 switch (ret)
1792 {
1793 case 0: /*** rendering ***/
1794 {
1795 config.render = (config.render + 1) % 3;
1796 if (config.render == 2)
1797 {
1798 /* progressive mode is only possible through component cable */
1799 if (!VIDEO_HaveComponentCable())
1800 {
1801 config.render = 0;
1802 }
1803 }
1804 if (config.render == 1)
1805 sprintf (items[0].text,"Display: INTERLACED");
1806 else if (config.render == 2)
1807 sprintf (items[0].text, "Display: PROGRESSIVE");
1808 else
1809 sprintf (items[0].text, "Display: ORIGINAL");
1810
1811 reinit = 1;
1812 break;
1813 }
1814
1815 case 1: /*** tv mode ***/
1816 {
1817 config.tv_mode = (config.tv_mode + 1) % 3;
1818 if (config.tv_mode == 0)
1819 sprintf (items[1].text, "TV Mode: 60HZ");
1820 else if (config.tv_mode == 1)
1821 sprintf (items[1].text, "TV Mode: 50HZ");
1822 else
1823 sprintf (items[1].text, "TV Mode: 50/60HZ");
1824 reinit = 1;
1825 break;
1826 }
1827
1828 case 2: /*** VSYNC ***/
1829 {
1830 config.vsync ^= 1;
1831 if (config.vsync)
1832 sprintf (items[2].text, "VSYNC: AUTO");
1833 else
1834 sprintf (items[2].text, "VSYNC: OFF");
1835 reinit = 1;
1836 break;
1837 }
1838
1839 case 3: /*** GX Texture filtering ***/
1840 {
1841 config.bilinear ^= 1;
1842 sprintf (items[3].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
1843 break;
1844 }
1845
1846 case 4: /*** GX Copy filtering (deflickering filter) ***/
1847 {
1848 config.vfilter ^= 1;
1849 sprintf (items[4].text, "Deflickering Filter: %s", config.vfilter ? "AUTO" : "OFF");
1850 break;
1851 }
1852
1853 #ifdef HW_RVL
1854 case 5: /*** VIDEO Trap filtering ***/
1855 {
1856 config.trap ^= 1;
1857 sprintf (items[5].text, "Trap Filter: %s", config.trap ? " ON" : "OFF");
1858 break;
1859 }
1860
1861 case 6: /*** VIDEO Gamma correction ***/
1862 {
1863 if (system_hw)
1864 {
1865 update_gamma();
1866 state[0] = m->arrows[0]->state;
1867 state[1] = m->arrows[1]->state;
1868 m->max_buttons = 0;
1869 m->max_images = 0;
1870 m->arrows[0]->state = 0;
1871 m->arrows[1]->state = 0;
1872 m->screenshot = 255;
1873 strcpy(m->title,"");
1874 GUI_OptionBox(m,update_gamma,"Gamma Correction",(void *)&config.gamma,0.1,0.1,3.0,0);
1875 m->max_buttons = 4;
1876 m->max_images = 6;
1877 m->arrows[0]->state = state[0];
1878 m->arrows[1]->state = state[1];
1879 m->screenshot = 0;
1880 strcpy(m->title,"Video Settings");
1881 sprintf (items[6].text, "Gamma Correction: %1.1f", config.gamma);
1882 VIDEO_SetGamma(VI_GM_1_0);
1883 VIDEO_Flush();
1884 }
1885 else
1886 {
1887 GUI_WaitPrompt("Error","Please load a game first !\n");
1888 }
1889 break;
1890 }
1891 #endif
1892
1893 case VI_OFFSET: /*** LCD filter (soft) ***/
1894 {
1895 if (config.ntsc)
1896 {
1897 GUI_WaitPrompt("Error","NTSC filter must be disabled\n");
1898 break;
1899 }
1900
1901 int16 ratio = ((config.lcd * 100) + 254) / 255;
1902 GUI_OptionBox(m,0,"LCD Ghosting Ratio (%)",(void *)&ratio,1,0,100,1);
1903 if (ratio > 0)
1904 {
1905 sprintf (items[VI_OFFSET].text, "LCD Ghosting Filter: %d%%", ratio);
1906 }
1907 else
1908 {
1909 sprintf (items[VI_OFFSET].text, "LCD Ghosting Filter: OFF");
1910 }
1911 config.lcd = (ratio * 255) / 100;
1912 break;
1913 }
1914
1915 case VI_OFFSET+1: /*** NTSC filter (soft) ***/
1916 {
1917 if (config.lcd)
1918 {
1919 GUI_WaitPrompt("Error","LCD filter must be disabled\n");
1920 break;
1921 }
1922
1923 config.ntsc = (config.ntsc + 1) % 5;
1924 if (config.ntsc == 1)
1925 {
1926 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: COMPOSITE");
1927 }
1928 else if (config.ntsc == 2)
1929 {
1930 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: S-VIDEO");
1931 }
1932 else if (config.ntsc == 3)
1933 {
1934 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: RGB");
1935 }
1936 else if (config.ntsc == 4)
1937 {
1938 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: MANUAL");
1939 strcpy(items[VI_OFFSET+5+2].text, items[VI_OFFSET+2].text);
1940 strcpy(items[VI_OFFSET+5+3].text, items[VI_OFFSET+3].text);
1941 strcpy(items[VI_OFFSET+5+4].text, items[VI_OFFSET+4].text);
1942 strcpy(items[VI_OFFSET+5+5].text, items[VI_OFFSET+5].text);
1943 strcpy(items[VI_OFFSET+5+6].text, items[VI_OFFSET+6].text);
1944 strcpy(items[VI_OFFSET+5+2].comment, items[VI_OFFSET+2].comment);
1945 strcpy(items[VI_OFFSET+5+3].comment, items[VI_OFFSET+3].comment);
1946 strcpy(items[VI_OFFSET+5+4].comment, items[VI_OFFSET+4].comment);
1947 strcpy(items[VI_OFFSET+5+5].comment, items[VI_OFFSET+5].comment);
1948 strcpy(items[VI_OFFSET+5+6].comment, items[VI_OFFSET+6].comment);
1949 sprintf(items[VI_OFFSET+2].text, "NTSC Sharpness: %1.1f", config.ntsc_sharpness);
1950 sprintf(items[VI_OFFSET+3].text, "NTSC Resolution: %1.1f", config.ntsc_resolution);
1951 sprintf(items[VI_OFFSET+4].text, "NTSC Artifacts: %1.1f", config.ntsc_artifacts);
1952 sprintf(items[VI_OFFSET+5].text, "NTSC Color Bleed: %1.1f", config.ntsc_bleed);
1953 sprintf(items[VI_OFFSET+6].text, "NTSC Color Fringing: %1.1f", config.ntsc_fringing);
1954 strcpy(items[VI_OFFSET+2].comment, "Adjust edge contrast enhancement/blurring");
1955 strcpy(items[VI_OFFSET+3].comment, "Adjust image resolution");
1956 strcpy(items[VI_OFFSET+4].comment, "Adjust artifacts caused by color changes");
1957 strcpy(items[VI_OFFSET+5].comment, "Adjust color resolution reduction");
1958 strcpy(items[VI_OFFSET+6].comment, "Adjust artifacts caused by brightness changes");
1959 ntsc_offset = 5;
1960 m->max_items = VI_OFFSET + 11 + (config.aspect == 0);
1961 }
1962 else
1963 {
1964 sprintf (items[VI_OFFSET+1].text, "NTSC Filter: OFF");
1965 strcpy(items[VI_OFFSET+2].text, items[VI_OFFSET+5+2].text);
1966 strcpy(items[VI_OFFSET+3].text, items[VI_OFFSET+5+3].text);
1967 strcpy(items[VI_OFFSET+4].text, items[VI_OFFSET+5+4].text);
1968 strcpy(items[VI_OFFSET+5].text, items[VI_OFFSET+5+5].text);
1969 strcpy(items[VI_OFFSET+6].text, items[VI_OFFSET+5+6].text);
1970 strcpy(items[VI_OFFSET+2].comment, items[VI_OFFSET+5+2].comment);
1971 strcpy(items[VI_OFFSET+3].comment, items[VI_OFFSET+5+3].comment);
1972 strcpy(items[VI_OFFSET+4].comment, items[VI_OFFSET+5+4].comment);
1973 strcpy(items[VI_OFFSET+5].comment, items[VI_OFFSET+5+5].comment);
1974 strcpy(items[VI_OFFSET+6].comment, items[VI_OFFSET+5+6].comment);
1975 ntsc_offset = 0;
1976 m->max_items = VI_OFFSET + 6 + (config.aspect == 0);
1977 }
1978 break;
1979 }
1980
1981 case VI_OFFSET+2: /*** NTSC Sharpness ***/
1982 GUI_OptionBox(m,update_bgm,"NTSC Sharpness",(void *)&config.ntsc_sharpness,0.01,-1.0,1.0,0);
1983 sprintf(items[VI_OFFSET+2].text, "NTSC Sharpness: %1.2f", config.ntsc_sharpness);
1984 break;
1985
1986 case VI_OFFSET+3: /*** NTSC Resolution ***/
1987 GUI_OptionBox(m,update_bgm,"NTSC Resolution",(void *)&config.ntsc_resolution,0.01,0.0,1.0,0);
1988 sprintf(items[VI_OFFSET+3].text, "NTSC Resolution: %1.2f", config.ntsc_resolution);
1989 break;
1990
1991 case VI_OFFSET+4: /*** NTSC Artifacts ***/
1992 GUI_OptionBox(m,update_bgm,"NTSC Artifacts",(void *)&config.ntsc_artifacts,0.01,-1.0,0.0,0);
1993 sprintf(items[VI_OFFSET+4].text, "NTSC Artifacts: %1.2f", config.ntsc_artifacts);
1994 break;
1995
1996 case VI_OFFSET+5: /*** NTSC Color Bleed ***/
1997 GUI_OptionBox(m,update_bgm,"NTSC Color Bleed",(void *)&config.ntsc_bleed,0.01,-1.0,1.0,0);
1998 sprintf(items[VI_OFFSET+5].text, "NTSC Color Bleed: %1.2f", config.ntsc_bleed);
1999 break;
2000
2001 case VI_OFFSET+6: /*** NTSC Color Fringing ***/
2002 GUI_OptionBox(m,update_bgm,"NTSC Color Fringing",(void *)&config.ntsc_fringing,0.01,-1.0,1.0,0);
2003 sprintf(items[VI_OFFSET+6].text, "NTSC Color Fringing: %1.2f", config.ntsc_fringing);
2004 break;
2005
2006 case VI_OFFSET+7: /*** overscan emulation ***/
2007 {
2008 config.overscan = (config.overscan + 1) & 3;
2009 if (config.overscan == 3)
2010 sprintf (items[VI_OFFSET+ntsc_offset+2].text, "Borders: FULL");
2011 else if (config.overscan == 2)
2012 sprintf (items[VI_OFFSET+ntsc_offset+2].text, "Borders: H ONLY");
2013 else if (config.overscan == 1)
2014 sprintf (items[VI_OFFSET+ntsc_offset+2].text, "Borders: V ONLY");
2015 else
2016 sprintf (items[VI_OFFSET+ntsc_offset+2].text, "Borders: NONE");
2017 break;
2018 }
2019
2020 case VI_OFFSET+8: /*** Game Gear extended screen */
2021 {
2022 config.gg_extra ^= 1;
2023 sprintf(items[VI_OFFSET+ntsc_offset+3].text, "GG Screen: %s", config.gg_extra ? "EXTENDED":"ORIGINAL");
2024 break;
2025 }
2026
2027 case VI_OFFSET+9: /*** aspect ratio ***/
2028 {
2029 config.aspect = (config.aspect + 1) % 3;
2030 if (config.aspect == 1)
2031 sprintf (items[VI_OFFSET+ntsc_offset+4].text,"Aspect: ORIGINAL (4:3)");
2032 else if (config.aspect == 2)
2033 sprintf (items[VI_OFFSET+ntsc_offset+4].text, "Aspect: ORIGINAL (16:9)");
2034 else
2035 sprintf (items[VI_OFFSET+ntsc_offset+4].text, "Aspect: SCALED");
2036
2037 if (config.aspect)
2038 {
2039 /* disable items */
2040 m->max_items = VI_OFFSET + ntsc_offset + 6;
2041
2042 /* reset menu selection */
2043 if (m->selected < 2)
2044 {
2045 m->offset = VI_OFFSET + ntsc_offset + 2;
2046 m->selected = 2;
2047 }
2048 }
2049 else
2050 {
2051 /* enable items */
2052 m->max_items = VI_OFFSET + ntsc_offset + 7;
2053 }
2054 break;
2055 }
2056
2057 case VI_OFFSET+10: /*** screen position ***/
2058 {
2059 if (system_hw)
2060 {
2061 state[0] = m->arrows[0]->state;
2062 state[1] = m->arrows[1]->state;
2063 m->max_buttons = 0;
2064 m->max_images = 0;
2065 m->arrows[0]->state = 0;
2066 m->arrows[1]->state = 0;
2067 m->screenshot = 255;
2068 strcpy(m->title,"");
2069 GUI_OptionBox2(m,"X Offset","Y Offset",&config.xshift,&config.yshift,1,-99,99);
2070 m->max_buttons = 4;
2071 m->max_images = 6;
2072 m->arrows[0]->state = state[0];
2073 m->arrows[1]->state = state[1];
2074 m->screenshot = 0;
2075 strcpy(m->title,"Video Settings");
2076 sprintf (items[VI_OFFSET+ntsc_offset+5].text, "Screen Position: (%s%02d,%s%02d)",
2077 (config.xshift < 0) ? "":"+", config.xshift,
2078 (config.yshift < 0) ? "":"+", config.yshift);
2079 }
2080 else
2081 {
2082 GUI_WaitPrompt("Error","Please load a game first !\n");
2083 }
2084 break;
2085 }
2086
2087 case VI_OFFSET+11: /*** screen scaling ***/
2088 {
2089 if (system_hw)
2090 {
2091 state[0] = m->arrows[0]->state;
2092 state[1] = m->arrows[1]->state;
2093 m->max_buttons = 0;
2094 m->max_images = 0;
2095 m->arrows[0]->state = 0;
2096 m->arrows[1]->state = 0;
2097 m->screenshot = 255;
2098 strcpy(m->title,"");
2099 GUI_OptionBox2(m,"X Scale","Y Scale",&config.xscale,&config.yscale,1,-99,99);
2100 m->max_buttons = 4;
2101 m->max_images = 6;
2102 m->arrows[0]->state = state[0];
2103 m->arrows[1]->state = state[1];
2104 m->screenshot = 0;
2105 strcpy(m->title,"Video Settings");
2106 sprintf (items[VI_OFFSET+ntsc_offset+6].text, "Screen Scaling: (%s%02d,%s%02d)",
2107 (config.xscale < 0) ? "":"+", config.xscale,
2108 (config.yscale < 0) ? "":"+", config.yscale);
2109 }
2110 else
2111 {
2112 GUI_WaitPrompt("Error","Please load a game first !\n");
2113 }
2114 break;
2115 }
2116
2117 case -1:
2118 {
2119 quit = 1;
2120 break;
2121 }
2122 }
2123 }
2124
2125 if (reinit && system_hw)
2126 {
2127 /* framerate might have changed, reinitialize audio timings */
2128 audio_init(snd.sample_rate, get_framerate());
2129 }
2130
2131 GUI_DeleteMenu(m);
2132 }
2133
2134 /****************************************************************************
2135 * Controllers Settings menu
2136 ****************************************************************************/
2137 static int player = 0;
ctrlmenu_cb(void)2138 static void ctrlmenu_cb(void)
2139 {
2140 int i, cnt = 1;
2141 char msg[16];
2142 gui_menu *m = &menu_ctrls;
2143
2144 if (m->bg_images[7].state & IMAGE_VISIBLE)
2145 {
2146 /* draw device port number */
2147 if (config.input[player].device != -1)
2148 {
2149 sprintf(msg,"%d",config.input[player].port + 1);
2150 if (m->selected == 11)
2151 FONT_write(msg,16,m->items[11].x+m->items[11].w+2,m->items[11].y+m->items[11].h+2,640,(GXColor)DARK_GREY);
2152 else
2153 FONT_write(msg,14,m->items[11].x+m->items[11].w,m->items[11].y+m->items[11].h,640,(GXColor)DARK_GREY);
2154 }
2155 }
2156
2157 /* draw players index */
2158 for (i=2; i<MAX_DEVICES+2; i++)
2159 {
2160 if (m->selected == i)
2161 {
2162 FONT_writeCenter("Player", 16, m->buttons[i].x + 2, m->buttons[i].x + 54, m->buttons[i].y + (m->buttons[i].h - 16)/2 + 16, (GXColor)DARK_GREY);
2163 }
2164 else
2165 {
2166 FONT_writeCenter("Player", 14, m->buttons[i].x + 4, m->buttons[i].x + 54, m->buttons[i].y + (m->buttons[i].h - 14)/2 + 14, (GXColor)DARK_GREY);
2167 }
2168
2169 if (input.dev[i-2] != NO_DEVICE)
2170 {
2171 sprintf(msg,"%d",cnt++);
2172 if (m->selected == i)
2173 {
2174 FONT_writeCenter(msg,18,m->items[i].x+2,m->items[i].x+m->items[i].w+2,m->buttons[i].y+(m->buttons[i].h-18)/2+18,(GXColor)DARK_GREY);
2175 }
2176 else
2177 {
2178 FONT_writeCenter(msg,16,m->items[i].x,m->items[i].x+m->items[i].w,m->buttons[i].y+(m->buttons[i].h - 16)/2+16,(GXColor)DARK_GREY);
2179 }
2180 }
2181 }
2182 }
2183
2184 /* Set menu elements depending on current system configuration */
ctrlmenu_raz(void)2185 static void ctrlmenu_raz(void)
2186 {
2187 int i,max = 0;
2188 gui_menu *m = &menu_ctrls;
2189
2190 /* update players buttons */
2191 for (i=0; i<MAX_DEVICES; i++)
2192 {
2193 if (input.dev[i] == NO_DEVICE)
2194 {
2195 m->buttons[i+2].data = &button_player_none_data;
2196 m->buttons[i+2].state &= ~BUTTON_ACTIVE;
2197 strcpy(m->items[i+2].comment,"");
2198 }
2199 else
2200 {
2201 m->buttons[i+2].data = &button_player_data;
2202 m->buttons[i+2].state |= BUTTON_ACTIVE;
2203 if ((cart.special & HW_J_CART) && (i > 4))
2204 sprintf(m->items[i+2].comment,"Configure Player %d (J-CART) settings", max + 1);
2205 else
2206 sprintf(m->items[i+2].comment,"Configure Player %d settings", max + 1);
2207 max++;
2208 }
2209 }
2210
2211 /* update buttons navigation */
2212 if (input.dev[0] != NO_DEVICE)
2213 m->buttons[0].shift[3] = 2;
2214 else if (input.dev[4] != NO_DEVICE)
2215 m->buttons[0].shift[3] = 6;
2216 else if (input.dev[5] != NO_DEVICE)
2217 m->buttons[0].shift[3] = 7;
2218 else
2219 m->buttons[0].shift[3] = 0;
2220 if (input.dev[4] != NO_DEVICE)
2221 m->buttons[1].shift[3] = 5;
2222 else if (input.dev[5] != NO_DEVICE)
2223 m->buttons[1].shift[3] = 6;
2224 else if (input.dev[0] != NO_DEVICE)
2225 m->buttons[1].shift[3] = 1;
2226 else
2227 m->buttons[1].shift[3] = 0;
2228
2229 if (input.dev[1] != NO_DEVICE)
2230 m->buttons[2].shift[1] = 1;
2231 else if (input.dev[4] != NO_DEVICE)
2232 m->buttons[2].shift[1] = 4;
2233 else if (input.dev[5] != NO_DEVICE)
2234 m->buttons[2].shift[1] = 5;
2235 else
2236 m->buttons[2].shift[1] = 0;
2237
2238 if (input.dev[4] != NO_DEVICE)
2239 m->buttons[5].shift[1] = 1;
2240 else if (input.dev[5] != NO_DEVICE)
2241 m->buttons[5].shift[1] = 2;
2242 else
2243 m->buttons[5].shift[1] = 0;
2244
2245 if (input.dev[3] != NO_DEVICE)
2246 m->buttons[6].shift[0] = 1;
2247 else if (input.dev[0] != NO_DEVICE)
2248 m->buttons[6].shift[0] = 4;
2249 else
2250 m->buttons[6].shift[0] = 0;
2251
2252 if (input.dev[5] != NO_DEVICE)
2253 m->buttons[6].shift[1] = 1;
2254 else
2255 m->buttons[6].shift[1] = 0;
2256
2257 if (input.dev[6] != NO_DEVICE)
2258 m->buttons[7].shift[1] = 1;
2259 else
2260 m->buttons[7].shift[1] = 0;
2261
2262 if (input.dev[7] != NO_DEVICE)
2263 m->buttons[8].shift[1] = 1;
2264 else
2265 m->buttons[8].shift[1] = 0;
2266
2267 if (input.dev[4] != NO_DEVICE)
2268 m->buttons[7].shift[0] = 1;
2269 else if (input.dev[3] != NO_DEVICE)
2270 m->buttons[7].shift[0] = 2;
2271 else if (input.dev[0] != NO_DEVICE)
2272 m->buttons[7].shift[0] = 5;
2273 else
2274 m->buttons[7].shift[0] = 0;
2275 }
2276
ctrlmenu(void)2277 static void ctrlmenu(void)
2278 {
2279 int old_player = -1;
2280 int i = 0;
2281 int update = 0;
2282 gui_item *items = NULL;
2283 u8 *special = NULL;
2284 u32 exp, index = 0;
2285
2286 /* System devices */
2287 gui_item items_sys[2][14] =
2288 {
2289 {
2290 {NULL,Ctrl_none_png ,"","Select Port 1 device",110,130,48,72},
2291 {NULL,Ctrl_gamepad_png ,"","Select Port 1 device",100,109,68,92},
2292 {NULL,Ctrl_mouse_png ,"","Select Port 1 device", 97,113,64,88},
2293 {NULL,Ctrl_menacer_png ,"","Select Port 1 device", 94,113,80,88},
2294 {NULL,Ctrl_justifiers_png ,"","Select Port 1 device", 88,117,80,84},
2295 {NULL,Ctrl_xe_1ap_png ,"","Select Port 1 device", 98,118,72,84},
2296 {NULL,Ctrl_activator_png ,"","Select Port 1 device", 94,121,72,80},
2297 {NULL,Ctrl_lightphaser_png ,"","Select Port 1 device", 89,109,88,92},
2298 {NULL,Ctrl_paddle_png ,"","Select Port 1 device", 86,117,96,84},
2299 {NULL,Ctrl_sportspad_png ,"","Select Port 1 device", 95,117,76,84},
2300 {NULL,Ctrl_graphic_board_png ,"","Select Port 1 device", 90,105,88,96},
2301 {NULL,Ctrl_mastertap_png ,"","Select Port 1 device", 96,104,76,96},
2302 {NULL,Ctrl_teamplayer_png ,"","Select Port 1 device", 94,109,80,92},
2303 {NULL,Ctrl_4wayplay_png ,"","Select Port 1 device", 98,110,72,92}
2304 },
2305 {
2306 {NULL,Ctrl_none_png ,"","Select Port 2 device",110,300,48,72},
2307 {NULL,Ctrl_gamepad_png ,"","Select Port 2 device",100,279,68,92},
2308 {NULL,Ctrl_mouse_png ,"","Select Port 2 device", 97,283,64,88},
2309 {NULL,Ctrl_menacer_png ,"","Select Port 2 device", 94,283,80,88},
2310 {NULL,Ctrl_justifiers_png ,"","Select Port 2 device", 88,287,80,84},
2311 {NULL,Ctrl_xe_1ap_png ,"","Select Port 2 device", 98,288,72,84},
2312 {NULL,Ctrl_activator_png ,"","Select Port 2 device", 94,291,72,80},
2313 {NULL,Ctrl_lightphaser_png ,"","Select Port 2 device", 89,279,88,92},
2314 {NULL,Ctrl_paddle_png ,"","Select Port 2 device", 86,287,96,84},
2315 {NULL,Ctrl_sportspad_png ,"","Select Port 2 device", 95,287,76,84},
2316 {NULL,Ctrl_graphic_board_png ,"","Select Port 2 device", 90,275,88,96},
2317 {NULL,Ctrl_mastertap_png ,"","Select Port 1 device", 96,274,76,96},
2318 {NULL,Ctrl_teamplayer_png ,"","Select Port 2 device", 94,279,80,92},
2319 {NULL,Ctrl_4wayplay_png ,"","Select Port 2 device", 98,280,72,92}
2320 }
2321 };
2322
2323 /* Specific controller options */
2324 gui_item items_special[4][4] =
2325 {
2326 {
2327 /* Gamepad option */
2328 {NULL,Ctrl_pad3b_png,"Pad\nType","Use 3-buttons Pad",528,180,44,28},
2329 {NULL,Ctrl_pad6b_png,"Pad\nType","Use 6-buttons Pad",528,180,44,28},
2330 {NULL,Ctrl_pad2b_png,"Pad\nType","Use 2-buttons Pad",528,180,44,28},
2331 {NULL,Ctrl_pad_auto_png,"Pad\nType","Auto-detect Pad type",528,180,44,28},
2332 },
2333 {
2334 /* Mouse option */
2335 {NULL,ctrl_option_off_png,"Invert\nMouse","Enable/Disable Y-Axis inversion",534,180,24,24},
2336 {NULL,ctrl_option_on_png ,"Invert\nMouse","Enable/Disable Y-Axis inversion",534,180,24,24},
2337 {NULL,NULL,"","",0,0,0,0},
2338 {NULL,NULL,"","",0,0,0,0},
2339 },
2340 {
2341 /* Gun option */
2342 {NULL,ctrl_option_off_png,"Show\nCursor","Enable/Disable Lightgun cursor",534,180,24,24},
2343 {NULL,ctrl_option_on_png ,"Show\nCursor","Enable/Disable Lightgun cursor",534,180,24,24},
2344 {NULL,NULL,"","",0,0,0,0},
2345 {NULL,NULL,"","",0,0,0,0},
2346 },
2347 {
2348 /* no option */
2349 {NULL,NULL,"No Option","",436,180,160,52},
2350 {NULL,NULL,"","",0,0,0,0},
2351 {NULL,NULL,"","",0,0,0,0},
2352 {NULL,NULL,"","",0,0,0,0},
2353 }
2354 };
2355
2356 /* Player Configuration device items */
2357 #ifdef HW_RVL
2358 gui_item items_device[6] =
2359 {
2360 {NULL,ctrl_option_off_png ,"Input\nDevice","Select Input Controller",534,244,24,24},
2361 {NULL,ctrl_gamecube_png ,"Input\nDevice","Select Input Controller",530,246,36,24},
2362 {NULL,ctrl_wiimote_png ,"Input\nDevice","Select Input Controller",526,250,40,12},
2363 {NULL,ctrl_nunchuk_png ,"Input\nDevice","Select Input Controller",532,242,32,32},
2364 {NULL,ctrl_classic_png ,"Input\nDevice","Select Input Controller",526,242,40,32},
2365 {NULL,ctrl_wiiu_png ,"Input\nDevice","Select Input Controller",526,246,40,24},
2366 };
2367 #else
2368 gui_item items_device[2] =
2369 {
2370 {NULL,ctrl_option_off_png ,"Input\nDevice","Select Input Controller",534,244,24,24},
2371 {NULL,ctrl_gamecube_png ,"Input\nDevice","Select Input Controller",530,246,36,24}
2372 };
2373 #endif
2374
2375 /* initialize menu */
2376 gui_menu *m = &menu_ctrls;
2377 GUI_InitMenu(m);
2378
2379 /* initialize custom buttons */
2380 button_player_data.texture[0] = gxTextureOpenPNG(button_player_data.image[0],0);
2381 button_player_data.texture[1] = gxTextureOpenPNG(button_player_data.image[1],0);
2382 button_player_none_data.texture[0] = gxTextureOpenPNG(button_player_none_data.image[0],0);
2383
2384 /* initialize custom images */
2385 for (i=0; i<14; i++)
2386 {
2387 items_sys[1][i].texture = items_sys[0][i].texture = gxTextureOpenPNG(items_sys[0][i].data,0);
2388 }
2389 items_special[0][0].texture = gxTextureOpenPNG(items_special[0][0].data,0);
2390 items_special[0][1].texture = gxTextureOpenPNG(items_special[0][1].data,0);
2391 items_special[0][2].texture = gxTextureOpenPNG(items_special[0][2].data,0);
2392 items_special[0][3].texture = gxTextureOpenPNG(items_special[0][3].data,0);
2393 items_special[2][0].texture = items_special[1][0].texture = gxTextureOpenPNG(items_special[1][0].data,0);
2394 items_special[2][1].texture = items_special[1][1].texture = gxTextureOpenPNG(items_special[1][1].data,0);
2395 items_device[0].texture = items_special[1][0].texture;
2396 items_device[1].texture = gxTextureOpenPNG(items_device[1].data,0);
2397 #ifdef HW_RVL
2398 items_device[2].texture = gxTextureOpenPNG(items_device[2].data,0);
2399 items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0);
2400 items_device[4].texture = gxTextureOpenPNG(items_device[4].data,0);
2401 if (WiiDRC_Inited())
2402 {
2403 items_device[5].texture = gxTextureOpenPNG(items_device[5].data,0);
2404 }
2405 #endif
2406
2407 /* restore current menu elements */
2408 player = 0;
2409 ctrlmenu_raz();
2410 memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item));
2411 memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item));
2412
2413 /* menu title slide effect */
2414 m->selected = 0;
2415 GUI_SlideMenuTitle(m,strlen("Controller "));
2416
2417 while (update != -1)
2418 {
2419 /* draw menu */
2420 GUI_DrawMenu(m);
2421
2422 /* update menu */
2423 update = GUI_UpdateMenu(m);
2424
2425 if (update > 0)
2426 {
2427 switch (m->selected)
2428 {
2429 case 0: /* update port 1 system */
2430 {
2431 /* fixed configurations */
2432 if (system_hw)
2433 {
2434 if (cart.special & HW_TEREBI_OEKAKI)
2435 {
2436 GUI_WaitPrompt("Error","Terebi Oekaki detected !");
2437 break;
2438 }
2439 else if (system_hw == SYSTEM_PICO)
2440 {
2441 GUI_WaitPrompt("Error","PICO hardware detected !");
2442 break;
2443 }
2444 }
2445
2446 /* next connected device */
2447 input.system[0]++;
2448
2449 /* allow only one connected mouse */
2450 if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE))
2451 {
2452 input.system[0] += 3;
2453 }
2454
2455 /* Menacer & Justifiers on Port B only */
2456 if (input.system[0] == SYSTEM_MENACER)
2457 {
2458 input.system[0] += 2;
2459 }
2460
2461 /* allow only one gun type */
2462 if ((input.system[0] == SYSTEM_LIGHTPHASER) && ((input.system[1] == SYSTEM_MENACER) || (input.system[1] == SYSTEM_JUSTIFIER)))
2463 {
2464 input.system[0]++;
2465 }
2466
2467 /* allow only one connected graphic board */
2468 if ((input.system[0] == SYSTEM_GRAPHIC_BOARD) && (input.system[1] == SYSTEM_GRAPHIC_BOARD))
2469 {
2470 input.system[0]++;
2471 }
2472
2473 /* 4-wayplay uses both ports */
2474 if (input.system[0] == SYSTEM_WAYPLAY)
2475 {
2476 input.system[1] = SYSTEM_WAYPLAY;
2477 }
2478
2479 /* loop back */
2480 if (input.system[0] > SYSTEM_WAYPLAY)
2481 {
2482 input.system[0] = NO_SYSTEM;
2483 input.system[1] = SYSTEM_GAMEPAD;
2484 }
2485
2486 /* reset I/O ports */
2487 io_init();
2488 input_reset();
2489
2490 /* save current configuration */
2491 old_system[0] = input.system[0];
2492 old_system[1] = input.system[1];
2493
2494 /* update menu elements */
2495 ctrlmenu_raz();
2496 memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item));
2497 memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item));
2498
2499 if (m->bg_images[7].state & IMAGE_VISIBLE)
2500 {
2501 /* slide out configuration window */
2502 GUI_DrawMenuFX(m, 20, 1);
2503
2504 /* remove configuration window */
2505 m->bg_images[7].state &= ~IMAGE_VISIBLE;
2506
2507 /* disable configuration buttons */
2508 m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2509 m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2510 m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2511
2512 /* update directions */
2513 m->buttons[2].shift[3] = 0;
2514 m->buttons[3].shift[3] = 0;
2515 m->buttons[4].shift[3] = 0;
2516 m->buttons[5].shift[3] = 0;
2517 m->buttons[6].shift[3] = 0;
2518 m->buttons[7].shift[3] = 0;
2519 m->buttons[8].shift[3] = 0;
2520 m->buttons[9].shift[3] = 0;
2521
2522 /* update title */
2523 sprintf(m->title,"Controller Settings");
2524 }
2525 break;
2526 }
2527
2528 case 1: /* update port 2 system */
2529 {
2530 /* fixed configurations */
2531 if (system_hw)
2532 {
2533 if (cart.special & HW_TEREBI_OEKAKI)
2534 {
2535 GUI_WaitPrompt("Error","Terebi Oekaki detected !");
2536 break;
2537 }
2538 else if (system_hw == SYSTEM_PICO)
2539 {
2540 GUI_WaitPrompt("Error","PICO hardware detected !");
2541 break;
2542 }
2543 }
2544
2545 /* next connected device */
2546 input.system[1]++;
2547
2548 /* allow only one connected mouse */
2549 if ((input.system[0] == SYSTEM_MOUSE) && (input.system[1] == SYSTEM_MOUSE))
2550 {
2551 input.system[1]++;
2552 }
2553
2554 /* allow only one gun type */
2555 if ((input.system[0] == SYSTEM_LIGHTPHASER) && (input.system[1] == SYSTEM_MENACER))
2556 {
2557 input.system[1]++;
2558 }
2559
2560 /* allow only one gun type */
2561 if ((input.system[0] == SYSTEM_LIGHTPHASER) && (input.system[1] == SYSTEM_JUSTIFIER))
2562 {
2563 input.system[1]++;
2564 }
2565
2566 /* allow only one connected graphic board */
2567 if ((input.system[0] == SYSTEM_GRAPHIC_BOARD) && (input.system[1] == SYSTEM_GRAPHIC_BOARD))
2568 {
2569 input.system[1]++;
2570 }
2571
2572 /* 4-wayplay uses both ports */
2573 if (input.system[1] == SYSTEM_WAYPLAY)
2574 {
2575 input.system[0] = SYSTEM_WAYPLAY;
2576 }
2577
2578 /* loop back */
2579 if (input.system[1] > SYSTEM_WAYPLAY)
2580 {
2581 input.system[1] = NO_SYSTEM;
2582 input.system[0] = SYSTEM_GAMEPAD;
2583 }
2584
2585 /* reset I/O ports */
2586 io_init();
2587 input_reset();
2588
2589 /* save current configuration */
2590 old_system[0] = input.system[0];
2591 old_system[1] = input.system[1];
2592
2593 /* update menu elements */
2594 ctrlmenu_raz();
2595 memcpy(&m->items[0],&items_sys[0][input.system[0]],sizeof(gui_item));
2596 memcpy(&m->items[1],&items_sys[1][input.system[1]],sizeof(gui_item));
2597
2598 if (m->bg_images[7].state & IMAGE_VISIBLE)
2599 {
2600 /* slide out configuration window */
2601 GUI_DrawMenuFX(m, 20, 1);
2602
2603 /* remove configuration window */
2604 m->bg_images[7].state &= ~IMAGE_VISIBLE;
2605
2606 /* disable configuration buttons */
2607 m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2608 m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2609 m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2610
2611 /* update directions */
2612 m->buttons[2].shift[3] = 0;
2613 m->buttons[3].shift[3] = 0;
2614 m->buttons[4].shift[3] = 0;
2615 m->buttons[5].shift[3] = 0;
2616 m->buttons[6].shift[3] = 0;
2617 m->buttons[7].shift[3] = 0;
2618 m->buttons[8].shift[3] = 0;
2619 m->buttons[9].shift[3] = 0;
2620
2621 /* update title */
2622 sprintf(m->title,"Controller Settings");
2623 }
2624
2625 break;
2626 }
2627
2628 case 2:
2629 case 3:
2630 case 4:
2631 case 5:
2632 case 6:
2633 case 7:
2634 case 8:
2635 case 9:
2636 {
2637 /* remove duplicate assigned inputs */
2638 for (i=0; i<MAX_INPUTS; i++)
2639 {
2640 if ((i!=player) && (config.input[i].port == config.input[player].port) &&
2641 ((config.input[i].device == config.input[player].device) || ((config.input[i].device * config.input[player].device) == 2)))
2642 {
2643 config.input[i].device = -1;
2644 config.input[i].port = i%4;
2645 }
2646 }
2647
2648 /* save device index */
2649 index = m->selected - 2;
2650
2651 /* update player index */
2652 old_player = player;
2653 player = 0;
2654 for (i=0; i<index; i++)
2655 {
2656 if (input.dev[i] != NO_DEVICE) player ++;
2657 }
2658
2659 if (m->bg_images[7].state & IMAGE_VISIBLE)
2660 {
2661 /* if already displayed, do nothing */
2662 if (old_player == player) break;
2663
2664 /* slide out configuration window */
2665 GUI_DrawMenuFX(m, 20, 1);
2666 }
2667 else
2668 {
2669 /* append configuration window */
2670 m->bg_images[7].state |= IMAGE_VISIBLE;
2671
2672 /* enable configuration buttons */
2673 m->buttons[10].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
2674 m->buttons[11].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
2675 m->buttons[12].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
2676
2677 /* update directions */
2678 m->buttons[2].shift[3] = 8;
2679 m->buttons[3].shift[3] = 7;
2680 m->buttons[4].shift[3] = 6;
2681 m->buttons[5].shift[3] = 5;
2682 m->buttons[6].shift[3] = 4;
2683 m->buttons[7].shift[3] = 3;
2684 m->buttons[8].shift[3] = 2;
2685 m->buttons[9].shift[3] = 1;
2686 }
2687
2688 /* retrieve current player informations */
2689 switch (input.dev[index])
2690 {
2691 case DEVICE_PAD2B:
2692 case DEVICE_PAD3B:
2693 case DEVICE_PAD6B:
2694 {
2695 if (input.system[index/4] == SYSTEM_MASTERTAP)
2696 {
2697 /* force 2-buttons pad */
2698 items = items_special[3];
2699 special = NULL;
2700 }
2701 else
2702 {
2703 items = items_special[0];
2704 special = &config.input[player].padtype;
2705 }
2706 break;
2707 }
2708
2709 case DEVICE_MOUSE:
2710 {
2711 items = items_special[1];
2712 special = &config.invert_mouse;
2713 break;
2714 }
2715
2716 case DEVICE_LIGHTGUN:
2717 {
2718 items = items_special[2];
2719 if ((input.system[1] == SYSTEM_MENACER) || (input.system[1] == SYSTEM_JUSTIFIER))
2720 {
2721 /* Menacer & Justifiers affected to entries 4 & 5 */
2722 special = &config.gun_cursor[index & 1];
2723 }
2724 else
2725 {
2726 /* Lightphasers affected to entries 0 & 4 */
2727 special = &config.gun_cursor[index / 4];
2728 }
2729 break;
2730 }
2731
2732 default:
2733 {
2734 items = items_special[3];
2735 special = NULL;
2736 break;
2737 }
2738 }
2739
2740 if (special)
2741 {
2742 memcpy(&m->items[10],&items[*special],sizeof(gui_item));
2743 }
2744 else
2745 {
2746 memcpy(&m->items[10],&items[0],sizeof(gui_item));
2747 }
2748
2749 memcpy(&m->items[11],&items_device[config.input[player].device + 1],sizeof(gui_item));
2750
2751 /* slide in configuration window */
2752 m->buttons[10].shift[2] = 10 - m->selected;
2753 m->buttons[11].shift[2] = 11 - m->selected;
2754 m->buttons[12].shift[2] = 12 - m->selected;
2755 m->selected = 10;
2756 GUI_DrawMenuFX(m, 20, 0);
2757
2758 /* some devices require analog sticks */
2759 if ((input.dev[index] == DEVICE_XE_1AP) && ((config.input[player].device == -1) || (config.input[player].device == 1)))
2760 {
2761 GUI_WaitPrompt("Warning","One Analog Stick required !");
2762 }
2763 else if ((input.dev[index] == DEVICE_ACTIVATOR) && ((config.input[player].device != 0) && (config.input[player].device != 3)))
2764 {
2765 GUI_WaitPrompt("Warning","Two Analog Sticks required !");
2766 }
2767
2768 /* update title */
2769 if ((cart.special & HW_J_CART) && (player > 1))
2770 {
2771 sprintf(m->title,"Controller Settings (Player %d) (J-CART)",player+1);
2772 }
2773 else
2774 {
2775 sprintf(m->title,"Controller Settings (Player %d)",player+1);
2776 }
2777 break;
2778 }
2779
2780 case 10: /* specific option */
2781 {
2782 if (special)
2783 {
2784 /* specific case: controller type */
2785 if (input.dev[index] < 0x03)
2786 {
2787 /* switch pad type */
2788 *special = (*special + 1) & 0x03;
2789
2790 /* reinitialize emulated device(s) */
2791 io_init();
2792 input_reset();
2793 }
2794 else
2795 {
2796 /* switch option */
2797 *special ^= 1;
2798 }
2799
2800 /* update menu items */
2801 memcpy(&m->items[10],&items[*special],sizeof(gui_item));
2802 }
2803 break;
2804 }
2805
2806 case 11: /* input controller selection */
2807 {
2808 /* no input device */
2809 if (config.input[player].device < 0)
2810 {
2811 /* always try gamecube controllers first */
2812 config.input[player].device = 0;
2813 config.input[player].port = 0;
2814 }
2815 else
2816 {
2817 /* try next port */
2818 config.input[player].port ++;
2819 }
2820
2821 /* autodetect connected gamecube controllers */
2822 if (config.input[player].device == 0)
2823 {
2824 /* find first connected controller */
2825 exp = 0;
2826 while ((config.input[player].port < 4) && !exp)
2827 {
2828 VIDEO_WaitVSync ();
2829 exp = PAD_ScanPads() & (1<<config.input[player].port);
2830 if (!exp) config.input[player].port ++;
2831 }
2832
2833 /* no more gamecube controller */
2834 if (config.input[player].port >= 4)
2835 {
2836 #ifdef HW_RVL
2837 /* test wiimote */
2838 config.input[player].port = 0;
2839 config.input[player].device = 1;
2840 #else
2841 /* no input controller left */
2842 config.input[player].device = -1;
2843 config.input[player].port = player%4;
2844 #endif
2845 }
2846 }
2847
2848 #ifdef HW_RVL
2849 /* autodetect connected wiimotes (without nunchuk) */
2850 if (config.input[player].device == 1)
2851 {
2852 /* find first connected controller */
2853 exp = 255;
2854 while ((config.input[player].port < 4) && (exp == 255))
2855 {
2856 WPAD_Probe(config.input[player].port,&exp);
2857
2858 /* check if this is a Wii U Pro Controller */
2859 if (exp == WPAD_EXP_CLASSIC)
2860 {
2861 WPADData *data = WPAD_Data(config.input[player].port);
2862 if (data->exp.classic.type == 2)
2863 exp = 255;
2864 }
2865
2866 /* try next port if no wimote available */
2867 if (exp == 255)
2868 config.input[player].port ++;
2869 }
2870
2871 /* no more wiimote */
2872 if (config.input[player].port >= 4)
2873 {
2874 /* test wiimote+nunchuk */
2875 config.input[player].port = 0;
2876 config.input[player].device = 2;
2877 }
2878 }
2879
2880 /* autodetect connected wiimote+nunchuk */
2881 if (config.input[player].device == 2)
2882 {
2883 /* test current port */
2884 exp = 255;
2885 if (config.input[player].port < 4)
2886 {
2887 WPAD_Probe(config.input[player].port,&exp);
2888 }
2889
2890 /* find first connected controller */
2891 while ((config.input[player].port < 4) && (exp != WPAD_EXP_NUNCHUK))
2892 {
2893 /* try next port */
2894 config.input[player].port ++;
2895 if (config.input[player].port < 4)
2896 {
2897 exp = 255;
2898 WPAD_Probe(config.input[player].port,&exp);
2899 }
2900 }
2901
2902 /* no more wiimote+nunchuk */
2903 if (config.input[player].port >= 4)
2904 {
2905 /* test classic controllers */
2906 config.input[player].port = 0;
2907 config.input[player].device = 3;
2908 }
2909 }
2910
2911 /* autodetect connected classic controllers */
2912 if (config.input[player].device == 3)
2913 {
2914 /* test current port */
2915 exp = 255;
2916 if (config.input[player].port < 4)
2917 {
2918 WPAD_Probe(config.input[player].port,&exp);
2919 }
2920
2921 /* find first connected controller */
2922 while ((config.input[player].port<4) && (exp != WPAD_EXP_CLASSIC))
2923 {
2924 /* try next port */
2925 config.input[player].port ++;
2926 if (config.input[player].port < 4)
2927 {
2928 exp = 255;
2929 WPAD_Probe(config.input[player].port,&exp);
2930 }
2931 }
2932
2933 if (config.input[player].port >= 4)
2934 {
2935 /* test WiiU gamepad */
2936 config.input[player].device = 4;
2937 config.input[player].port = 0;
2938 }
2939 }
2940
2941 /* autodetect WiiU gamepad */
2942 if (config.input[player].device == 4)
2943 {
2944 /* support for only one gamepad */
2945 if (!WiiDRC_Inited() || !WiiDRC_Connected() || (config.input[player].port >= 1))
2946 {
2947 /* no input controller left */
2948 config.input[player].device = -1;
2949 config.input[player].port = player%4;
2950 }
2951 }
2952 #endif
2953
2954 /* update menu items */
2955 memcpy(&m->items[11],&items_device[config.input[player].device + 1],sizeof(gui_item));
2956
2957 break;
2958 }
2959
2960 case 12: /* Controller Keys Configuration */
2961 {
2962 if (config.input[player].device >= 0)
2963 {
2964 GUI_MsgBoxOpen("Keys Configuration", "",0);
2965 if (!system_hw && special && (*special == 3))
2966 {
2967 /* no auto-detected pad type, use 6-buttons key mapping as default */
2968 gx_input_Config(config.input[player].port, config.input[player].device, DEVICE_PAD6B);
2969 }
2970 else
2971 {
2972 gx_input_Config(config.input[player].port, config.input[player].device, input.dev[index]);
2973 }
2974 GUI_MsgBoxClose();
2975 }
2976 break;
2977 }
2978 }
2979 }
2980
2981 /* Close Window */
2982 else if (update < 0)
2983 {
2984 if (m->bg_images[7].state & IMAGE_VISIBLE)
2985 {
2986 /* slide out configuration window */
2987 GUI_DrawMenuFX(m, 20, 1);
2988
2989 /* disable configuration window */
2990 m->bg_images[7].state &= ~IMAGE_VISIBLE;
2991
2992 /* disable configuration buttons */
2993 m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2994 m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2995 m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
2996
2997 /* clear directions */
2998 m->buttons[2].shift[3] = 0;
2999 m->buttons[3].shift[3] = 0;
3000 m->buttons[4].shift[3] = 0;
3001 m->buttons[5].shift[3] = 0;
3002 m->buttons[6].shift[3] = 0;
3003 m->buttons[7].shift[3] = 0;
3004 m->buttons[8].shift[3] = 0;
3005 m->buttons[9].shift[3] = 0;
3006
3007 /* update selector */
3008 m->selected -= m->buttons[m->selected].shift[2];
3009
3010 /* restore title */
3011 sprintf(m->title,"Controller Settings");
3012
3013 /* stay in menu */
3014 update = 0;
3015 }
3016 else
3017 {
3018 /* check we have at least one connected input before leaving */
3019 old_player = player;
3020 player = 0;
3021 for (i=0; i<MAX_DEVICES; i++)
3022 {
3023 /* check inputs */
3024 if (input.dev[i] != NO_DEVICE)
3025 {
3026 if (config.input[player].device != -1)
3027 break;
3028 player++;
3029 }
3030 }
3031 player = old_player;
3032
3033 /* no input connected */
3034 if (i == MAX_DEVICES)
3035 {
3036 /* stay in menu */
3037 GUI_WaitPrompt("Error","No input connected !");
3038 update = 0;
3039 }
3040 }
3041 }
3042 }
3043
3044 /* remove duplicate assigned inputs before leaving */
3045 for (i=0; i<MAX_INPUTS; i++)
3046 {
3047 if ((i!=player) && (config.input[i].port == config.input[player].port) &&
3048 ((config.input[i].device == config.input[player].device) || ((config.input[i].device * config.input[player].device) == 2)))
3049 {
3050 config.input[i].device = -1;
3051 config.input[i].port = i%4;
3052 }
3053 }
3054
3055 /* disable configuration window */
3056 m->bg_images[7].state &= ~IMAGE_VISIBLE;
3057
3058 /* disable configuration buttons */
3059 m->buttons[10].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
3060 m->buttons[11].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
3061 m->buttons[12].state &= (~BUTTON_VISIBLE & ~BUTTON_ACTIVE);
3062
3063 /* clear directions */
3064 m->buttons[2].shift[3] = 0;
3065 m->buttons[3].shift[3] = 0;
3066 m->buttons[4].shift[3] = 0;
3067 m->buttons[5].shift[3] = 0;
3068 m->buttons[6].shift[3] = 0;
3069 m->buttons[7].shift[3] = 0;
3070 m->buttons[8].shift[3] = 0;
3071 m->buttons[9].shift[3] = 0;
3072
3073 /* clear menu items */
3074 memset(&m->items[0],0,sizeof(gui_item));
3075 memset(&m->items[1],0,sizeof(gui_item));
3076 memset(&m->items[10],0,sizeof(gui_item));
3077 memset(&m->items[11],0,sizeof(gui_item));
3078
3079 /* clear player buttons */
3080 m->buttons[2].data = NULL;
3081 m->buttons[3].data = NULL;
3082 m->buttons[4].data = NULL;
3083 m->buttons[5].data = NULL;
3084 m->buttons[6].data = NULL;
3085 m->buttons[7].data = NULL;
3086 m->buttons[8].data = NULL;
3087 m->buttons[9].data = NULL;
3088
3089 /* delete menu */
3090 GUI_DeleteMenu(m);
3091
3092 /* delete custom buttons */
3093 gxTextureClose(&button_player_data.texture[0]);
3094 gxTextureClose(&button_player_data.texture[1]);
3095 gxTextureClose(&button_player_none_data.texture[0]);
3096
3097 /* delete custom images */
3098 for (i=0; i<14; i++)
3099 {
3100 gxTextureClose(&items_sys[0][i].texture);
3101 }
3102 gxTextureClose(&items_special[0][0].texture);
3103 gxTextureClose(&items_special[0][1].texture);
3104 gxTextureClose(&items_special[0][2].texture);
3105 gxTextureClose(&items_special[0][3].texture);
3106 gxTextureClose(&items_special[1][0].texture);
3107 gxTextureClose(&items_special[1][1].texture);
3108 gxTextureClose(&items_device[1].texture);
3109 #ifdef HW_RVL
3110 gxTextureClose(&items_device[2].texture);
3111 gxTextureClose(&items_device[3].texture);
3112 gxTextureClose(&items_device[4].texture);
3113 if (WiiDRC_Inited())
3114 {
3115 gxTextureClose(&items_device[5].texture);
3116 }
3117 #endif
3118 }
3119
3120 /****************************************************************************
3121 * Main Option menu
3122 *
3123 ****************************************************************************/
optionmenu(void)3124 static void optionmenu(void)
3125 {
3126 int ret, quit = 0;
3127 gui_menu *m = &menu_options;
3128
3129 GUI_InitMenu(m);
3130 GUI_DrawMenuFX(m,30,0);
3131
3132 while (quit == 0)
3133 {
3134 ret = GUI_RunMenu(m);
3135
3136 switch (ret)
3137 {
3138 case 0:
3139 GUI_DeleteMenu(m);
3140 systemmenu();
3141 GUI_InitMenu(m);
3142 break;
3143 case 1:
3144 GUI_DeleteMenu(m);
3145 videomenu();
3146 GUI_InitMenu(m);
3147 break;
3148 case 2:
3149 GUI_DeleteMenu(m);
3150 soundmenu();
3151 GUI_InitMenu(m);
3152 break;
3153 case 3:
3154 GUI_DeleteMenu(m);
3155 ctrlmenu();
3156 GUI_InitMenu(m);
3157 break;
3158 case 4:
3159 GUI_DeleteMenu(m);
3160 prefmenu();
3161 GUI_InitMenu(m);
3162 break;
3163 case -1:
3164 quit = 1;
3165 break;
3166 }
3167 }
3168
3169 config_save();
3170 GUI_DrawMenuFX(m,30,1);
3171 GUI_DeleteMenu(m);
3172 }
3173
3174 /****************************************************************************
3175 * Save Manager menu
3176 *
3177 ****************************************************************************/
3178 static t_slot slots[5];
3179 static gx_texture *star;
3180
savemenu_cb(void)3181 static void savemenu_cb(void)
3182 {
3183 int i;
3184 char msg[16];
3185
3186 if (sram.on)
3187 {
3188 FONT_write("Backup Memory",16,buttons_saves[0].x+16,buttons_saves[0].y+(buttons_saves[0].h-16)/2+16,buttons_saves[0].x+buttons_saves[0].w,(GXColor)DARK_GREY);
3189 if (slots[0].valid)
3190 {
3191 sprintf(msg,"%d/%02d/%02d",slots[0].day,slots[0].month,slots[0].year);
3192 FONT_alignRight(msg,12,buttons_saves[0].x+buttons_saves[0].w-16,buttons_saves[0].y+(buttons_saves[0].h-28)/2+12,(GXColor)DARK_GREY);
3193 sprintf(msg,"%02d:%02d",slots[0].hour,slots[0].min);
3194 FONT_alignRight(msg,12,buttons_saves[0].x+buttons_saves[0].w-16,buttons_saves[0].y+(buttons_saves[0].h-28)/2+28,(GXColor)DARK_GREY);
3195 }
3196
3197 if (sram.crc != crc32(0, &sram.sram[0], 0x10000))
3198 gxDrawTexture(star,22,buttons_saves[0].y+(buttons_saves[0].h-star->height)/2,star->width,star->height,255);
3199 }
3200 else
3201 {
3202 FONT_writeCenter("Backup Memory disabled",16,buttons_saves[0].x,buttons_saves[0].x+buttons_saves[0].w,buttons_saves[0].y+(buttons_saves[0].h-16)/2+16,(GXColor)DARK_GREY);
3203 }
3204
3205 for (i=1; i<5; i++)
3206 {
3207 if (slots[i].valid)
3208 {
3209 sprintf(msg,"Slot %d",i);
3210 FONT_write(msg,16,buttons_saves[i].x+16,buttons_saves[i].y+(buttons_saves[i].h-16)/2+16,buttons_saves[i].x+buttons_saves[i].w,(GXColor)DARK_GREY);
3211 sprintf(msg,"%d/%02d/%02d",slots[i].day,slots[i].month,slots[i].year);
3212 FONT_alignRight(msg,12,buttons_saves[i].x+buttons_saves[i].w-16,buttons_saves[i].y+(buttons_saves[i].h-28)/2+12,(GXColor)DARK_GREY);
3213 sprintf(msg,"%02d:%02d",slots[i].hour,slots[i].min);
3214 FONT_alignRight(msg,12,buttons_saves[i].x+buttons_saves[i].w-16,buttons_saves[i].y+(buttons_saves[i].h-28)/2+28,(GXColor)DARK_GREY);
3215 }
3216 else
3217 {
3218 FONT_write("Empty Slot",16,buttons_saves[i].x+16,buttons_saves[i].y+(buttons_saves[i].h-16)/2+16,buttons_saves[i].x+buttons_saves[i].h,(GXColor)DARK_GREY);
3219 }
3220
3221 if (i == config.s_default)
3222 gxDrawTexture(star,22,buttons_saves[i].y+(buttons_saves[i].h-star->height)/2,star->width,star->height,255);
3223 }
3224 }
3225
savemenu(void)3226 static int savemenu(void)
3227 {
3228 int i, update = 0;
3229 int ret = 0;
3230 int slot = -1;
3231 char filename[MAXPATHLEN];
3232 gui_menu *m = &menu_saves;
3233 FILE *snap;
3234
3235 star = gxTextureOpenPNG(Star_full_png,0);
3236 GUI_InitMenu(m);
3237 GUI_DrawMenuFX(m,30,0);
3238
3239 m->bg_images[3].state &= ~IMAGE_SLIDE_TOP;
3240 m->bg_images[4].state &= ~IMAGE_SLIDE_BOTTOM;
3241 m->bg_images[5].state &= ~IMAGE_SLIDE_TOP;
3242
3243 /* detect existing files */
3244 for (i=0; i<5; i++)
3245 slot_autodetect(i, config.s_device, &slots[i]);
3246
3247 /* SRAM disabled */
3248 if (sram.on)
3249 {
3250 m->buttons[0].state |= BUTTON_ACTIVE;
3251 m->buttons[1].shift[0] = 1;
3252 }
3253 else
3254 {
3255 m->buttons[0].state &= ~BUTTON_ACTIVE;
3256 m->buttons[1].shift[0] = 0;
3257 if (m->selected == 0)
3258 m->selected = 1;
3259 }
3260
3261 while (update != -1)
3262 {
3263 /* slot selection */
3264 if ((m->selected < 5) && (slot != m->selected))
3265 {
3266 /* update slot */
3267 slot = m->selected;
3268
3269 /* delete previous texture if any */
3270 gxTextureClose(&bg_saves[0].texture);
3271 bg_saves[0].state &= ~IMAGE_VISIBLE;
3272 bg_saves[1].state |= IMAGE_VISIBLE;
3273
3274 /* state slot */
3275 if (!config.s_device && slot && slots[slot].valid)
3276 {
3277 /* open screenshot file */
3278 sprintf (filename, "%s/saves/%s__%d.png", DEFAULT_PATH, rom_filename, slot - 1);
3279 snap = fopen(filename, "rb");
3280 if (snap)
3281 {
3282 /* load texture from file */
3283 bg_saves[0].texture = gxTextureOpenPNG(0,snap);
3284 if (bg_saves[0].texture)
3285 {
3286 /* set menu background */
3287 bg_saves[0].w = bg_saves[0].texture->width * 2;
3288 if (config.aspect & 2) bg_saves[0].w = (bg_saves[0].w * 3) / 4;
3289 bg_saves[0].h = bg_saves[0].texture->height * 2;
3290 bg_saves[0].x = (vmode->fbWidth - bg_saves[0].w) / 2;
3291 bg_saves[0].y = (vmode->efbHeight - bg_saves[0].h) / 2;
3292 bg_saves[0].state |= IMAGE_VISIBLE;
3293 bg_saves[1].state &= ~IMAGE_VISIBLE;
3294 }
3295 fclose(snap);
3296 }
3297 }
3298 }
3299
3300 /* draw menu */
3301 GUI_DrawMenu(m);
3302
3303 /* update menu */
3304 update = GUI_UpdateMenu(m);
3305
3306 if (update > 0)
3307 {
3308 switch (m->selected)
3309 {
3310 case 0:
3311 case 1:
3312 case 2:
3313 case 3:
3314 case 4: /* Slot selection */
3315 {
3316 /* enable right window */
3317 m->bg_images[7].state |= IMAGE_VISIBLE;
3318 m->buttons[5].state |= BUTTON_VISIBLE;
3319 m->buttons[6].state |= BUTTON_VISIBLE;
3320 m->buttons[7].state |= BUTTON_VISIBLE;
3321 m->buttons[8].state |= BUTTON_VISIBLE;
3322
3323 /* only enable valid options */
3324 if (slots[slot].valid)
3325 {
3326 m->buttons[5].state |= BUTTON_ACTIVE;
3327 m->buttons[7].state |= BUTTON_ACTIVE;
3328 m->buttons[6].shift[0] = 1;
3329 m->buttons[6].shift[1] = 1;
3330 m->buttons[8].shift[0] = 1;
3331 m->selected = 5;
3332 }
3333 else
3334 {
3335 m->buttons[5].state &= ~BUTTON_ACTIVE;
3336 m->buttons[7].state &= ~BUTTON_ACTIVE;
3337 m->buttons[6].shift[0] = 0;
3338 m->buttons[6].shift[1] = 2;
3339 m->buttons[8].shift[0] = (slot > 0) ? 2 : 0;
3340 m->selected = 8;
3341 }
3342
3343 /* state slot 'only' button */
3344 if (slot > 0)
3345 {
3346 m->buttons[6].state |= BUTTON_ACTIVE;
3347 m->buttons[5].shift[1] = 1;
3348 m->buttons[7].shift[0] = 1;
3349 }
3350 else
3351 {
3352 m->buttons[6].state &= ~BUTTON_ACTIVE;
3353 m->buttons[5].shift[1] = 2;
3354 m->buttons[7].shift[0] = 2;
3355 }
3356
3357 /* disable left buttons */
3358 m->buttons[0].state &= ~BUTTON_ACTIVE;
3359 m->buttons[1].state &= ~BUTTON_ACTIVE;
3360 m->buttons[2].state &= ~BUTTON_ACTIVE;
3361 m->buttons[3].state &= ~BUTTON_ACTIVE;
3362 m->buttons[4].state &= ~BUTTON_ACTIVE;
3363
3364 /* keep current selection highlighted */
3365 m->buttons[slot].state |= BUTTON_SELECTED;
3366
3367 /* slide in window */
3368 GUI_DrawMenuFX(m, 20, 0);
3369
3370 break;
3371 }
3372
3373 case 5: /* load file */
3374 {
3375 if (slots[slot].valid)
3376 {
3377 ret = slot_load(slot,config.s_device);
3378
3379 /* force exit */
3380 if (ret > 0)
3381 {
3382 GUI_DrawMenuFX(m, 20, 1);
3383 m->buttons[slot].state &= ~BUTTON_SELECTED;
3384 m->bg_images[7].state &= ~IMAGE_VISIBLE;
3385 if (sram.on)
3386 m->buttons[0].state |= BUTTON_ACTIVE;
3387 m->buttons[1].state |= BUTTON_ACTIVE;
3388 m->buttons[2].state |= BUTTON_ACTIVE;
3389 m->buttons[3].state |= BUTTON_ACTIVE;
3390 m->buttons[4].state |= BUTTON_ACTIVE;
3391 m->buttons[5].state &= ~BUTTON_VISIBLE;
3392 m->buttons[6].state &= ~BUTTON_VISIBLE;
3393 m->buttons[7].state &= ~BUTTON_VISIBLE;
3394 m->buttons[8].state &= ~BUTTON_VISIBLE;
3395 m->selected = slot;
3396 update = -1;
3397 }
3398 }
3399 break;
3400 }
3401
3402 case 6: /* set default slot */
3403 {
3404 config.s_default = slot;
3405 config_save();
3406 break;
3407 }
3408
3409 case 7: /* delete file */
3410 {
3411 if (slots[slot].valid)
3412 {
3413 if (GUI_WaitConfirm("Warning","Delete Save File ?"))
3414 {
3415 if (slot_delete(slot,config.s_device) >= 0)
3416 {
3417 /* hide screenshot */
3418 gxTextureClose(&bg_saves[0].texture);
3419 bg_saves[0].state &= ~IMAGE_VISIBLE;
3420 bg_saves[1].state |= IMAGE_VISIBLE;
3421 slots[slot].valid = 0;
3422 update = -1;
3423 }
3424 }
3425 }
3426 break;
3427 }
3428
3429 case 8: /* save file */
3430 {
3431 ret = slot_save(slot,config.s_device);
3432
3433 /* force exit */
3434 if (ret > 0)
3435 {
3436 GUI_DrawMenuFX(m, 20, 1);
3437 m->buttons[slot].state &= ~BUTTON_SELECTED;
3438 m->bg_images[7].state &= ~IMAGE_VISIBLE;
3439 if (sram.on)
3440 m->buttons[0].state |= BUTTON_ACTIVE;
3441 m->buttons[1].state |= BUTTON_ACTIVE;
3442 m->buttons[2].state |= BUTTON_ACTIVE;
3443 m->buttons[3].state |= BUTTON_ACTIVE;
3444 m->buttons[4].state |= BUTTON_ACTIVE;
3445 m->buttons[5].state &= ~BUTTON_VISIBLE;
3446 m->buttons[6].state &= ~BUTTON_VISIBLE;
3447 m->buttons[7].state &= ~BUTTON_VISIBLE;
3448 m->buttons[8].state &= ~BUTTON_VISIBLE;
3449 m->selected = slot;
3450 update = -1;
3451 }
3452 break;
3453 }
3454
3455 default:
3456 break;
3457 }
3458 }
3459
3460 if (update < 0)
3461 {
3462 /* close right window */
3463 if (m->bg_images[7].state & IMAGE_VISIBLE)
3464 {
3465 /* slide out window */
3466 GUI_DrawMenuFX(m, 20, 1);
3467
3468 /* clear current selection */
3469 m->buttons[slot].state &= ~BUTTON_SELECTED;
3470
3471 /* enable left buttons */
3472 if (sram.on)
3473 m->buttons[0].state |= BUTTON_ACTIVE;
3474 m->buttons[1].state |= BUTTON_ACTIVE;
3475 m->buttons[2].state |= BUTTON_ACTIVE;
3476 m->buttons[3].state |= BUTTON_ACTIVE;
3477 m->buttons[4].state |= BUTTON_ACTIVE;
3478
3479 /* disable right window */
3480 m->bg_images[7].state &= ~IMAGE_VISIBLE;
3481 m->buttons[5].state &= ~BUTTON_VISIBLE;
3482 m->buttons[6].state &= ~BUTTON_VISIBLE;
3483 m->buttons[7].state &= ~BUTTON_VISIBLE;
3484 m->buttons[8].state &= ~BUTTON_VISIBLE;
3485
3486 /* stay in menu */
3487 m->selected = slot;
3488 update = 0;
3489 }
3490 }
3491 }
3492
3493 /* leave menu */
3494 m->bg_images[3].state |= IMAGE_SLIDE_TOP;
3495 m->bg_images[4].state |= IMAGE_SLIDE_BOTTOM;
3496 m->bg_images[5].state |= IMAGE_SLIDE_TOP;
3497 GUI_DrawMenuFX(m,30,1);
3498 GUI_DeleteMenu(m);
3499 gxTextureClose(&star);
3500 return ret;
3501 }
3502
3503 /****************************************************************************
3504 * Load Game menu
3505 *
3506 ****************************************************************************/
loadgamemenu()3507 static int loadgamemenu ()
3508 {
3509 int ret, filetype;
3510 gui_menu *m = &menu_load;
3511 GUI_InitMenu(m);
3512 GUI_DrawMenuFX(m,30,0);
3513
3514 while (1)
3515 {
3516 ret = GUI_RunMenu(m);
3517
3518 switch (ret)
3519 {
3520 /*** Button B ***/
3521 case -1:
3522 GUI_DrawMenuFX(m,30,1);
3523 GUI_DeleteMenu(m);
3524 return 0;
3525
3526 /*** Load from selected device */
3527 default:
3528 {
3529 /* ROM File type */
3530 filetype = ret - 1;
3531
3532 /* Try to open current directory */
3533 if (ret > 0)
3534 {
3535 ret = OpenDirectory(config.l_device, filetype);
3536 }
3537 else
3538 {
3539 ret = OpenDirectory(TYPE_RECENT, filetype);
3540 }
3541
3542 if (ret)
3543 {
3544 GUI_DeleteMenu(m);
3545 if (FileSelector(filetype) > 0)
3546 {
3547 /* directly jump to game */
3548 return 1;
3549 }
3550 GUI_InitMenu(m);
3551 }
3552 break;
3553 }
3554 }
3555 }
3556
3557 return 0;
3558 }
3559
3560 /***************************************************************************
3561 * Show rom info screen
3562 ***************************************************************************/
showrominfo(void)3563 static void showrominfo (void)
3564 {
3565 char items[15][64];
3566
3567 /* fill ROM infos */
3568 sprintf (items[0], "Console Type: %s", rominfo.consoletype);
3569 sprintf (items[1], "Copyright: %s", rominfo.copyright);
3570 sprintf (items[2], "Company Name: %s", get_company());
3571 sprintf (items[3], "Domestic Name:");
3572 sprintf (items[4], "%s",rominfo.domestic);
3573 sprintf (items[5], "International Name:");
3574 sprintf (items[6], "%s",rominfo.international);
3575 sprintf (items[7], "Type: %s (%s)",rominfo.ROMType, strcmp(rominfo.ROMType, "AI") ? "Game" : "Educational");
3576 sprintf (items[8], "Product ID: %s", rominfo.product);
3577 sprintf (items[9], "Checksum: %04x (%04x) (%s)", rominfo.checksum, rominfo.realchecksum,
3578 (rominfo.checksum == rominfo.realchecksum) ? "GOOD" : "BAD");
3579
3580 sprintf (items[10], "Supports: ");
3581 if (rominfo.peripherals & (1 << 1))
3582 {
3583 strcat(items[10],get_peripheral(1));
3584 strcat(items[10],", ");
3585 }
3586 else if (rominfo.peripherals & (1 << 0))
3587 {
3588 strcat(items[10],get_peripheral(0));
3589 strcat(items[10],", ");
3590 }
3591 if (rominfo.peripherals & (1 << 7))
3592 {
3593 strcat(items[10],get_peripheral(7));
3594 strcat(items[10],", ");
3595 }
3596 if (rominfo.peripherals & (1 << 8))
3597 {
3598 strcat(items[10],get_peripheral(8));
3599 strcat(items[10],", ");
3600 }
3601 if (rominfo.peripherals & (1 << 11))
3602 {
3603 strcat(items[10],get_peripheral(11));
3604 strcat(items[10],", ");
3605 }
3606 if (rominfo.peripherals & (1 << 13))
3607 {
3608 strcat(items[10],get_peripheral(13));
3609 strcat(items[10],", ");
3610 }
3611 if (strlen(items[10]) > 10)
3612 items[10][strlen(items[10]) - 2] = 0;
3613
3614 sprintf (items[11], "ROM end: $%06X", rominfo.romend);
3615
3616 if (sram.custom)
3617 sprintf (items[12], "Serial EEPROM");
3618 else if (sram.detected)
3619 sprintf (items[12], "SRAM Start: $%06X", sram.start);
3620 else
3621 sprintf (items[12], "No Backup Memory specified");
3622
3623 if (sram.custom == 1)
3624 sprintf (items[13], "Type: I2C (24Cxx)");
3625 else if (sram.custom == 2)
3626 sprintf (items[13], "Type: SPI (25x512/95x512)");
3627 else if (sram.custom == 3)
3628 sprintf (items[13], "Type: I2C (93C46)");
3629 else if (sram.detected)
3630 sprintf (items[13], "SRAM End: $%06X", sram.end);
3631 else if (sram.on)
3632 sprintf (items[13], "SRAM enabled by default");
3633 else
3634 sprintf (items[13], "SRAM disabled by default");
3635
3636 if (region_code == REGION_USA)
3637 sprintf (items[14], "Region Code: %s (USA)", rominfo.country);
3638 else if (region_code == REGION_EUROPE)
3639 sprintf (items[14], "Region Code: %s (EUR)", rominfo.country);
3640 else if (region_code == REGION_JAPAN_NTSC)
3641 sprintf (items[14], "Region Code: %s (JPN)", rominfo.country);
3642 else if (region_code == REGION_JAPAN_PAL)
3643 sprintf (items[14], "Region Code: %s (JPN-PAL)", rominfo.country);
3644
3645 GUI_TextWindow(&menu_main, "ROM Header Info", items, 15, 15);
3646 }
3647
3648 /***************************************************************************
3649 * Show credits
3650 ***************************************************************************/
showcredits(void)3651 static void showcredits(void)
3652 {
3653 int offset = 0;
3654
3655 gx_texture *texture = gxTextureOpenPNG(Bg_credits_png,0);
3656 s16 p = 0;
3657
3658 while (!p)
3659 {
3660 gxClearScreen ((GXColor)BLACK);
3661 if (texture)
3662 gxDrawTexture(texture, (640-texture->width)/2, (480-texture->height)/2, texture->width, texture->height,255);
3663
3664 FONT_writeCenter("Genesis Plus GX Core", 24, 0, 640, 480 - offset, (GXColor)LIGHT_BLUE);
3665 FONT_writeCenter("improved emulation code & additional features by Eke-Eke", 18, 0, 640, 516 - offset, (GXColor)WHITE);
3666 FONT_writeCenter("original Genesis Plus (1.3) version by Charles MacDonald", 18, 0, 640, 534 - offset, (GXColor)WHITE);
3667 FONT_writeCenter("original Z80 core by Juergen Buchmueller", 18, 0, 640, 552 - offset, (GXColor)WHITE);
3668 FONT_writeCenter("original 68k core (Musashi) by Karl Stenerud", 18, 0, 640, 570 - offset, (GXColor)WHITE);
3669 FONT_writeCenter("original YM2612/2413 cores by Jarek Burczynski, Tatsuyuki Satoh", 18, 0, 640, 588 - offset, (GXColor)WHITE);
3670 FONT_writeCenter("SVP core by Gravydas Ignotas (Notaz)", 18, 0, 640, 606 - offset, (GXColor)WHITE);
3671 FONT_writeCenter("Blip Buffer Library & NTSC Video Filter by Shay Green (Blargg)", 18, 0, 640, 624 - offset, (GXColor)WHITE);
3672 FONT_writeCenter("3-Band EQ implementation by Neil C", 18, 0, 640, 642 - offset, (GXColor)WHITE);
3673 FONT_writeCenter("Ogg Vorbis 'Tremor' Library by Xiph.org Foundation", 18, 0, 640, 660 - offset, (GXColor)WHITE);
3674 FONT_writeCenter("CHD Library by Aaron Giles, Romain Tisserand", 18, 0, 640, 678 - offset, (GXColor)WHITE);
3675 FONT_writeCenter("FLAC Library by Josh Coalson & Xiph.org Foundation", 18, 0, 640, 696 - offset, (GXColor)WHITE);
3676 FONT_writeCenter("ZLIB Library by Jean-loup Gailly & Mark Adler", 18, 0, 640, 714 - offset, (GXColor)WHITE);
3677 FONT_writeCenter("LZMA Library by Igor Pavlov", 18, 0, 640, 732 - offset, (GXColor)WHITE);
3678
3679 FONT_writeCenter("Special thanks to ...", 20, 0, 640, 772 - offset, (GXColor)LIGHT_GREEN);
3680 FONT_writeCenter("Nemesis, Tasco Deluxe, Mask of Destiny, Bart Trzynadlowski, Haze,", 18, 0, 640, 808 - offset, (GXColor)WHITE);
3681 FONT_writeCenter("Jorge Cwik, Stef, Notaz, AamirM, Steve Snake, Charles MacDonald", 18, 0, 640, 826 - offset, (GXColor)WHITE);
3682 FONT_writeCenter("Spritesmind & SMS Power forums members for their technical help", 18, 0, 640, 844 - offset, (GXColor)WHITE);
3683
3684 FONT_writeCenter("Gamecube & Wii port", 24, 0, 640, 902 - offset, (GXColor)LIGHT_BLUE);
3685 FONT_writeCenter("porting code, GUI engine & design by Eke-Eke", 18, 0, 640, 938 - offset, (GXColor)WHITE);
3686 FONT_writeCenter("original Gamecube port by Softdev, Honkeykong & Markcube", 18, 0, 640, 956 - offset, (GXColor)WHITE);
3687 FONT_writeCenter("original icons, logo & button design by Low Lines", 18, 0, 640, 974 - offset, (GXColor)WHITE);
3688 FONT_writeCenter("credit illustration by Orioto (Deviant Art)", 18, 0, 640, 992 - offset, (GXColor)WHITE);
3689 FONT_writeCenter("memory card icon design by Brakken", 18, 0, 640, 1010 - offset, (GXColor)WHITE);
3690 FONT_writeCenter("libogc by Shagkur & various other contibutors", 18, 0, 640, 1028 - offset, (GXColor)WHITE);
3691 FONT_writeCenter("libfat by Chism", 18, 0, 640, 1046 - offset, (GXColor)WHITE);
3692 FONT_writeCenter("wiiuse by Michael Laforest (Para)", 18, 0, 640, 1064 - offset, (GXColor)WHITE);
3693 FONT_writeCenter("asndlib & OGG player by Francisco Mu�oz (Hermes)", 18, 0, 640, 1082 - offset, (GXColor)WHITE);
3694 FONT_writeCenter("libwiidrc by Fix94", 18, 0, 640, 1100 - offset, (GXColor)WHITE);
3695 FONT_writeCenter("libpng by their respective authors", 18, 0, 640, 1118 - offset, (GXColor)WHITE);
3696 FONT_writeCenter("devkitPPC by Wintermute", 18, 0, 640, 1136 - offset, (GXColor)WHITE);
3697
3698 FONT_writeCenter("Special thanks to ...", 20, 0, 640, 1176 - offset, (GXColor)LIGHT_GREEN);
3699 FONT_writeCenter("Softdev, Tmbinc, Costis, Emukiddid, Team Twiizer", 18, 0, 640, 1212 - offset, (GXColor)WHITE);
3700 FONT_writeCenter("Brakken & former Tehskeen members for their support", 18, 0, 640, 1230 - offset, (GXColor)WHITE);
3701 FONT_writeCenter("Anca, my wife, for her patience & various ideas", 18, 0, 640, 1248 - offset, (GXColor)WHITE);
3702
3703 gxSetScreen();
3704 p = m_input.keys;
3705 gxSetScreen();
3706 p |= m_input.keys;
3707 offset ++;
3708 if (offset > 1222)
3709 offset = 0;
3710 }
3711
3712 gxTextureClose(&texture);
3713 }
3714
exitmenu(void)3715 static void exitmenu(void)
3716 {
3717 char title[64];
3718 char infos[64];
3719 char *items[3] =
3720 {
3721 "View Credits",
3722 #ifdef HW_RVL
3723 "Exit to System Menu",
3724 #else
3725 "Reset System",
3726 #endif
3727 "Return to Loader",
3728 };
3729
3730 #ifdef HW_RVL
3731 extern u8 __Arena2Lo[];
3732 sprintf(title, "%s (IOS %d)", VERSION, IOS_GetVersion());
3733 if ((u32)SYS_GetArena2Lo() > (u32)__Arena2Lo)
3734 sprintf(infos, "%d bytes free (MEM2)", (u32)SYS_GetArena2Size());
3735 else
3736 sprintf(infos, "%d bytes free (MEM1)", (u32)SYS_GetArena1Size());
3737 #else
3738 sprintf(title, "%s (GCN)", VERSION);
3739 sprintf(infos, "%d bytes free", (u32)SYS_GetArenaSize());
3740 #endif
3741
3742 /* check if loader stub exists */
3743 int maxitems = reload ? 3 : 2;
3744
3745 /* display option window */
3746 switch (GUI_OptionWindow(&menu_main, title, infos, items, maxitems))
3747 {
3748 case 0: /* credits */
3749 GUI_DeleteMenu(&menu_main);
3750 showcredits();
3751 GUI_InitMenu(&menu_main);
3752 break;
3753
3754 case 1: /* reset */
3755 #ifdef HW_RVL
3756 gxTextureClose(&w_pointer);
3757 #endif
3758 GUI_DeleteMenu(&menu_main);
3759 GUI_FadeOut();
3760 shutdown();
3761 #ifdef HW_RVL
3762 SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
3763 #else
3764 SYS_ResetSystem(SYS_HOTRESET,0,0);
3765 #endif
3766 break;
3767
3768 case 2: /* exit to loader */
3769 #ifdef HW_RVL
3770 gxTextureClose(&w_pointer);
3771 #endif
3772 GUI_DeleteMenu(&menu_main);
3773 GUI_FadeOut();
3774 shutdown();
3775 SYS_ResetSystem(SYS_SHUTDOWN,0,0);
3776 __lwp_thread_stopmultitasking(*reload);
3777 break;
3778
3779 default:
3780 break;
3781 }
3782 }
3783
3784 /****************************************************************************
3785 * Main Menu
3786 *
3787 ****************************************************************************/
3788
mainmenu_cb(void)3789 static void mainmenu_cb(void)
3790 {
3791 char temp[4];
3792 gui_menu *m = &menu_main;
3793 int status = areplay_get_status();
3794
3795 /* Action Replay Switch current status */
3796 if (status == AR_SWITCH_TRAINER)
3797 strcpy(temp,"TM");
3798 else if (status == AR_SWITCH_ON)
3799 strcpy(temp,"ON");
3800 else
3801 strcpy(temp,"OFF");
3802
3803 /* Display informations */
3804 if (m->selected == 6)
3805 {
3806 FONT_writeCenter("Action\nReplay", 14, m->items[6].x, m->items[6].x + 54, m->items[6].y + (m->items[6].h - 28)/2 + 14, (GXColor)DARK_GREY);
3807 FONT_writeCenter(temp, 11, m->items[6].x + 56 + 3, m->items[6].x + 78 + 2, m->items[6].y + (m->items[6].h - 11)/2 + 11, (GXColor)DARK_GREY);
3808 }
3809 else
3810 {
3811 FONT_writeCenter("Action\nReplay", 12, m->items[6].x + 4, m->items[6].x + 54, m->items[6].y + (m->items[6].h - 24)/2 + 12, (GXColor)DARK_GREY);
3812 FONT_writeCenter(temp, 10, m->items[6].x + 56, m->items[6].x + 78, m->items[6].y + (m->items[6].h - 10)/2 + 10, (GXColor)DARK_GREY);
3813 }
3814 }
3815
mainmenu(void)3816 void mainmenu(void)
3817 {
3818 char filename[MAXPATHLEN];
3819 int status, quit = 0;
3820
3821 /* Autosave Backup RAM */
3822 slot_autosave(0, config.s_device);
3823
3824 #ifdef HW_RVL
3825 /* Detect shutdown request */
3826 if (Shutdown)
3827 {
3828 GUI_FadeOut();
3829 shutdown();
3830 if (reload)
3831 {
3832 /* exit to loader if requested */
3833 SYS_ResetSystem(SYS_SHUTDOWN,0,0);
3834 __lwp_thread_stopmultitasking(*reload);
3835 }
3836 else
3837 {
3838 /* shutdown system by default */
3839 SYS_ResetSystem(SYS_POWEROFF, 0, 0);
3840 }
3841 }
3842
3843 /* Wiimote pointer */
3844 w_pointer = gxTextureOpenPNG(generic_point_png,0);
3845 #endif
3846
3847 gui_menu *m = &menu_main;
3848
3849 /* Update main menu */
3850 if (!m->screenshot)
3851 {
3852 if (config.bg_overlay)
3853 {
3854 bg_main[1].state |= IMAGE_VISIBLE;
3855 bg_misc[1].state |= IMAGE_VISIBLE;
3856 bg_ctrls[1].state |= IMAGE_VISIBLE;
3857 bg_list[1].state |= IMAGE_VISIBLE;
3858 bg_saves[2].state |= IMAGE_VISIBLE;
3859 }
3860 else
3861 {
3862 bg_main[1].state &= ~IMAGE_VISIBLE;
3863 bg_misc[1].state &= ~IMAGE_VISIBLE;
3864 bg_ctrls[1].state &= ~IMAGE_VISIBLE;
3865 bg_list[1].state &= ~IMAGE_VISIBLE;
3866 bg_saves[2].state &= ~IMAGE_VISIBLE;
3867 }
3868
3869 if (system_hw)
3870 {
3871 m->screenshot = 128;
3872 m->bg_images[0].state &= ~IMAGE_VISIBLE;
3873 m->items[0].y -= 90;
3874 m->items[1].y -= 90;
3875 m->items[2].y -= 90;
3876 m->buttons[0].y -= 90;
3877 m->buttons[1].y -= 90;
3878 m->buttons[2].y -= 90;
3879 m->buttons[0].shift[1] = 3;
3880 m->buttons[1].shift[1] = 3;
3881 m->buttons[2].shift[1] = 3;
3882 m->buttons[3].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3883 m->buttons[4].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3884 m->buttons[5].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3885 m->buttons[7].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3886 m->buttons[8].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3887 m->buttons[9].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3888 if (areplay_get_status() >= 0)
3889 {
3890 menu_main.buttons[6].state |= (BUTTON_VISIBLE | BUTTON_ACTIVE);
3891 menu_main.items[6].data = Button_sm_grey_png;
3892 menu_main.cb = mainmenu_cb;
3893 menu_main.buttons[3].shift[1] = 3;
3894 menu_main.buttons[7].shift[0] = 1;
3895 menu_main.buttons[8].shift[2] = 2;
3896 }
3897 }
3898 }
3899
3900 GUI_InitMenu(m);
3901 GUI_DrawMenuFX(m,10,0);
3902
3903 while (quit == 0)
3904 {
3905 switch (GUI_RunMenu(m))
3906 {
3907 /*** Load Game Menu ***/
3908 case 0:
3909 {
3910 GUI_DrawMenuFX(m,30,1);
3911 GUI_DeleteMenu(m);
3912
3913 if (loadgamemenu())
3914 {
3915 /* restart emulation */
3916 reloadrom();
3917
3918 /* check current controller configuration */
3919 if (!gx_input_FindDevices())
3920 {
3921 GUI_InitMenu(m);
3922 GUI_DrawMenuFX(m,30,0);
3923 GUI_WaitPrompt("Error","Invalid Controllers Settings");
3924 break;
3925 }
3926
3927 /* exit to game and reinitialize emulation */
3928 gxClearScreen((GXColor)BLACK);
3929 gxSetScreen();
3930 quit = 1;
3931 break;
3932 }
3933
3934 GUI_InitMenu(m);
3935 GUI_DrawMenuFX(m,30,0);
3936 break;
3937 }
3938
3939 /*** Options Menu */
3940 case 1:
3941 {
3942 GUI_DrawMenuFX(m,30,1);
3943 GUI_DeleteMenu(m);
3944 optionmenu();
3945 GUI_InitMenu(m);
3946 GUI_DrawMenuFX(m,30,0);
3947 break;
3948 }
3949
3950 /*** Exit Menu ***/
3951 case 2:
3952 {
3953 exitmenu();
3954 break;
3955 }
3956
3957 /*** Save Manager ***/
3958 case 3:
3959 {
3960 GUI_DrawMenuFX(m,30,1);
3961 GUI_DeleteMenu(m);
3962
3963 if (savemenu())
3964 {
3965 /* check current controller configuration */
3966 if (!gx_input_FindDevices())
3967 {
3968 GUI_InitMenu(m);
3969 GUI_DrawMenuFX(m,30,0);
3970 GUI_WaitPrompt("Error","Invalid Controllers Settings");
3971 break;
3972 }
3973
3974 /* exit to game */
3975 quit = 1;
3976 break;
3977 }
3978
3979 GUI_InitMenu(m);
3980 GUI_DrawMenuFX(m,30,0);
3981 break;
3982 }
3983
3984 /*** Soft / Hard reset ***/
3985 case 4:
3986 {
3987 /* check current controller configuration */
3988 if (!gx_input_FindDevices())
3989 {
3990 GUI_WaitPrompt("Error","Invalid Controllers Settings");
3991 break;
3992 }
3993
3994 /* reinitialize emulation */
3995 GUI_DrawMenuFX(m,10,1);
3996 GUI_DeleteMenu(m);
3997 gxClearScreen((GXColor)BLACK);
3998 gxSetScreen();
3999
4000 if (system_hw & SYSTEM_MD)
4001 {
4002 /* Soft Reset */
4003 gen_reset(0);
4004 }
4005 else if ((system_hw == SYSTEM_SMS) && (region_code != REGION_JAPAN_NTSC))
4006 {
4007 /* assert RESET input (export Master System 1 only) */
4008 io_reg[0x0D] &= ~IO_RESET_HI;
4009 }
4010 else
4011 {
4012 /* Hard Reset */
4013 system_reset();
4014 }
4015
4016 /* exit to game */
4017 quit = 1;
4018 break;
4019 }
4020
4021 /*** Cheats menu ***/
4022 case 5:
4023 {
4024 GUI_DrawMenuFX(m,30,1);
4025 GUI_DeleteMenu(m);
4026 CheatMenu();
4027 GUI_InitMenu(m);
4028 GUI_DrawMenuFX(m,30,0);
4029 break;
4030 }
4031
4032 /*** Action Replay switch ***/
4033 case 6:
4034 {
4035 status = (areplay_get_status() + 1) % (AR_SWITCH_TRAINER + 1);
4036 areplay_set_status(status);
4037 status = areplay_get_status();
4038 GUI_DeleteMenu(m);
4039 if (status == AR_SWITCH_TRAINER) m->items[6].data = Button_sm_blue_png;
4040 else if (status == AR_SWITCH_ON) m->items[6].data = Button_sm_yellow_png;
4041 else m->items[6].data = Button_sm_grey_png;
4042 GUI_InitMenu(m);
4043 break;
4044 }
4045
4046 /*** Return to Game ***/
4047 case 7:
4048 case -1:
4049 {
4050 if (system_hw)
4051 {
4052 /* check current controller configuration */
4053 if (!gx_input_FindDevices())
4054 {
4055 GUI_WaitPrompt("Error","Invalid Controllers Settings");
4056 break;
4057 }
4058
4059 /* exit to game */
4060 GUI_DrawMenuFX(m,10,1);
4061 GUI_DeleteMenu(m);
4062 quit = 1;
4063 }
4064 break;
4065 }
4066
4067 /*** Game Capture ***/
4068 case 8:
4069 {
4070 /* PNG filename */
4071 sprintf(filename,"%s/snaps/%s.png", DEFAULT_PATH, rom_filename);
4072
4073 /* Save file and return */
4074 gxSaveScreenshot(filename);
4075 break;
4076 }
4077
4078 /*** ROM information screen ***/
4079 case 9:
4080 {
4081 showrominfo();
4082 break;
4083 }
4084 }
4085 }
4086
4087 /*** Remove any still held buttons ***/
4088 while (PAD_ButtonsHeld(0))
4089 {
4090 VIDEO_WaitVSync();
4091 PAD_ScanPads();
4092 }
4093 #ifdef HW_RVL
4094 while (WPAD_ButtonsHeld(0))
4095 {
4096 VIDEO_WaitVSync();
4097 WPAD_ScanPads();
4098 }
4099 gxTextureClose(&w_pointer);
4100
4101 /* USB Mouse support */
4102 if ((input.system[0] == SYSTEM_MOUSE) || (input.system[1] == SYSTEM_MOUSE))
4103 {
4104 MOUSE_Init();
4105 }
4106 else
4107 {
4108 MOUSE_Deinit();
4109 }
4110 #endif
4111 }
4112