1
/* FakeNES - A free, portable, Open Source NES emulator.
3
gui.c: Implementation of the object-based GUI.
5
Copyright (c) 2001-2006, FakeNES Team.
6
This is free software. See 'LICENSE' for details.
7
You must read and accept the license prior to use. */
38
// TODO: Add configuration for the real-time game rewinder.
40
static BITMAP *gui_buffer = NULL;
42
static int dialog_x = 0;
43
static int dialog_y = 0;
44
static BOOL restart_dialog = FALSE;
47
ENUM gui_theme_id = -1;
48
const GUI_THEME *last_theme = NULL;
50
RGB *gui_image_palette = NULL;
51
static BITMAP *gui_mouse_sprite = NULL;
52
static BITMAP *background_image = NULL;
54
BOOL gui_is_active = FALSE;
55
static BOOL gui_needs_restart = FALSE;
56
static BOOL want_exit = FALSE;
58
static USTRING message_buffer;
60
static PALETTE custom_palette;
62
static int save_state_index = 0; /* For save states. */
63
static int replay_index = 0; /* For replays. */
65
/* Text that appears in "unused" menu slots for recent items. */
66
#define UNUSED_SLOT_TEXT "Empty"
68
/* Number of slots available in each of the associated menus. */
69
#define OPEN_RECENT_SLOTS 10
70
#define REPLAY_SLOTS 10
71
#define SAVE_STATE_SLOTS 10
73
static USTRING open_recent_filenames[OPEN_RECENT_SLOTS];
74
static USTRING open_recent_menu_texts[OPEN_RECENT_SLOTS];
75
static USTRING replay_titles[REPLAY_SLOTS];
76
static USTRING replay_menu_texts[REPLAY_SLOTS];
77
static USTRING save_state_titles[SAVE_STATE_SLOTS];
78
static USTRING save_state_menu_texts[SAVE_STATE_SLOTS];
80
static BOOL lock_recent = FALSE;
82
/* Keep these in order! */
83
#include "gui/themes.h"
84
#include "gui/objects.h"
85
#include "gui/menus.h"
86
#include "gui/dialogs.h"
90
static INLINE void update_menus (void)
92
static USTRING audio_menu_volume_text;
95
DISABLE_MENU_ITEM(audio_output_menu_subsystem_openal);
100
DISABLE_MENU_ITEM(main_menu_resume);
101
DISABLE_MENU_ITEM(main_menu_close);
102
DISABLE_SUBMENU(main_replay_menu);
103
DISABLE_MENU_ITEM(main_menu_cheat_manager);
104
DISABLE_MENU_ITEM(main_menu_save_snapshot);
105
DISABLE_MENU_ITEM(main_menu_advance_frame);
106
DISABLE_MENU_ITEM(machine_menu_reset);
107
DISABLE_MENU_ITEM(machine_menu_power_cycle);
108
DISABLE_SUBMENU(machine_save_state_menu);
109
DISABLE_SUBMENU(audio_record_menu);
110
DISABLE_MENU_ITEM(video_layers_menu_flip_mirroring);
111
DISABLE_MENU_ITEM(options_menu_reset_clock);
114
/* Page buffer and VSync are not supported in OpenGL mode. */
115
SET_MENU_ITEM_ENABLED(video_menu_page_buffer, !video_is_opengl_mode ());
116
SET_MENU_ITEM_ENABLED(video_menu_vsync, !video_is_opengl_mode ());
118
TOGGLE_MENU_ITEM(main_open_recent_menu_lock, lock_recent);
120
TOGGLE_MENU_ITEM(main_replay_select_menu_0, (replay_index == 0));
121
TOGGLE_MENU_ITEM(main_replay_select_menu_1, (replay_index == 1));
122
TOGGLE_MENU_ITEM(main_replay_select_menu_2, (replay_index == 2));
123
TOGGLE_MENU_ITEM(main_replay_select_menu_3, (replay_index == 3));
124
TOGGLE_MENU_ITEM(main_replay_select_menu_4, (replay_index == 4));
126
TOGGLE_MENU_ITEM(machine_menu_show_status, video_display_status);
128
TOGGLE_MENU_ITEM(machine_menu_timing_smoothest, (machine_timing == MACHINE_TIMING_SMOOTH));
129
TOGGLE_MENU_ITEM(machine_menu_timing_most_accurate, (machine_timing == MACHINE_TIMING_ACCURATE));
131
TOGGLE_MENU_ITEM(machine_save_state_select_menu_0, (save_state_index == 0));
132
TOGGLE_MENU_ITEM(machine_save_state_select_menu_1, (save_state_index == 1));
133
TOGGLE_MENU_ITEM(machine_save_state_select_menu_2, (save_state_index == 2));
134
TOGGLE_MENU_ITEM(machine_save_state_select_menu_3, (save_state_index == 3));
135
TOGGLE_MENU_ITEM(machine_save_state_select_menu_4, (save_state_index == 4));
136
TOGGLE_MENU_ITEM(machine_save_state_select_menu_5, (save_state_index == 5));
137
TOGGLE_MENU_ITEM(machine_save_state_select_menu_6, (save_state_index == 6));
138
TOGGLE_MENU_ITEM(machine_save_state_select_menu_7, (save_state_index == 7));
139
TOGGLE_MENU_ITEM(machine_save_state_select_menu_8, (save_state_index == 8));
140
TOGGLE_MENU_ITEM(machine_save_state_select_menu_9, (save_state_index == 9));
142
TOGGLE_MENU_ITEM(machine_save_state_autosave_menu_disabled, (input_autosave_interval == 0));
143
TOGGLE_MENU_ITEM(machine_save_state_autosave_menu_10_seconds, (input_autosave_interval == 10));
144
TOGGLE_MENU_ITEM(machine_save_state_autosave_menu_30_seconds, (input_autosave_interval == 30));
145
TOGGLE_MENU_ITEM(machine_save_state_autosave_menu_60_seconds, (input_autosave_interval == 60));
147
TOGGLE_MENU_ITEM(machine_region_menu_automatic, (machine_region == MACHINE_REGION_AUTOMATIC));
148
TOGGLE_MENU_ITEM(machine_region_menu_ntsc, (machine_region == MACHINE_REGION_NTSC));
149
TOGGLE_MENU_ITEM(machine_region_menu_pal, (machine_region == MACHINE_REGION_PAL));
151
TOGGLE_MENU_ITEM(machine_speed_up_down_menu_50_percent, COMPARE_TWO_REALS(timing_speed_multiplier, 0.5));
152
TOGGLE_MENU_ITEM(machine_speed_up_down_menu_100_percent, COMPARE_TWO_REALS(timing_speed_multiplier, 1.0));
153
TOGGLE_MENU_ITEM(machine_speed_up_down_menu_200_percent, COMPARE_TWO_REALS(timing_speed_multiplier, 2.0));
155
TOGGLE_MENU_ITEM(machine_menu_speed_cap, speed_cap);
157
TOGGLE_MENU_ITEM(machine_frame_skip_menu_automatic, (frame_skip == -1));
158
TOGGLE_MENU_ITEM(machine_frame_skip_menu_disabled, (frame_skip == 0));
159
TOGGLE_MENU_ITEM(machine_frame_skip_menu_1_frames, (frame_skip == 1));
160
TOGGLE_MENU_ITEM(machine_frame_skip_menu_2_frames, (frame_skip == 2));
161
TOGGLE_MENU_ITEM(machine_frame_skip_menu_3_frames, (frame_skip == 3));
162
TOGGLE_MENU_ITEM(machine_frame_skip_menu_4_frames, (frame_skip == 4));
163
TOGGLE_MENU_ITEM(machine_frame_skip_menu_5_frames, (frame_skip == 5));
164
TOGGLE_MENU_ITEM(machine_frame_skip_menu_6_frames, (frame_skip == 6));
165
TOGGLE_MENU_ITEM(machine_frame_skip_menu_7_frames, (frame_skip == 7));
166
TOGGLE_MENU_ITEM(machine_frame_skip_menu_8_frames, (frame_skip == 8));
167
TOGGLE_MENU_ITEM(machine_frame_skip_menu_9_frames, (frame_skip == 9));
168
TOGGLE_MENU_ITEM(machine_frame_skip_menu_10_frames, (frame_skip == 10));
170
TOGGLE_MENU_ITEM(audio_menu_enable_apu, apu_options.enabled);
171
TOGGLE_MENU_ITEM(audio_menu_enable_output, audio_options.enable_output);
173
TOGGLE_MENU_ITEM(audio_menu_emulation_fast, (apu_options.emulation == APU_EMULATION_FAST));
174
TOGGLE_MENU_ITEM(audio_menu_emulation_accurate, (apu_options.emulation == APU_EMULATION_ACCURATE));
175
TOGGLE_MENU_ITEM(audio_menu_emulation_high_quality, (apu_options.emulation == APU_EMULATION_HIGH_QUALITY));
177
TOGGLE_MENU_ITEM(audio_menu_volume_auto_normalize, apu_options.normalize);
179
TOGGLE_MENU_ITEM(audio_channels_menu_square_1, apu_options.enable_square_1);
180
TOGGLE_MENU_ITEM(audio_channels_menu_square_2, apu_options.enable_square_2);
181
TOGGLE_MENU_ITEM(audio_channels_menu_triangle, apu_options.enable_triangle);
182
TOGGLE_MENU_ITEM(audio_channels_menu_noise, apu_options.enable_noise);
183
TOGGLE_MENU_ITEM(audio_channels_menu_dmc, apu_options.enable_dmc);
184
TOGGLE_MENU_ITEM(audio_channels_menu_extra_1, apu_options.enable_extra_1);
185
TOGGLE_MENU_ITEM(audio_channels_menu_extra_2, apu_options.enable_extra_2);
186
TOGGLE_MENU_ITEM(audio_channels_menu_extra_3, apu_options.enable_extra_3);
188
TOGGLE_MENU_ITEM(audio_output_menu_subsystem_allegro, (audio_options.subsystem == AUDIO_SUBSYSTEM_ALLEGRO));
189
TOGGLE_MENU_ITEM(audio_output_menu_subsystem_openal, (audio_options.subsystem == AUDIO_SUBSYSTEM_OPENAL));
191
TOGGLE_MENU_ITEM(audio_output_menu_sampling_rate_automatic, (audio_options.sample_rate_hint == -1));
192
TOGGLE_MENU_ITEM(audio_output_menu_sampling_rate_22050_hz, (audio_options.sample_rate_hint == 22050));
193
TOGGLE_MENU_ITEM(audio_output_menu_sampling_rate_44100_hz, (audio_options.sample_rate_hint == 44100));
194
TOGGLE_MENU_ITEM(audio_output_menu_sampling_rate_48000_hz, (audio_options.sample_rate_hint == 48000));
196
TOGGLE_MENU_ITEM(audio_output_menu_mixing_mono, !apu_options.stereo);
197
TOGGLE_MENU_ITEM(audio_output_menu_mixing_stereo, (apu_options.stereo && !apu_options.swap_channels)); TOGGLE_MENU_ITEM(audio_output_menu_mixing_stereo_inverted, (apu_options.stereo && apu_options.swap_channels));
199
TOGGLE_MENU_ITEM(audio_output_buffer_menu_automatic, (audio_options.buffer_length_ms_hint == -1));
200
TOGGLE_MENU_ITEM(audio_output_buffer_menu_30ms, (audio_options.buffer_length_ms_hint == 30));
201
TOGGLE_MENU_ITEM(audio_output_buffer_menu_50ms, (audio_options.buffer_length_ms_hint == 50));
202
TOGGLE_MENU_ITEM(audio_output_buffer_menu_75ms, (audio_options.buffer_length_ms_hint == 75));
203
TOGGLE_MENU_ITEM(audio_output_buffer_menu_100ms, (audio_options.buffer_length_ms_hint == 100));
204
TOGGLE_MENU_ITEM(audio_output_buffer_menu_125ms, (audio_options.buffer_length_ms_hint == 125));
205
TOGGLE_MENU_ITEM(audio_output_buffer_menu_150ms, (audio_options.buffer_length_ms_hint == 150));
206
TOGGLE_MENU_ITEM(audio_output_buffer_menu_175ms, (audio_options.buffer_length_ms_hint == 175));
207
TOGGLE_MENU_ITEM(audio_output_buffer_menu_200ms, (audio_options.buffer_length_ms_hint == 200));
211
TOGGLE_MENU_ITEM(video_driver_dos_menu_vga, (gfx_driver->id == GFX_VGA));
212
TOGGLE_MENU_ITEM(video_driver_dos_menu_vga_mode_x, (gfx_driver->id == GFX_MODEX));
213
TOGGLE_MENU_ITEM(video_driver_dos_menu_vesa, (gfx_driver->id == GFX_VESA1));
214
TOGGLE_MENU_ITEM(video_driver_dos_menu_vesa_2_banked, (gfx_driver->id == GFX_VESA2B));
215
TOGGLE_MENU_ITEM(video_driver_dos_menu_vesa_2_linear, (gfx_driver->id == GFX_VESA2L));
216
TOGGLE_MENU_ITEM(video_driver_dos_menu_vesa_3, (gfx_driver->id == GFX_VESA3));
217
TOGGLE_MENU_ITEM(video_driver_dos_menu_vesa_vbe_af, (gfx_driver->id == GFX_VBEAF));
219
#endif /* ALLEGRO_DOS */
221
#ifdef ALLEGRO_WINDOWS
223
TOGGLE_MENU_ITEM(video_driver_windows_menu_directx, (gfx_driver->id == GFX_DIRECTX));
224
TOGGLE_MENU_ITEM(video_driver_windows_menu_directx_window, (gfx_driver->id == GFX_DIRECTX_WIN));
225
TOGGLE_MENU_ITEM(video_driver_windows_menu_directx_overlay, (gfx_driver->id == GFX_DIRECTX_OVL));
226
TOGGLE_MENU_ITEM(video_driver_windows_menu_gdi, (gfx_driver->id == GFX_GDI));
228
#endif /* ALLEGRO_WINDOWS */
232
TOGGLE_MENU_ITEM(video_driver_linux_menu_vga, (gfx_driver->id == GFX_VGA));
233
TOGGLE_MENU_ITEM(video_driver_linux_menu_vga_mode_x, (gfx_driver->id == GFX_MODEX));
234
TOGGLE_MENU_ITEM(video_driver_linux_menu_vesa_vbe_af, (gfx_driver->id == GFX_VBEAF));
236
TOGGLE_MENU_ITEM(video_driver_linux_menu_framebuffer, (gfx_driver->id == GFX_FBCON));
239
TOGGLE_MENU_ITEM(video_driver_linux_menu_svgalib, (gfx_driver->id == GFX_SVGALIB));
242
#endif /* ALLEGRO_LINUX */
246
TOGGLE_MENU_ITEM(video_driver_unix_menu_x_windows, (gfx_driver->id == GFX_XWINDOWS));
247
TOGGLE_MENU_ITEM(video_driver_unix_menu_x_windows_full, (gfx_driver->id == GFX_XWINDOWS_FULLSCREEN));
248
TOGGLE_MENU_ITEM(video_driver_unix_menu_x_dga, (gfx_driver->id == GFX_XDGA));
249
TOGGLE_MENU_ITEM(video_driver_unix_menu_x_dga_full, (gfx_driver->id == GFX_XDGA_FULLSCREEN));
250
TOGGLE_MENU_ITEM(video_driver_unix_menu_x_dga_2, (gfx_driver->id == GFX_XDGA2));
252
#endif /* ALLEGRO_UNIX */
256
TOGGLE_MENU_ITEM(video_driver_menu_opengl_full, (gfx_driver->id == GFX_OPENGL_FULLSCREEN));
257
TOGGLE_MENU_ITEM(video_driver_menu_opengl_win, (gfx_driver->id == GFX_OPENGL_WINDOWED));
259
#endif /* USE_ALLEGROGL */
261
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_256_224, ((SCREEN_W == 256) && (SCREEN_H == 224)));
262
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_256_240, ((SCREEN_W == 256) && (SCREEN_H == 240)));
263
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_512_448, ((SCREEN_W == 512) && (SCREEN_H == 448)));
264
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_512_480, ((SCREEN_W == 512) && (SCREEN_H == 480)));
265
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_768_672, ((SCREEN_W == 768) && (SCREEN_H == 672)));
266
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_768_720, ((SCREEN_W == 768) && (SCREEN_H == 720)));
267
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_1024_896, ((SCREEN_W == 1024) && (SCREEN_H == 896)));
268
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_1024_960, ((SCREEN_W == 1024) && (SCREEN_H == 960)));
269
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_1280_1120, ((SCREEN_W == 1280) && (SCREEN_H == 1120)));
270
TOGGLE_MENU_ITEM(video_resolution_proportionate_menu_1280_1200, ((SCREEN_W == 1280) && (SCREEN_H == 1200)));
272
TOGGLE_MENU_ITEM(video_resolution_menu_320_240, ((SCREEN_W == 320) && (SCREEN_H == 240)));
273
TOGGLE_MENU_ITEM(video_resolution_menu_400_300, ((SCREEN_W == 400) && (SCREEN_H == 300)));
274
TOGGLE_MENU_ITEM(video_resolution_menu_640_480, ((SCREEN_W == 640) && (SCREEN_H == 480)));
275
TOGGLE_MENU_ITEM(video_resolution_menu_800_600, ((SCREEN_W == 800) && (SCREEN_H == 600)));
276
TOGGLE_MENU_ITEM(video_resolution_menu_1024_768, ((SCREEN_W == 1024) && (SCREEN_H == 768)));
277
TOGGLE_MENU_ITEM(video_resolution_menu_1152_864, ((SCREEN_W == 1152) && (SCREEN_H == 864)));
278
TOGGLE_MENU_ITEM(video_resolution_menu_1280_960, ((SCREEN_W == 1280) && (SCREEN_H == 960)));
279
TOGGLE_MENU_ITEM(video_resolution_menu_1280_1024, ((SCREEN_W == 1280) && (SCREEN_H == 1024)));
280
TOGGLE_MENU_ITEM(video_resolution_menu_1600_1200, ((SCREEN_W == 1600) && (SCREEN_H == 1200)));
282
TOGGLE_MENU_ITEM(video_color_depth_menu_paletted_8_bit, (video_get_color_depth () == 8));
283
TOGGLE_MENU_ITEM(video_color_depth_menu_true_color_15_bit, (video_get_color_depth () == 15));
284
TOGGLE_MENU_ITEM(video_color_depth_menu_true_color_16_bit, (video_get_color_depth () == 16));
285
TOGGLE_MENU_ITEM(video_color_depth_menu_true_color_24_bit, (video_get_color_depth () == 24));
286
TOGGLE_MENU_ITEM(video_color_depth_menu_true_color_32_bit, (video_get_color_depth () == 32));
288
TOGGLE_MENU_ITEM(video_buffer_menu_match_resolution, ((video_buffer_width == -1) && (video_buffer_height == -1)));
289
TOGGLE_MENU_ITEM(video_buffer_menu_256_240, ((video_buffer_width == 256) && (video_buffer_height == 240)));
290
TOGGLE_MENU_ITEM(video_buffer_menu_320_240, ((video_buffer_width == 320) && (video_buffer_height == 240)));
291
TOGGLE_MENU_ITEM(video_buffer_menu_512_480, ((video_buffer_width == 512) && (video_buffer_height == 480)));
292
TOGGLE_MENU_ITEM(video_buffer_menu_640_480, ((video_buffer_width == 640) && (video_buffer_height == 480)));
293
TOGGLE_MENU_ITEM(video_buffer_menu_256_256, ((video_buffer_width == 256) && (video_buffer_height == 256)));
294
TOGGLE_MENU_ITEM(video_buffer_menu_512_512, ((video_buffer_width == 512) && (video_buffer_height == 512)));
296
TOGGLE_MENU_ITEM(video_blitter_menu_automatic, (video_get_blitter () == VIDEO_BLITTER_AUTOMATIC));
297
TOGGLE_MENU_ITEM(video_blitter_menu_normal, (video_get_blitter () == VIDEO_BLITTER_NORMAL));
298
TOGGLE_MENU_ITEM(video_blitter_menu_des, (video_get_blitter () == VIDEO_BLITTER_DES));
299
TOGGLE_MENU_ITEM(video_blitter_menu_interpolated_2x, (video_get_blitter () == VIDEO_BLITTER_INTERPOLATED_2X));
300
TOGGLE_MENU_ITEM(video_blitter_menu_interpolated_2x_hq, (video_get_blitter () == VIDEO_BLITTER_INTERPOLATED_2X_HQ));
301
TOGGLE_MENU_ITEM(video_blitter_menu_2xscl, (video_get_blitter () == VIDEO_BLITTER_2XSCL));
302
TOGGLE_MENU_ITEM(video_blitter_menu_desii, (video_get_blitter () == VIDEO_BLITTER_DESII));
303
TOGGLE_MENU_ITEM(video_blitter_menu_super_2xscl, (video_get_blitter () == VIDEO_BLITTER_SUPER_2XSCL));
304
TOGGLE_MENU_ITEM(video_blitter_menu_ultra_2xscl, (video_get_blitter () == VIDEO_BLITTER_ULTRA_2XSCL));
305
TOGGLE_MENU_ITEM(video_blitter_menu_hq2x, (video_get_blitter () == VIDEO_BLITTER_HQ2X));
306
TOGGLE_MENU_ITEM(video_blitter_menu_ntsc, (video_get_blitter () == VIDEO_BLITTER_NTSC));
307
TOGGLE_MENU_ITEM(video_blitter_menu_interpolated_3x, (video_get_blitter () == VIDEO_BLITTER_INTERPOLATED_3X));
308
TOGGLE_MENU_ITEM(video_blitter_menu_hq3x, (video_get_blitter () == VIDEO_BLITTER_HQ3X));
309
TOGGLE_MENU_ITEM(video_blitter_menu_hq4x, (video_get_blitter () == VIDEO_BLITTER_HQ4X));
310
TOGGLE_MENU_ITEM(video_blitter_menu_stretched, (video_get_blitter () == VIDEO_BLITTER_STRETCHED));
312
TOGGLE_MENU_ITEM(video_filters_menu_scanlines_25_percent, (video_get_filter_list () & VIDEO_FILTER_SCANLINES_LOW));
313
TOGGLE_MENU_ITEM(video_filters_menu_scanlines_50_percent, (video_get_filter_list () & VIDEO_FILTER_SCANLINES_MEDIUM));
314
TOGGLE_MENU_ITEM(video_filters_menu_scanlines_100_percent, (video_get_filter_list () & VIDEO_FILTER_SCANLINES_HIGH));
316
TOGGLE_MENU_ITEM(video_menu_fullscreen, video_force_fullscreen);
317
TOGGLE_MENU_ITEM(video_menu_page_buffer, video_enable_page_buffer);
318
TOGGLE_MENU_ITEM(video_menu_vsync, video_enable_vsync);
320
TOGGLE_MENU_ITEM(video_palette_menu_ntsc_color, (video_get_palette_id () == DATA_INDEX(DEFAULT_PALETTE)));
321
TOGGLE_MENU_ITEM(video_palette_menu_ntsc_grayscale, (video_get_palette_id () == DATA_INDEX(GRAYSCALE_PALETTE)));
322
TOGGLE_MENU_ITEM(video_palette_menu_gnuboy, (video_get_palette_id () == DATA_INDEX(GNUBOY_PALETTE)));
323
TOGGLE_MENU_ITEM(video_palette_menu_nester, (video_get_palette_id () == DATA_INDEX(NESTER_PALETTE)));
324
TOGGLE_MENU_ITEM(video_palette_menu_nesticle, (video_get_palette_id () == DATA_INDEX(NESTICLE_PALETTE)));
325
TOGGLE_MENU_ITEM(video_palette_menu_modern_ntsc, (video_get_palette_id () == DATA_INDEX(MODERN_NTSC_PALETTE)));
326
TOGGLE_MENU_ITEM(video_palette_menu_modern_pal, (video_get_palette_id () == DATA_INDEX(MODERN_PAL_PALETTE)));
327
TOGGLE_MENU_ITEM(video_palette_menu_ega_mode_1, (video_get_palette_id () == DATA_INDEX(EGA_PALETTE_1)));
328
TOGGLE_MENU_ITEM(video_palette_menu_ega_mode_2, (video_get_palette_id () == DATA_INDEX(EGA_PALETTE_2)));
329
TOGGLE_MENU_ITEM(video_palette_menu_custom, (video_get_palette_id () == -1));
331
TOGGLE_MENU_ITEM(video_layers_menu_sprites_a, ppu_enable_sprite_layer_a);
332
TOGGLE_MENU_ITEM(video_layers_menu_sprites_b, ppu_enable_sprite_layer_b);
333
TOGGLE_MENU_ITEM(video_layers_menu_background, ppu_enable_background_layer);
334
TOGGLE_MENU_ITEM(video_layers_menu_hide_horizontal_scrolling, (video_edge_clipping & VIDEO_EDGE_CLIPPING_HORIZONTAL));
335
TOGGLE_MENU_ITEM(video_layers_menu_hide_vertical_scrolling, (video_edge_clipping & VIDEO_EDGE_CLIPPING_VERTICAL));
337
TOGGLE_MENU_ITEM(input_menu_enable_zapper, input_enable_zapper);
339
TOGGLE_MENU_ITEM(options_cpu_usage_menu_passive, (cpu_usage == CPU_USAGE_PASSIVE));
340
TOGGLE_MENU_ITEM(options_cpu_usage_menu_normal, (cpu_usage == CPU_USAGE_NORMAL));
341
TOGGLE_MENU_ITEM(options_cpu_usage_menu_aggressive, (cpu_usage == CPU_USAGE_AGGRESSIVE));
343
TOGGLE_MENU_ITEM(options_gui_theme_menu_classic, (last_theme == &classic_theme));
344
TOGGLE_MENU_ITEM(options_gui_theme_menu_stainless_steel, (last_theme == &stainless_steel_theme));
345
TOGGLE_MENU_ITEM(options_gui_theme_menu_zero_4, (last_theme == &zero_4_theme));
346
TOGGLE_MENU_ITEM(options_gui_theme_menu_panta, (last_theme == &panta_theme));
347
TOGGLE_MENU_ITEM(options_gui_theme_menu_xodiac, (last_theme == &xodiac_theme));
348
TOGGLE_MENU_ITEM(options_gui_theme_menu_monochrome, (last_theme == &monochrome_theme));
349
TOGGLE_MENU_ITEM(options_gui_theme_menu_essence, (last_theme == &essence_theme));
350
TOGGLE_MENU_ITEM(options_gui_theme_menu_voodoo, (last_theme == &voodoo_theme));
351
TOGGLE_MENU_ITEM(options_gui_theme_menu_hugs_and_kisses, (last_theme == &hugs_and_kisses_theme));
353
/* TODO: Find a better way to do this. */
354
uszprintf (audio_menu_volume_text, sizeof (audio_menu_volume_text),
355
"Current volume: %d%%", (int)ROUND((apu_options.volume * 100.0)));
356
audio_menu[AUDIO_MENU_VOLUME_TEXT].text = audio_menu_volume_text;
359
void gui_load_config (void)
361
gui_theme_id = get_config_int ("gui", "theme", GUI_THEME_PANTA);
362
lock_recent = get_config_int ("gui", "lock_recent", FALSE);
365
void gui_save_config (void)
370
STRING_CLEAR(save_path);
371
strncpy (save_path, get_config_string ("gui", "save_path", "./"),
372
sizeof (save_path) - 1);
373
set_config_string ("gui", "save_path", save_path);
376
strncpy (host, get_config_string ("netplay", "host", ""), (sizeof(host) - 1));
377
set_config_string ("netplay", "host", host);
379
set_config_int ("gui", "theme", gui_theme_id);
380
set_config_int ("gui", "lock_recent", lock_recent);
387
/* Set up replacement objects. */
388
gui_menu_draw_menu = sl_draw_menu;
389
gui_menu_draw_menu_item = sl_draw_menu_item;
391
/* Set up menus & dialogs. */
397
CHECK_MENU_ITEM(video_menu_fullscreen);
398
DISABLE_MENU_ITEM(video_menu_fullscreen);
399
DISABLE_MENU(options_cpu_usage_menu);
401
#endif /* ALLEGRO_DOS */
406
DISABLE_MENU_ITEM(video_driver_linux_menu_framebuffer);
409
DISABLE_MENU_ITEM(video_driver_linux_menu_svgalib);
412
#endif /* !ALLEGRO_LINUX */
414
/* Select default palette. */
415
CHECK_MENU_ITEM(video_palette_menu_modern_ntsc);
417
/* Load up recent items. */
419
main_open_recent_menu_clear ();
421
for (index = 0; index < OPEN_RECENT_SLOTS; index++)
425
UCHAR *filename = open_recent_filenames[index];
426
UCHAR *text = open_recent_menu_texts[index];
427
MENU *menu = &main_open_recent_menu[index];
430
uszprintf (key, sizeof (key), "recent%d", index);
432
path = get_config_string ("gui", key, NULL);
436
uszprintf (filename, USTRING_SIZE, "%s", path);
437
uszprintf (text, USTRING_SIZE, "&%d: %s", index, get_filename
444
menu->flags &= ~D_DISABLED;
447
/* Cheap hack to fix palette. */
448
gui_is_active = TRUE;
450
gui_is_active = FALSE;
459
/* Save recent items. */
461
for (index = 0; index < OPEN_RECENT_SLOTS; index++)
464
const UCHAR *filename = open_recent_filenames[index];
470
uszprintf (key, sizeof (key), "recent%d", index);
472
set_config_string ("gui", key, filename);
479
int show_gui (BOOL first_run)
487
/* Clear restart flag. */
488
gui_needs_restart = FALSE;
492
result = gui_open ();
496
WARN("Failed to open GUI");
497
return ((8 + result));
509
/* Update menu states. */
512
/* Run main dialog. */
513
run_dialog (main_dialog, -1);
516
gui_close (want_exit);
518
} while (gui_needs_restart);
523
int gui_alert (const UCHAR *title, const UCHAR *s1, const UCHAR *s2, const
524
UCHAR *s3, const UCHAR *b1, const UCHAR *b2, int c1, int c2)
526
/* Alert dialog with 1 or 2 buttons. The title, first string, and first
527
button are required. The rest are optional and may be NULL.
529
This function can even be called when the GUI isn't open. It'll
530
automatically open the GUI long enough to display the dialog. */
533
BOOL gui_opened = FALSE;
537
DIALOG *objstr1, *objstr2, *objstr3;
538
DIALOG *objbtn1, *objbtn2;
539
int s1len, s2len, s3len;
546
/* Handle any NULL entries. */
548
if (!s2) s2 = empty_string;
549
if (!s3) s3 = empty_string;
551
if (ustrlen (s2) == 0)
552
collapse += (text_height (font) + 3);
553
if (ustrlen (s3) == 0)
554
collapse += (text_height (font) + 3);
560
result = gui_open ();
564
WARN("Failed to open GUI");
565
return ((8 + result));
572
dialog = load_dialog (alert_dialog_base);
575
WARN("Failed to create dialog structure");
579
/* Get all objects. */
581
objframe = &dialog[ALERT_DIALOG_FRAME];
582
objxbutton = &dialog[ALERT_DIALOG_CLOSE_BUTTON];
583
objstr1 = &dialog[ALERT_DIALOG_STRING_1];
584
objstr2 = &dialog[ALERT_DIALOG_STRING_2];
585
objstr3 = &dialog[ALERT_DIALOG_STRING_3];
586
objbtn1 = &dialog[ALERT_DIALOG_BUTTON_1];
587
objbtn2 = &dialog[ALERT_DIALOG_BUTTON_2];
589
/* Calculate string lengths (in pixels). */
591
s1len = text_length (font, s1);
592
s2len = text_length (font, s2);
593
s3len = text_length (font, s3);
597
objframe->w = (9 + MAX3(s1len, s2len, s3len) + 9);
598
objframe->dp2 = (char *)title;
600
objxbutton->x = ((objframe->w - objxbutton->w) - 4);
602
/* Set up strings. */
604
objstr1->x = ((objframe->w / 2) - (s1len / 2));
605
objstr1->dp2 = (char *)s1;
607
objstr2->x = ((objframe->w / 2) - (s2len / 2));
608
objstr2->dp2 = (char *)s2;
610
objstr3->x = ((objframe->w / 2) - (s3len / 2));
611
objstr3->dp2 = (char *)s3;
613
/* Set up buttons. */
615
objbtn1->x = ((objframe->w / 2) - (objbtn1->w / 2));
616
objbtn1->dp = (char *)b1;
619
objbtn1->y -= collapse;
623
objbtn1->x -= ((objbtn2->w / 2) + 4);
625
objbtn2->x = ((objbtn1->x + objbtn1->w) + 8);
626
objbtn2->dp = (char *)b2;
629
objbtn2->y -= collapse;
633
/* Hide the unused button. */
635
objbtn2->flags |= D_HIDDEN;
636
objbtn2->flags |= D_DISABLED;
639
/* Collapse frame. */
640
objframe->h -= collapse;
643
result = show_dialog (dialog, ALERT_DIALOG_BUTTON_1);
645
/* Destroy dialog. */
646
unload_dialog (dialog);
654
if (result == ALERT_DIALOG_BUTTON_1)
655
return (1); /* OK. */
657
return (2); /* Cancel. */
660
void gui_message (int color, const UCHAR *message, ...)
666
va_start (format, message);
667
uvszprintf (message_buffer, USTRING_SIZE, message, format);
673
color = GUI_TEXT_COLOR;
675
draw_message (color);
678
video_message (message_buffer);
679
video_message_duration = 3000;
681
log_printf ("GUI: %s", message_buffer);
684
void gui_heartbeat (void)
686
/* Called in varous places to process NetPlay (if active), refresh the
687
screen, and rest() to minimize CPU usage in the GUI. */
694
if (cpu_usage == CPU_USAGE_PASSIVE)
696
else if (cpu_usage == CPU_USAGE_NORMAL)
700
void gui_handle_keypress (int c, int scancode)
707
main_menu_save_snapshot ();
714
/* Toggle status display. */
715
machine_menu_show_status ();
722
/* Quick save state. */
723
machine_save_state_menu_quick_save ();
725
/* See if the save succeeded. */
726
if (check_save_state (-1))
727
message_local ("QuickSave: OK");
729
message_local ("QuickSave: Failed");
736
/* Quick load state. */
738
if (!(input_mode & INPUT_MODE_REPLAY))
739
machine_save_state_menu_quick_load ();
747
machine_save_state_menu_save ();
756
if (!(input_mode & INPUT_MODE_REPLAY))
757
machine_save_state_menu_restore ();
764
/* Toggle sprites. */
766
video_layers_menu_sprites_a ();
767
video_layers_menu_sprites_b ();
774
/* Toggle background. */
775
video_layers_menu_background ();
782
/* Toggle half speed mode. */
784
timing_half_speed = !timing_half_speed;
785
timing_update_speed ();
792
/* Start/stop replay recording. */
794
if (!(input_mode & INPUT_MODE_REPLAY_PLAY))
796
if (input_mode & INPUT_MODE_REPLAY_RECORD)
797
main_replay_record_menu_stop ();
799
main_replay_record_menu_start ();
816
/* Select state slot. */
818
if (!(input_mode & INPUT_MODE_CHAT))
820
save_state_index = (scancode - KEY_0);
822
message_local ("Machine state slot set to %d.",
832
audio_menu_volume_decrease ();
839
audio_menu_volume_increase ();
848
void gui_stop_replay (void)
850
main_replay_play_menu_stop ();
853
void gui_set_theme (const GUI_THEME *theme)
861
memcpy (&gui_theme, theme, sizeof (GUI_THEME));
863
video_set_palette (NULL);
865
for (index = 0; index < GUI_TOTAL_COLORS; index++)
866
pack_color (&gui_theme[index]);
868
gui_bg_color = GUI_FILL_COLOR;
869
gui_fg_color = GUI_TEXT_COLOR;
870
gui_mg_color = GUI_DISABLED_COLOR;
873
/* --- Utility functions. --- */
875
static INLINE void set_autosave (int interval)
877
/* This function simply sets the save state autosave interval to
878
'interval' seconds (in game speed, not real world speed :b). */
880
input_autosave_interval = interval;
884
message_local ("Autosave disabled.");
886
message_local ("Autosave interval set to %d seconds.", interval);
889
static INLINE void close_file (void);
890
static int main_replay_menu_select (void);
892
static INLINE int load_file (const UCHAR *filename)
894
/* This function loads the ROM specified by filename. The file is NOT
895
automatically added to the recent items list. That must be done
896
manually (currently by main_menu_open()).
898
NSFs are also supported, and are determined from their extension.
899
GZipped/Zipped NSFs are not supported however.
901
The return value of this function should be passed back to the calling
902
dialog (e.g, D_CLOSE to close it and start the emulation, etc.). */
906
status_message ("Loading, please wait...");
908
if (ustricmp (get_extension (filename), "NSF") == 0)
910
/* Attempt to intercept NSF file. */
912
if (!nsf_open (filename))
914
gui_message (GUI_ERROR_COLOR, "Failed to load NSF file!");
922
/* Clear status bar. */
927
/* Close currently open ROM and save data. */
931
/* Big Batch O' Botches. */
932
rom_is_loaded = TRUE;
933
memset(&global_rom, 0, sizeof(global_rom));
934
/* Mapper #0 = NONE. */
935
mmc_force (&nsf_mapper);
937
/* Initialize machine. */
940
/* Update window title. */
941
uszprintf (scratch, sizeof (scratch), "FakeNES - %s", get_filename (filename));
942
set_window_title (scratch);
944
/* Unfreeze audio. */
949
/* Re-freeze audio. */
952
/* Close NSF file. */
959
rom_is_loaded = FALSE;
965
if (load_rom (filename, &rom) != 0)
967
gui_message (GUI_ERROR_COLOR, "Failed to load ROM!");
975
/* Clear status bar. */
980
/* Close currently open ROM and save data. */
984
memcpy (&global_rom, &rom, sizeof (ROM));
986
/* Update save state titles. */
987
machine_save_state_menu_select ();
988
/* Update replay titles. */
989
main_replay_menu_select ();
991
rom_is_loaded = TRUE;
993
/* Initialize machine. */
996
/* Clear the game clock. */
997
options_menu_reset_clock ();
999
ENABLE_MENU_ITEM(main_menu_resume);
1000
ENABLE_MENU_ITEM(main_menu_close);
1001
ENABLE_SUBMENU(main_replay_menu);
1002
ENABLE_MENU_ITEM(main_menu_cheat_manager);
1003
ENABLE_MENU_ITEM(main_menu_save_snapshot);
1004
ENABLE_MENU_ITEM(main_menu_advance_frame);
1005
ENABLE_MENU_ITEM(machine_menu_reset);
1006
ENABLE_MENU_ITEM(machine_menu_power_cycle);
1007
ENABLE_SUBMENU(machine_save_state_menu);
1008
ENABLE_SUBMENU(audio_record_menu);
1009
ENABLE_MENU_ITEM(video_layers_menu_flip_mirroring);
1010
ENABLE_MENU_ITEM(options_menu_reset_clock);
1012
/* Update window title. */
1013
uszprintf (scratch, sizeof (scratch), "FakeNES - %s", get_filename
1014
(global_rom.filename));
1015
set_window_title (scratch);
1021
static INLINE void close_file (void)
1023
/* Unloads the current ROM and returns the emulator to it's default
1032
/* Close machine. */
1036
free_rom (&global_rom);
1037
rom_is_loaded = FALSE;
1042
static int open_lobby (void)
1044
/* This function handles the entire GUI end of the NetPlay lobby. It
1045
does not return until the NetPlay session has been terminated.
1047
Returns one of the following:
1048
D_O_K - The NetPlay session has been closed, by pressing either
1049
the [ x] close button or the Cancel button.
1050
D_CLOSE - The Netplay session is still open, all neccessary data
1051
has been distributed and subsequently loaded, and control
1052
should be transfered to the main loop. */
1060
DIALOG *obj_message;
1066
DIALOG_PLAYER *player;
1069
bmp = gui_get_screen ();
1075
dialog = lobby_dialog;
1077
/* Center dialog. */
1078
centre_dialog (dialog);
1080
while (dialog[index].d1 != SL_FRAME_END)
1082
/* Update colors. */
1084
DIALOG *object = &dialog[index];
1086
object->fg = GUI_TEXT_COLOR;
1087
object->bg = gui_bg_color;
1092
/* Get dialog objects. */
1093
obj_frame = &dialog[LOBBY_DIALOG_FRAME];
1094
obj_chat = &dialog[LOBBY_DIALOG_CHAT];
1095
obj_list = &dialog[LOBBY_DIALOG_LIST];
1096
obj_message = &dialog[LOBBY_DIALOG_MESSAGE];
1097
obj_load = &dialog[LOBBY_DIALOG_LOAD_BUTTON];
1098
obj_ok = &dialog[LOBBY_DIALOG_OK_BUTTON];
1100
/* Set up dialog objects. */
1102
obj_frame->dp3 = DATA_TO_FONT(LARGE_FONT);
1104
obj_chat->bg = makecol (0, 0, 0);
1105
obj_chat->fg = makecol (240, 240, 240);
1106
obj_chat->d1 = ((sizeof (chat) / MAX_UCHAR_LENGTH) - 1);
1107
obj_chat->dp = chat;
1109
obj_list->bg = makecol (0, 0, 0);
1110
obj_list->fg = makecol (240, 240, 240);
1111
obj_list->d1 = ((sizeof (list) / MAX_UCHAR_LENGTH) - 1);
1112
obj_list->dp = list;
1114
obj_message->d1 = ((sizeof (message) / MAX_UCHAR_LENGTH) - 1);
1115
obj_message->dp = message;
1117
if (netplay_mode != NETPLAY_MODE_SERVER_OPEN)
1118
obj_load->flags |= D_DISABLED;
1120
obj_ok->flags |= D_DISABLED;
1122
/* Clear text buffers. */
1123
USTRING_CLEAR(chat);
1124
USTRING_CLEAR(list);
1125
USTRING_CLEAR(message);
1129
player = init_dialog (dialog, -1);
1132
gui_message (GUI_ERROR_COLOR, "Failed to create dialog player!");
1136
while (update_dialog (player))
1138
netplay_enumerate_chat (chat, sizeof(chat));
1139
netplay_enumerate_clients (list, sizeof(list));
1142
object_message (obj_chat, MSG_DRAW, 0);
1143
object_message (obj_list, MSG_DRAW, 0);
1149
object_id = shutdown_dialog (player);
1153
case LOBBY_DIALOG_OK_BUTTON:
1158
/* End NetPlay session. */
1164
/* Draw background. */
1167
message_local ("NetPlay session closed.");
1174
/* --- Menu handlers. --- */
1176
static int main_menu_resume (void)
1181
static int main_menu_open (void)
1190
if (gui_alert ("Confirmation", "A ROM is already loaded.", "If you continue, any unsaved progress will be lost.", "Are you sure?", "&OK", "&Cancel", 0, 0) == 2)
1197
/* Retrive path from configuration file. */
1198
USTRING_CLEAR(path);
1200
ustrncat (path, get_config_string ("gui", "open_path", "~/"), (sizeof(path) - 1));
1202
ustrncat (path, get_config_string ("gui", "open_path", "/"), (sizeof(path) - 1));
1205
locked = get_config_int ("gui", "lock_paths", FALSE);
1208
result = gui_file_select ("Open", "Supported file types (*.NES, *.GZ, *.ZIP, *.NSF)", path, sizeof(path), "*.nes;*.gz;*.zip;*.nsf");
1210
result = gui_file_select ("Open", "Supported file types (*.NES, *.NSF)", path, sizeof(path), "*.nes;*.nsf");
1216
set_config_string ("gui", "open_path", replace_filename (scratch, path, "", sizeof (scratch)));
1221
/* Dialog was OK'ed. */
1225
result = load_file (path);
1226
if ((result == D_CLOSE) && !lock_recent)
1228
/* Load succeeded; add file to recent items list. */
1232
/* Move all existing entries down by 1 slot. */
1233
for (index = (OPEN_RECENT_SLOTS - 2); index >= 0; index--)
1234
ustrncpy (open_recent_filenames[(index + 1)], open_recent_filenames[index], USTRING_SIZE);
1236
/* Add new entry to the beginning of the list. */
1237
uszprintf (open_recent_filenames[0], USTRING_SIZE, "%s", path);
1241
for (index = 0; index < OPEN_RECENT_SLOTS; index++)
1243
const UCHAR *filename = open_recent_filenames[index];
1244
UCHAR *text = open_recent_menu_texts[index];
1245
MENU *menu = &main_open_recent_menu[index];
1249
/* Build menu text. */
1250
uszprintf (text, USTRING_SIZE, "&%d: %s", index, get_filename (filename));
1253
menu->flags &= ~D_DISABLED;
1257
/* Build menu text. */
1258
uszprintf (text, USTRING_SIZE, "&%d: %s", index, UNUSED_SLOT_TEXT);
1261
menu->flags |= D_DISABLED;
1264
/* Set menu text. */
1272
/* Dialog was cancelled. */
1276
#define OPEN_RECENT_MENU_HANDLER(index) \
1277
static int main_open_recent_menu_##index (void) \
1279
if (rom_is_loaded) \
1281
if (gui_alert ("Confirmation", "A ROM is already loaded.", "If you continue, any unsaved progress will be lost.", "Are you sure?", "&OK", "&Cancel", 0, 0) == 2) \
1288
return (load_file (open_recent_filenames[index])); \
1291
OPEN_RECENT_MENU_HANDLER(0)
1292
OPEN_RECENT_MENU_HANDLER(1)
1293
OPEN_RECENT_MENU_HANDLER(2)
1294
OPEN_RECENT_MENU_HANDLER(3)
1295
OPEN_RECENT_MENU_HANDLER(4)
1296
OPEN_RECENT_MENU_HANDLER(5)
1297
OPEN_RECENT_MENU_HANDLER(6)
1298
OPEN_RECENT_MENU_HANDLER(7)
1299
OPEN_RECENT_MENU_HANDLER(8)
1300
OPEN_RECENT_MENU_HANDLER(9)
1302
#undef OPEN_RECENT_MENU_HANDLER
1304
static int main_open_recent_menu_lock (void)
1306
lock_recent = !lock_recent;
1312
static int main_open_recent_menu_clear (void)
1316
for (index = 0; index < OPEN_RECENT_SLOTS; index++)
1318
UCHAR *filename = open_recent_filenames[index];
1319
UCHAR *text = open_recent_menu_texts[index];
1320
MENU *menu = &main_open_recent_menu[index];
1322
USTRING_CLEAR(filename);
1324
/* Build menu text. */
1325
uszprintf (text, USTRING_SIZE, "&%d: %s", index, UNUSED_SLOT_TEXT);
1331
menu->flags |= D_DISABLED;
1337
static int main_menu_close (void)
1339
if (gui_alert ("Confirmation", "If you continue, any unsaved progress will be lost.", "Are you sure you want to unload the ROM?", NULL, "&OK", "&Cancel", 0, 0) == 2)
1348
/* Clear the screen and restore background. */
1354
#define REPLAY_SELECT_MENU_HANDLER(index) \
1355
static int main_replay_select_menu_##index (void) \
1357
replay_index = index; \
1359
message_local ("Replay slot set to %d.", index); \
1363
REPLAY_SELECT_MENU_HANDLER(0)
1364
REPLAY_SELECT_MENU_HANDLER(1)
1365
REPLAY_SELECT_MENU_HANDLER(2)
1366
REPLAY_SELECT_MENU_HANDLER(3)
1367
REPLAY_SELECT_MENU_HANDLER(4)
1368
REPLAY_SELECT_MENU_HANDLER(5)
1369
REPLAY_SELECT_MENU_HANDLER(6)
1370
REPLAY_SELECT_MENU_HANDLER(7)
1371
REPLAY_SELECT_MENU_HANDLER(8)
1372
REPLAY_SELECT_MENU_HANDLER(9)
1374
#undef REPLAY_SELECT_MENU_HANDLER
1376
static int main_replay_menu_select (void)
1380
for (index = 0; index < REPLAY_SLOTS; index++)
1385
title = replay_titles[index];
1386
text = replay_menu_texts[index];
1389
get_replay_title (index, title, USTRING_SIZE);
1391
/* Build menu text. */
1392
uszprintf (text, USTRING_SIZE, "&%d: %s", index, title);
1395
main_replay_select_menu[index].text = text;
1401
static int main_replay_record_menu_start (void)
1405
/* Duplicate title. */
1406
ustrncpy (title, replay_titles[replay_index], USTRING_SIZE);
1408
/* Patch up duplicate. */
1409
fix_save_title (title, sizeof (title));
1416
/* Allow user to customize title before save. */
1418
dialog = main_replay_record_start_dialog;
1420
objtitle = &dialog[MAIN_REPLAY_RECORD_START_DIALOG_TITLE];
1422
objtitle->d1 = NEW_SAVE_TITLE_SIZE;
1423
objtitle->dp = title;
1425
if (show_dialog (dialog, -1) !=
1426
MAIN_REPLAY_RECORD_START_DIALOG_OK_BUTTON)
1428
/* Dialog was cancelled. */
1433
/* Open replay file. */
1434
if (!open_replay (replay_index, "w", title))
1436
gui_message (GUI_ERROR_COLOR, "Failed to open new machine state "
1442
DISABLE_MENU_ITEM(main_menu_open);
1443
DISABLE_SUBMENU(main_open_recent_menu);
1444
DISABLE_MENU_ITEM(main_menu_close);
1445
DISABLE_MENU_ITEM(main_replay_record_menu_start);
1446
ENABLE_MENU_ITEM(main_replay_record_menu_stop);
1447
DISABLE_SUBMENU(main_replay_select_menu);
1448
DISABLE_SUBMENU(main_replay_play_menu);
1449
DISABLE_SUBMENU(machine_save_state_autosave_menu);
1450
DISABLE_SUBMENU(netplay_menu);
1452
/* Enter replay recording mode. */
1453
input_mode |= INPUT_MODE_REPLAY;
1454
input_mode |= INPUT_MODE_REPLAY_RECORD;
1456
message_local ("Replay recording session started.");
1458
/* Update replay titles. */
1459
main_replay_menu_select ();
1464
static int main_replay_record_menu_stop (void)
1469
/* Exit replay recording mode. */
1470
input_mode &= ~INPUT_MODE_REPLAY;
1471
input_mode &= ~INPUT_MODE_REPLAY_RECORD;
1473
ENABLE_MENU_ITEM(main_menu_open);
1474
ENABLE_SUBMENU(main_open_recent_menu);
1475
ENABLE_MENU_ITEM(main_menu_close);
1476
ENABLE_MENU_ITEM(main_replay_record_menu_start);
1477
DISABLE_MENU_ITEM(main_replay_record_menu_stop);
1478
ENABLE_SUBMENU(main_replay_select_menu);
1479
ENABLE_SUBMENU(main_replay_play_menu);
1480
ENABLE_SUBMENU(machine_save_state_autosave_menu);
1481
ENABLE_SUBMENU(netplay_menu);
1483
message_local ("Replay recording session stopped.");
1488
static int main_replay_play_menu_start (void)
1490
if (!open_replay (replay_index, "r", NULL))
1492
gui_message (GUI_ERROR_COLOR, "Failed to open machine state file.");
1497
DISABLE_MENU_ITEM(main_menu_open);
1498
DISABLE_SUBMENU(main_open_recent_menu);
1499
DISABLE_MENU_ITEM(main_menu_close);
1500
DISABLE_MENU_ITEM(main_replay_play_menu_start);
1501
ENABLE_MENU_ITEM(main_replay_play_menu_stop);
1502
DISABLE_SUBMENU(main_replay_select_menu);
1503
DISABLE_SUBMENU(main_replay_record_menu);
1504
DISABLE_MENU_ITEM(main_menu_cheat_manager);
1505
DISABLE_MENU_ITEM(machine_menu_reset);
1506
DISABLE_MENU_ITEM(machine_menu_power_cycle);
1507
DISABLE_MENU_ITEM(machine_save_state_menu_quick_load);
1508
DISABLE_MENU_ITEM(machine_save_state_menu_restore);
1509
DISABLE_SUBMENU(netplay_menu);
1511
/* Enter replay playback mode. */
1512
input_mode &= ~INPUT_MODE_PLAY;
1513
input_mode |= INPUT_MODE_REPLAY;
1514
input_mode |= INPUT_MODE_REPLAY_PLAY;
1516
message_local ("Replay playback started.");
1521
static int main_replay_play_menu_stop (void)
1526
/* Exit replay playback mode. */
1527
if (!(input_mode & INPUT_MODE_CHAT))
1528
input_mode |= INPUT_MODE_PLAY;
1529
input_mode &= ~INPUT_MODE_REPLAY;
1530
input_mode &= ~INPUT_MODE_REPLAY_PLAY;
1532
ENABLE_MENU_ITEM(main_menu_open);
1533
ENABLE_SUBMENU(main_open_recent_menu);
1534
ENABLE_MENU_ITEM(main_menu_close);
1535
ENABLE_MENU_ITEM(main_replay_play_menu_start);
1536
DISABLE_MENU_ITEM(main_replay_play_menu_stop);
1537
ENABLE_SUBMENU(main_replay_select_menu);
1538
ENABLE_SUBMENU(main_replay_record_menu);
1539
ENABLE_MENU_ITEM(main_menu_cheat_manager);
1540
ENABLE_MENU_ITEM(machine_menu_reset);
1541
ENABLE_MENU_ITEM(machine_menu_power_cycle);
1542
ENABLE_MENU_ITEM(machine_save_state_menu_quick_load);
1543
ENABLE_MENU_ITEM(machine_save_state_menu_restore);
1544
ENABLE_SUBMENU(netplay_menu);
1547
message_local ("Replay playback stopped.");
1549
message_local ("Replay playback finished.");
1554
static int main_menu_cheat_manager (void)
1556
if (show_dialog (main_cheat_manager_dialog, -1) ==
1557
MAIN_CHEAT_MANAGER_DIALOG_SAVE_BUTTON)
1565
static int main_menu_save_snapshot (void)
1569
for (index = 0; index < 999; index++)
1574
uszprintf (filename, sizeof (filename), "%s_%03d.pcx", get_filename
1575
(global_rom.filename), index);
1577
/* Merge it with our save path. */
1578
get_save_path (filename, sizeof (filename));
1580
if (exists (filename))
1583
save_bitmap (filename, video_buffer, video_palette);
1585
message_local ("Snapshot saved to %s.", filename);
1590
gui_message (GUI_ERROR_COLOR, "Couldn't find a suitable image "
1596
static int main_menu_advance_frame (void)
1598
frames_to_execute = 1;
1603
static int main_menu_save_configuration (void)
1606
gui_alert ("Confirmation", "Configuration has been saved.", NULL, NULL, "&OK", NULL, 0, 0);
1611
static int main_menu_exit (void)
1617
if (gui_alert ("Confirmation", "A ROM is currently loaded.", "If you continue, any unsaved progress will be lost.", "Really exit?", "&OK", "&Cancel", 0, 0) == 2)
1639
#define SAVE_STATE_SELECT_MENU_HANDLER(index) \
1640
static int machine_save_state_select_menu_##index (void) \
1642
save_state_index = index; \
1644
message_local ("Machine state slot set to %d.", index); \
1648
SAVE_STATE_SELECT_MENU_HANDLER(0);
1649
SAVE_STATE_SELECT_MENU_HANDLER(1);
1650
SAVE_STATE_SELECT_MENU_HANDLER(2);
1651
SAVE_STATE_SELECT_MENU_HANDLER(3);
1652
SAVE_STATE_SELECT_MENU_HANDLER(4);
1653
SAVE_STATE_SELECT_MENU_HANDLER(5);
1654
SAVE_STATE_SELECT_MENU_HANDLER(6);
1655
SAVE_STATE_SELECT_MENU_HANDLER(7);
1656
SAVE_STATE_SELECT_MENU_HANDLER(8);
1657
SAVE_STATE_SELECT_MENU_HANDLER(9);
1659
#undef SAVE_STATE_MENU_HANDLER
1661
static int machine_save_state_menu_quick_save (void)
1663
if (!save_state (-1, "QUICKSAVE"))
1665
gui_message (GUI_ERROR_COLOR, "Quick Save failed.");
1673
static int machine_save_state_menu_quick_load (void)
1675
if (!load_state (-1))
1677
gui_message (GUI_ERROR_COLOR, "Quick Load failed.");
1685
static int machine_save_state_menu_save (void)
1690
/* Duplicate title. */
1691
ustrncpy (title, save_state_titles[save_state_index], sizeof (title));
1693
/* Patch up duplicate. */
1694
fix_save_title (title, sizeof (title));
1701
/* Allow user to customize title before save. */
1703
dialog = machine_save_state_save_dialog;
1705
objtitle = &dialog[MACHINE_SAVE_STATE_SAVE_DIALOG_TITLE];
1707
objtitle->d1 = NEW_SAVE_TITLE_SIZE;
1708
objtitle->dp = title;
1710
if (show_dialog (dialog, -1) !=
1711
MACHINE_SAVE_STATE_SAVE_DIALOG_OK_BUTTON)
1718
if (!save_state (save_state_index, title))
1720
gui_message (GUI_ERROR_COLOR, "Failed to open new machine state "
1726
message_local ("Machine state saved to slot %d.", save_state_index);
1728
/* Update save state titles. */
1729
machine_save_state_menu_select ();
1734
static int machine_save_state_menu_restore (void)
1736
if (!load_state (save_state_index))
1738
gui_message (GUI_ERROR_COLOR, "Failed to open machine state file.");
1743
message_local ("Machine state loaded from slot %d.", save_state_index);
1748
static int machine_save_state_menu_select (void)
1752
for (index = 0; index < SAVE_STATE_SLOTS; index++)
1757
title = save_state_titles[index];
1758
text = save_state_menu_texts[index];
1761
get_state_title (index, title, USTRING_SIZE);
1763
/* Build menu text. */
1764
uszprintf (text, USTRING_SIZE, "&%d: %s", index, title);
1767
machine_save_state_select_menu[index].text = text;
1773
static int machine_save_state_autosave_menu_disabled (void)
1780
static int machine_save_state_autosave_menu_10_seconds (void)
1787
static int machine_save_state_autosave_menu_30_seconds (void)
1794
static int machine_save_state_autosave_menu_60_seconds (void)
1801
static int machine_save_state_autosave_menu_custom (void)
1805
seconds = input_autosave_interval;
1807
if (get_integer_input ("Custom", &seconds, "seconds"))
1808
set_autosave (seconds);
1813
static int machine_region_menu_automatic (void)
1815
machine_region = MACHINE_REGION_AUTOMATIC;
1816
timing_update_machine_type ();
1819
message_local ("System region set to automatic.");
1824
static int machine_region_menu_ntsc (void)
1826
machine_region = MACHINE_REGION_NTSC;
1827
timing_update_machine_type ();
1830
message_local ("System region set to NTSC.");
1835
static int machine_region_menu_pal (void)
1837
machine_region = MACHINE_REGION_PAL;
1838
timing_update_machine_type ();
1841
message_local ("System region set to PAL.");
1846
static int machine_speed_up_down_menu_50_percent (void)
1848
timing_speed_multiplier = 0.5;
1849
timing_update_speed ();
1853
message_local ("Machine speed factor set to 50%%.");
1858
static int machine_speed_up_down_menu_100_percent (void)
1860
timing_speed_multiplier = 1.0;
1861
timing_update_speed ();
1865
message_local ("Machine speed factor set to 100%%.");
1870
static int machine_speed_up_down_menu_200_percent (void)
1872
timing_speed_multiplier = 2.0;
1873
timing_update_speed ();
1877
message_local ("Machine speed factor set to 200%%.");
1882
static int machine_speed_up_down_menu_custom (void)
1886
value = (timing_speed_multiplier * 100.0);
1888
if (get_float_input ("Custom", &value, "percent"))
1890
timing_speed_multiplier = (value / 100.0);
1891
timing_update_speed ();
1895
message_local ("Machine speed factor set to custom.");
1901
static int machine_frame_skip_menu_automatic (void)
1906
message_local ("Frame skip set to automatic.");
1911
static int machine_frame_skip_menu_disabled (void)
1916
message_local ("Frame skip disabled.");
1921
#define FRAME_SKIP_MENU_HANDLER(frames) \
1922
static int machine_frame_skip_menu_##frames##_frames (void) \
1924
frame_skip = frames; \
1926
message_local ("Frame skip set to %d frames.", frames); \
1930
FRAME_SKIP_MENU_HANDLER(1)
1931
FRAME_SKIP_MENU_HANDLER(2)
1932
FRAME_SKIP_MENU_HANDLER(3)
1933
FRAME_SKIP_MENU_HANDLER(4)
1934
FRAME_SKIP_MENU_HANDLER(5)
1935
FRAME_SKIP_MENU_HANDLER(6)
1936
FRAME_SKIP_MENU_HANDLER(7)
1937
FRAME_SKIP_MENU_HANDLER(8)
1938
FRAME_SKIP_MENU_HANDLER(9)
1939
FRAME_SKIP_MENU_HANDLER(10)
1941
#undef FRAME_SKIP_MENU_HANDLER
1943
static int machine_frame_skip_menu_custom (void)
1947
frames = frame_skip;
1949
if (get_integer_input ("Custom", &frames, "frames"))
1951
frame_skip = frames;
1954
message_local ("Frame skip set to %d frames.", frames);
1960
static int machine_menu_show_status (void)
1962
video_display_status = (! video_display_status);
1968
static int machine_menu_reset (void)
1970
/* Confirm reset. */
1972
if (gui_alert ("Confirmation", "This action will reset the virtual machine.", "If you continue, any unsaved progress will be lost.", "Really reset the virtual machine?", "&OK", "&Cancel", 0, 0) == 2)
1981
/* Clear the game clock. */
1982
options_menu_reset_clock ();
1988
static int machine_menu_power_cycle (void)
1990
/* Confirm power cycle. */
1992
if (gui_alert ("Confirmation", "This action will power cycle the virtual machine.", "If you continue, any unsaved progress will be lost.", "Really power cycle the virtual machine?", "&OK", "&Cancel", 0, 0) == 2)
2002
/* Clear the game clock. */
2003
options_menu_reset_clock ();
2009
static int machine_menu_timing_smoothest (void)
2011
machine_timing = MACHINE_TIMING_SMOOTH;
2012
timing_update_speed ();
2015
message_local ("Machine timing mode set to smoothest.");
2020
static int machine_menu_timing_most_accurate (void)
2022
machine_timing = MACHINE_TIMING_ACCURATE;
2023
timing_update_speed ();
2026
message_local ("Machine timing mode set to most accurate.");
2031
static int machine_menu_speed_cap (void)
2033
speed_cap = !speed_cap;
2036
message_local ("Speed cap %s.", get_enabled_text (speed_cap));
2041
static int audio_menu_enable_apu (void)
2043
apu_options.enabled = !apu_options.enabled;
2048
message_local ("APU emulation %s.",
2049
get_enabled_text (apu_options.enabled));
2054
static int audio_menu_enable_output (void)
2056
audio_options.enable_output = !audio_options.enable_output;
2061
message_local ("Audio output %s.", get_enabled_text (audio_options.enable_output));
2066
static int audio_menu_emulation_fast (void)
2068
apu_options.emulation = APU_EMULATION_FAST;
2073
gui_alert ("Accuracy Warning", "The fast emulation mode may introduce permanent accuracy glitches into save states, "
2074
"replays and the game rewinder.",
2075
"Only use it if you have a very slow computer that cannot handle one of the other emulation modes.",
2076
NULL, "&OK", NULL, 0, 0);
2078
message_local ("APU emulation quality set to fast.");
2083
static int audio_menu_emulation_accurate (void)
2085
apu_options.emulation = APU_EMULATION_ACCURATE;
2090
message_local ("APU emulation quality set to accurate.");
2095
static int audio_menu_emulation_high_quality (void)
2097
apu_options.emulation = APU_EMULATION_HIGH_QUALITY;
2102
message_local ("APU emulation quality set to high quality.");
2107
#define AUDIO_CHANNELS_MENU_HANDLER(id, name) \
2108
static int audio_channels_menu_##id (void) \
2110
BOOL *enabled = &apu_options.enable_##id ; \
2111
*enabled = !*enabled; \
2114
message_local ("APU " name " %s.", get_enabled_text (*enabled)); \
2118
AUDIO_CHANNELS_MENU_HANDLER(square_1, "first square wave channel")
2119
AUDIO_CHANNELS_MENU_HANDLER(square_2, "second square wave channel")
2120
AUDIO_CHANNELS_MENU_HANDLER(triangle, "triangle wave channel")
2121
AUDIO_CHANNELS_MENU_HANDLER(noise, "noise channel")
2122
AUDIO_CHANNELS_MENU_HANDLER(dmc, "delta modulation channel")
2123
AUDIO_CHANNELS_MENU_HANDLER(extra_1, "first expansion channel")
2124
AUDIO_CHANNELS_MENU_HANDLER(extra_2, "second expansion channel")
2125
AUDIO_CHANNELS_MENU_HANDLER(extra_3, "third expansion channel")
2127
#undef AUDIO_CHANNELS_MENU_HANDLER
2129
static int audio_channels_menu_enable_all (void)
2131
apu_options.enable_square_1 = TRUE;
2132
apu_options.enable_square_2 = TRUE;
2133
apu_options.enable_triangle = TRUE;
2134
apu_options.enable_noise = TRUE;
2135
apu_options.enable_dmc = TRUE;
2136
apu_options.enable_extra_1 = TRUE;
2137
apu_options.enable_extra_2 = TRUE;
2138
apu_options.enable_extra_3 = TRUE;
2144
message_local ("All APU channels enabled.");
2149
static int audio_channels_menu_disable_all (void)
2151
apu_options.enable_square_1 = FALSE;
2152
apu_options.enable_square_2 = FALSE;
2153
apu_options.enable_triangle = FALSE;
2154
apu_options.enable_noise = FALSE;
2155
apu_options.enable_dmc = FALSE;
2156
apu_options.enable_extra_1 = FALSE;
2157
apu_options.enable_extra_2 = FALSE;
2158
apu_options.enable_extra_3 = FALSE;
2164
message_local ("All APU channels disabled.");
2169
static int audio_output_menu_subsystem_allegro (void)
2171
audio_options.subsystem = AUDIO_SUBSYSTEM_ALLEGRO;
2176
message_local ("Audio subsystem set to Allegro.");
2181
static int audio_output_menu_subsystem_openal (void)
2183
audio_options.subsystem = AUDIO_SUBSYSTEM_OPENAL;
2188
message_local ("Audio subsystem set to OpenAL.");
2193
#define AUDIO_OUTPUT_MENU_SAMPLING_RATE_HANDLER(rate) \
2194
static int audio_output_menu_sampling_rate_##rate##_hz (void) \
2196
audio_options.sample_rate_hint = rate; \
2199
message_local ("Audio sampling rate set to %d Hz.", rate); \
2203
AUDIO_OUTPUT_MENU_SAMPLING_RATE_HANDLER(22050)
2204
AUDIO_OUTPUT_MENU_SAMPLING_RATE_HANDLER(44100)
2205
AUDIO_OUTPUT_MENU_SAMPLING_RATE_HANDLER(48000)
2207
#undef AUDIO_OUTPUT_MENU_SAMPLING_RATE_HANDLER
2209
static int audio_output_menu_sampling_rate_automatic (void)
2211
audio_options.sample_rate_hint = -1;
2216
message_local ("Audio sampling rate set to automatic.");
2221
static int audio_output_menu_sampling_rate_custom (void)
2225
rate = audio_options.sample_rate_hint;
2227
if (get_integer_input ("Custom", &rate, "Hz"))
2229
audio_options.sample_rate_hint = rate;
2234
message_local ("Audio sampling rate set to %d Hz.", rate);
2240
static int audio_output_menu_mixing_mono (void)
2242
apu_options.stereo = FALSE;
2247
gui_message (GUI_TEXT_COLOR, "Audio output set to mono.");
2252
static int audio_output_menu_mixing_stereo (void)
2254
apu_options.stereo = TRUE;
2255
apu_options.swap_channels = FALSE;
2260
gui_alert ("Information", "Stereo output may not be supported for all games, such as those with custom sound hardware (e.g MMC5, VRC6, etc.).",
2261
"In cases where stereo output is not available, FakeNES will temporarily revert to mono output.",
2262
"This is a harmless, accuracy-related procedure and should not be considered a bug.",
2265
message_local ("Audio output set to stereo.");
2270
static int audio_output_menu_mixing_stereo_inverted (void)
2272
apu_options.stereo = TRUE;
2273
apu_options.swap_channels = TRUE;
2278
message_local ("Audio output set to reverse stereo.");
2283
#define AUDIO_OUTPUT_BUFFER_MENU_HANDLER(length_ms) \
2284
static int audio_output_buffer_menu_##length_ms##ms (void) \
2286
audio_options.buffer_length_ms_hint = length_ms; \
2289
message_local ("Audio buffer size set to %dms.", length_ms); \
2293
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(30)
2294
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(50)
2295
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(75)
2296
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(100)
2297
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(125)
2298
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(150)
2299
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(175)
2300
AUDIO_OUTPUT_BUFFER_MENU_HANDLER(200)
2302
#undef AUDIO_OUTPUT_BUFFER_MENU_HANDLER
2304
static int audio_output_buffer_menu_automatic (void)
2306
audio_options.buffer_length_ms_hint = -1;
2311
message_local ("Audio buffer size set to automatic.");
2316
static int audio_output_buffer_menu_custom (void)
2318
int ms = audio_options.buffer_length_ms_hint;
2319
if (get_integer_input ("Custom", &ms, "ms"))
2321
audio_options.buffer_length_ms_hint = ms;
2326
message_local ("Audio buffer size set to %dms.", ms);
2332
static int audio_menu_volume_increase (void)
2334
apu_options.volume += 0.25;
2335
if (apu_options.volume > 4.0)
2336
apu_options.volume = 4.0;
2340
message_local ("Audio master volume level increased to %d%%.",
2341
(int)ROUND(apu_options.volume * 100.0));
2346
static int audio_menu_volume_decrease (void)
2348
apu_options.volume -= 0.25;
2349
if (apu_options.volume < 0)
2350
apu_options.volume = 0;
2354
message_local ("Audio master volume level decreased to %d%%.",
2355
(int)ROUND(apu_options.volume * 100.0));
2360
static int audio_menu_volume_custom (void)
2364
percent = ROUND(apu_options.volume * 100.0);
2366
if (get_integer_input ("Custom", &percent, "percent"))
2368
apu_options.volume = (percent / 100.0);
2371
message_local ("Audio master volume level set to %d%%.", percent);
2377
static int audio_menu_volume_reset (void)
2379
apu_options.volume = 1.0;
2382
message_local ("Audio master volume level reset to %d%%.",
2383
(int)ROUND(apu_options.volume * 100.0));
2388
static int audio_menu_volume_auto_normalize (void)
2390
apu_options.normalize = !apu_options.normalize;
2395
message_local ("Audio volume level normalization %s.",
2396
get_enabled_text (apu_options.normalize));
2401
static int audio_record_menu_start (void)
2405
for (index = 0; index < 999; index++)
2409
uszprintf (filename, sizeof (filename), "%s_%03d.wav", get_filename
2410
(global_rom.filename), index);
2412
/* Merge it with our save path. */
2413
get_save_path (filename, sizeof (filename));
2415
if (exists (filename))
2418
if (audio_open_wav (filename) == 0)
2420
DISABLE_MENU_ITEM(audio_record_menu_start);
2421
ENABLE_MENU_ITEM(audio_record_menu_stop);
2424
message_local ("Audio WAV recording started to %s.", filename);
2429
gui_message (GUI_ERROR_COLOR, "Couldn't find a suitable image "
2435
static int audio_record_menu_stop (void)
2439
ENABLE_MENU_ITEM(audio_record_menu_start);
2440
DISABLE_MENU_ITEM(audio_record_menu_stop);
2442
message_local ("Audio WAV recording stopped.");
2447
static int video_menu_fullscreen (void)
2449
video_force_fullscreen = !video_force_fullscreen;
2452
gui_needs_restart = TRUE;
2456
static int video_menu_page_buffer (void)
2458
video_enable_page_buffer = !video_enable_page_buffer;
2465
message_local ("Page buffering %s.", get_enabled_text
2466
(video_enable_page_buffer));
2471
static int video_menu_vsync (void)
2473
video_enable_vsync = !video_enable_vsync;
2476
message_local ("VSync %s.", get_enabled_text (video_enable_vsync));
2481
static int video_menu_color (void)
2484
DIALOG *objhue, *objsat, *objbright, *objcon, *objgamma;
2488
dialog = video_color_dialog;
2490
/* Get slider objects. */
2492
objhue = &dialog[VIDEO_COLOR_DIALOG_HUE];
2493
objsat = &dialog[VIDEO_COLOR_DIALOG_SATURATION];
2494
objbright = &dialog[VIDEO_COLOR_DIALOG_BRIGHTNESS];
2495
objcon = &dialog[VIDEO_COLOR_DIALOG_CONTRAST];
2496
objgamma = &dialog[VIDEO_COLOR_DIALOG_GAMMA];
2498
/* Load configuration. */
2500
objhue->d2 = (get_config_int ("video", "hue", 0) + 100);
2501
objsat->d2 = (get_config_int ("video", "saturation", 0) + 100);
2502
objbright->d2 = (get_config_int ("video", "brightness", 0) + 100);
2503
objcon->d2 = (get_config_int ("video", "contrast", 0) + 100);
2504
objgamma->d2 = (get_config_int ("video", "gamma", 0) + 100);
2507
result = show_dialog (dialog, -1);
2509
if (result == VIDEO_COLOR_DIALOG_SAVE_BUTTON)
2511
/* Save configuration. */
2513
set_config_int ("video", "hue", (objhue->d2 - 100));
2514
set_config_int ("video", "saturation", (objsat->d2 - 100));
2515
set_config_int ("video", "brightness", (objbright->d2 - 100));
2516
set_config_int ("video", "contrast", (objcon->d2 - 100));
2517
set_config_int ("video", "gamma", (objgamma->d2 - 100));
2519
/* Reinitialize palette to the load new configuration. */
2520
video_set_palette (NULL);
2522
/* Display changes. */
2525
else if (result == VIDEO_COLOR_DIALOG_RESET_BUTTON)
2527
/* Save defaults. */
2529
set_config_int ("video", "hue", 0);
2530
set_config_int ("video", "saturation", 0);
2531
set_config_int ("video", "brightness", 0);
2532
set_config_int ("video", "contrast", 0);
2533
set_config_int ("video", "gamma", 0);
2535
/* Reinitialize palette to the load new configuration. */
2536
video_set_palette (NULL);
2538
/* Display changes. */
2545
#define DRIVER_MENU_HANDLER(driver, id) \
2546
static int video_driver_menu_##driver (void) \
2548
video_set_driver (id); \
2549
gui_needs_restart = TRUE; \
2553
#define DRIVER_MENU_HANDLER_EX(system, driver, id) \
2554
static int video_driver_##system##_menu_##driver (void) \
2556
video_set_driver (id); \
2557
gui_needs_restart = TRUE; \
2561
DRIVER_MENU_HANDLER(automatic, GFX_AUTODETECT)
2565
DRIVER_MENU_HANDLER_EX(dos, vga, GFX_VGA)
2566
DRIVER_MENU_HANDLER_EX(dos, vga_mode_x, GFX_MODEX)
2567
DRIVER_MENU_HANDLER_EX(dos, vesa, GFX_VESA1)
2568
DRIVER_MENU_HANDLER_EX(dos, vesa_2_banked, GFX_VESA2B)
2569
DRIVER_MENU_HANDLER_EX(dos, vesa_2_linear, GFX_VESA2L)
2570
DRIVER_MENU_HANDLER_EX(dos, vesa_3, GFX_VESA3)
2571
DRIVER_MENU_HANDLER_EX(dos, vesa_vbe_af, GFX_VBEAF)
2573
#endif /* ALLEGRO_DOS */
2575
#ifdef ALLEGRO_WINDOWS
2577
DRIVER_MENU_HANDLER_EX(windows, directx, GFX_DIRECTX)
2578
DRIVER_MENU_HANDLER_EX(windows, directx_window, GFX_DIRECTX_WIN)
2579
DRIVER_MENU_HANDLER_EX(windows, directx_overlay, GFX_DIRECTX_OVL)
2580
DRIVER_MENU_HANDLER_EX(windows, gdi, GFX_GDI)
2582
#endif /* ALLEGRO_WINDOWS */
2584
#ifdef ALLEGRO_LINUX
2586
DRIVER_MENU_HANDLER_EX(linux, vga, GFX_VGA)
2587
DRIVER_MENU_HANDLER_EX(linux, vga_mode_x, GFX_MODEX)
2588
DRIVER_MENU_HANDLER_EX(linux, vesa_vbe_af, GFX_VBEAF)
2590
DRIVER_MENU_HANDLER_EX(linux, framebuffer, GFX_FBCON)
2592
DRIVER_MENU_HANDLER_EX(linux, framebuffer, NULL)
2595
DRIVER_MENU_HANDLER_EX(linux, svgalib, GFX_SVGALIB)
2597
DRIVER_MENU_HANDLER_EX(linux, svgalib, NULL)
2600
#endif /* ALLEGRO_LINUX */
2604
DRIVER_MENU_HANDLER_EX(unix, x_windows, GFX_XWINDOWS)
2605
DRIVER_MENU_HANDLER_EX(unix, x_windows_full, GFX_XWINDOWS_FULLSCREEN)
2606
DRIVER_MENU_HANDLER_EX(unix, x_dga, GFX_XDGA)
2607
DRIVER_MENU_HANDLER_EX(unix, x_dga_full, GFX_XDGA_FULLSCREEN)
2608
DRIVER_MENU_HANDLER_EX(unix, x_dga_2, GFX_XDGA2)
2610
#endif /* ALLEGRO_UNIX */
2612
#ifdef USE_ALLEGROGL
2614
DRIVER_MENU_HANDLER(opengl, GFX_OPENGL)
2615
DRIVER_MENU_HANDLER(opengl_full, GFX_OPENGL_FULLSCREEN)
2616
DRIVER_MENU_HANDLER(opengl_win, GFX_OPENGL_WINDOWED)
2618
#endif /* USE_ALLEGROGL */
2620
#undef DRIVER_MENU_HANDLER
2621
#undef DRIVER_MENU_HANDLER_EX
2623
#define RESOLUTION_MENU_HANDLER(width, height) \
2624
static int video_resolution_menu_##width##_##height (void) \
2626
video_set_resolution (width, height); \
2627
gui_needs_restart = TRUE; \
2631
#define RESOLUTION_MENU_HANDLER_EX(type, width, height) \
2632
static int video_resolution_##type##_menu_##width##_##height (void) \
2634
video_set_resolution (width, height); \
2635
gui_needs_restart = TRUE; \
2639
RESOLUTION_MENU_HANDLER_EX(proportionate, 256, 224)
2640
RESOLUTION_MENU_HANDLER_EX(proportionate, 256, 240)
2641
RESOLUTION_MENU_HANDLER_EX(proportionate, 512, 448)
2642
RESOLUTION_MENU_HANDLER_EX(proportionate, 512, 480)
2643
RESOLUTION_MENU_HANDLER_EX(proportionate, 768, 672)
2644
RESOLUTION_MENU_HANDLER_EX(proportionate, 768, 720)
2645
RESOLUTION_MENU_HANDLER_EX(proportionate, 1024, 896)
2646
RESOLUTION_MENU_HANDLER_EX(proportionate, 1024, 960)
2647
RESOLUTION_MENU_HANDLER_EX(proportionate, 1280, 1120)
2648
RESOLUTION_MENU_HANDLER_EX(proportionate, 1280, 1200)
2650
RESOLUTION_MENU_HANDLER(320, 240)
2651
RESOLUTION_MENU_HANDLER(400, 300)
2652
RESOLUTION_MENU_HANDLER(640, 480)
2653
RESOLUTION_MENU_HANDLER(800, 600)
2654
RESOLUTION_MENU_HANDLER(1024, 768)
2655
RESOLUTION_MENU_HANDLER(1152, 864)
2656
RESOLUTION_MENU_HANDLER(1280, 960)
2657
RESOLUTION_MENU_HANDLER(1280, 1024)
2658
RESOLUTION_MENU_HANDLER(1600, 1200)
2660
#undef RESOLUTION_MENU_HANDLER
2661
#undef RESOLUTION_MENU_HANDLER_EX
2663
static int video_resolution_menu_custom (void)
2670
if (get_resolution_input ("Custom", &width, &height))
2672
video_set_resolution (width, height);
2674
gui_needs_restart = TRUE;
2681
static int video_color_depth_menu_paletted_8_bit (void)
2683
video_set_color_depth (8);
2685
gui_needs_restart = TRUE;
2689
static int video_color_depth_menu_true_color_15_bit (void)
2691
video_set_color_depth (15);
2693
gui_needs_restart = TRUE;
2697
static int video_color_depth_menu_true_color_16_bit (void)
2699
video_set_color_depth (16);
2701
gui_needs_restart = TRUE;
2705
static int video_color_depth_menu_true_color_24_bit (void)
2707
video_set_color_depth (24);
2709
gui_needs_restart = TRUE;
2713
static int video_color_depth_menu_true_color_32_bit (void)
2715
video_set_color_depth (32);
2717
gui_needs_restart = TRUE;
2721
static int video_buffer_menu_match_resolution (void)
2723
video_buffer_width =
2724
video_buffer_height = -1;
2725
video_init_buffer ();
2733
#define BUFFER_MENU_HANDLER(width, height) \
2734
static int video_buffer_menu_##width##_##height (void) \
2736
video_buffer_width = width; \
2737
video_buffer_height = height; \
2738
video_init_buffer (); \
2744
BUFFER_MENU_HANDLER(256, 240)
2745
BUFFER_MENU_HANDLER(320, 240)
2746
BUFFER_MENU_HANDLER(512, 480)
2747
BUFFER_MENU_HANDLER(640, 480)
2748
BUFFER_MENU_HANDLER(256, 256)
2749
BUFFER_MENU_HANDLER(512, 512)
2751
#undef BUFFER_MENU_HANDLER
2753
static int video_buffer_menu_custom (void)
2757
width = video_buffer_width;
2758
height = video_buffer_height;
2760
if (get_resolution_input ("Custom", &width, &height))
2762
video_buffer_width = width;
2763
video_buffer_height = height;
2764
video_init_buffer ();
2774
#define BLITTER_MENU_HANDLER(name, caption, id) \
2775
static int video_blitter_menu_##name (void) \
2777
video_set_blitter (id); \
2780
message_local ("Video blitter set to %s.", caption); \
2784
BLITTER_MENU_HANDLER(automatic, "automatic", VIDEO_BLITTER_AUTOMATIC)
2785
BLITTER_MENU_HANDLER(normal, "normal", VIDEO_BLITTER_NORMAL)
2786
BLITTER_MENU_HANDLER(des, "des engine", VIDEO_BLITTER_DES)
2787
BLITTER_MENU_HANDLER(interpolated_2x, "interpolated (2x)", VIDEO_BLITTER_INTERPOLATED_2X)
2788
BLITTER_MENU_HANDLER(interpolated_2x_hq, "interpolated (2x HQ)", VIDEO_BLITTER_INTERPOLATED_2X_HQ)
2789
BLITTER_MENU_HANDLER(2xscl, "2xSCL engine", VIDEO_BLITTER_2XSCL)
2790
BLITTER_MENU_HANDLER(desii, "des 2 engine", VIDEO_BLITTER_DESII)
2791
BLITTER_MENU_HANDLER(super_2xscl, "super 2xSCL engine", VIDEO_BLITTER_SUPER_2XSCL)
2792
BLITTER_MENU_HANDLER(ultra_2xscl, "ultra 2xSCL engine", VIDEO_BLITTER_ULTRA_2XSCL)
2793
BLITTER_MENU_HANDLER(hq2x, "hq2x filter", VIDEO_BLITTER_HQ2X)
2794
BLITTER_MENU_HANDLER(ntsc, "ntsc engine", VIDEO_BLITTER_NTSC)
2795
BLITTER_MENU_HANDLER(interpolated_3x, "interpolated (3x)", VIDEO_BLITTER_INTERPOLATED_3X)
2796
BLITTER_MENU_HANDLER(hq3x, "hq3x filter", VIDEO_BLITTER_HQ3X)
2797
BLITTER_MENU_HANDLER(hq4x, "hq4x filter", VIDEO_BLITTER_HQ4X)
2798
BLITTER_MENU_HANDLER(stretched, "stretched", VIDEO_BLITTER_STRETCHED)
2800
#undef BLITTER_MENU_HANDLER
2802
static int video_blitter_menu_configure (void)
2804
switch (video_get_blitter ())
2806
case VIDEO_BLITTER_NTSC:
2809
DIALOG *objhue, *objsat, *objhuew, *objbright, *objcon, *objgamma,
2810
*objsharp, *objres, *objart, *objbleed, *objfring, *objmerge,
2811
*objdbl[3], *objinterp;
2812
int merge_fields, doubling, interpolated;
2816
/* Create dialog. */
2818
dialog = create_dialog (ntsc_config_dialog_base, "ntsc");
2822
/* Get slider objects. */
2824
objhue = &dialog[NTSC_CONFIG_DIALOG_HUE];
2825
objhuew = &dialog[NTSC_CONFIG_DIALOG_HUE_WARPING];
2826
objsat = &dialog[NTSC_CONFIG_DIALOG_SATURATION];
2827
objbright = &dialog[NTSC_CONFIG_DIALOG_BRIGHTNESS];
2828
objcon = &dialog[NTSC_CONFIG_DIALOG_CONTRAST];
2829
objgamma = &dialog[NTSC_CONFIG_DIALOG_GAMMA];
2830
objsharp = &dialog[NTSC_CONFIG_DIALOG_SHARPNESS];
2831
objres = &dialog[NTSC_CONFIG_DIALOG_RESOLUTION];
2832
objart = &dialog[NTSC_CONFIG_DIALOG_ARTIFACTS];
2833
objbleed = &dialog[NTSC_CONFIG_DIALOG_COLOR_BLEED];
2834
objfring = &dialog[NTSC_CONFIG_DIALOG_COLOR_FRINGING];
2835
objmerge = &dialog[NTSC_CONFIG_DIALOG_REDUCE_FLICKER];
2836
objdbl[0] = &dialog[NTSC_CONFIG_DIALOG_SCANLINE_DOUBLING_NORMAL];
2837
objdbl[1] = &dialog[NTSC_CONFIG_DIALOG_SCANLINE_DOUBLING_BRIGHTEN];
2838
objdbl[2] = &dialog[NTSC_CONFIG_DIALOG_SCANLINE_DOUBLING_DARKEN];
2839
objinterp = &dialog[NTSC_CONFIG_DIALOG_INTERPOLATED];
2841
/* Load configuration. */
2843
objhue->d2 = (get_config_int ("ntsc", "hue", 0) + 100);
2844
objhuew->d2 = (get_config_int ("ntsc", "hue_warping", 0) + 100);
2845
objsat->d2 = (get_config_int ("ntsc", "saturation", 20) + 100);
2846
objbright->d2 = (get_config_int ("ntsc", "brightness", 10) + 100);
2847
objcon->d2 = (get_config_int ("ntsc", "contrast", 0) + 100);
2848
objgamma->d2 = (get_config_int ("ntsc", "gamma", 0) + 100);
2849
objsharp->d2 = (get_config_int ("ntsc", "sharpness", 40) + 100);
2850
objres->d2 = (get_config_int ("ntsc", "resolution", 30) + 100);
2851
objart->d2 = (get_config_int ("ntsc", "artifacts", 0) + 100);
2852
objbleed->d2 = (get_config_int ("ntsc", "bleed", 0) + 100);
2853
objfring->d2 = (get_config_int ("ntsc", "fringing", 0) + 100);
2855
merge_fields = get_config_int ("ntsc", "merge_fields", 1); /* Default On */
2857
objmerge->flags |= D_SELECTED;
2859
doubling = fix (get_config_int ("ntsc", "doubling", 2), 0, 2); /* Default Darken */
2861
objdbl[doubling]->flags |= D_SELECTED;
2863
interpolated = get_config_int ("ntsc", "interpolated", 1); /* Default On */
2865
objinterp->flags |= D_SELECTED;
2868
result = show_dialog (dialog, -1);
2870
/* Destroy dialog. */
2871
unload_dialog (dialog);
2873
if (result == NTSC_CONFIG_DIALOG_SAVE_BUTTON)
2875
/* Save configuration. */
2877
set_config_int ("ntsc", "hue", (objhue->d2 - 100));
2878
set_config_int ("ntsc", "hue_warping", (objhuew->d2 - 100));
2879
set_config_int ("ntsc", "saturation", (objsat->d2 - 100));
2880
set_config_int ("ntsc", "brightness", (objbright->d2 - 100));
2881
set_config_int ("ntsc", "contrast", (objcon->d2 - 100));
2882
set_config_int ("ntsc", "gamma", (objgamma->d2 - 100));
2883
set_config_int ("ntsc", "sharpness", (objsharp->d2 - 100));
2884
set_config_int ("ntsc", "resolution", (objres->d2 - 100));
2885
set_config_int ("ntsc", "artifacts", (objart->d2 - 100));
2886
set_config_int ("ntsc", "bleed", (objbleed->d2 - 100));
2887
set_config_int ("ntsc", "fringing", (objfring->d2 - 100));
2889
merge_fields = ((objmerge->flags & D_SELECTED) ? 1 : 0);
2891
set_config_int ("ntsc", "merge_fields", merge_fields);
2893
for (index = 0; index < 3; index++)
2895
if (objdbl[index]->flags & D_SELECTED)
2899
set_config_int ("ntsc", "doubling", doubling);
2901
interpolated = ((objinterp->flags & D_SELECTED) ? 1 : 0);
2903
set_config_int ("ntsc", "interpolated", interpolated);
2905
/* Reinitialize blitter to the load new configuration. */
2906
video_blitter_reinit ();
2908
/* Display changes. */
2911
else if (result == NTSC_CONFIG_DIALOG_SET_BUTTON)
2918
objpres[0] = &dialog[NTSC_CONFIG_DIALOG_PRESETS_DEFAULT];
2919
objpres[1] = &dialog[NTSC_CONFIG_DIALOG_PRESETS_COMPOSITE];
2920
objpres[2] = &dialog[NTSC_CONFIG_DIALOG_PRESETS_SVIDEO];
2921
objpres[3] = &dialog[NTSC_CONFIG_DIALOG_PRESETS_RGB];
2922
objpres[4] = &dialog[NTSC_CONFIG_DIALOG_PRESETS_MONOCHROME];
2924
for (index = 0; index < 5; index++)
2926
if (objpres[index]->flags & D_SELECTED)
2930
set_config_int ("ntsc", "preset", preset);
2932
/* Reinitialize blitter to the load new configuration. */
2933
video_blitter_reinit ();
2935
/* Display changes. */
2942
case VIDEO_BLITTER_STRETCHED:
2946
/* Load configuration. */
2948
width = get_config_int ("video", "stretch_width", 512);
2949
height = get_config_int ("video", "stretch_height", 480);
2951
if (get_resolution_input ("Stretched", &width, &height))
2953
/* Save configuration. */
2955
set_config_int ("video", "stretch_width", width);
2956
set_config_int ("video", "stretch_height", height);
2958
/* Reinitialize blitter to the load new configuration. */
2959
video_blitter_reinit ();
2961
/* Display changes. */
2970
gui_alert ("Error", "There are no configuration parameters "
2971
"available for the selected blitter.", NULL, NULL, "&OK", NULL,
2981
static int video_filters_menu_scanlines_25_percent (void)
2985
filters = video_get_filter_list ();
2986
LIST_TOGGLE(filters, VIDEO_FILTER_SCANLINES_LOW);
2987
video_set_filter_list (filters);
2993
message_local ("Scanlines video filter %s.", get_enabled_text_ex
2994
((filters & VIDEO_FILTER_SCANLINES_LOW), "enabled (25%)"));
2999
static int video_filters_menu_scanlines_50_percent (void)
3003
filters = video_get_filter_list ();
3004
LIST_TOGGLE(filters, VIDEO_FILTER_SCANLINES_MEDIUM);
3005
video_set_filter_list (filters);
3011
message_local ("Scanlines video filter %s.", get_enabled_text_ex
3012
((filters & VIDEO_FILTER_SCANLINES_MEDIUM), "enabled (50%)"));
3017
static int video_filters_menu_scanlines_100_percent (void)
3021
filters = video_get_filter_list ();
3022
LIST_TOGGLE(filters, VIDEO_FILTER_SCANLINES_HIGH);
3023
video_set_filter_list (filters);
3029
message_local ("Scanlines video filter %s.", get_enabled_text_ex
3030
((filters & VIDEO_FILTER_SCANLINES_HIGH), "enabled (100%)"));
3035
static int video_layers_menu_sprites_a (void)
3037
ppu_enable_sprite_layer_a = !ppu_enable_sprite_layer_a;
3040
message_local ("Video sprites layer A %s.", get_enabled_text
3041
(ppu_enable_sprite_layer_a));
3046
static int video_layers_menu_sprites_b (void)
3048
ppu_enable_sprite_layer_b = !ppu_enable_sprite_layer_b;
3051
message_local ("Video sprites layer B %s.", get_enabled_text
3052
(ppu_enable_sprite_layer_b));
3058
static int video_layers_menu_background (void)
3060
ppu_enable_background_layer = !ppu_enable_background_layer;
3063
message_local ("Video background layer %s.", get_enabled_text
3064
(ppu_enable_background_layer));
3069
static int video_layers_menu_hide_horizontal_scrolling (void)
3071
LIST clipping = video_edge_clipping;
3073
if (clipping & VIDEO_EDGE_CLIPPING_HORIZONTAL)
3074
clipping &= ~VIDEO_EDGE_CLIPPING_HORIZONTAL;
3076
clipping |= VIDEO_EDGE_CLIPPING_HORIZONTAL;
3078
video_edge_clipping = clipping;
3082
message_local ("Video horizontal edge clipping %s.", get_enabled_text
3083
(video_edge_clipping & VIDEO_EDGE_CLIPPING_HORIZONTAL));
3088
static int video_layers_menu_hide_vertical_scrolling (void)
3090
LIST clipping = video_edge_clipping;
3092
if (clipping & VIDEO_EDGE_CLIPPING_VERTICAL)
3093
clipping &= ~VIDEO_EDGE_CLIPPING_VERTICAL;
3095
clipping |= VIDEO_EDGE_CLIPPING_VERTICAL;
3097
video_edge_clipping = clipping;
3101
message_local ("Video vertical edge clipping %s.", get_enabled_text
3102
(video_edge_clipping & VIDEO_EDGE_CLIPPING_VERTICAL));
3107
static int video_layers_menu_flip_mirroring (void)
3109
ppu_invert_mirroring ();
3114
#define PALETTE_MENU_HANDLER(name, caption, id) \
3115
static int video_palette_menu_##name (void) \
3117
video_set_palette (DATA_TO_RGB(id)); \
3118
video_set_palette_id (DATA_INDEX(id)); \
3121
message_local ("Video palette set to %s.", caption); \
3125
#ifdef ALLEGRO_WINDOWS
3126
/* Kludge to get around a conflict with Win32 API. */
3127
#undef DEFAULT_PALETTE
3130
PALETTE_MENU_HANDLER(ntsc_color, "NTSC color", DEFAULT_PALETTE)
3131
PALETTE_MENU_HANDLER(ntsc_grayscale, "NTSC grayscale", GRAYSCALE_PALETTE)
3132
PALETTE_MENU_HANDLER(gnuboy, "gnuboy", GNUBOY_PALETTE)
3133
PALETTE_MENU_HANDLER(nester, "NESter", NESTER_PALETTE)
3134
PALETTE_MENU_HANDLER(nesticle, "NESticle", NESTICLE_PALETTE)
3135
PALETTE_MENU_HANDLER(modern_ntsc, "modern NTSC", MODERN_NTSC_PALETTE)
3136
PALETTE_MENU_HANDLER(modern_pal, "modern PAL", MODERN_PAL_PALETTE)
3137
PALETTE_MENU_HANDLER(ega_mode_1, "EGA (mode 1)", EGA_PALETTE_1)
3138
PALETTE_MENU_HANDLER(ega_mode_2, "EGA (mode 2)", EGA_PALETTE_2)
3140
#undef PALETTE_MENU_HANDLER
3142
static int video_palette_menu_custom (void)
3147
file = pack_fopen ("fakenes.pal", "r");
3151
gui_message (GUI_ERROR_COLOR, "Error opening FAKENES.PAL!");
3156
memset (custom_palette, 0, sizeof (PALETTE));
3158
for (index = 1; index <= 64; index++)
3160
custom_palette[index].r = ROUND((pack_getc (file) / 4.0));
3161
custom_palette[index].g = ROUND((pack_getc (file) / 4.0));
3162
custom_palette[index].b = ROUND((pack_getc (file) / 4.0));
3167
video_set_palette (((RGB *)custom_palette));
3168
video_set_palette_id (-1);
3174
message_local ("Video palette set to custom.");
3179
static int input_menu_configure (void)
3181
BOOL allow_conflicts, toggled_auto, merge_players;
3184
DIALOG *objconf, *objauto, *objmerge, *objturbo;
3186
/* Load configuration. */
3188
allow_conflicts = get_config_int ("input", "allow_conflicts", FALSE);
3189
toggled_auto = get_config_int ("input", "toggled_auto", FALSE);
3190
merge_players = get_config_int ("input", "merge_players", FALSE);
3191
turbo_rate = get_config_float ("input", "turbo_rate", 0.5);
3195
dialog = input_configure_dialog;
3197
/* Get dialog objects. */
3199
objconf = &dialog[INPUT_CONFIGURE_DIALOG_ALLOW_CONFLICTS];
3200
objauto = &dialog[INPUT_CONFIGURE_DIALOG_TOGGLED_AUTO];
3201
objmerge = &dialog[INPUT_CONFIGURE_DIALOG_MERGE_PLAYERS];
3202
objturbo = &dialog[INPUT_CONFIGURE_DIALOG_TURBO];
3204
/* Set up objects. */
3206
if (allow_conflicts)
3207
objconf->flags |= D_SELECTED;
3210
objauto->flags |= D_SELECTED;
3213
objmerge->flags |= D_SELECTED;
3215
objturbo->d2 = ROUND((turbo_rate * 100.0));
3219
if (show_dialog (dialog, -1) ==
3220
INPUT_CONFIGURE_DIALOG_SAVE_BUTTON)
3222
/* Save configuration. */
3224
allow_conflicts = TRUE_OR_FALSE(objconf->flags & D_SELECTED);
3225
toggled_auto = TRUE_OR_FALSE(objauto->flags & D_SELECTED);
3226
merge_players = TRUE_OR_FALSE(objmerge->flags & D_SELECTED);
3228
turbo_rate = (objturbo->d2 / 100.0);
3230
/* Save existing configuration so we don't lose it. */
3231
input_save_config ();
3233
/* Make any necessary changes. */
3235
set_config_int ("input", "allow_conflicts", allow_conflicts);
3236
set_config_int ("input", "toggled_auto", toggled_auto);
3237
set_config_int ("input", "merge_players", merge_players);
3238
set_config_float ("input", "turbo_rate", turbo_rate);
3240
/* Reload configuration with our changes. */
3241
input_load_config ();
3247
static int input_menu_enable_zapper (void)
3249
input_enable_zapper = !input_enable_zapper;
3252
message_local ("Zapper emulation %s.", get_enabled_text
3253
(input_enable_zapper));
3258
static int options_cpu_usage_menu_passive (void)
3260
cpu_usage = CPU_USAGE_PASSIVE;
3263
message_local ("System CPU usage set to passive.");
3268
static int options_cpu_usage_menu_normal (void)
3270
cpu_usage = CPU_USAGE_NORMAL;
3273
message_local ("System CPU usage set to normal.");
3278
static int options_cpu_usage_menu_aggressive (void)
3280
cpu_usage = CPU_USAGE_AGGRESSIVE;
3283
message_local ("System CPU usage set to aggressive.");
3288
static int options_menu_paths (void)
3290
USTRING open_path, save_path;
3293
DIALOG *objopen, *objlock, *objsave;
3295
/* Load configuration. */
3297
USTRING_CLEAR(open_path);
3298
ustrncat (open_path, get_config_string ("gui", "open_path", "/"),
3299
(sizeof (open_path) - 1));
3301
USTRING_CLEAR(save_path);
3302
ustrncat (save_path, get_config_string ("gui", "save_path", "./"),
3303
(sizeof (save_path) - 1));
3305
locked = get_config_int ("gui", "lock_paths", FALSE);
3308
dialog = options_paths_dialog;
3310
/* Get dialog objects. */
3312
objopen = &dialog[OPTIONS_PATHS_DIALOG_OPEN_PATH];
3313
objlock = &dialog[OPTIONS_PATHS_DIALOG_LOCKED];
3314
objsave = &dialog[OPTIONS_PATHS_DIALOG_SAVE_PATH];
3316
/* Set up objects. */
3318
objopen->dp = open_path;
3319
objopen->d1 = ((sizeof (open_path) / MAX_UCHAR_LENGTH) - 1);
3321
objsave->dp = save_path;
3322
objsave->d1 = ((sizeof (save_path) / MAX_UCHAR_LENGTH) - 1);
3325
objlock->flags |= D_SELECTED;
3329
if (show_dialog (dialog, -1) == OPTIONS_PATHS_DIALOG_OK_BUTTON)
3331
/* Save configuration. */
3333
set_config_string ("gui", "open_path", open_path);
3334
set_config_string ("gui", "save_path", save_path);
3336
set_config_int ("gui", "lock_paths",
3337
TRUE_OR_FALSE(objlock->flags & D_SELECTED));
3343
#define OPTIONS_GUI_THEME_MENU_HANDLER(name) \
3344
static int options_gui_theme_menu_##name (void) \
3346
set_##name##_theme (); \
3347
gui_needs_restart = TRUE; \
3351
OPTIONS_GUI_THEME_MENU_HANDLER(classic)
3352
OPTIONS_GUI_THEME_MENU_HANDLER(stainless_steel)
3353
OPTIONS_GUI_THEME_MENU_HANDLER(zero_4)
3354
OPTIONS_GUI_THEME_MENU_HANDLER(panta)
3355
OPTIONS_GUI_THEME_MENU_HANDLER(xodiac)
3356
OPTIONS_GUI_THEME_MENU_HANDLER(monochrome)
3357
OPTIONS_GUI_THEME_MENU_HANDLER(essence)
3358
OPTIONS_GUI_THEME_MENU_HANDLER(voodoo)
3359
OPTIONS_GUI_THEME_MENU_HANDLER(hugs_and_kisses)
3361
#undef OPTIONS_GUI_THEME_MENU_HANDLER
3363
static int options_menu_reset_clock (void)
3370
static int netplay_menu_start_as_server (void)
3377
DIALOG *obj_host_label;
3382
/* Load configuration. */
3386
port = get_config_int ("netplay", "port", NETPLAY_DEFAULT_PORT);
3388
STRING_CLEAR(port_str);
3389
sprintf (port_str, "%d", port);
3391
USTRING_CLEAR(nick);
3392
ustrncat (nick, get_config_string ("netplay", "nick", "Player"), (sizeof(nick) - 1));
3395
dialog = netplay_dialog;
3397
/* Get dialog objects. */
3398
obj_host_label = &dialog[NETPLAY_DIALOG_HOST_LABEL];
3399
obj_host = &dialog[NETPLAY_DIALOG_HOST];
3400
obj_port = &dialog[NETPLAY_DIALOG_PORT];
3401
obj_nick = &dialog[NETPLAY_DIALOG_NICK];
3403
/* Set up dialog objects. */
3405
obj_host_label->flags |= D_DISABLED;
3408
obj_host->dp = host;
3409
obj_host->flags |= D_DISABLED;
3411
obj_port->d1 = ((sizeof (port_str) / MAX_UCHAR_LENGTH) - 1);
3412
obj_port->dp = port_str;
3414
obj_nick->d1 = ((sizeof (nick) / MAX_UCHAR_LENGTH) - 1);
3415
obj_nick->dp = nick;
3417
/* Display dialog. */
3418
if (show_dialog (dialog, -1) != NETPLAY_DIALOG_OK_BUTTON)
3421
/* Integerize port. */
3422
port = atoi (port_str);
3424
/* Save configuration. */
3425
set_config_int ("netplay", "port", port);
3426
set_config_string ("netplay", "nick", nick);
3428
/* Start NetPlay session. */
3430
if (!netplay_open_server (port))
3432
gui_message (GUI_ERROR_COLOR, "Failed to open server!");
3436
message_local ("NetPlay session opened.");
3439
netplay_set_nickname (nick);
3442
return (open_lobby ());
3445
static int netplay_menu_start_as_client (void)
3452
DIALOG *obj_host_label;
3457
/* Load configuration. */
3460
strncat (host, get_config_string ("netplay", "host", ""), (sizeof(host) - 1));
3462
port = get_config_int ("netplay", "port", NETPLAY_DEFAULT_PORT);
3464
STRING_CLEAR(port_str);
3465
sprintf (port_str, "%d", port);
3467
USTRING_CLEAR(nick);
3468
ustrncat (nick, get_config_string ("netplay", "nick", "Player"), (sizeof(nick) - 1));
3471
dialog = netplay_dialog;
3473
/* Get dialog objects. */
3474
obj_host_label = &dialog[NETPLAY_DIALOG_HOST_LABEL];
3475
obj_host = &dialog[NETPLAY_DIALOG_HOST];
3476
obj_port = &dialog[NETPLAY_DIALOG_PORT];
3477
obj_nick = &dialog[NETPLAY_DIALOG_NICK];
3479
/* Set up dialog objects. */
3481
obj_host_label->flags &= ~D_DISABLED;
3483
obj_host->d1 = ((sizeof (host) / MAX_UCHAR_LENGTH) - 1);
3484
obj_host->dp = host;
3485
obj_host->flags &= ~D_DISABLED;
3487
obj_port->d1 = ((sizeof (port_str) / MAX_UCHAR_LENGTH) - 1);
3488
obj_port->dp = port_str;
3490
obj_nick->d1 = ((sizeof (nick) / MAX_UCHAR_LENGTH) - 1);
3491
obj_nick->dp = nick;
3493
/* Display dialog. */
3494
if (show_dialog (dialog, -1) != NETPLAY_DIALOG_OK_BUTTON)
3497
/* Integerize port. */
3498
port = atoi (port_str);
3500
/* Save configuration. */
3501
set_config_string ("netplay", "host", host);
3502
set_config_int ("netplay", "port", port);
3503
set_config_string ("netplay", "nick", nick);
3505
/* Start NetPlay session. */
3507
if (!netplay_open_client (host, port))
3509
gui_message (GUI_ERROR_COLOR, "Failed to connect to remote host!");
3513
message_local ("NetPlay session opened.");
3516
netplay_set_nickname (nick);
3519
return (open_lobby ());
3522
static int help_menu_view_license (void)
3528
/* Create dialog. */
3529
dialog = load_dialog (viewer_dialog_base);
3532
WARN("Failed to create dialog structure");
3538
objframe = &dialog[VIEWER_DIALOG_FRAME];
3539
objview = &dialog[VIEWER_DIALOG_TEXT];
3541
/* Set up objects. */
3543
objframe->dp2 = "License";
3545
objview->dp = get_console_text ();
3548
show_dialog (dialog, -1);
3550
/* Destroy dialog. */
3551
unload_dialog (dialog);
3556
static int help_menu_view_log (void)
3562
/* Create dialog. */
3563
dialog = load_dialog (viewer_dialog_base);
3566
WARN("Failed to create dialog structure");
3572
objframe = &dialog[VIEWER_DIALOG_FRAME];
3573
objview = &dialog[VIEWER_DIALOG_TEXT];
3575
/* Set up objects. */
3577
objframe->dp2 = "Log";
3579
objview->dp = get_log_text ();
3582
show_dialog (dialog, -1);
3584
/* Destroy dialog. */
3585
unload_dialog (dialog);
3590
static int help_menu_keyboard_shortcuts (void)
3592
show_dialog (help_keyboard_shortcuts_dialog, -1);
3597
static int help_menu_about (void)
3599
gui_alert ("About", "FakeNES version " VERSION_STRING " "
3600
ALLEGRO_PLATFORM_STR, "Get the latest from "
3601
"http://fakenes.sourceforge.net/.", NULL, "&OK", NULL, 'o', 0);
3606
static int help_menu_fakenes_team (void)
3608
show_dialog (help_fakenes_team_dialog, -1);
3614
/* ---- Dialog handlers. ---- */
3617
static int main_cheat_manager_dialog_list (DIALOG *dialog)
3620
DIALOG *main_dialog;
3621
DIALOG *obj_enabled;
3625
if (cpu_patch_count == 0)
3628
patch = &cpu_patch_info[dialog->d1];
3630
/* Get main dialog. */
3631
main_dialog = main_cheat_manager_dialog;
3633
/* Get "Enabled" checkbox. */
3634
obj_enabled = &main_dialog[MAIN_CHEAT_MANAGER_DIALOG_ENABLED_CHECKBOX];
3637
obj_enabled->flags |= D_SELECTED;
3639
obj_enabled->flags &= ~D_SELECTED;
3642
object_message (obj_enabled, MSG_DRAW, 0);
3648
static int main_cheat_manager_dialog_add (DIALOG *dialog)
3650
DIALOG *main_dialog;
3658
if (cpu_patch_count >= CPU_MAX_PATCHES)
3660
gui_alert ("Error", "The patch list is already full.", NULL, NULL,
3661
"&OK", NULL, 'o', 0);
3667
main_dialog = main_cheat_manager_add_dialog;
3669
/* Get dialog objects. */
3670
obj_title = &main_dialog[MAIN_CHEAT_MANAGER_ADD_DIALOG_TITLE];
3671
obj_code = &main_dialog[MAIN_CHEAT_MANAGER_ADD_DIALOG_CODE];
3673
/* Set up dialog objects. */
3675
USTRING_CLEAR(title);
3676
obj_title->d1 = NEW_SAVE_TITLE_SIZE;
3677
obj_title->dp = title;
3679
USTRING_CLEAR(code);
3680
obj_code->d1 = (11 - 1);
3681
obj_code->dp = code;
3684
if (show_dialog (main_dialog, -1) !=
3685
MAIN_CHEAT_MANAGER_ADD_DIALOG_OK_BUTTON)
3690
patch = &cpu_patch_info[cpu_patch_count];
3692
if (cheats_decode (code, &patch->address, &patch->value,
3693
&patch->match_value) != 0)
3695
gui_alert ("Error", "You must enter a valid Game Genie (or NESticle "
3696
"raw) code.", NULL, NULL, "&OK", NULL, 'o', 0);
3702
ustrncat (patch->title, title, (USTRING_SIZE - 1));
3705
patch->enabled = TRUE;
3709
if ((value = cpu_read (patch->address)) == patch->match_value)
3711
/* Activate patch. */
3712
patch->active = TRUE;
3714
cpu_patch_table[patch->address] = (patch->value - value);
3720
static int main_cheat_manager_dialog_remove (DIALOG *dialog)
3722
DIALOG *main_dialog;
3729
if (cpu_patch_count == 0)
3732
main_dialog = main_cheat_manager_dialog;
3734
start = main_dialog[MAIN_CHEAT_MANAGER_DIALOG_LIST].d1;
3735
src = &cpu_patch_info[start];
3737
/* Disable patch. */
3740
if (gui_alert ("Confirmation", "Really deactivate and remove this "
3741
"patch?", NULL, NULL, "&OK", "&Cancel", 'o', 'c') == 2)
3746
cpu_patch_table[src->address] = 0;
3749
for (index = (start + 1); index < cpu_patch_count; index++)
3753
src = &cpu_patch_info[index];
3754
dest = &cpu_patch_info[(index - 1)];
3756
memcpy (dest, src, sizeof (CPU_PATCH));
3759
src = &cpu_patch_info[(cpu_patch_count - 1)];
3761
memset (src, 0, sizeof (CPU_PATCH));
3762
sprintf (src->title, "?");
3766
if (cpu_patch_count == 0)
3768
main_dialog[MAIN_CHEAT_MANAGER_DIALOG_ENABLED_CHECKBOX].flags &=
3775
static int main_cheat_manager_dialog_enabled (DIALOG *dialog)
3782
if (cpu_patch_count == 0)
3784
dialog->flags &= ~D_SELECTED;
3789
obj_list = &main_cheat_manager_dialog[MAIN_CHEAT_MANAGER_DIALOG_LIST];
3791
patch = &cpu_patch_info[obj_list->d1];
3793
patch->enabled = TRUE_OR_FALSE(dialog->flags & D_SELECTED);
3796
if (!patch->enabled && patch->active)
3798
patch->active = FALSE;
3800
cpu_patch_table[patch->address] = 0;
3802
else if (patch->enabled && !patch->active)
3806
if ((value = cpu_read (patch->address)) == patch->match_value)
3809
patch->active = TRUE;
3811
cpu_patch_table[patch->address] = (patch->value - value);
3816
object_message (obj_list, MSG_DRAW, 0);
3822
static USTRING main_cheat_manager_dialog_list_texts[CPU_MAX_PATCHES];
3824
static char *main_cheat_manager_dialog_list_filler (int index, int *list_size)
3828
CPU_PATCH *patch = &cpu_patch_info[index];
3829
UCHAR *text = main_cheat_manager_dialog_list_texts[index];
3831
USTRING_CLEAR(text);
3832
uszprintf (text, USTRING_SIZE, "$%04x -$%02x +$%02x %s ",
3833
patch->address, patch->match_value, patch->value, (patch->active ?
3834
"Active" : " Idle "));
3837
ustrncat (text, patch->title, (USTRING_SIZE - 1));
3843
RT_ASSERT(list_size);
3845
*list_size = cpu_patch_count;
3851
static int selected_player = -1;
3852
static int selected_player_device = INPUT_DEVICE_NONE;
3854
static int input_configure_dialog_player_select (DIALOG *dialog)
3856
DIALOG *main_dialog;
3862
selected_player = dialog->d2;
3863
selected_player_device = input_get_player_device (selected_player);
3865
main_dialog = input_configure_dialog;
3867
first = INPUT_CONFIGURE_DIALOG_DEVICE_0_SELECT;
3868
last = INPUT_CONFIGURE_DIALOG_DEVICE_7_SELECT;
3870
for (index = first; index <= last; index++)
3871
main_dialog[index].flags &= ~D_SELECTED;
3873
main_dialog[(first + selected_player_device)].flags |= D_SELECTED;
3877
for (index = first; index <= last; index++)
3878
object_message (&main_dialog[index], MSG_DRAW, 0);
3880
first = INPUT_CONFIGURE_DIALOG_SET_BUTTON_AUTO_1;
3881
last = INPUT_CONFIGURE_DIALOG_SET_BUTTON_AUTO_8;
3883
for (index = first; index <= last; index++)
3885
DIALOG *dialog = &main_dialog[index];
3889
if (input_get_player_button_param (selected_player, dialog->d2,
3890
INPUT_PLAYER_BUTTON_PARAM_AUTO))
3892
dialog->flags |= D_SELECTED;
3896
dialog->flags &= ~D_SELECTED;
3899
object_message (dialog, MSG_DRAW, 0);
3902
first = INPUT_CONFIGURE_DIALOG_SET_BUTTON_TURBO_1;
3903
last = INPUT_CONFIGURE_DIALOG_SET_BUTTON_TURBO_8;
3905
for (index = first; index <= last; index++)
3907
DIALOG *dialog = &main_dialog[index];
3911
if (input_get_player_button_param (selected_player, dialog->d2,
3912
INPUT_PLAYER_BUTTON_PARAM_TURBO))
3914
dialog->flags |= D_SELECTED;
3918
dialog->flags &= ~D_SELECTED;
3921
object_message (dialog, MSG_DRAW, 0);
3929
static int input_configure_dialog_device_select (DIALOG *dialog)
3933
if (selected_player < 0)
3935
gui_alert ("Error", "Please select a player to modify first.", NULL,
3936
NULL, "&OK", NULL, 'o', 0);
3941
selected_player_device = dialog->d2;
3943
input_set_player_device (selected_player, selected_player_device);
3948
static int input_configure_dialog_set_buttons (DIALOG *dialog)
3954
if (selected_player < 0)
3956
gui_alert ("Error", "Please select a player to modify first.", NULL,
3957
NULL, "&OK", NULL, 'o', 0);
3959
if (dialog->proc == sl_checkbox)
3960
dialog->flags ^= D_SELECTED;
3965
button = dialog->d2;
3969
case 0: /* Map button. */
3971
if (selected_player_device == INPUT_DEVICE_NONE)
3973
gui_alert ("Error", "The selected player is currently "
3974
"disabled.", NULL, NULL, "&OK", NULL, 'o', 0);
3979
if (selected_player_device == INPUT_DEVICE_MOUSE)
3981
gui_alert ("Error", "Unable to set buttons for mouse at this "
3982
"time.", NULL, NULL, "&OK", NULL, 'o', 0);
3987
message_local ("Scanning for device changes, press ESC to cancel.");
3989
input_map_player_button (selected_player, button);
3994
case 1: /* Set auto. */
3996
input_set_player_button_param (selected_player, button,
3997
INPUT_PLAYER_BUTTON_PARAM_AUTO, (dialog->flags & D_SELECTED));
4002
case 2: /* Set turbo. */
4004
input_set_player_button_param (selected_player, button,
4005
INPUT_PLAYER_BUTTON_PARAM_TURBO, (dialog->flags & D_SELECTED));
4017
static int input_configure_dialog_calibrate (DIALOG *dialog)
4021
if (selected_player < 0)
4023
gui_alert ("Error", "Please select a player to modify first.", NULL,
4024
NULL, "&OK", NULL, 'o', 0);
4029
switch (selected_player_device)
4031
case INPUT_DEVICE_JOYSTICK_1:
4032
case INPUT_DEVICE_JOYSTICK_2:
4036
index = (selected_player_device - INPUT_DEVICE_JOYSTICK_1);
4038
while (joy[index].flags & JOYFLAG_CALIBRATE)
4042
message_local ("%s, and press any key.",
4043
calibrate_joystick_name (index));
4045
while (!keypressed ())
4048
ureadkey (&scancode);
4050
if (scancode == KEY_ESC)
4052
gui_message (GUI_ERROR_COLOR, "Joystick calibration "
4058
if (calibrate_joystick (index) != 0)
4060
gui_alert ("Error", "An unknown error occured while "
4061
"attempting to calibrate the device.", NULL, NULL, "&OK",
4068
gui_alert ("Calibration Complete", "The selected device has been "
4069
"calibrated.", NULL, NULL, "&Save", NULL, 's', 0);
4071
save_joystick_data (NULL);
4078
gui_alert ("Error", "The selected device does not require "
4079
"calibration.", NULL, NULL, "&OK", NULL, 'o', 0);
4088
static int lobby_dialog_load (void)
4090
/* Note: D_CLOSE means success, D_O_K means failure. */
4091
if (main_menu_open () == D_CLOSE)
4095
obj_ok = &lobby_dialog[LOBBY_DIALOG_OK_BUTTON];
4097
obj_ok->flags &= ~D_DISABLED;
4100
object_message (obj_ok, MSG_DRAW, 0);