📄 sdllink.c
字号:
/*Copyright (C) 1997-2007 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )http://www.zsnes.comhttp://sourceforge.net/projects/zsneshttps://zsnes.bountysource.comThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseversion 2 as published by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "../gblhdr.h"#include "sw_draw.h"#include "gl_draw.h"#include <stdbool.h>#include <SDL_thread.h>#include <sys/time.h>#include <time.h>#include "audio.h"#include "safelib.h"#include "../cfg.h"#include "../input.h"typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned long DWORD;typedef Uint32 UINT32;typedef long long _int64;typedef long long LARGE_INTEGER;#define QueryPerformanceCounter(x) asm volatile("rdtsc" : "=a"(((unsigned int *)(x))[0]),"=d"(((unsigned int *)x)[1]))typedef enum { FALSE = 0, TRUE = 1 } BOOL;typedef enum vidstate_e { vid_null, vid_none, vid_soft, vid_gl } vidstate_t;/* VIDEO VARIABLES */SDL_Surface *surface;int SurfaceLocking = 0;int SurfaceX, SurfaceY;static DWORD WindowWidth = 256;static DWORD WindowHeight = 224;static DWORD FullScreen = 0;static vidstate_t sdl_state = vid_null;static int UseOpenGL = 0;static const int BitDepth = 16;DWORD FirstVid = 1;void SwitchFullScreen (void);DWORD SMode=0;DWORD DSMode=0;DWORD prevHQMode=-1;extern DWORD converta;extern DWORD *BitConv32Ptr;extern DWORD *RGBtoYUVPtr;extern BYTE GUIWFVID[];extern BYTE GUISMODE[];extern BYTE GUIDSMODE[];extern BYTE GUIHQ2X[];extern BYTE GUIHQ3X[];extern BYTE GUIHQ4X[];extern BYTE GUIRESIZE[];extern BYTE GUIM7VID[];/* JOYSTICK AND KEYBOARD INPUT */SDL_Joystick *JoystickInput[5];unsigned int AxisOffset[5] = {256 + 128 + 64}; // per joystick offsets inunsigned int ButtonOffset[5] = {448}; // pressed. We have 128 + 64unsigned int HatOffset[5] = {448}; // bytes for all joysticks. Weunsigned int BallOffset[5] = {448}; // can control all 5 players.int shiftptr = 0;int offset;DWORD numlockptr;extern unsigned char pressed[];extern int CurKeyPos;extern int CurKeyReadPos;extern int KeyBuffer[16];/* MOUSE INPUT */static float MouseMinX = 0;static float MouseMaxX = 256;static float MouseMinY = 0;static float MouseMaxY = 223;static int MouseX, MouseY;static int MouseMove2X, MouseMove2Y;unsigned char MouseButton;static float MouseXScale = 1.0;static float MouseYScale = 1.0;DWORD LastUsedPos = 0;DWORD CurMode = -1;extern BYTE GUIOn;extern BYTE GUIOn2;extern BYTE EMUPause;static BYTE IsActivated = 1;/* TIMER VARIABLES/MACROS */// millisecond per world update#define UPDATE_TICKS_GAME (1000.0/59.948743718592964824120603015060)#define UPDATE_TICKS_GAMEPAL (20.0)#define UPDATE_TICKS_GUI (1000.0/36.0)#define UPDATE_TICKS_UDP (1000.0/60.0)int T60HZEnabled = 0;int T36HZEnabled = 0;float end, end2;float start, start2;float update_ticks_pc, update_ticks_pc2;// Used for semaphore codestatic SDL_sem *sem_frames = NULL;static struct timeval sem_start;void sem_sleep_rdy(void);void sem_sleep_die(void);float sem_GetTicks(void);extern unsigned char romispal;/* FUNCTION DECLARATIONS */void clearwin (void);void drawscreenwin(void);void initwinvideo();unsigned int sdl_keysym_to_pc_scancode(int);void ProcessKeyBuf(int);void UpdateSound(void *userdata, Uint8 * stream, int len);void GUI36hzcall(void);void Game60hzcall(void);_int64 copymaskRB = 0x001FF800001FF800LL;_int64 copymaskG = 0x0000FC000000FC00LL;_int64 copymagic = 0x0008010000080100LL;#ifdef __OPENGL__void gl_clearwin(void);#endifstatic void adjustMouseXScale(void){ MouseXScale = (MouseMaxX - MouseMinX) / ((float) WindowWidth);}static void adjustMouseYScale(void){ MouseYScale = (MouseMaxY - MouseMinY) / ((float) WindowHeight);}void SetHQx(unsigned int ResX, unsigned int ResY){ int maxHQ; if(ResX/256 < ResY/224) maxHQ = ResX/256; else maxHQ = ResY/224; if(maxHQ >= 2) { GUIHQ2X[cvidmode] = 1; GUIHQ3X[cvidmode] = 0; GUIHQ4X[cvidmode] = 0; } else { GUIHQ2X[cvidmode] = 0; GUIHQ3X[cvidmode] = 0; GUIHQ4X[cvidmode] = 0; }}void SetHiresOpt(unsigned int ResX, unsigned int ResY){ if(ResX >= 512 && ResY >= 448) GUIM7VID[cvidmode] = 1; else GUIM7VID[cvidmode] = 0;}void Clear2xSaIBuffer();int Main_Proc(void){ SDL_Event event; unsigned int key; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_ACTIVEEVENT: IsActivated = event.active.gain; break; case SDL_KEYDOWN: if ((event.key.keysym.sym == SDLK_RETURN) && (event.key.keysym.mod & KMOD_ALT)) { SwitchFullScreen(); break; } if (event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT) shiftptr = 1; if (event.key.keysym.mod & KMOD_NUM) numlockptr = 1; else numlockptr = 0; key = sdl_keysym_to_pc_scancode(event.key.keysym.sym); if (key < 448) { pressed[key] = 1; ProcessKeyBuf(event.key.keysym.sym); } break; case SDL_KEYUP: if (event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT) shiftptr = 0; key = sdl_keysym_to_pc_scancode(event.key.keysym.sym); if (key < 448) { pressed[key] = 0; } break; case SDL_MOUSEMOTION: if (FullScreen) { MouseX += event.motion.xrel; MouseY += event.motion.yrel; } else { MouseX = ((int) ((float) event.motion.x) * MouseXScale); MouseY = ((int) ((float) event.motion.y) * MouseYScale); } if (MouseX < MouseMinX) MouseX = MouseMinX; if (MouseX > MouseMaxX) MouseX = MouseMaxX; if (MouseY < MouseMinY) MouseY = MouseMinY; if (MouseY > MouseMaxY) MouseY = MouseMaxY; break; case SDL_MOUSEBUTTONDOWN: /* button 2 = enter (i.e. select) button 4 = mouse wheel up (treat as "up" key) button 5 = mouse wheel down (treat as "down" key) */ switch (event.button.button) { case 4: ProcessKeyBuf(SDLK_UP); break; case 5: ProcessKeyBuf(SDLK_DOWN); break; case 3: MouseButton |= 2; break; case 2: ProcessKeyBuf(SDLK_RETURN); // Yes, this is intentional - DDOI case 1: MouseButton |= event.button.button; break; } break; case SDL_MOUSEBUTTONUP: switch (event.button.button) { case 1: case 2: MouseButton &= ~event.button.button; break; case 3: MouseButton &= ~2; break; } break; case SDL_JOYHATMOTION: // POV hats act as direction pad offset = HatOffset[event.jhat.which]; if (offset >= (256 + 128 + 64)) break; switch (event.jhat.value) { case SDL_HAT_CENTERED: pressed[offset] = 0; pressed[offset + 1] = 0; pressed[offset + 2] = 0; pressed[offset + 3] = 0; break; case SDL_HAT_UP: pressed[offset + 3] = 1; pressed[offset + 2] = 0; break; case SDL_HAT_RIGHTUP: pressed[offset] = 1; pressed[offset + 3] = 1; pressed[offset + 1] = 0; pressed[offset + 2] = 0; break; case SDL_HAT_RIGHT: pressed[offset] = 1; pressed[offset + 1] = 0; break; case SDL_HAT_RIGHTDOWN: pressed[offset] = 1; pressed[offset + 2] = 1; pressed[offset + 1] = 0; pressed[offset + 3] = 0; break; case SDL_HAT_DOWN: pressed[offset + 2] = 1; pressed[offset + 3] = 0; break; case SDL_HAT_LEFTDOWN: pressed[offset + 1] = 1; pressed[offset + 2] = 1; pressed[offset] = 0; pressed[offset + 3] = 0; break; case SDL_HAT_LEFT: pressed[offset + 1] = 1; pressed[offset] = 0; break; case SDL_HAT_LEFTUP: pressed[offset + 1] = 1; pressed[offset + 3] = 1; pressed[offset] = 0; pressed[offset + 2] = 0; break; } break; /* joystick trackball code untested; change the test values if the motion is too sensitive (or not sensitive enough) */ case SDL_JOYBALLMOTION: offset = BallOffset[event.jball.which]; offset += event.jball.ball; if (offset >= (256 + 128 + 64)) break; if (event.jball.xrel < -100) { pressed[offset] = 0; pressed[offset + 1] = 1; } if (event.jball.xrel > 100) { pressed[offset] = 1; pressed[offset + 1] = 0; } if (event.jball.yrel < -100) { pressed[offset + 2] = 0; pressed[offset + 3] = 1; } if (event.jball.yrel > 100) { pressed[offset + 2] = 1; pressed[offset + 3] = 0; } break; case SDL_JOYAXISMOTION: offset = AxisOffset[event.jaxis.which]; offset += event.jaxis.axis * 2; if (offset >= (256 + 128 + 64)) break; //printf("DEBUG axis offset: %d\n", offset); if (event.jaxis.value < -(joy_sensitivity)) { pressed[offset + 1] = 1; pressed[offset + 0] = 0; } else if (event.jaxis.value > joy_sensitivity) { pressed[offset + 0] = 1; pressed[offset + 1] = 0; } else { pressed[offset + 0] = 0; pressed[offset + 1] = 0; } break; case SDL_JOYBUTTONDOWN: offset = ButtonOffset[event.jbutton.which]; offset += event.jbutton.button; //printf("DEBUG button offset: %d\n", offset); if (offset >= (256 + 128 + 64)) break; pressed[offset] = 1; break; case SDL_JOYBUTTONUP: offset = ButtonOffset[event.jbutton.which]; offset += event.jbutton.button; //printf("DEBUG button offset: %d\n", offset); if (offset >= (256 + 128 + 64)) break; pressed[offset] = 0; break; case SDL_QUIT: exit(0); break;#ifdef __OPENGL__ case SDL_VIDEORESIZE: if(!GUIRESIZE[cvidmode]) { surface = SDL_SetVideoMode(WindowWidth, WindowHeight, BitDepth, surface->flags & ~SDL_RESIZABLE); adjustMouseXScale(); adjustMouseYScale(); break; } WindowWidth = SurfaceX = event.resize.w; WindowHeight = SurfaceY = event.resize.h; SetHQx(SurfaceX,SurfaceY); SetHiresOpt(SurfaceX,SurfaceY); surface = SDL_SetVideoMode(WindowWidth, WindowHeight, BitDepth, surface->flags); adjustMouseXScale(); adjustMouseYScale(); glViewport(0,0, WindowWidth, WindowHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (cvidmode == 20) { if (224*WindowWidth > 256*WindowHeight && WindowHeight) { glOrtho (- ((float) 224*WindowWidth)/((float) 256*WindowHeight), ((float) 224*WindowWidth)/((float) 256*WindowHeight), -1, 1, -1, 1); } else if (224*WindowWidth < 256*WindowHeight && WindowWidth) { glOrtho (-1, 1,- ((float) 256*WindowHeight)/((float) 224*WindowWidth), ((float) 256*WindowHeight)/((float) 224*WindowWidth), -1, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -