📄 msdos.cpp
字号:
/* * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. * * (c) Copyright 1996 - 2001 Gary Henderson (gary@daniver.demon.co.uk) and * Jerremy Koot (jkoot@snes9x.com) * * Super FX C emulator code * (c) Copyright 1997 - 1999 Ivar (Ivar@snes9x.com) and * Gary Henderson. * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. * * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. * C4 C code (c) Copyright 2001 Gary Henderson (gary@daniver.demon.co.uk). * * DOS port code contains the works of other authors. See headers in * individual files. * * Snes9x homepage: www.snes9x.com * * Permission to use, copy, modify and distribute Snes9x in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Snes9x is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Snes9x or software derived from Snes9x. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so everyone can benefit from the modifications * in future versions. * * Super NES and Super Nintendo Entertainment System are trademarks of * Nintendo Co., Limited and its subsidiary companies. */#include <allegro.h>#undef TRUE#undef FALSE#include <string.h>#include <ctype.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <stdio.h>#include "swinder.h"#include "sb.h"#include "scancode.h"#include <dpmi.h>#include <go32.h>#include "snes9x.h"#include "memmap.h"#include "debug.h"#include "ppu.h"#include "snapshot.h"#include "gfx.h"#include "display.h"#include "apu.h"#include "soundux.h"#ifdef NETPLAY_SUPPORT#include "netplay.h"#endif#define COUNT(a) (sizeof(a) / sizeof(a[0]))#define sti() __asm__ __volatile__ ("sti": : :"memory")#define cli() __asm__ __volatile__ ("cli": : :"memory")static int screen_pitch = 0;uint32 screen_width = 0;uint32 screen_height = 0;static int mode = -1;static bool8 planar = FALSE;static bool8 in_text_mode = TRUE;static bool8 stretch = FALSE;BITMAP *off_screen;static BITMAP *sub_screen;static uint8 *Delta = NULL;static int num_sidewinders = 0;static bool8 grip_initialised = FALSE;extern int NumControllers;static bool8 mouse_installed = FALSE;static int prev_mouse_x = 0;static int prev_mouse_y = 0;static uint32 superscope_turbo = 0;static uint32 superscope_pause = 0;static int mouse_offset_x = 0;static int mouse_offset_y = 0;static double mouse_scale_h = 1.0;static double mouse_scale_v = 1.0;static bool8 wait_for_vsync = FALSE;static bool8 interpolate = FALSE;uint32 last_rendered_width = 0;uint32 last_rendered_height = 0;#ifdef GRIP_SUPPORT#include "grip.h"void InitGrip ();void ReadGrip ();#endif#ifdef SIDEWINDER_SUPPORTvoid InitSidewinders ();int ReadSidewinders ();extern bool8 alternate_sidewinder_mapping;#endifextern uint32 joypads [5];extern BITMAP *screen;void SaveScreenshot ();#ifdef JOYSTICK_SUPPORTextern bool8 joystick_has_four_buttons;extern bool8 joystick_has_six_buttons;extern bool8 joystick_has_eight_buttons;#endif#define ATTRCON_ADDR 0x3c0#define MISC_ADDR 0x3c2#define VGAENABLE_ADDR 0x3c3#define SEQ_ADDR 0x3c4#define GRACON_ADDR 0x3ce#define CRTC_ADDR 0x3d4#define STATUS_ADDR 0x3datypedef struct{ unsigned port; unsigned char index; unsigned char value;} Register;typedef Register *RegisterPtr;void outRegArray (Register *r, int n);Register scr256x256[] ={ { 0x3c2, 0x00, 0xe3},{ 0x3d4, 0x00, 0x5f},{ 0x3d4, 0x01, 0x3f}, { 0x3d4, 0x02, 0x40},{ 0x3d4, 0x03, 0x82},{ 0x3d4, 0x04, 0x4A}, { 0x3d4, 0x05, 0x9A},{ 0x3d4, 0x06, 0x23},{ 0x3d4, 0x07, 0xb2}, { 0x3d4, 0x08, 0x00},{ 0x3d4, 0x09, 0x61},{ 0x3d4, 0x10, 0x0a}, { 0x3d4, 0x11, 0xac},{ 0x3d4, 0x12, 0xff},{ 0x3d4, 0x13, 0x20}, { 0x3d4, 0x14, 0x40},{ 0x3d4, 0x15, 0x07},{ 0x3d4, 0x16, 0x1a}, { 0x3d4, 0x17, 0xa3},{ 0x3c4, 0x01, 0x01},{ 0x3c4, 0x04, 0x0e}, { 0x3ce, 0x05, 0x40},{ 0x3ce, 0x06, 0x05},{ 0x3c0, 0x10, 0x41}, { 0x3c0, 0x13, 0x00}};typedef struct{ int width; int height; int mode;} Mode;static Mode modes [] = { {320, 240, GFX_MODEX}, // 0 {320, 200, GFX_VGA}, // 1 {256, 256, GFX_VGA}, // 2 {640, 480, GFX_AUTODETECT}, // 3 {640, 480, GFX_VESA1}, // 4 {640, 480, GFX_VESA2B}, // 5 {640, 480, GFX_VESA2L}, // 6 {640, 400, GFX_XTENDED}, // 7 {800, 600, GFX_AUTODETECT}, // 8 {320, 240, GFX_AUTODETECT}, // 9 {640, 480, GFX_AUTODETECT}, // 10 {512, 384, GFX_AUTODETECT}, // 11 {800, 600, GFX_AUTODETECT} // 12};void S9xGraphicsMode (){ if (in_text_mode) { if (mode < 0) { if (Settings.SixteenBit) { if (Settings.SupportHiRes || interpolate) mode = 10; else mode = 9; } else { if (Settings.SupportHiRes) mode = 3; else mode = 2; } } int ret; do { screen_width = modes [mode].width; screen_height = modes [mode].height; set_color_depth (Settings.SixteenBit ? 16: 8); if (modes [mode].mode == GFX_VGA) ret = set_gfx_mode (modes [mode].mode, 320, 200, 0, 0); else ret = set_gfx_mode (modes [mode].mode, modes [mode].width, modes [mode].height, 0, 0); } while (ret < 0 && ++mode < COUNT(modes)); planar = modes [mode].mode == GFX_MODEX; if (ret < 0) { fprintf (stderr, "Unable to switch to requested screen mode/resolution:\n%s\n", allegro_error); S9xExit (); } if (modes [mode].mode == GFX_VGA && screen_width == 256) { outRegArray (scr256x256, sizeof (scr256x256) / sizeof (Register)); screen->w = screen->cr = 256; screen->h = screen->cb = 256; for (int i = 1; i < 256; i++) screen->line[i] = screen->line[i - 1] + 256; } clear_to_color (screen, 0); if (install_keyboard ()) { set_gfx_mode (GFX_TEXT, 0, 0, 0, 0); fprintf (stdout, "Keyboard initialisation failed.\n"); S9xExit (); } if (!install_mouse ()) { mouse_installed = TRUE; set_mouse_range (0, 0, screen_width, screen_height); position_mouse (screen_width / 2, screen_height / 2); prev_mouse_x = mouse_x; prev_mouse_y = mouse_y; } else mouse_installed = FALSE; in_text_mode = FALSE; }}void S9xTextMode (){ if (!in_text_mode) { set_color_depth (8); remove_keyboard (); remove_mouse (); set_gfx_mode (GFX_TEXT, 0, 0, 0, 0); in_text_mode = TRUE; }}void S9xInitDisplay (int argc, char **argv){ if (allegro_init () < 0) { fprintf (stdout, "Unable to initialise Allegro library.\n"); S9xExit (); } extern int i_love_bill; if (mode >= 9 || (mode < 0 && Settings.SixteenBit)) { set_color_depth (16); Settings.Transparency = TRUE; Settings.SixteenBit = TRUE; } else { set_color_depth (8); Settings.Transparency = FALSE; Settings.SixteenBit = FALSE; } /*i_love_bill = FALSE;*/ off_screen = create_bitmap (IMAGE_WIDTH + 2, IMAGE_HEIGHT); GFX.Screen = (uint8 *) off_screen->dat; if (!GFX.Screen) { fprintf (stdout, "Cannot allocate screen buffer.\n"); S9xExit (); } GFX.Pitch = off_screen->w; if (Settings.SixteenBit) { GFX.Pitch *= 2; sub_screen = create_bitmap ((IMAGE_WIDTH + 2), IMAGE_HEIGHT); Delta = new uint8 [(IMAGE_WIDTH + 2) * IMAGE_HEIGHT * 2]; if (!sub_screen || !Delta) { fprintf (stdout, "Cannot allocate screen buffer.\n"); S9xExit (); } GFX.SubScreen = (uint8 *) sub_screen->dat; GFX.ZBuffer = (uint8 *) malloc (off_screen->w * IMAGE_HEIGHT); GFX.SubZBuffer = (uint8 *) malloc (off_screen->w * IMAGE_HEIGHT); } else { GFX.SubScreen = GFX.Screen; GFX.ZBuffer = (uint8 *) malloc (off_screen->w * IMAGE_HEIGHT); GFX.SubZBuffer = NULL; sub_screen = NULL; Delta = NULL; } screen_pitch = off_screen->w;}void S9xDeinitDisplay (){ S9xTextMode ();#ifdef GRIP_SUPPORT if (grip_initialised) { GrShutdown (); GrUnlink (); }#endif destroy_bitmap (off_screen); if (sub_screen) destroy_bitmap (sub_screen); delete Delta; if (GFX.ZBuffer) free ((char *) GFX.ZBuffer); if (GFX.SubZBuffer) free ((char *) GFX.SubZBuffer); GFX.ZBuffer = NULL; GFX.SubZBuffer = NULL;}void S9xInitInputDevices (){ if (Settings.JoystickEnabled) {#ifdef GRIP_SUPPORT InitGrip (); if (grip_initialised) num_sidewinders = 0; else#endif#ifdef SIDEWINDER_SUPPORT {#ifdef GRIP_SUPPORT usleep (20000);#endif InitSidewinders (); }#else { /* empty */ }#endif#ifdef JOYSTICK_SUPPORT if (joystick_has_four_buttons) joy_type = JOY_TYPE_4BUTTON; else if (joystick_has_six_buttons) joy_type = JOY_TYPE_6BUTTON; else if (joystick_has_eight_buttons) joy_type = JOY_TYPE_8BUTTON; else joy_type = JOY_TYPE_2PADS; if (num_sidewinders == 0 && !grip_initialised) initialise_joystick ();#endif }}#ifdef JOYSTICK_SUPPORTvoid InitJoysticks (){}static int old_joy_left = 0;static int old_joy_right = 0;static int old_joy_up = 0;static int old_joy_down = 0;static int old_joy_b1 = 0;static int old_joy_b2 = 0;static int old_joy_b3 = 0;static int old_joy_b4 = 0;static int old_joy_b5 = 0;static int old_joy_b6 = 0;static int old_joy_b7 = 0;static int old_joy_b8 = 0;static int old_joy2_left = 0;static int old_joy2_right = 0;static int old_joy2_up = 0;static int old_joy2_down = 0;static int old_joy2_b1 = 0;static int old_joy2_b2 = 0;void ReadJoysticks (){ if (num_sidewinders == 0 && !grip_initialised) { poll_joystick (); if (!joystick_has_four_buttons && !joystick_has_six_buttons && !joystick_has_eight_buttons) { if (joy_b1 ^ old_joy_b1) { if (joy_b1) joypads [0] |= SNES_A_MASK; else joypads [0] &= ~SNES_A_MASK; } if (joy_b2 ^ old_joy_b2) { if (joy_b2) joypads [0] |= SNES_B_MASK; else joypads [0] &= ~SNES_B_MASK; } } else { if (joy_b1 ^ old_joy_b1) { if (joy_b1) joypads [0] |= SNES_Y_MASK; else joypads [0] &= ~SNES_Y_MASK; } if (joy_b2 ^ old_joy_b2) { if (joy_b2) joypads [0] |= SNES_X_MASK; else joypads [0] &= ~SNES_X_MASK; } } if (joy_b3 ^ old_joy_b3) { if (joy_b3) joypads [0] |= SNES_B_MASK; else joypads [0] &= ~SNES_B_MASK; } if (joy_b4 ^ old_joy_b4) { if (joy_b4) joypads [0] |= SNES_A_MASK; else joypads [0] &= ~SNES_A_MASK; } if (joy_b5 ^ old_joy_b5) { if (joy_b5) joypads [0] |= SNES_TL_MASK; else joypads [0] &= ~SNES_TL_MASK; } if (joy_b6 ^ old_joy_b6) { if (joy_b6) joypads [0] |= SNES_TR_MASK; else joypads [0] &= ~SNES_TR_MASK; } if (joy_b7 ^ old_joy_b7) { if (joy_b7) joypads [0] |= SNES_SELECT_MASK; else joypads [0] &= ~SNES_SELECT_MASK; } if (joy_b8 ^ old_joy_b8) { if (joy_b8) joypads [0] |= SNES_START_MASK; else joypads [0] &= ~SNES_START_MASK; } if (joy_left ^ old_joy_left) { if (joy_left) joypads [0] |= SNES_LEFT_MASK; else joypads [0] &= ~SNES_LEFT_MASK; } if (joy_right ^ old_joy_right) { if (joy_right) joypads [0] |= SNES_RIGHT_MASK; else joypads [0] &= ~SNES_RIGHT_MASK; } if (joy_up ^ old_joy_up) { if (joy_up) joypads [0] |= SNES_UP_MASK; else joypads [0] &= ~SNES_UP_MASK; } if (joy_down ^ old_joy_down) { if (joy_down) joypads [0] |= SNES_DOWN_MASK; else joypads [0] &= ~SNES_DOWN_MASK; } if (!joystick_has_four_buttons && !joystick_has_six_buttons && !joystick_has_eight_buttons) { if (joy2_b1 ^ old_joy2_b1) { if (joy2_b1) joypads [1] |= SNES_A_MASK; else joypads [1] &= ~SNES_A_MASK; } if (joy2_b2 ^ old_joy2_b2) { if (joy2_b2) joypads [1] |= SNES_B_MASK; else joypads [1] &= ~SNES_B_MASK; } if (joy2_left ^ old_joy2_left) { if (joy2_left) joypads [1] |= SNES_LEFT_MASK; else joypads [1] &= ~SNES_LEFT_MASK; } if (joy2_right ^ old_joy2_right) { if (joy2_right) joypads [1] |= SNES_RIGHT_MASK; else joypads [1] &= ~SNES_RIGHT_MASK; } if (joy2_up ^ old_joy2_up) { if (joy2_up) joypads [1] |= SNES_UP_MASK; else joypads [1] &= ~SNES_UP_MASK; } if (joy2_down ^ old_joy2_down) { if (joy2_down) joypads [1] |= SNES_DOWN_MASK; else joypads [1] &= ~SNES_DOWN_MASK; } } old_joy_left = joy_left; old_joy_right = joy_right; old_joy_up = joy_up; old_joy_down = joy_down; old_joy_b1 = joy_b1; old_joy_b2 = joy_b2; old_joy_b3 = joy_b3; old_joy_b4 = joy_b4; old_joy_b5 = joy_b5; old_joy_b6 = joy_b6; old_joy_b7 = joy_b7; old_joy_b8 = joy_b8; old_joy2_left = joy2_left; old_joy2_right = joy2_right; old_joy2_up = joy2_up;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -