/** * parse_args(): Parse command line arguments. * @param argc Number of command line arguments. * @param argv Array of command line arguments. * @return Pointer to startup information struct. (MUST BE free()'d BY CALLER!) */ Gens_StartupInfo_t* parse_args(int argc, char *argv[]) { int c; int error = 0; int option_index = 0; // Create the startup information struct. Gens_StartupInfo_t *startup = (Gens_StartupInfo_t*)malloc(sizeof(Gens_StartupInfo_t)); startup->mode = GSM_IDLE; startup->filename[0] = 0x00; #if defined(GENS_OS_WIN32) && !defined(GENS_WIN32_CONSOLE) startup->enable_debug_console = 0; #endif while (1) { c = getopt_long(argc, argv, "", long_options, &option_index); if (c == -1) break; if (c == '?') { error = 1; continue; } if (!strcmp(long_options[option_index].name, opt1arg_str[OPT1_GAME].option)) { // Startup ROM. if (optarg && optarg[0] != 0x00) parse_startup_rom(optarg, startup); continue; } // Test string options. TEST_OPTION_STRING(opt1arg_str[OPT1_ROMPATH].option, Rom_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_SAVEPATH].option, State_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_SRAMPATH].option, SRAM_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_BRAMPATH].option, BRAM_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_DUMPWAVPATH].option, PathNames.Dump_WAV_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_DUMPGYMPATH].option, PathNames.Dump_GYM_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_SCREENSHOTPATH].option, PathNames.Screenshot_Dir); TEST_OPTION_STRING(opt1arg_str[OPT1_GENESISBIOS].option, BIOS_Filenames.MD_TMSS); TEST_OPTION_STRING(opt1arg_str[OPT1_USACDBIOS].option, BIOS_Filenames.SegaCD_US); TEST_OPTION_STRING(opt1arg_str[OPT1_EUROPECDBIOS].option, BIOS_Filenames.MegaCD_EU); TEST_OPTION_STRING(opt1arg_str[OPT1_JAPANCDBIOS].option, BIOS_Filenames.MegaCD_JP); TEST_OPTION_STRING(opt1arg_str[OPT1_32X68KBIOS].option, BIOS_Filenames._32X_MC68000); TEST_OPTION_STRING(opt1arg_str[OPT1_32XMSH2BIOS].option, BIOS_Filenames._32X_MSH2); TEST_OPTION_STRING(opt1arg_str[OPT1_32XSSH2BIOS].option, BIOS_Filenames._32X_SSH2); TEST_OPTION_ENABLE(optBarg_str[OPTB_GREYSCALE], Greyscale); TEST_OPTION_ENABLE(optBarg_str[OPTB_INVERT], Invert_Color); //TEST_OPTION_ENABLE(optBarg_str[OPTB_SCALE], Scale_Colors); TEST_OPTION_ENABLE(optBarg_str[OPTB_SPRITELIMIT], Sprite_Over); TEST_OPTION_NUMERIC(opt1arg_str[OPT1_FRAMESKIP].option, Frame_Skip); TEST_OPTION_ENABLE(optBarg_str[OPTB_Z80], Z80_State); TEST_OPTION_ENABLE(optBarg_str[OPTB_YM2612], YM2612_Enable); TEST_OPTION_ENABLE(optBarg_str[OPTB_YM2612_IMPROVED], YM2612_Improv); TEST_OPTION_ENABLE(optBarg_str[OPTB_DAC], DAC_Enable); TEST_OPTION_ENABLE(optBarg_str[OPTB_PSG], PSG_Enable); TEST_OPTION_ENABLE(optBarg_str[OPTB_PCM], PCM_Enable); TEST_OPTION_ENABLE(optBarg_str[OPTB_PWM], PWM_Enable); TEST_OPTION_ENABLE(optBarg_str[OPTB_CDDA], CDDA_Enable); TEST_OPTION_ENABLE(optBarg_str[OPTB_PERFECT_SYNC], SegaCD_Accurate); TEST_OPTION_NUMERIC(opt1arg_str[OPT1_MSH2_SPEED].option, MSH2_Speed); TEST_OPTION_NUMERIC(opt1arg_str[OPT1_SSH2_SPEED].option, SSH2_Speed); TEST_OPTION_ENABLE(optBarg_str[OPTB_LED], Show_LED); TEST_OPTION_ENABLE(optBarg_str[OPTB_FIXCHKSUM], Auto_Fix_CS); TEST_OPTION_ENABLE(optBarg_str[OPTB_AUTOPAUSE], Auto_Pause); TEST_OPTION_NUMERIC(opt1arg_str[OPT1_RAMCART_SIZE].option, BRAM_Ex_Size); // Contrast / Brightness TEST_OPTION_NUMERIC_SCALE(opt1arg_str[OPT1_CONTRAST].option, Contrast_Level, 100); TEST_OPTION_NUMERIC_SCALE(opt1arg_str[OPT1_BRIGHTNESS].option, Brightness_Level, 100); // Other options that can't be handled by macros. if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_STRETCH].enable)) { vdraw_set_stretch(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_STRETCH].disable)) { vdraw_set_stretch(false); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_SOUND].enable)) { audio_set_enabled(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_SOUND].disable)) { audio_set_enabled(false); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_STEREO].enable)) { audio_set_stereo(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_STEREO].disable)) { audio_set_stereo(false); } #ifdef GENS_OS_WIN32 else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_SWBLIT].enable)) { vdraw_set_sw_render(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_SWBLIT].disable)) { vdraw_set_sw_render(false); } #endif /* GENS_OS_WIN32 */ else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_FASTBLUR].enable)) { vdraw_set_fast_blur(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_FASTBLUR].disable)) { vdraw_set_fast_blur(false); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_FPS].enable)) { vdraw_set_fps_enabled(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_FPS].disable)) { vdraw_set_fps_enabled(false); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_MSG].enable)) { vdraw_set_msg_enabled(true); } else if (!strcmp(long_options[option_index].name, optBarg_str[OPTB_MSG].disable)) { vdraw_set_fps_enabled(false); } else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_FS].option)) { vdraw_set_fullscreen(true); } else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_WINDOW].option)) { vdraw_set_fullscreen(false); } else if (!strcmp(long_options[option_index].name, opt1arg_str[OPT1_SOUNDRATE].option)) { int rate = atoi(optarg); if (rate == 11025 || rate == 22050 || rate == 44100) { audio_set_sound_rate(rate); } else { fprintf(stderr, "Invalid sound rate: %d\n", rate); exit(1); } } else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_QUICKEXIT].option)) { Quick_Exit = 1; } #ifdef GENS_CDROM else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_BOOT_CD].option)) { // Boot SegaCD on startup. startup->mode = GSM_BOOT_CD; } #endif #if defined(GENS_OS_WIN32) && !defined(GENS_WIN32_CONSOLE) else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_DEBUG_CONSOLE].option)) { // Enable Debug console. startup->enable_debug_console = 1; } #endif #if defined(GENS_OS_WIN32) else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_ANSI].option)) { // ANSI mode. This is checked by libgsft_w32u, // so we don't have to do anything here. } #endif else if (!strcmp(long_options[option_index].name, opt0arg_str[OPT0_HELP].option)) { _usage(argv[0]); } else { _usage(argv[0]); } } // Make sure contrast and brightness are in range. if (Contrast_Level < 0) Contrast_Level = 0; else if (Contrast_Level > 200) Contrast_Level = 200; if (Brightness_Level < 0) Brightness_Level = 0; else if (Brightness_Level > 200) Brightness_Level = 200; if (optind < argc - 1 || error) { fputs("Arguments not understood.\n", stderr); _usage(argv[0]); } else if (optind == (argc - 1)) { // Startup ROM. if (argv[optind] && argv[optind][0] != 0x00) parse_startup_rom(argv[optind], startup); } // Return the startup information. return startup; }
/** * Init_Genesis(): Initialize the Genesis with the specified ROM image. * @param MD_ROM ROM image struct. * @return 1 if successful. */ int Init_Genesis(ROM_t* MD_ROM) { // Clear the sound buffer. audio_clear_sound_buffer(); Flag_Clr_Scr = 1; Settings.Paused = Frame_Number = 0; SRAM_Start = SRAM_End = SRAM_ON = SRAM_Write = 0; Controller_1_COM = Controller_2_COM = 0; #ifdef GENS_DEBUGGER STOP_DEBUGGING(); #endif #if 0 // TODO: Replace with MDP "exclusive mode" later. if (!Kaillera_Client_Running) #endif Init_Genesis_SRAM(MD_ROM); // Check what country code should be used. // TODO: Get rid of magic numbers. switch (Country) { default: case -1: // Autodetection. Detect_Country_Genesis(MD_ROM); break; case 0: // Japan (NTSC) Game_Mode = 0; CPU_Mode = 0; break; case 1: // US (NTSC) Game_Mode = 1; CPU_Mode = 0; break; case 2: // Europe (PAL) Game_Mode = 1; CPU_Mode = 1; break; case 3: // Japan (PAL) Game_Mode = 0; CPU_Mode = 1; break; } VDP_Num_Vis_Lines = 224; Gen_Version = 0x20 + 0x0; // Version de la megadrive (0x0 - 0xF) // Byteswap the ROM data. be16_to_cpu_array(Rom_Data, Rom_Size); ROM_ByteSwap_State |= ROM_BYTESWAPPED_MD_ROM; // Reset all CPUs and other components. M68K_Reset(0); Z80_Reset(); VDP_Reset(); // Initialize the controller state. Init_Controllers(); // Set clock rates depending on the CPU mode (NTSC / PAL). Set_Clock_Freq(0); // If auto-fix checksum is enabled, fix the ROM checksum. if (Auto_Fix_CS) ROM::fixChecksum(); // Initialize sound. if (audio_get_enabled()) { audio_end(); if (audio_init(AUDIO_BACKEND_DEFAULT)) audio_set_enabled(false); else { if (audio_play_sound) audio_play_sound(); } } Reset_Update_Timers(); // Set the appropriate frame update function pointers. Update_Frame = Do_Genesis_Frame; Update_Frame_Fast = Do_Genesis_Frame_No_VDP; return 1; }