This is menudefs.c in view mode; [Download] [Up]
/* * menudefs.c - Definition of menu commands and settings. * * Written by * Ettore Perazzoli (ettore@comm2000.it) * * This file is part of VICE, the Versatile Commodore Emulator. * See README for copyright notice. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. * */ #include "vice.h" #include <dir.h> #include <fcntl.h> #include <io.h> #include <stdio.h> #include <unistd.h> #include "menudefs.h" #include "grabkey.h" #include "joystick.h" #include "kbd.h" #include "log.h" #include "sound.h" #include "tui.h" #include "tuiview.h" #include "ui.h" /* FIXME: Argh!! Megakludge! <dir.h> #defines `DRIVE', which we need in "drive.h". */ #undef DRIVE #include "attach.h" #include "autostart.h" #include "drive.h" #include "fsdevice.h" #include "info.h" #include "machine.h" #include "serial.h" #include "tapeunit.h" #include "true1541.h" #include "utils.h" #include "video.h" /* ------------------------------------------------------------------------- */ tui_menu_t ui_attach_submenu; tui_menu_t ui_detach_submenu; tui_menu_t ui_drive_submenu; tui_menu_t ui_info_submenu; tui_menu_t ui_joystick_settings_submenu; tui_menu_t ui_main_menu; tui_menu_t ui_quit_submenu; tui_menu_t ui_reset_submenu; tui_menu_t ui_sound_buffer_size_submenu; tui_menu_t ui_sound_sample_rate_submenu; tui_menu_t ui_sound_submenu; tui_menu_t ui_special_submenu; tui_menu_t ui_video_submenu; tui_menu_t ui_settings_submenu; /* ------------------------------------------------------------------------ */ static TUI_MENU_CALLBACK(attach_disk_callback) { char *s; if (been_activated) { char *default_item, *directory; char *name; s = (char *)serial_get_file_name((int)param); fname_split(s, &directory, &default_item); name = tui_file_selector("Attach a disk image", directory, "*.[dx]6[4z]", default_item, read_disk_image_contents); if (name != NULL && (s == NULL || strcasecmp(name, s) != 0) && file_system_attach_disk((int)param, name) < 0) { tui_error("Invalid disk image."); } ui_update_menus(); free(directory), free(default_item); if (name != NULL) free(name); } s = (char *)serial_get_file_name((int)param); if (s == NULL || *s == '\0') return "(none)"; else return s; } static TUI_MENU_CALLBACK(attach_tape_callback) { char *s; if (been_activated) { char *directory, *default_item; char *name; s = (char *)serial_get_file_name(1); fname_split(s, &directory, &default_item); name = tui_file_selector("Attach a tape image", directory, "*.t6[4z]", default_item, read_tape_image_contents); if (name != NULL && (s == NULL || strcasecmp(s, name) != 0) && serial_select_file(DT_TAPE, 1, name) < 0) { tui_error("Invalid tape image."); } ui_update_menus(); free(directory), free(default_item); if (name != NULL) free(name); } s = (char *)serial_get_file_name(1); if (s == NULL || *s == '\0') return "(none)"; else return s; } static TUI_MENU_CALLBACK(autostart_callback) { if (been_activated) { if (autostart_device((int)param) < 0) tui_error("Cannot autostart device #%d", (int)param); } return NULL; } static TUI_MENU_CALLBACK(detach_disk_callback) { char *s; if (been_activated) { file_system_detach_disk((int)param); ui_update_menus(); } s = (char *)serial_get_file_name((int)param); if (s == NULL || *s == '\0') return "(none)"; else return s; } static TUI_MENU_CALLBACK(detach_tape_callback) { char *s; if (been_activated) { serial_remove(1); ui_update_menus(); } s = (char *)serial_get_file_name(1); if (s == NULL || *s == '\0') return "(none)"; else return s; } /* ------------------------------------------------------------------------ */ #if 0 static TUI_MENU_CALLBACK(change_workdir_callback) { char s[256]; if (!been_activated) return NULL; *s = '\0'; if (tui_input_string("Change working directory", "New directory:", s, 255) == -1) return NULL; remove_spaces(s); if (*s == '\0') return NULL; if (chdir(s) == -1) tui_error("Invalid directory."); return NULL; } #endif /* ------------------------------------------------------------------------- */ static TUI_MENU_CALLBACK(resolution_submenu_callback) { int mode; resources_get_value("VGAMode", (resource_value_t *) &mode); return vga_modes[mode].description; } TUI_MENU_DEFINE_RADIO(VGAMode) static TUI_MENU_CALLBACK(refresh_rate_submenu_callback) { int v; resources_get_value("RefreshRate", (resource_value_t *) &v); if (v == 0) { return "Auto"; } else { static char s[256]; sprintf(s, "1/%d", v); return s; } } TUI_MENU_DEFINE_RADIO(RefreshRate) TUI_MENU_DEFINE_TOGGLE(VideoCache) #ifndef USE_MIDAS_SOUND TUI_MENU_DEFINE_TOGGLE(TripleBuffering) #endif /* ------------------------------------------------------------------------- */ TUI_MENU_DEFINE_RADIO(True1541ExtendImagePolicy) static TUI_MENU_CALLBACK(true1541_extend_image_policy_submenu_callback) { int v; resources_get_value("True1541ExtendImagePolicy", (resource_value_t *) &v); switch (v) { case TRUE1541_EXTEND_NEVER: return "Never extend"; case TRUE1541_EXTEND_ASK: return "Ask on extend"; case TRUE1541_EXTEND_ACCESS: return "Extend on access"; default: return "Unknown"; } } static tui_menu_item_def_t true1541_extend_image_policy_submenu[] = { { "_Never extend", "Never create more than 35 tracks", radio_True1541ExtendImagePolicy_callback, (void *) TRUE1541_EXTEND_NEVER, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Ask on extend", "Ask the user before creating extra tracks", radio_True1541ExtendImagePolicy_callback, (void *) TRUE1541_EXTEND_ASK, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Extend on access", "Automagically extend the disk image if extra (>35) tracks are accessed", radio_True1541ExtendImagePolicy_callback, (void *) TRUE1541_EXTEND_ACCESS, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; TUI_MENU_DEFINE_TOGGLE(True1541) static TUI_MENU_CALLBACK(toggle_True1541SyncFactor_callback) { int value; resources_get_value("True1541SyncFactor", (resource_value_t *) &value); if (been_activated) { if (value == TRUE1541_SYNC_PAL) value = TRUE1541_SYNC_NTSC; else value = TRUE1541_SYNC_PAL; resources_set_value("True1541SyncFactor", (resource_value_t) value); } switch (value) { case TRUE1541_SYNC_PAL: return "PAL"; case TRUE1541_SYNC_NTSC: return "NTSC"; default: return "(Custom)"; } } TUI_MENU_DEFINE_RADIO(True1541IdleMethod) static TUI_MENU_CALLBACK(true1541_idle_method_submenu_callback) { int value; resources_get_value("True1541IdleMethod", (resource_value_t *) &value); switch (value) { case TRUE1541_IDLE_NO_IDLE: return "None"; case TRUE1541_IDLE_TRAP_IDLE: return "Trap idle"; case TRUE1541_IDLE_SKIP_CYCLES: return "Skip cycles"; default: return "(Unknown)"; } } static tui_menu_item_def_t true1541_idle_method_submenu[] = { { "_None", "Always run the 1541 CPU as on the real thing", radio_True1541IdleMethod_callback, (void *) TRUE1541_IDLE_NO_IDLE, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Trap Idle", "Stop running the 1541 CPU when entering the idle DOS loop", radio_True1541IdleMethod_callback, (void *) TRUE1541_IDLE_TRAP_IDLE, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Skip Cycles", "Skip 1541 CPU cycles when the IEC bus is not used for a while", radio_True1541IdleMethod_callback, (void *) TRUE1541_IDLE_SKIP_CYCLES, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; TUI_MENU_DEFINE_TOGGLE(True1541ParallelCable) static tui_menu_item_def_t true1541_settings_submenu[] = { { "True 1541 _Emulation:", "Enable hardware-level floppy drive emulation", toggle_True1541_callback, NULL, 3, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "True 1541 _Sync Factor:", "Select 1541/machine clock ratio", toggle_True1541SyncFactor_callback, NULL, 8, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "True 1541 _Idle Method:", "Select method for disk drive idle", true1541_idle_method_submenu_callback, NULL, 11, TUI_MENU_BEH_CONTINUE, true1541_idle_method_submenu, "True 1541 idle method" }, { "--" }, { "Enable _Parallel Cable:", "Enable a SpeedDOS-compatible parallel cable", toggle_True1541ParallelCable_callback, NULL, 3, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "_40-Track Image Support:", "Settings for dealing with 40-track disk images", true1541_extend_image_policy_submenu_callback, NULL, 16, TUI_MENU_BEH_CONTINUE, true1541_extend_image_policy_submenu, "" }, { NULL } }; /* ------------------------------------------------------------------------- */ TUI_MENU_DEFINE_TOGGLE(Sound) static TUI_MENU_CALLBACK(sound_sample_rate_submenu_callback) { static char s[256]; int value; resources_get_value("SoundSampleRate", (resource_value_t *) &value); sprintf(s, "%d Hz", value); return s; } TUI_MENU_DEFINE_RADIO(SoundSampleRate) TUI_MENU_DEFINE_RADIO(SoundBufferSize) static TUI_MENU_CALLBACK(sound_buffer_size_submenu_callback) { static char s[256]; int value; resources_get_value("SoundBufferSize", (resource_value_t *) &value); sprintf(s, "%d msec", value); return s; } TUI_MENU_DEFINE_RADIO(SoundOversample) static TUI_MENU_CALLBACK(sound_oversample_submenu_callback) { static char s[40]; int value; resources_get_value("SoundOversample", (resource_value_t *) &value); if (value != 0) { int n = 1, i; for (i = 0; i < value; i++) n *= 2; sprintf(s, "%dx", n); return s; } else return "None"; } TUI_MENU_DEFINE_RADIO(SoundSpeedAdjustment) static TUI_MENU_CALLBACK(sound_synchronization_submenu_callback) { int value; resources_get_value("SoundSpeedAdjustment", (resource_value_t *) &value); switch (value) { case SOUND_ADJUST_FLEXIBLE: return "Flexible"; case SOUND_ADJUST_ADJUSTING: return "Adjusting"; case SOUND_ADJUST_EXACT: return "Exact"; default: return "Unknown"; } } static tui_menu_item_def_t sample_rate_submenu[] = { { "_0: 8000 Hz", "Set sampling rate to 8000 Hz", radio_SoundSampleRate_callback, (void *) 8000, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_1: 11025 Hz", "Set sampling rate to 11025 Hz", radio_SoundSampleRate_callback, (void *) 11025, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_2: 22050 Hz", "Set sampling rate to 22050 Hz", radio_SoundSampleRate_callback, (void *) 22050, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_3: 44100 Hz", "Set sampling rate to 44100 Hz", radio_SoundSampleRate_callback, (void *) 44100, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; static tui_menu_item_def_t sound_buffer_size_submenu[] = { { "_1: 50 msec", "Set sound buffer size to 50 msec", radio_SoundBufferSize_callback, (void *) 50, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_2: 100 msec", "Set sound buffer size to 100 msec", radio_SoundBufferSize_callback, (void *) 100, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_3: 150 msec", "Set sound buffer size to 150 msec", radio_SoundBufferSize_callback, (void *) 150, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_4: 200 msec", "Set sound buffer size to 200 msec", radio_SoundBufferSize_callback, (void *) 200, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_5: 250 msec", "Set sound buffer size to 250 msec", radio_SoundBufferSize_callback, (void *) 250, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_6: 300 msec", "Set sound buffer size to 300 msec", radio_SoundBufferSize_callback, (void *) 300, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_7: 350 msec", "Set sound buffer size to 350 msec", radio_SoundBufferSize_callback, (void *) 350, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; static tui_menu_item_def_t sound_oversample_submenu[] = { { "_None", "Disable oversampling", radio_SoundOversample_callback, (void *) 0, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_2x", "Enable 2x oversampling", radio_SoundOversample_callback, (void *) 1, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_4x", "Enable 4x oversampling", radio_SoundOversample_callback, (void *) 2, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_8x", "Enable 8x oversampling", radio_SoundOversample_callback, (void *) 3, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; static tui_menu_item_def_t sound_synchronization_submenu[] = { { "_Flexible", "Slightly adapt sound playback speed to the speed of the emulator", radio_SoundSpeedAdjustment_callback, (void *) SOUND_ADJUST_FLEXIBLE, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Adjusting", "Fully adapt the playback speed to the emulator, avoiding clicks when it's slower", radio_SoundSpeedAdjustment_callback, (void *) SOUND_ADJUST_ADJUSTING, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Exact", "Don't adapt sound playback: make the emulator finetune its speed to the playback", radio_SoundSpeedAdjustment_callback, (void *) SOUND_ADJUST_EXACT, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; static tui_menu_item_def_t sound_submenu[] = { { "Sound _Playback:", "Enable sound output", toggle_Sound_callback, NULL, 3, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "_Sample Frequency:", "Choose sound output sampling rate", sound_sample_rate_submenu_callback, NULL, 10, TUI_MENU_BEH_CONTINUE, sample_rate_submenu, "Sample rate" }, { "Sound _Buffer Size:", "Specify playback latency", sound_buffer_size_submenu_callback, NULL, 10, TUI_MENU_BEH_CONTINUE, sound_buffer_size_submenu, "Latency" }, { "_Oversampling Factor:", "Specify amount of oversampling on sound output", sound_oversample_submenu_callback, NULL, 4, TUI_MENU_BEH_CONTINUE, sound_oversample_submenu, "Oversample" }, { "S_ynchronization Method:", "Specify method used to synchronize the sound playback with the emulator", sound_synchronization_submenu_callback, NULL, 9, TUI_MENU_BEH_CONTINUE, sound_synchronization_submenu, "Synchronization" }, { NULL } }; /* ------------------------------------------------------------------------- */ /* Joystick settings. */ static TUI_MENU_CALLBACK(get_joystick_device_callback) { int port = (int) param; char *resource = port == 1 ? "JoyDevice1" : "JoyDevice2"; int value; resources_get_value(resource, (resource_value_t *) &value); switch (value) { case JOYDEV_NONE: return "None"; case JOYDEV_NUMPAD: return "Numpad + Right Ctrl"; case JOYDEV_KEYSET1: return "Keyset A"; case JOYDEV_KEYSET2: return "Keyset B"; case JOYDEV_HW1: return "Joystick #1"; case JOYDEV_HW2: return "Joystick #2"; } return "Unknown"; } static TUI_MENU_CALLBACK(set_joy_device_callback) { int port = (int) param >> 8; char *resource = port == 1 ? "JoyDevice1" : "JoyDevice2"; if (been_activated) { resources_set_value(resource, (resource_value_t) ((int) param & 0xff)); ui_update_menus(); } else { int value; resources_get_value(resource, (resource_value_t *) &value); if (value == ((int) param & 0xff)) *become_default = 1; } return NULL; } static TUI_MENU_CALLBACK(swap_joysticks_callback) { int value1, value2, tmp; if (been_activated) { resources_get_value("JoyDevice1", (resource_value_t *) &value1); resources_get_value("JoyDevice2", (resource_value_t *) &value2); tmp = value1; value1 = value2; value2 = tmp; resources_set_value("JoyDevice1", (resource_value_t) value1); resources_set_value("JoyDevice2", (resource_value_t) value2); ui_update_menus(); } return NULL; } static tui_menu_item_def_t joy_device_1_submenu[] = { { "N_one", "No joystick device attached", set_joy_device_callback, (void *) (0x100 | JOYDEV_NONE), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "--" }, { "_Numpad + Right Ctrl", "Use numeric keypad for movement and right Ctrl for fire", set_joy_device_callback, (void *) (0x100 | JOYDEV_NUMPAD), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "Keyset _A", "Use keyset A", set_joy_device_callback, (void *) (0x100 | JOYDEV_KEYSET1), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "Keyset _B", "Use keyset B", set_joy_device_callback, (void *) (0x100 | JOYDEV_KEYSET2), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "--" }, { "PC Joystick #_1", "Use real PC joystick #1", set_joy_device_callback, (void *) (0x100 | JOYDEV_HW1), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "PC Joystick #_2", "Use real PC joystick #2", set_joy_device_callback, (void *) (0x100 | JOYDEV_HW2), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; static tui_menu_item_def_t joy_device_2_submenu[] = { { "N_one", "No joystick device attached", set_joy_device_callback, (void *) (0x200 | JOYDEV_NONE), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "--" }, { "_Numpad + Right Ctrl", "Use numeric keypad for movement and right Ctrl for fire", set_joy_device_callback, (void *) (0x200 | JOYDEV_NUMPAD), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "Keyset _A", "Use keyset A", set_joy_device_callback, (void *) (0x200 | JOYDEV_KEYSET1), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "Keyset _B", "Use keyset B", set_joy_device_callback, (void *) (0x200 | JOYDEV_KEYSET2), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "--" }, { "Joystick #_1", "Use real joystick #1", set_joy_device_callback, (void *) (0x200 | JOYDEV_HW1), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "Joystick #_2", "Use real joystick #2", set_joy_device_callback, (void *) (0x200 | JOYDEV_HW2), 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { NULL } }; static TUI_MENU_CALLBACK(keyset_callback) { int direction, number; int value; char s[256]; number = (int) param >> 8; direction = (int) param & 0xff; sprintf(s, "KeySet%d%s", number, joystick_direction_to_string(direction)); if (been_activated) { kbd_code_t key; int width = 60, height = 5; int x = CENTER_X(width), y = CENTER_Y(height); tui_area_t backing_store = NULL; char msg[80]; sprintf(msg, "Press key for %s%s (Esc for none)...", direction == KEYSET_FIRE ? "" : "direction ", joystick_direction_to_string(direction)); tui_display_window(x, y, width, height, MESSAGE_BORDER, MESSAGE_BACK, NULL, &backing_store); tui_set_attr(MESSAGE_FORE, MESSAGE_BACK, 0); tui_display(CENTER_X(strlen(msg)), y + 2, 0, msg); /* Do not allow Alt as we need it for hotkeys. */ do key = grab_key(); while (key == K_LEFTALT || key == K_RIGHTALT); tui_area_put(backing_store, x, y); tui_area_free(backing_store); if (key == K_ESC) key = K_NONE; resources_set_value(s, (resource_value_t) key); } resources_get_value(s, (resource_value_t *) &value); return kbd_code_to_string((kbd_code_t) value); } #define DEFINE_KEYSET_MENU(num) \ static tui_menu_item_def_t keyset_##num##_submenu[] = { \ { "_1: South West:", \ "Specify key for diagonal down-left direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_SW), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_2: South:", \ "Specify key for the down direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_S), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_3: South East:", \ "Specify key for the diagonal down-right direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_SE), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_4: West:", \ "Specify key for the left direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_W), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_6: East:", \ "Specify key for the right direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_E), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_7: North West:", \ "Specify key for the diagonal up-left direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_NW), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_8: North:", \ "Specify key for the up direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_N), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_9: North East:", \ "Specify key for the diagonal up-right direction", \ keyset_callback, (void *) ((num << 8) | KEYSET_NE), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_0: Fire", \ "Specify key for the fire button", \ keyset_callback, (void *) ((num << 8) | KEYSET_FIRE), 12, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { NULL } \ }; DEFINE_KEYSET_MENU(1) DEFINE_KEYSET_MENU(2) static tui_menu_item_def_t single_joystick_submenu[] = { { "Joystick _Device:", "Specify device for joystick emulation", get_joystick_device_callback, (void *) 1, 19, TUI_MENU_BEH_CONTINUE, joy_device_1_submenu, "Joystick" }, { "--" }, { "Configure Keyset _A...", "Configure keyboard set A for joystick emulation", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, keyset_1_submenu, "Keyset A" }, { "Configure Keyset _B...", "Configure keyboard set B for joystick emulation", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, keyset_2_submenu, "Keyset B" }, { NULL } }; static tui_menu_item_def_t double_joystick_submenu[] = { { "_Swap", "Swap joystick ports", swap_joysticks_callback, NULL, 0, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "--" }, { "Port #_1:", "Specify device for emulation of joystick in port #1", get_joystick_device_callback, (void *) 1, 19, TUI_MENU_BEH_CONTINUE, joy_device_1_submenu, "Joystick #1" }, { "Port #_2:", "Specify device for emulation of joystick in port #2", get_joystick_device_callback, (void *) 2, 19, TUI_MENU_BEH_CONTINUE, joy_device_2_submenu, "Joystick #2" }, { "--" }, { "Configure Keyset _A...", "Configure keyboard set A for joystick emulation", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, keyset_1_submenu, "Keyset A" }, { "Configure Keyset _B...", "Configure keyboard set B for joystick emulation", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, keyset_2_submenu, "Keyset B" }, { NULL } }; /* ------------------------------------------------------------------------- */ static TUI_MENU_CALLBACK(save_settings_callback) { if (been_activated) { if (resources_save(NULL) < 0) tui_error("Cannot save settings."); else tui_message("Settings saved successfully."); } return NULL; } static TUI_MENU_CALLBACK(load_settings_callback) { if (been_activated) { if (resources_load(NULL) < 0) tui_error("Cannot load settings."); else tui_message("Settings loaded successfully."); } return NULL; } static TUI_MENU_CALLBACK(restore_default_settings_callback) { if (been_activated) { resources_set_defaults(); tui_message("Default settings restored."); } return NULL; } static TUI_MENU_CALLBACK(quit_callback) { if (been_activated) { _setcursortype(_NORMALCURSOR); normvideo(); clrscr(); serial_remove(-1); exit(0); } return NULL; } static tui_menu_item_def_t quit_submenu[] = { { "_Not really!", "Go back to the menu", NULL, NULL, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "_Yes, exit emulator", "Leave the emulator completely", quit_callback, NULL, 0, TUI_MENU_BEH_RESUME, NULL, NULL }, { NULL } }; /* ------------------------------------------------------------------------ */ static void mon_trap(ADDRESS addr, void *data) { mon(addr); } static TUI_MENU_CALLBACK(monitor_callback) { if (been_activated) maincpu_trigger_trap(mon_trap, 0); return NULL; } /* ------------------------------------------------------------------------- */ static TUI_MENU_CALLBACK(soft_reset_callback) { if (been_activated) { maincpu_trigger_reset(); } /* This way, the "Not Really!" item is always the default one. */ *become_default = 0; return NULL; } static TUI_MENU_CALLBACK(hard_reset_callback) { if (been_activated) { mem_powerup(); maincpu_trigger_reset(); } /* This way, the "Not Really!" item is always the default one. */ *become_default = 0; return NULL; } static tui_menu_item_def_t reset_submenu[] = { { "_Not Really!", "Go back to the menu", NULL, NULL, 0, TUI_MENU_BEH_CLOSE, NULL, NULL }, { "Do a _Soft Reset", "Do a soft reset without resetting the memory", soft_reset_callback, NULL, 0, TUI_MENU_BEH_RESUME, NULL, NULL }, { "Do a _Hard Reset", "Clear memory and reset as after a power-up", hard_reset_callback, NULL, 0, TUI_MENU_BEH_RESUME, NULL, NULL }, { NULL } }; /* ------------------------------------------------------------------------- */ static TUI_MENU_CALLBACK(show_copyright_callback) { if (been_activated) { static char *str_list[] = { "", "V I C E", "Version " VERSION, #ifdef UNSTABLE "(unstable)", #endif "", "Copyright (c) 1996-1998 Ettore Perazzoli", "Copyright (c) 1996-1998 Andre' Fachat", "Copyright (c) 1993-1994, 1997-1998 Teemu Rantanen", "Copyright (c) 1997-1998 Daniel Sladic", "Copyright (c) 1998 Andreas Boose", "Copyright (c) 1993-1996 Jouko Valta", "Copyright (c) 1993-1994 Jarkko Sonninen", "", "Official VICE homepage:", "http://www.tu-chemnitz.de/~fachat/vice/vice.html", #ifdef UNSTABLE "", "WARNING: this is an *unstable* test version!", "Please check out the homepage for the latest updates.", #endif "" }; int num_items = sizeof(str_list) / sizeof(*str_list); tui_area_t backing_store = NULL; int height, width; int y, x, i; for (width = i = 0; i < num_items; i++) { int l = strlen(str_list[i]); if (l > width) width = l; } width += 4; height = num_items + 2; x = CENTER_X(width); y = CENTER_Y(height); tui_display_window(x, y, width, height, MESSAGE_BORDER, MESSAGE_BACK, "About VICE", &backing_store); tui_set_attr(MESSAGE_FORE, MESSAGE_BACK, 0); for (i = 0; i < num_items; i++) tui_display(CENTER_X(strlen(str_list[i])), y + i + 1, 0, "%s", str_list[i]); getkey(); tui_area_put(backing_store, x, y); tui_area_free(backing_store); } return NULL; } static TUI_MENU_CALLBACK(show_info_callback) { if (been_activated) tui_view_text(70, 20, NULL, (const char *)param); return NULL; } static tui_menu_item_def_t info_submenu[] = { { "_Copyright", "VICE copyright information", show_copyright_callback, NULL, 0, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "_Who made what?", "VICE contributors", show_info_callback, (void *)contrib_text, 0, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "_License", "VICE license (GNU General Public License)", show_info_callback, (void *)license_text, 0, TUI_MENU_BEH_CONTINUE, NULL, NULL }, { "_No warranty!", "VICE is distributed WITHOUT ANY WARRANTY!", show_info_callback, (void *)warranty_text, 0, TUI_MENU_BEH_CONTINUE }, { NULL } }; /* ------------------------------------------------------------------------- */ /* This is a bit of a hack, but I prefer this way instead of writing 1,000 menu entries... */ static void create_ui_video_submenu(void) { static tui_menu_t refresh_rate_submenu, vga_mode_submenu; refresh_rate_submenu = tui_menu_create("Refresh", 1); { int i; char label[256], desc[256]; for (i = 1; i <= 10; i++) { if (i != 10) sprintf(label, "1/_%d", i); else strcpy(label, "1/1_0"); if (i == 1) sprintf(desc, "Set refresh rate to 1/%d (update every frame)", i); else sprintf(desc, "Set refresh rate to 1/%d (update once every %d frames)", i, i); tui_menu_add_item(refresh_rate_submenu, label, desc, radio_RefreshRate_callback, (void *)i, 0, TUI_MENU_BEH_CLOSE); } tui_menu_add_separator(refresh_rate_submenu); tui_menu_add_item(refresh_rate_submenu, "_Automatic", "Let the emulator select an appropriate refresh rate automagically", radio_RefreshRate_callback, NULL, 0, TUI_MENU_BEH_CLOSE); } vga_mode_submenu = tui_menu_create("VGA Resolution", 1); { int i; for (i = 0; i < NUM_VGA_MODES; i++) { char s1[256], s2[256]; /* FIXME: hotkeys work only for less than 11 elements. */ sprintf(s1, "Mode _%d: %s", i, vga_modes[i].description); sprintf(s2, "Set VGA resolution to %s", vga_modes[i].description); tui_menu_add_item(vga_mode_submenu, s1, s2, radio_VGAMode_callback, (void *)i, 0, TUI_MENU_BEH_CLOSE); } } ui_video_submenu = tui_menu_create("Video Settings", 1); tui_menu_add_submenu(ui_video_submenu,"_VGA Resolution:", "Choose screen resolution for video emulation", vga_mode_submenu, resolution_submenu_callback, NULL, 8); tui_menu_add_submenu(ui_video_submenu, "_Refresh Rate:", "Choose frequency of screen refresh", refresh_rate_submenu, refresh_rate_submenu_callback, NULL, 4); tui_menu_add_item(ui_video_submenu, "Video _Cache:", "Enable screen cache (disabled when using triple buffering)", toggle_VideoCache_callback, NULL, 3, TUI_MENU_BEH_CONTINUE); #ifndef USE_MIDAS_SOUND tui_menu_add_item(ui_video_submenu, "_Triple Buffering:", "Enable triple buffering for smoother animations (when available)", toggle_TripleBuffering_callback, NULL, 3, TUI_MENU_BEH_CONTINUE); #endif } /* ------------------------------------------------------------------------- */ TUI_MENU_DEFINE_TOGGLE(FileSystemDevice8) TUI_MENU_DEFINE_TOGGLE(FileSystemDevice9) TUI_MENU_DEFINE_TOGGLE(FileSystemDevice10) TUI_MENU_DEFINE_TOGGLE(FileSystemDevice11) TUI_MENU_DEFINE_TOGGLE(FSDevice8ConvertP00) TUI_MENU_DEFINE_TOGGLE(FSDevice9ConvertP00) TUI_MENU_DEFINE_TOGGLE(FSDevice10ConvertP00) TUI_MENU_DEFINE_TOGGLE(FSDevice11ConvertP00) TUI_MENU_DEFINE_TOGGLE(FSDevice8SaveP00) TUI_MENU_DEFINE_TOGGLE(FSDevice9SaveP00) TUI_MENU_DEFINE_TOGGLE(FSDevice10SaveP00) TUI_MENU_DEFINE_TOGGLE(FSDevice11SaveP00) TUI_MENU_DEFINE_TOGGLE(FSDevice8HideCBMFiles) TUI_MENU_DEFINE_TOGGLE(FSDevice9HideCBMFiles) TUI_MENU_DEFINE_TOGGLE(FSDevice10HideCBMFiles) TUI_MENU_DEFINE_TOGGLE(FSDevice11HideCBMFiles) static TUI_MENU_CALLBACK(set_fsdevice_directory_callback) { int unit = (int) param; char *v; char rname[256]; sprintf(rname, "FSDevice%dDir", unit); if (been_activated) { char *path; int len = 255; resources_get_value(rname, (resource_value_t *) &v); if (len < strlen(v) * 2) len = strlen(v) * 2; path = alloca(len + 1); strcpy(path, v); if (tui_input_string("Insert path", "Path:", path, len) != -1) { remove_spaces(path); fsdevice_set_directory(path, unit); } } resources_get_value(rname, (resource_value_t *) &v); return v; } #define DEFINE_FSDEVICE_SUBMENU(num) \ tui_menu_item_def_t fsdevice##num##_submenu[] = { \ { "_Directory:", \ "Specify access directory for device" #num, \ set_fsdevice_directory_callback, (void *) (num), 40, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "--" }, \ { "_Allow access:", \ "Allow device" #num " to access the MS-DOS file system", \ toggle_FileSystemDevice##num##_callback, NULL, 3, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_Convert P00 names:", \ "Handle P00 names on device " #num, \ toggle_FSDevice##num##ConvertP00_callback, NULL, 3, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_Save P00 files:", \ "Create P00 files on device " #num, \ toggle_FSDevice##num##SaveP00_callback, NULL, 3, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { "_Hide non-P00 files: ", \ "Display only P00 files on device " #num, \ toggle_FSDevice##num##HideCBMFiles_callback, NULL, 3, \ TUI_MENU_BEH_CONTINUE, NULL, NULL }, \ { NULL } \ }; DEFINE_FSDEVICE_SUBMENU(8) DEFINE_FSDEVICE_SUBMENU(9) DEFINE_FSDEVICE_SUBMENU(10) DEFINE_FSDEVICE_SUBMENU(11) tui_menu_item_def_t fsdevice_submenu[] = { { "Drive _8...", "Settings for drive #8", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, fsdevice8_submenu, "Drive 8 directory access" }, { "Drive _9...", "Settings for drive #9", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, fsdevice9_submenu, "Drive 9 directory access" }, { "Drive 1_0...", "Settings for drive #10", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, fsdevice10_submenu, "Drive 10 directory access" }, { "Drive 1_1...", "Settings for drive #11", NULL, NULL, 0, TUI_MENU_BEH_CONTINUE, fsdevice11_submenu, "Drive 11 directory access" }, { NULL } }; TUI_MENU_DEFINE_TOGGLE(NoTraps) /* ------------------------------------------------------------------------- */ static TUI_MENU_CALLBACK(speed_submenu_callback) { static char s[1024]; int value; resources_get_value("Speed", (resource_value_t *) &value); if (value) { sprintf(s, "%d%%", value); return s; } else return "None"; } static TUI_MENU_CALLBACK(speed_callback) { if (been_activated) { int value = (int)param; if (value < 0) { char buf[25]; *buf = '\0'; if (tui_input_string("Maximum Speed", "Enter maximum speed (%%):", buf, 25) == 0) { value = atoi(buf); if (value > 1000) value = 1000; else if (value < 0) value = 0; } else return NULL; } resources_set_value("Speed", (resource_value_t) value); } return NULL; } TUI_MENU_DEFINE_TOGGLE(WarpMode) TUI_MENU_DEFINE_TOGGLE(UseLeds) static void create_special_submenu(int has_serial_traps) { static tui_menu_t speed_submenu; ui_special_submenu = tui_menu_create("Other Settings", 1); /* Speed limit submenu. */ { int i; int speed[4] = { 100, 50, 20, 10 }; char s1[256], s2[256]; speed_submenu = tui_menu_create("Speed Limit", 1); for (i = 0; i < 4; i++) { if (speed[i] == 100) sprintf(s1, "Limit speed to the one of the real %s", machine_name); else sprintf(s1, "Limit speed to %d%% of the real %s", speed[i], machine_name); sprintf(s2, "_%d%%", speed[i]); tui_menu_add_item(speed_submenu, s2, s1, speed_callback, (void *)speed[i], 5, TUI_MENU_BEH_CLOSE); } tui_menu_add_item(speed_submenu, "_No Limit", "Run the emulator as fast as possible", speed_callback, (void *)0, 5, TUI_MENU_BEH_CLOSE); tui_menu_add_separator(speed_submenu); tui_menu_add_item(speed_submenu, "_Custom...", "Specify a custom relative speed value", speed_callback, (void *)-1, 5, TUI_MENU_BEH_CLOSE); } tui_menu_add_submenu(ui_special_submenu, "_Speed Limit:", "Specify a custom speed limit", speed_submenu, speed_submenu_callback, NULL, 5); tui_menu_add_item(ui_special_submenu, "Enable _Warp Mode:", "Make the emulator run as fast as possible skipping lots of frames", toggle_WarpMode_callback, NULL, 3, TUI_MENU_BEH_CONTINUE); /* File system access. */ { tui_menu_t tmp = tui_menu_create("MS-DOS Directory Access", 1); tui_menu_add_separator(ui_special_submenu); tui_menu_add(tmp, fsdevice_submenu); tui_menu_add_submenu(ui_special_submenu, "MS-DOS _Directory Access...", "Options to access MS-DOS directories from within the emulator", tmp, NULL, NULL, 0); } if (has_serial_traps) tui_menu_add_item(ui_special_submenu, "Disable Kernal _Traps:", "Disable the Kernal ROM patches used by tape and fast drive emulation", toggle_NoTraps_callback, NULL, 4, TUI_MENU_BEH_CONTINUE); tui_menu_add_separator(ui_special_submenu); tui_menu_add_item(ui_special_submenu, "Use _Keyboard LEDs:", "Use PC keyboard LEDs for the 1541 drive and Warp Mode", toggle_UseLeds_callback, NULL, 4, TUI_MENU_BEH_CONTINUE); } /* ------------------------------------------------------------------------- */ void ui_create_main_menu(int has_tape, int has_true1541, int has_serial_traps, int num_joysticks) { /* Main menu. */ ui_main_menu = tui_menu_create(NULL, 1); ui_attach_submenu = tui_menu_create("Attach Images", 1); tui_menu_add_item(ui_attach_submenu, "Drive #_8:", "Attach disk image for disk drive #8", attach_disk_callback, (void *)8, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_attach_submenu, "Drive #_9:", "Attach disk image for disk drive #9", attach_disk_callback, (void *)9, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_attach_submenu, "Drive #1_0:", "Attach disk image for disk drive #10", attach_disk_callback, (void *)10, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_attach_submenu, "Drive #1_1:", "Attach disk image for disk drive #11", attach_disk_callback, (void *)11, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_attach_submenu, "Autostart _Drive 8", "Reset the emulator and run the first program in the disk in drive 8", autostart_callback, (void *)8, 0, TUI_MENU_BEH_RESUME); if (has_tape) { tui_menu_add_separator(ui_attach_submenu); tui_menu_add_item(ui_attach_submenu,"_Tape:", "Attach tape image for cassette player (device #1)", attach_tape_callback, NULL, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_attach_submenu, "Autostart Ta_pe", "Reset the emulator and run the first program on the tape image", autostart_callback, (void *)1, 0, TUI_MENU_BEH_RESUME); } ui_detach_submenu = tui_menu_create("Detach Images", 1); tui_menu_add_item(ui_detach_submenu, "Drive #_8:", "Remove disk from disk drive #8", detach_disk_callback, (void *)8, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_detach_submenu,"Drive #_9:", "Remove disk from disk drive #9", detach_disk_callback, (void *)9, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_detach_submenu, "Drive #1_0:", "Remove disk from disk drive #10", detach_disk_callback, (void *)10, 30, TUI_MENU_BEH_CONTINUE); tui_menu_add_item(ui_detach_submenu, "Drive #1_1:", "Remove disk from disk drive #11", detach_disk_callback, (void *)11, 30, TUI_MENU_BEH_CONTINUE); if (has_tape) { tui_menu_add_separator(ui_detach_submenu); tui_menu_add_item(ui_detach_submenu, "_Tape:", "Remove tape from cassette player (device #1)", detach_tape_callback, NULL, 30, TUI_MENU_BEH_CONTINUE); } tui_menu_add_submenu(ui_main_menu, "_Attach Image...", "Insert virtual disks, tapes or cartridges in the emulated machine", ui_attach_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); tui_menu_add_submenu(ui_main_menu, "_Detach Image...", "Remove virtual disks, tapes or cartridges from the emulated machine", ui_detach_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); #if 0 tui_menu_add_item(ui_main_menu, "_Change Working Directory...", "Change the current working directory", change_workdir_callback, NULL, 0, TUI_MENU_BEH_CONTINUE); #endif tui_menu_add_separator(ui_main_menu); create_ui_video_submenu(); tui_menu_add_submenu(ui_main_menu, "_Video Settings...", "Screen parameters", ui_video_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); if (has_true1541) { ui_drive_submenu = tui_menu_create("1541 Settings", 1); tui_menu_add(ui_drive_submenu, true1541_settings_submenu); tui_menu_add_submenu(ui_main_menu, "_1541 Settings...", "Drive emulation settings", ui_drive_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); } ui_sound_submenu = tui_menu_create("Audio Settings", 1); tui_menu_add(ui_sound_submenu, sound_submenu); tui_menu_add_submenu(ui_main_menu, "_Sound Settings...", "Sampling rate, sound output, soundcard settings", ui_sound_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); if (num_joysticks > 0) { ui_joystick_settings_submenu = tui_menu_create("Joystick Settings", 1); tui_menu_add_submenu(ui_main_menu, "_Joystick Settings...", "Joystick settings", ui_joystick_settings_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); if (num_joysticks == 2) tui_menu_add(ui_joystick_settings_submenu, double_joystick_submenu); else /* Just one joystick. */ tui_menu_add(ui_joystick_settings_submenu, single_joystick_submenu); } create_special_submenu(has_serial_traps); tui_menu_add_submenu(ui_main_menu, "_Other Settings...", "Extra emulation features", ui_special_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); tui_menu_add_separator(ui_main_menu); ui_settings_submenu = tui_menu_create("Configuration Commands", 1); tui_menu_add_item(ui_settings_submenu, "_Write Configuration", "Save current settings as default for next session", save_settings_callback, NULL, 0, TUI_MENU_BEH_CLOSE); tui_menu_add_item(ui_settings_submenu, "_Load Configuration", "Load saved settings from previous session", load_settings_callback, NULL, 0, TUI_MENU_BEH_CLOSE); tui_menu_add_item(ui_settings_submenu, "Restore _Factory Defaults", "Set default settings", restore_default_settings_callback, NULL, 0, TUI_MENU_BEH_CLOSE); tui_menu_add_submenu(ui_main_menu, "_Configuration Commands...", "Commands to save, retrieve and restore settings", ui_settings_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); tui_menu_add_separator(ui_main_menu); tui_menu_add_item(ui_main_menu, "_Monitor", "Enter the built-in machine language monitor", monitor_callback, NULL, 0, TUI_MENU_BEH_RESUME); ui_reset_submenu = tui_menu_create("Reset?", 1); tui_menu_add(ui_reset_submenu, reset_submenu); tui_menu_add_submenu(ui_main_menu, "_Reset ", "Reset the machine", ui_reset_submenu, NULL, NULL, 0); ui_quit_submenu = tui_menu_create("Quit", 1); tui_menu_add(ui_quit_submenu, quit_submenu); tui_menu_add_submenu(ui_main_menu, "_Quit", "Quit emulator", ui_quit_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); tui_menu_add_separator(ui_main_menu); ui_info_submenu = tui_menu_create("Info", 1); tui_menu_add(ui_info_submenu, info_submenu); tui_menu_add_submenu(ui_main_menu, "VICE _Info...", "VICE is Free Software distributed under the GNU General Public License!", ui_info_submenu, NULL, 0, TUI_MENU_BEH_CONTINUE); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.