gsplus/src/options.c

396 lines
16 KiB
C
Raw Normal View History

/*
GSPLUS - Advanced Apple IIGS Emulator Environment
Based on the KEGS emulator written by Kent Dickey
See COPYRIGHT.txt for Copyright information
See LICENSE.txt for license (GPL v2)
*/
2018-02-27 12:56:45 +00:00
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "options.h"
#include "glog.h"
#include "defc.h"
2018-03-27 04:31:40 +00:00
// config is parsed in config.c :: config_parse_config_gsplus_file()
// cli is parsed here. would be nice to reuse some code
2018-02-27 12:56:45 +00:00
// Halts on bad reads. Sets flags via engine_s.s:set_halt_act() function
extern int g_halt_on_bad_read; // defined in sim65816.c
// Ignore bad memory accesses.
2018-02-27 12:56:45 +00:00
extern int g_ignore_bad_acc; // defined in sim65816.c
// Ignore red alert halts.
2018-02-27 12:56:45 +00:00
extern int g_ignore_halts; // defined in sim65816.c
// Size of RAM memory expansion card in bytes (default = 8*1024*1024 = 8MB)
extern int g_mem_size_exp; // defined in sim65816.c
// Implemented in display drivers (not SDL2 though) ?
extern int g_screen_redraw_skip_amt; // defined in video.c, implemented in various driver files
// Using simple dhires color map
extern int g_use_dhr140; // defined in video.c
// Force B/W hires modes
extern int g_use_bw_hires; // defined in video.c
// Set starting X/Y positions
extern int g_startx; // defined in video.c
extern int g_starty; // defined in video.c
// Use High DPI (Retina) display - SDL2
extern int g_highdpi; // defined in video.c
// Create borderless window - SDL2
extern int g_borderless; // defined in video.c
// Allow window resizing, dragging to scale - SDL2
extern int g_resizeable; // defined in video.c
2018-02-27 12:56:45 +00:00
// Enable Dagen's scanline simulator (SDL2)
extern int g_scanline_simulator; // defined in sim65816.c
// Ethernet (interface?)
extern int g_ethernet; // defined in sim65816.c
// Enable and set port for Dagen's debugger
extern int g_dbg_enable_port; // defined in debug.c
// Set preferred audio frequency
extern int g_preferred_rate; // defined in sound_driver.c, implemented in various driver files
// Enable/disable audio
2018-02-27 12:56:45 +00:00
extern int g_audio_enable; // defined in sound.c
// Start in fullscreen mode
extern int g_fullscreen; // defined in adb.c, because weird driver writing for x
2018-03-27 04:31:40 +00:00
// Specify the joystick - SDL2
extern int g_joystick_number; // defined in joystick_driver.c
extern int g_joystick_x_axis; // defined in joystick_driver.c
extern int g_joystick_y_axis; // defined in joystick_driver.c
extern int g_joystick_x2_axis; // defined in joystick_driver.c
extern int g_joystick_y2_axis; // defined in joystick_driver.c
extern int g_joystick_button_0; // defined in joystick_driver.c
extern int g_joystick_button_1; // defined in joystick_driver.c
extern int g_joystick_button_2; // defined in joystick_driver.c
extern int g_joystick_button_3; // defined in joystick_driver.c
2018-02-27 12:56:45 +00:00
// DEPRECATED: force bit depth (15/16/24) for X-Windows, might still work.
extern int g_force_depth; // defined in sim65816.c
// DEPRECATED: Use X shared memory (MIT-SHM)
extern int g_use_shmem; // defined in all the various drivers
// DEPRECATED: Set DISPLAY environment variable for X-Windows
extern char g_display_env[512]; // defined in sim65816.c
// DEPRECATED: Set VERBOSE flags for one or more subsystems as defined below
extern int Verbose; // defined in sim65816.c
// #define VERBOSE_DISK 0x001
// #define VERBOSE_IRQ 0x002
// #define VERBOSE_CLK 0x004
// #define VERBOSE_SHADOW 0x008
// #define VERBOSE_IWM 0x010
// #define VERBOSE_DOC 0x020
// #define VERBOSE_ADB 0x040
// #define VERBOSE_SCC 0x080
// #define VERBOSE_TEST 0x100
// #define VERBOSE_VIDEO 0x200
// #define VERBOSE_MAC
// This is deprecated because it is not well-defined or supported
// It should still work and some sort of system should be put in place
// to extend and fix this, or take it out.
extern const char *g_config_gsplus_name_list[];
extern char g_config_gsplus_screenshot_dir[];
extern char *final_arg;
static const char parse_log_prefix[] = "Option set [CLI]:";
// this is here because we need to flip a bit to force B/W modes
extern int g_cur_a2_stat;
void help_exit(); // displays the cli help text and exits with 1
2018-03-27 04:31:40 +00:00
int parse_int(const char *str1, int min, int max)
{
int tmp;
tmp = strtol(str1, 0, 0);
if (tmp > max) { tmp = max; }
if (tmp < min) { tmp = min; }
printf ( "TMP %d\n", tmp);
return tmp;
}
int parse_cli_options(int argc, char **argv) {
2018-02-27 12:56:45 +00:00
int i;
int tmp1;
int skip_amt;
char *final_arg = 0;
for(i = 1; i < argc; i++) {
if( (!strcmp("-?", argv[i])) || (!strcmp("-h", argv[i])) || (!strcmp("-help", argv[i]))) {
help_exit();
} else if(!strcmp("-badrd", argv[i])) {
glogf("%s Halting on bad reads", parse_log_prefix);
g_halt_on_bad_read = 2;
} else if(!strcmp("-fullscreen", argv[i])) {
glogf("%s Starting emulator in fullscreen", parse_log_prefix);
g_fullscreen = 1;
} else if(!strcmp("-highdpi", argv[i])) {
glogf("%s Creating window in High DPI mode", parse_log_prefix);
g_highdpi = 1;
} else if(!strcmp("-borderless", argv[i])) {
glogf("%s Creating borderless window", parse_log_prefix);
g_borderless = 1;
} else if(!strcmp("-resizeable", argv[i])) {
glogf("%s Window will be resizeable", parse_log_prefix);
g_resizeable = 1;
2018-02-27 12:56:45 +00:00
} else if(!strcmp("-noignbadacc", argv[i])) {
glogf("%s Not ignoring bad memory accesses", parse_log_prefix);
g_ignore_bad_acc = 0;
} else if(!strcmp("-noignhalt", argv[i])) {
glogf("%s Not ignoring code red halts", parse_log_prefix);
g_ignore_halts = 0;
} else if(!strcmp("-mem", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-mem' missing argument", parse_log_prefix);
exit(1);
}
g_mem_size_exp = strtol(argv[i+1], 0, 0) & 0x00ff0000;
glogf("%s Using %d as memory size", parse_log_prefix, g_mem_size_exp);
i++;
} else if(!strcmp("-skip", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-skip' missing argument", parse_log_prefix);
exit(1);
}
skip_amt = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as skip_amt", parse_log_prefix, skip_amt);
g_screen_redraw_skip_amt = skip_amt;
i++;
} else if(!strcmp("-audio", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-audio' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as audio enable val", parse_log_prefix, tmp1);
g_audio_enable = tmp1;
i++;
} else if(!strcmp("-arate", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-arate' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as preferred audio rate", parse_log_prefix, tmp1);
g_preferred_rate = tmp1;
i++;
} else if(!strcmp("-v", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-v' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Setting Verbose = 0x%03x", parse_log_prefix, tmp1);
Verbose = tmp1;
i++;
} else if(!strcmp("-display", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-display' missing argument", parse_log_prefix);
exit(1);
}
glogf("%s Using %s as display", parse_log_prefix, argv[i+1]);
sprintf(g_display_env, "DISPLAY=%s", argv[i+1]);
putenv(&g_display_env[0]);
i++;
} else if(!strcmp("-noshm", argv[i])) {
glogf("%s Not using X shared memory", parse_log_prefix);
g_use_shmem = 0;
} else if(!strcmp("-joystick", argv[i])) {
2018-03-27 04:31:40 +00:00
if((i+1) >= argc) {
glogf("%s Error, option '-joy' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick number %d", parse_log_prefix, tmp1);
g_joystick_number = tmp1;
i++;
} else if(!strcmp("-joy_x", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_x' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick X axis %d", parse_log_prefix, tmp1);
g_joystick_x_axis = tmp1;
i++;
2018-03-27 04:31:40 +00:00
} else if(!strcmp("-joy_y", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_y' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Y axis %d", parse_log_prefix, tmp1);
g_joystick_y_axis = tmp1;
i++;
} else if(!strcmp("-joy_x2", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_x2' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick X2 axis %d", parse_log_prefix, tmp1);
g_joystick_x2_axis = tmp1;
i++;
2018-03-27 04:31:40 +00:00
} else if(!strcmp("-joy_y2", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_y2' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Y2 axis %d", parse_log_prefix, tmp1);
g_joystick_y2_axis = tmp1;
i++;
} else if(!strcmp("-joy_b0", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_b0' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 0 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_0 = tmp1;
i++;
} else if(!strcmp("-joy_b1", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_b1' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 1 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_1 = tmp1;
i++;
} else if(!strcmp("-joy_b2", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_b2' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 2 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_2 = tmp1;
i++;
} else if(!strcmp("-joy_b3", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy_b3' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 3 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_3 = tmp1;
i++;
2018-02-27 12:56:45 +00:00
} else if(!strcmp("-dhr140", argv[i])) {
glogf("%s Using simple dhires color map", parse_log_prefix);
g_use_dhr140 = 1;
} else if(!strcmp("-bw", argv[i])) {
glogf("%s Forcing black-and-white hires modes", parse_log_prefix);
g_cur_a2_stat |= ALL_STAT_COLOR_C021;
g_use_bw_hires = 1;
} else if(!strcmp("-scanline", argv[i])) {
glogf("%s Enable scanline simulation", parse_log_prefix);
if((i+1) >= argc) {
glogf("%s Error, option '-scanline' missing argument", parse_log_prefix);
exit(1);
}
2018-03-27 04:31:40 +00:00
tmp1 = parse_int(argv[i+1], 0, 100);
2018-02-27 12:56:45 +00:00
glogf("%s Setting scanline simulator darkness to %d%%", parse_log_prefix, tmp1);
g_scanline_simulator = tmp1;
i++;
} else if(!strcmp("-enet", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-enet' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as ethernet enable val", parse_log_prefix, tmp1);
g_ethernet = tmp1;
i++;
} else if(!strcmp("-x", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-x' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as x val", parse_log_prefix, tmp1);
g_startx = tmp1;
i++;
} else if(!strcmp("-y", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-y' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as y val", parse_log_prefix, tmp1);
g_starty = tmp1;
i++;
} else if(!strcmp("-config", argv[i])) { // Config file passed
if((i+1) >= argc) {
glogf("%s Error, option '-config' missing argument", parse_log_prefix);
exit(1);
}
glogf("%s Using %s as configuration file", parse_log_prefix, argv[i+1]);
g_config_gsplus_name_list[0] = argv[i+1]; // overwrite default list with passed item as sole option
g_config_gsplus_name_list[1] = 0; // terminate string array
i++;
} else if (!strcmp("-ssdir", argv[i])) { // screenshot directory passed
strcpy(g_config_gsplus_screenshot_dir, argv[i+1]);
struct stat path_stat;
stat(g_config_gsplus_screenshot_dir, &path_stat); // (weakly) validate path
if (!S_ISDIR(path_stat.st_mode)) {
strcpy(g_config_gsplus_screenshot_dir, "./");
}
glogf("%s Using %s for screenshot path", parse_log_prefix, g_config_gsplus_screenshot_dir);
i++;
} else if(!strcmp("-debugport", argv[i])) { // Debug port passed
if((i+1) >= argc) {
glogf("%s Error, option '-debugport' missing argument", parse_log_prefix);
exit(1);
}
g_dbg_enable_port = strtol(argv[i+1], 0, 0);
glogf("%s Using %d for debug port", parse_log_prefix, g_dbg_enable_port);
i++;
} else {
if ((i == (argc - 1)) && (strncmp("-", argv[i], 1) != 0)) {
final_arg = argv[i];
} else {
glogf("%s Error, bad option: %s for debug port", parse_log_prefix, argv[i]);
exit(3);
}
}
}
}
void help_exit() {
printf(" USAGE: \n\n");
printf(" ./gsplus # simple - uses default config.txt\n");
printf(" ./gsplus -config games_hds.gsp # set custom config file\n\n");
printf(" You need to supply your own Apple IIgs Firmware ROM image.\n");
printf(" Press F4 when running gsplus to enter config menu and select ROM image location.\n");
printf(" Or copy the ROM image to the gsplus directory.\n");
printf(" It will search for: \"ROM\", \"ROM.01\", \"ROM.03\" \n\n\n");
printf(" Other command line options: \n\n");
printf(" -badrd Halt on bad reads\n");
printf(" -noignbadacc Dont ignore bad memory accesses\n");
printf(" -noignhalt Dont ignore code red halts\n");
printf(" -test Allow testing\n");
printf(" -joystick Ignore joystick option\n");
printf(" -bw Force B/W modes\n");
printf(" -dhr140 Use simple double-hires color map\n");
printf(" -fullscreen Attempt to start emulator in fullscreen\n");
printf(" -highdpi Attempt to open window in high DPI\n");
printf(" -borderless Attempt to create borderless window\n");
printf(" -resizeable Allow you to resize window (non-integral scaling to pixel)\n");
2018-02-27 12:56:45 +00:00
printf(" -mem value Set memory size to value\n");
printf(" -skip value Set skip_amt to value\n");
printf(" -audio value Set audio enable to value\n");
printf(" -arate value Set preferred audio rate to value\n");
printf(" -enet value Set ethernet to value\n");
printf(" -config value Set config file to value\n");
printf(" -debugport value Set debugport to value\n");
printf(" -ssdir value Set screenshot save directory to value\n");
printf(" -scanline value Enable scanline simulator at value %%\n");
printf(" -x value Open emulator window at x value\n");
printf(" -y value Open emulator window at y value\n");
printf(" -v value Set verbose flags to value\n\n");
printf(" Note: The final argument, if not a flag, will be tried as a mountable device.\n\n");
exit(1);
}