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

📄 svga.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * 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. */#ifdef __linux#include <string.h>#include <ctype.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/io.h>#include <stdlib.h>#include <signal.h>#include <vga.h>#include <vgagl.h>#include <vgakeyboard.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"#define COUNT(a) (sizeof(a) / sizeof(a[0]))static bool8 planar;static int screen_pitch;static int screen_width;static int screen_height;static int mode = -1;static bool8 stretch = FALSE;static bool8 text_mode = TRUE;static bool8 interpolation = FALSE;static char prev_keystate [128] = "";static bool8 restore_modex = FALSE;static uint8 *DeltaScreen = NULL;static vga_modeinfo *info = NULL;static uint32 video_page_size = 64 * 1024;static uint32 selected_video_page = ~0;extern uint32 joypads [5];#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, G320x240x256}, // 0    {320, 200, G320x200x256}, // 1    {256, 256, G320x200x256}, // 2    {640, 480, G640x480x256}, // 3    {800, 600, G800x600x256}, // 4    {320, 200, G320x200x64K}, // 5    {640, 480, G640x480x64K}, // 6    {800, 600, G800x600x64K}, // 7};int S9xMinCommandLineArgs (){    return (2);}void S9xGraphicsMode (){    if (text_mode)    {	screen_width = modes [mode].width;	screen_height = modes [mode].height;	int ret = vga_setmode (modes [mode].mode);	if (ret < 0)	{	    fprintf (stderr, "Unable to switch to requested screen mode/resolution:\n");	    S9xExit ();	}	if (vga_setlinearaddressing () < 0)	{	    if (info->flags & EXT_INFO_AVAILABLE)		video_page_size = info->aperture_size;	    else		video_page_size = 64 * 1024;	}	else	    video_page_size = ~0;	if (modes [mode].mode == G320x200x256 && screen_width == 256)	{	    iopl(3);	    outRegArray (scr256x256, sizeof (scr256x256) / sizeof (Register));	    screen_pitch = screen_width;	}    	gl_setcontextvga (modes [mode].mode);	if (keyboard_init ())	{	    fprintf (stdout, "Keyboard initialisation failed.\n");	    S9xExit ();	}	text_mode = FALSE;	if (DeltaScreen)	    memset (DeltaScreen, 0xff, GFX.Pitch * IMAGE_HEIGHT);    }}void S9xTextMode (){//    if (!text_mode)    {	keyboard_close ();	vga_setmode (TEXT);	text_mode = TRUE;    }}static struct sigaction sig1handler;static struct sigaction oldsig1handler;static struct sigaction sig2handler;static struct sigaction oldsig2handler;void Sig1HandlerFunction(int){    extern void StopTimer ();    StopTimer ();    sigaction(SIGUSR2, &sig2handler, NULL);    sigaction(SIGUSR1, &oldsig1handler, NULL);    sigsetmask (0);    raise(SIGUSR1);}void Sig2HandlerFunction(int){    restore_modex = TRUE;    sigaction(SIGUSR1, &sig1handler, NULL);    sigaction(SIGUSR2, &oldsig2handler, NULL);    sigsetmask (0);    raise(SIGUSR2);}void S9xInitDisplay (int /*argc*/, char ** /*argv*/){    if (vga_init() < 0)    {	fprintf (stdout, "Unable to initialise vga.\n");	S9xExit ();    }    S9xTextMode ();    if (mode < 0)    {	if (Settings.SixteenBit)	    mode = 6;	else	    mode = 2;    }    info = vga_getmodeinfo (modes [mode].mode);    if (info->flags & IS_MODEX)	planar = 1;    if (info->flags & CAPABLE_LINEAR)	video_page_size = ~0;    else    if (info->flags & EXT_INFO_AVAILABLE)	video_page_size = info->aperture_size;    else	video_page_size = 64 * 1024;    if (!screen_pitch)	screen_pitch = info->linewidth;	    if (info->bytesperpixel > 1)    {	Settings.Transparency = TRUE;	Settings.SixteenBit = TRUE;    }    else    {	Settings.Transparency = FALSE;	Settings.SixteenBit = FALSE;    }    if (info->width >= 512 && info->height >= 578)	Settings.SupportHiRes = TRUE;    if (!Settings.SixteenBit || info->width < 512 || info->height < 240)	interpolation = FALSE;    if (interpolation)    {	GFX.Pitch = (IMAGE_WIDTH + 2) * 2;	GFX.Screen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	GFX.SubScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	DeltaScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	GFX.ZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);	GFX.SubZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);	if (!GFX.Screen || !GFX.SubScreen || !DeltaScreen || 	    !GFX.ZBuffer || !GFX.SubZBuffer)	{	    fprintf (stdout, "Cannot allocate screen buffer.\n");	    S9xExit ();	}    }    else    if (Settings.SixteenBit)    {	GFX.Pitch = IMAGE_WIDTH * 2;	GFX.Screen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	GFX.SubScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	GFX.ZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);	GFX.SubZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);	if (!GFX.Screen || !GFX.SubScreen)	{	    fprintf (stdout, "Cannot allocate screen buffer.\n");	    S9xExit ();	}    }    else    {	GFX.Pitch = IMAGE_WIDTH;	GFX.Screen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	if (!GFX.Screen)	{	    fprintf (stdout, "Cannot allocate screen buffer.\n");	    S9xExit ();	}	GFX.SubScreen = NULL;	DeltaScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	if (!DeltaScreen)	{	    fprintf (stdout, "Cannot allocate shadow screen buffer.\n");	    S9xExit ();        }	GFX.ZBuffer = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);	GFX.SubZBuffer = NULL;    }    ZeroMemory (GFX.Screen, GFX.Pitch * IMAGE_HEIGHT);    if (GFX.SubScreen)	ZeroMemory (GFX.SubScreen, GFX.Pitch * IMAGE_HEIGHT);    if (DeltaScreen)	ZeroMemory (DeltaScreen, GFX.Pitch * IMAGE_HEIGHT);    sig1handler.sa_handler = Sig1HandlerFunction;    sigemptyset (&sig1handler.sa_mask);    sig1handler.sa_flags = 0;    sig2handler.sa_handler = Sig2HandlerFunction;    sigemptyset (&sig2handler.sa_mask);    sig2handler.sa_flags = 0;    sigaction (SIGUSR1, &sig1handler, &oldsig1handler);    sigaction (SIGUSR2, &sig2handler, &oldsig2handler);}void S9xDeinitDisplay (){    S9xTextMode ();    if (GFX.Screen)	free ((char *) GFX.Screen);    if (GFX.SubScreen)	free ((char *) GFX.SubScreen);    if (DeltaScreen)	free ((char *) DeltaScreen);    if (GFX.ZBuffer)	free ((char *) GFX.ZBuffer);    if (GFX.SubZBuffer)	free ((char *) GFX.SubZBuffer);    GFX.Screen = NULL;    GFX.SubScreen = NULL;    DeltaScreen = NULL;    GFX.ZBuffer = NULL;    GFX.SubZBuffer = NULL;}void S9xSetPalette (){    uint16 Brightness = IPPU.MaxBrightness * 138;    for (int i = 0; i < 256; i++)	vga_setpalette (i, 			(((PPU.CGDATA [i] >> 0) & 0x1F) * Brightness) >> 10,			(((PPU.CGDATA [i] >> 5) & 0x1F) * Brightness) >> 10,			(((PPU.CGDATA [i] >> 10) & 0x1F) * Brightness) >> 10);}void S9xProcessEvents (bool8 block){    int fn = -1;    if (restore_modex)    {	restore_modex = FALSE;	ZeroMemory (prev_keystate, 128);	if (!text_mode && modes [mode].mode == G320x200x256 && screen_width == 256)	{	    iopl(3);	    outRegArray (scr256x256, sizeof (scr256x256) / sizeof (Register));	}	extern void InitTimer ();	InitTimer ();    }    if (block)    {//	keyboard_waitforupdate ();	usleep (10000);	keyboard_update ();    }    else	keyboard_update ();    char *keystate = keyboard_getstate ();    #define KEY_DOWN(a) (keystate[a])#define KEY_PRESS(a) (keystate[a] && !prev_keystate[a])#define KEY_WASPRESSED(a) (prev_keystate[a] && !keystate[a])#define PROCESS_KEY(k, b, v)\if (KEY_PRESS(k)) b |= v;\if (KEY_WASPRESSED(k)) b &= ~v;    if (KEY_PRESS (SCANCODE_ESCAPE))	S9xExit ();    // Joypad 1:    PROCESS_KEY(SCANCODE_K,		    joypads [0], SNES_RIGHT_MASK)    PROCESS_KEY(SCANCODE_CURSORBLOCKRIGHT,  joypads [0], SNES_RIGHT_MASK)    PROCESS_KEY(SCANCODE_H,		    joypads [0], SNES_LEFT_MASK)    PROCESS_KEY(SCANCODE_CURSORBLOCKLEFT,   joypads [0], SNES_LEFT_MASK)    PROCESS_KEY(SCANCODE_N,		    joypads [0], SNES_DOWN_MASK)    PROCESS_KEY(SCANCODE_J,		    joypads [0], SNES_DOWN_MASK)    PROCESS_KEY(SCANCODE_CURSORBLOCKDOWN,   joypads [0], SNES_DOWN_MASK)    PROCESS_KEY(SCANCODE_U,		    joypads [0], SNES_UP_MASK)    PROCESS_KEY(SCANCODE_CURSORBLOCKUP,	    joypads [0], SNES_UP_MASK)    PROCESS_KEY(SCANCODE_ENTER,		    joypads [0], SNES_START_MASK)    PROCESS_KEY(SCANCODE_SPACE,		    joypads [0], SNES_SELECT_MASK)    PROCESS_KEY(SCANCODE_A,		    joypads [0], SNES_TL_MASK)    PROCESS_KEY(SCANCODE_V,		    joypads [0], SNES_TL_MASK)    PROCESS_KEY(SCANCODE_Q,		    joypads [0], SNES_TL_MASK)    PROCESS_KEY(SCANCODE_Z,		    joypads [0], SNES_TR_MASK)    PROCESS_KEY(SCANCODE_B,		    joypads [0], SNES_TR_MASK)    PROCESS_KEY(SCANCODE_W,		    joypads [0], SNES_TR_MASK)    PROCESS_KEY(SCANCODE_S,		    joypads [0], SNES_X_MASK)    PROCESS_KEY(SCANCODE_M,		    joypads [0], SNES_X_MASK)    PROCESS_KEY(SCANCODE_E,		    joypads [0], SNES_X_MASK)    PROCESS_KEY(SCANCODE_X,		    joypads [0], SNES_Y_MASK)

⌨️ 快捷键说明

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