⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dos.c

📁 NES game Emulator in Linux.c and asm codes.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*

SNEeSe, an Open Source Super NES emulator.


Copyright (c) 1998-2004 Charles Bilyue'.
Portions Copyright (c) 2003-2004 Daniel Horchner.

This is free software.  See 'LICENSE' for details.
You must read and accept the license prior to use.

*/

//#define NO_GUI
/* DOS platform-specific code */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>

#include "wrapaleg.h"

#define GUI_DEFAULT 1

#ifdef ALLEGRO_DJGPP
#include <crt0.h>
void   __crt0_load_environment_file(char *_app_name){}
char **__crt0_glob_function(char *_arg){ return 0; }

#ifdef DEBUG
int _crt0_startup_flags = _CRT0_FLAG_FILL_DEADBEEF;
#endif
#endif

#ifdef ALLEGRO_DOS
BEGIN_COLOR_DEPTH_LIST
 COLOR_DEPTH_8
 COLOR_DEPTH_15
 COLOR_DEPTH_16
END_COLOR_DEPTH_LIST
#endif

#include "platform.h"
#include "helper.h"
#include "input.h"
#include "romload.h"
#include "apu/sound.h"
#include "cpu/cpu.h"
#include "guicore.h"
#include "version.h"

char home_dir[MAXPATH];
char cfg_name[MAXPATH];
char dat_name[MAXPATH];

char start_dir[MAXPATH] = "";

static float cfg_version;
static int cfg_changed;

/* Allegro internal var */
AL_VAR(int,_sound_hq);

void LoadConfigCurrent(void)
{
 char default_keymap[] = "45 39 41 43  5  4 23 19 17  1 65 66";
 char keymapbuf[81];

 SCREEN_MODE = get_config_int("display", "screenmode", 1);
#if defined(ALLEGRO_DOS)
 if (cfg_version >= 0.72 && SCREEN_MODE > 6) SCREEN_MODE = 0;
#elif defined(ALLEGRO_WINDOWS) || defined(ALLEGRO_UNIX) || defined(ALLEGRO_BEOS)
 if (cfg_version >= 0.72 && SCREEN_MODE > 7) SCREEN_MODE = 0;
#else
#error Unable to determine platform for limiting screen mode.
#endif

 display_process = (DISPLAY_PROCESS) get_config_int("display", "process", SDP_NONE);
 if ((unsigned) display_process >= NUM_DISPLAY_PROCESSES)
  display_process = SDP_NONE;

 stretch_x = get_config_int("display", "stretch_x", 0);
 if (stretch_x < 0) stretch_x = 0;
 else if (stretch_x > 16) stretch_x = 16;

 stretch_y = get_config_int("display", "stretch_y", 0);
 if (stretch_y < 0) stretch_y = 0;
 else if (stretch_y > 16) stretch_y = 16;

 /* 1-10,15,20,30,60 */
 FRAME_SKIP_MAX = get_config_int("display", "maxframeskip", 60);
 if (FRAME_SKIP_MAX > 60) FRAME_SKIP_MAX = 60;
 else if (FRAME_SKIP_MAX > 30 && FRAME_SKIP_MAX < 60) FRAME_SKIP_MAX = 30;
 else if (FRAME_SKIP_MAX > 20 && FRAME_SKIP_MAX < 30) FRAME_SKIP_MAX = 20;
 else if (FRAME_SKIP_MAX > 15 && FRAME_SKIP_MAX < 20) FRAME_SKIP_MAX = 15;
 else if (FRAME_SKIP_MAX > 10 && FRAME_SKIP_MAX < 15) FRAME_SKIP_MAX = 10;
 else if (FRAME_SKIP_MAX < 1) FRAME_SKIP_MAX = 1;

 /* 0-10,15,20,30,60 */
 FRAME_SKIP_MIN = get_config_int("display", "minframeskip", 0);
 if (FRAME_SKIP_MIN > 60) FRAME_SKIP_MIN = 60;
 else if (FRAME_SKIP_MIN > 30 && FRAME_SKIP_MIN < 60) FRAME_SKIP_MIN = 30;
 else if (FRAME_SKIP_MIN > 20 && FRAME_SKIP_MIN < 30) FRAME_SKIP_MIN = 20;
 else if (FRAME_SKIP_MIN > 15 && FRAME_SKIP_MIN < 20) FRAME_SKIP_MIN = 15;
 else if (FRAME_SKIP_MIN > 10 && FRAME_SKIP_MIN < 15) FRAME_SKIP_MIN = 10;
 if (FRAME_SKIP_MIN > FRAME_SKIP_MAX) FRAME_SKIP_MIN = FRAME_SKIP_MAX;

 memset(save_extension, 0, MAXEXT);
 strncpy(save_extension, get_config_string("paths", "saveextension", "SRM"), MAXEXT - 1);

 memset(save_dir, 0, MAXPATH);
 strncpy(save_dir, get_config_string("paths", "savedirectory", ""), MAXPATH - 1);

 SPC_ENABLED = get_config_int("hardware", "emulatespc", 1);

 sound_enabled = get_config_int("hardware", "outputsound", 2);
 if (sound_enabled > 2) sound_enabled = 0;

 sound_bits = get_config_int("audio", "sound_bits", 16);
 if (sound_bits != 8) sound_bits = 16;

 _sound_hq = get_config_int("audio", "sound_hq", 1);
 if (_sound_hq < 0 || _sound_hq > 2) _sound_hq = 1;

 sound_echo_enabled = get_config_int("audio", "enable_echo", 1);
 sound_gauss_enabled = get_config_int("audio", "enable_gauss", 1);

 use_mmx = (cpu_capabilities & CPU_MMX) ?
  get_config_int("extras", "use_mmx", TRUE) : 0;

 /* Enable FPU copies by default on non-MMX Pentium CPUs, except */
 /*  Pentium Overdrive CPUs for 486 systems */
 use_fpu_copies = (cpu_capabilities & CPU_FPU) ?
  get_config_int("extras", "use_fpu_copies",
  (cpu_family == 5 && cpu_model != 5 && !use_mmx &&
   !strcmp(cpu_vendor, "GenuineIntel"))) : 0;

 /* Enable cache preloading by default on Pentium class CPUs, except */
 /*  Pentium Overdrive CPUs for 486 systems */
 preload_cache = get_config_int("extras", "preload_cache",
  /* Pentium class CPU, except Pentium Overdrive CPUs for 486 systems */
  (cpu_family == 5 && cpu_model != 5));

 /* Enable partial cache preloading by default on Pentium class CPUs, */
 /*  and on 486DX2WBE and 486DX4 CPUs */
 preload_cache_2 = preload_cache ? preload_cache :
  get_config_int("extras", "preload_cache_2",
   ((cpu_family == 4 &&
   /* 486DX2WBE or 486DX4 */
    (cpu_model == 7 || cpu_model == 8 ||
   /* am5x86 */
    (cpu_model == 15 && !strcmp(cpu_vendor, "AuthenticAMD")))) ||
   /* Pentium class CPU */
   (cpu_family == 5)));

 CONTROLLER_1_TYPE = get_config_int("input", "controller_1_type", 0);
 if (CONTROLLER_1_TYPE > 2 || (CONTROLLER_1_TYPE == 2 && !mouse_available))
  CONTROLLER_1_TYPE = 0;

 CONTROLLER_2_TYPE = get_config_int("input", "controller_2_type", 0);
 if (CONTROLLER_2_TYPE > 2 || (CONTROLLER_2_TYPE == 2 && !mouse_available))
  CONTROLLER_2_TYPE = 0;

 memset(keymapbuf, 0, 81);
 strncpy(keymapbuf, get_config_string("input", "snes_pad_1_keys", default_keymap), 80);
 if (
  sscanf(keymapbuf, "%d%d%d%d%d%d%d%d%d%d%d%d",
   &input_player1.up, &input_player1.down, &input_player1.left, &input_player1.right,
   &input_player1.a, &input_player1.b, &input_player1.x, &input_player1.y, &input_player1.l, &input_player1.r,
   &input_player1.select, &input_player1.start) < 12)
 {
  sscanf(default_keymap, "%d%d%d%d%d%d%d%d%d%d%d%d",
   &input_player1.up, &input_player1.down, &input_player1.left, &input_player1.right,
   &input_player1.a, &input_player1.b, &input_player1.x, &input_player1.y, &input_player1.l, &input_player1.r,
   &input_player1.select, &input_player1.start);
 }

 strncpy(keymapbuf, get_config_string("input", "snes_pad_2_keys", default_keymap), 80);
 if (
  sscanf(keymapbuf, "%d%d%d%d%d%d%d%d%d%d%d%d",
   &input_player2.up, &input_player2.down, &input_player2.left, &input_player2.right,
   &input_player2.a, &input_player2.b, &input_player2.x, &input_player2.y, &input_player2.l, &input_player2.r,
   &input_player2.select, &input_player2.start) < 12)
 {
  sscanf(default_keymap, "%d%d%d%d%d%d%d%d%d%d%d%d",
   &input_player2.up, &input_player2.down, &input_player2.left, &input_player2.right,
   &input_player2.a, &input_player2.b, &input_player2.x, &input_player2.y, &input_player2.l, &input_player2.r,
   &input_player2.select, &input_player2.start);
 }
}

void FixupConfig(void)
{
 /* Compatibility with old screen modes */
 if (cfg_version < 0.72)
 {
  if (SCREEN_MODE > 8)
  {
   SCREEN_MODE = 0;
  }
  else
  {
   /* old 320x200x256 squash = no h-stretch, full v-stretch */
   if (SCREEN_MODE == 1)
   {
    SCREEN_MODE = 0;
    stretch_x = 0;
    stretch_y = 1;
   }

   /* old 640x480x16b stretch = 2x h-stretch, 2x v-stretch */
   else if (SCREEN_MODE == 7)
   {
    SCREEN_MODE = 6;
    stretch_x = 2;
    stretch_y = 2;
   }

   /* old 320x240x256 SVGA */
   else if (SCREEN_MODE == 8)
   {
    SCREEN_MODE = 1;
    stretch_x = 0;
    stretch_y = 0;
   }
  }
 }
}

int LoadConfig(void)
{
 cfg_version = get_config_float("base", "version", 0);
 if (((int) (cfg_version * 8192)) != ((int) (SNEESE_VERSION * 8192)))
 {
  LoadConfigCurrent();

  //handle old version cfg files
  FixupConfig();

  cfg_version = SNEESE_VERSION;
  cfg_changed = (0 - 1);
 }
 else
 {
  LoadConfigCurrent();
 }

 return 0;
}

void SaveConfig(void)
{
 /*
   Open the file in text mode. Under DOS and Windows the compiler's runtime
    system will do the conversion from NL (\n) to CR/LF (\r\n).
 */
 FILE *cfg = fopen(cfg_name, "w");

 if (cfg == NULL) return;
 fprintf(cfg,"# SNEeSe Configuration file\n");
 fprintf(cfg,"\n");
 fprintf(cfg,"# Do not edit [base] section, or all settings may be lost!\n");
 fprintf(cfg,"\n");
 fprintf(cfg, "[base]\n");
 fprintf(cfg, "version=%s\n", SNEESE_VERSION_STR);
 fprintf(cfg, "\n");
 fprintf(cfg, "# Important paths and file-related settings\n");
 fprintf(cfg, "[paths]\n");
 fprintf(cfg, "saveextension=%s\n", save_extension);
 fprintf(cfg, "savedirectory=%s\n", save_dir);
 fprintf(cfg, "\n");
 fprintf(cfg, "# Display settings\n");
 fprintf(cfg, "[display]\n");
 fprintf(cfg, "# Available screen modes:\n");
#ifdef ALLEGRO_DOS
 fprintf(cfg, "#  0:320x200x256 VGA       1:320x240x256 VESA2     2:320x240x256 MODE-X\n");
 fprintf(cfg, "#  3:256x239x256 VGA       4:320x200x16b VESA2     5:320x240x16b VESA2\n");
 fprintf(cfg, "#  6:640x480x16b VESA2\n");
#elif defined(ALLEGRO_WINDOWS) || defined(ALLEGRO_UNIX) || defined(ALLEGRO_BEOS)
 fprintf(cfg, "#  0:320x200x256 WIN       1:320x240x256 WIN       2:320x240x256 FS\n");
 fprintf(cfg, "#  3:256x239x256 WIN       4:320x200x16b WIN       5:320x240x16b WIN\n");
 fprintf(cfg, "#  6:640x480x16b WIN       7:640x480x16b FS\n");
#endif
 fprintf(cfg, "screenmode=%d\n", SCREEN_MODE);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Available screen processing methods:\n");
 fprintf(cfg, "#  0:none\n");
 fprintf(cfg, "process=%d\n", (int) display_process);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Stretch in horizontal (x) or vertical (y) directions:\n");
 fprintf(cfg, "#  0:no stretch   1:stretch   2+: zoom in by that factor\n");
 fprintf(cfg, "stretch_x=%d\n", stretch_x);
 fprintf(cfg, "stretch_y=%d\n", stretch_y);
 fprintf(cfg, "\n");

 fprintf(cfg, "# These specify how many frames to skip.\n");
 fprintf(cfg, "# maxframeskip sets the maximum number of frames that will be skipped before\n");
 fprintf(cfg, "#  a frame is drawn.\n");
 fprintf(cfg, "# minframeskip sets the number of frames that will always be skipped before\n");
 fprintf(cfg, "#  a frame is drawn. a min skip of 0 tells SNEeSe to wait for at least one\n");
 fprintf(cfg, "#  timer tick (50/60Hz) to have passed before emulating a frame (to slow\n");
 fprintf(cfg, "#  down machines that are running too fast)\n");
 fprintf(cfg, "# 'minframeskip' will never be above 'maxframeskip' - when loaded,\n");
 fprintf(cfg, "#  'maxframeskip' has precedence over 'minframeskip'.\n");
 fprintf(cfg, "# Setting 'minframeskip' and 'maxframeskip' to the same number effectively\n");
 fprintf(cfg, "#  disables all speed-throttling.\n");
 fprintf(cfg, "minframeskip=%d\n", FRAME_SKIP_MIN);
 fprintf(cfg, "maxframeskip=%d\n", FRAME_SKIP_MAX);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Emulated hardware options\n");
 fprintf(cfg, "[hardware]\n");
 fprintf(cfg, "# The following option selects emulation of SPC (1) or APU skip (0).\n");
 fprintf(cfg, "emulatespc=%d\n", SPC_ENABLED);
 fprintf(cfg, "# The following option selects whether to: (0) disable sound;\n");
 fprintf(cfg, "# (1) generate mono sound; (2) generate stereo sound.\n");
 fprintf(cfg, "# This option is ignored if SPC is disabled (emulatespc=0).\n");
 fprintf(cfg, "outputsound=%d\n", sound_enabled);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Audio output options\n");
 fprintf(cfg, "[audio]\n");
 fprintf(cfg, "# The following option selects size of audio samples output.\n");
 fprintf(cfg, "# Valid values: 8 or 16 (default).\n");
 fprintf(cfg, "sound_bits=%d\n", sound_bits);
 fprintf(cfg, "# The following option selects Allegro mixing quality.\n");
 fprintf(cfg, "# 0 = fast 8-bit, 1 (default) = 16-bit, 2 = 16-bit interpolated.\n");
 fprintf(cfg, "sound_hq=%d\n", _sound_hq);

 fprintf(cfg, "# The following option determines if the SNES echo effect\n");
 fprintf(cfg, "# and its corresponding FIR filter and SPC RAM update are\n");
 fprintf(cfg, "# emulated.\n");
 fprintf(cfg, "# Valid values: 0 = don't emulate, 1 = emulate (default).\n");
 fprintf(cfg, "enable_echo=%d\n", sound_echo_enabled);
 fprintf(cfg, "# The following option determines if the SNES 4-point pitch-\n");
 fprintf(cfg, "# regulated gaussian interpolation of sample data is emulated.\n");
 fprintf(cfg, "# Valid values: 0 = don't emulate, 1 = emulate (default).\n");
 fprintf(cfg, "enable_gauss=%d\n", sound_gauss_enabled);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Extra options that don't fit elsewhere\n");
 fprintf(cfg, "[extras]\n");
 fprintf(cfg, "# The following option determines if the FPU will be used to copy\n");
 fprintf(cfg, "# data, if available (0 = don't use).\n");
 fprintf(cfg, "use_fpu_copies=%d\n", use_fpu_copies ? 1 : 0);
 fprintf(cfg, "# The following option determines if MMX instructions will be used,\n");
 fprintf(cfg, "# if available (0 = don't use).\n");
 fprintf(cfg, "use_mmx=%d\n", use_mmx ? 1 : 0);
 fprintf(cfg, "# The following options determine if memory will be preloaded into\n");
 fprintf(cfg, "# the cache when it is expected it may help (0 = don't preload).\n");
 fprintf(cfg, "preload_cache=%d\n", preload_cache ? 1 : 0);
 fprintf(cfg, "preload_cache_2=%d\n", preload_cache_2 ? 1 : 0);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Input and controller options\n");
 fprintf(cfg, "[input]\n");
 fprintf(cfg, "# You can select joypad, mouse, or none for emulation on\n");
 fprintf(cfg, "# each controller.\n");
 fprintf(cfg, "controller_1_type=%d\n", CONTROLLER_1_TYPE);
 fprintf(cfg, "controller_2_type=%d\n", CONTROLLER_2_TYPE);
 fprintf(cfg, "\n");

 fprintf(cfg, "# Here you will find the control mappings for controller 1\n");
 fprintf(cfg, "# the numbers you see are scan codes, use the \"Define Keys\"\n");
 fprintf(cfg, "# option in the GUI to alter the keys, it's far easier!\n");
 fprintf(cfg, "\n");
 fprintf(cfg, "# Up Down Left Right A B X Y L R Select Start\n");
 fprintf(cfg, "snes_pad_1_keys=%d %d %d %d %d %d %d %d %d %d %d %d\n",
  input_player1.up, input_player1.down, input_player1.left, input_player1.right,
  input_player1.a, input_player1.b, input_player1.x, input_player1.y, input_player1.l, input_player1.r,
  input_player1.select, input_player1.start);

 fprintf(cfg, "\n");
 fprintf(cfg, "# Player 2's mappings are found here, see above.\n");
 fprintf(cfg, "snes_pad_2_keys=%d %d %d %d %d %d %d %d %d %d %d %d\n",
  input_player2.up, input_player2.down, input_player2.left, input_player2.right,
  input_player2.a, input_player2.b, input_player2.x, input_player2.y, input_player2.l, input_player2.r,
  input_player2.select, input_player2.start);

 fclose(cfg);
}

void cmdhelp(void)
{
 const char syntax[] =
  "Usage: SNEeSe [switches] [romname.ext] [switches]\n"
  "switches:\n"
  " -fl  Force LoROM memory map\n"
  " -fh  Force HiROM memory map\n"
  " -fi  Force interleaved ROM (only supported for HiROM)\n"
  " -fn  Force non-interleaved ROM\n"
  " -fvn Force NTSC video standard\n"
  " -fvp Force PAL video standard\n"
  " -h   Copier header exists\n"
  " -n   No copier header\n"
  " -m#  Set screen mode\n"
  " -se  Enable sound echo/FIR filter\n"
  " -sde Disable sound echo/FIR filter\n"
  " -sg  Enable sound gaussian filter\n"
  " -sdg Disable sound gaussian filter\n"
  " -ds  Disable sound\n"
  " -s   Enable sound (stereo)\n"
  " -sm  Enable sound (mono)\n"
  " -saveext RAM     Set extension for save RAM files\n"
  " -savedir .\\saves Set save directory\n"
  " -fps Start with frames-per-second (FPS) counter enabled\n"
  " -gui Enable GUI\n"
  " -cli Disable GUI\n"
  " -pt  Disable cache preloads    -pb  Enable cache preloads\n"
  " -pm  Enable MMX support        -pf  Enable FPU copies\n"
  " -pd  Disable MMX/FPU support\n";

 printf("%s", syntax);
}

/* Perform platform-specific initialization */
int platform_init(int argc, char **argv)
{
 char f_drive[MAXDRIVE], f_dir[MAXDIR], f_file[MAXFILE], f_ext[MAXEXT];

 /* Ensure stdout is not buffered */
 setvbuf(stdout, NULL, _IONBF, 0);

 allegro_init();

 if (cpu_family < 4)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -