📄 winlink.cpp
字号:
/*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.*/#define DIRECTINPUT_VERSION 0x0800#define DIRECTSOUND_VERSION 0x0800extern "C" { #include <windows.h> #include <stdio.h> #include <ctype.h> #include <ddraw.h> #include <mmsystem.h> #include <time.h>}#include <math.h>#include <dsound.h>#include <dinput.h>#include <winuser.h>#include "resource.h"#include "../cfg.h"#include "../input.h"/*December 17 2004 -NachI added some macros for inline assembly to keep compatibility between GCC and MSVCASM_BEGIN is to start an assembly sectionASM_END is to end itASM_COMMAND is for any simple command without a , in it example: dec eaxASM_COMMAND2 is when a command has a , for example: add ebx, 5ASM_COMMAND3 is when the parameter after the , is a variable example: mov eax, my_variableASM_CALL is for calling another function inside assembly sectionasm_call() can be treated like any C function, use it to call an assembly function from any normal C code.*/#ifdef __GNUC__ //MinGW//Simple start and end structure, set as volatile so perhaps we can use -O1+ later#define ASM_BEGIN asm volatile ( \ASM_COMMAND(pushad)#define ASM_END ASM_COMMAND(popad) \);//All commands need quotes and a newline and tab. C vars are _ prefixed#define ASM_COMMAND(line) #line"\n\t"#define ASM_COMMAND2(line, part2) #line", "#part2"\n\t"#define ASM_COMMAND3(line, var) #line", _"#var"\n\t"//Just for the prefix#define ASM_CALL(func) ASM_COMMAND(call _ ## func)//A function call is a simple register backup, call, restore#define asm_call(func) ASM_BEGIN \ASM_COMMAND(pushad) \ASM_CALL(func) \ASM_COMMAND(popad) \ASM_END#else //MSVC#define ASM_BEGIN _asm {#define ASM_END };//MSVC is all straight foward about these#define ASM_COMMAND(line) line#define ASM_COMMAND2(line, part2) line, part2#define ASM_COMMAND3(line, var) ASM_COMMAND2(line, var)//Next is not really special either#define ASM_CALL(func) ASM_COMMAND(call func)//Using this weird style because of MSVCs bad parsing#define asm_call(func) { _asm pushad \_asm call func \_asm popad };#endifDWORD WindowWidth = 256;DWORD WindowHeight = 224;DWORD FullScreen=0;DWORD Moving=0;DWORD SoundBufferSize=1024*18;DWORD FirstSound=1;int SoundEnabled=1;int UsePrimaryBuffer=0;DWORD FirstActivate = 1;#define BYTE unsigned char#define WORD unsigned short#define DWORD unsigned longHWND hMainWindow;HANDLE debugWindow = 0;extern "C"{HINSTANCE hInst;}LPDIRECTSOUND8 lpDirectSound = NULL;LPDIRECTSOUNDBUFFER8 lpSoundBuffer = NULL;LPDIRECTSOUNDBUFFER lpPrimaryBuffer = NULL;DSBUFFERDESC dsbd;LPVOID lpvPtr1;DWORD dwBytes1;LPVOID lpvPtr2;DWORD dwBytes2;LPDIRECTDRAW BasiclpDD = NULL;LPDIRECTDRAW7 lpDD = NULL;LPDIRECTDRAWSURFACE7 DD_Primary = NULL;LPDIRECTDRAWSURFACE7 DD_CFB = NULL;LPDIRECTDRAWSURFACE7 DD_CFB16 = NULL;LPDIRECTDRAWSURFACE7 DD_BackBuffer = NULL;LPDIRECTDRAWCLIPPER lpDDClipper = NULL;RECT rcWindow;LPDIRECTINPUT8 DInput = NULL;LPDIRECTINPUTDEVICE8 MouseInput = NULL;LPDIRECTINPUTDEVICE8 KeyboardInput = NULL;LPDIRECTINPUTDEVICE8 JoystickInput[5];DIJOYSTATE js[5];DWORD X1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD X2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD Y1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD Y2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD Z1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD Z2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD RX1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD RX2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD RY1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD RY2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD RZ1Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD RZ2Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD S01Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD S02Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD S11Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD S12Disable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD POVDisable[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD NumPOV[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD NumBTN[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};DWORD CurrentJoy=0;DWORD BitDepth;DWORD GBitMask;BYTE BackColor=0;DEVMODE mode;float MouseMinX=0;float MouseMaxX=256;float MouseMinY=0;float MouseMaxY=223;float MouseX;float MouseY;float MouseMoveX;float MouseMoveY;BYTE MouseButtonPressed;BYTE IsActivated=1;WORD PrevRes=0;RECT BlitArea;BYTE AltSurface=0;extern "C" {DWORD MouseButton;DWORD SurfaceX=0;DWORD SurfaceY=0;}HANDLE hLock, hThread;DWORD dwThreadId, dwThreadParam, semaphore_run;extern "C" {int SemaphoreMax = 5;void InitSemaphore();void ShutdownSemaphore();void DisplayWIPDisclaimer();void InitDebugger();void Clear2xSaIBuffer();void clear_display();}static char dinput8_dll[] = {"dinput8.dll\0"};static char dinput8_imp[] = {"DirectInput8Create\0"};static char ddraw_dll[] = {"ddraw.dll\0"};static char ddraw_imp[] = {"DirectDrawCreateEx\0"};static char dsound_dll[] = {"dsound.dll\0"};static char dsound_imp[] = {"DirectSoundCreate8\0"};static HMODULE hM_ddraw = NULL, hM_dsound = NULL,hM_dinput8 = NULL;typedef HRESULT (WINAPI* lpDirectInput8Create)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);static lpDirectInput8Create pDirectInput8Create;typedef HRESULT (WINAPI* lpDirectDrawCreateEx)( GUID FAR * lpGuid, LPVOID *lplpDD, REFIID iid,IUnknown FAR *pUnkOuter );static lpDirectDrawCreateEx pDirectDrawCreateEx;typedef HRESULT (WINAPI* lpDirectSoundCreate8)(LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter);static lpDirectSoundCreate8 pDirectSoundCreate8;extern "C" void FreeDirectX(){ FreeLibrary(hM_dsound); FreeLibrary(hM_ddraw); FreeLibrary(hM_dinput8); exit(0);}extern "C" void DXLoadError(){ if (MessageBox(NULL, "Sorry, you need to install or reinstall DirectX v8.0 or higher\nto use ZSNESW.\nWould you like to go to the DirectX homepage?", "Error", MB_ICONINFORMATION | MB_YESNO) == IDYES) { ShellExecute(NULL, NULL, "http://www.microsoft.com/directx/", NULL, NULL, 0); } FreeDirectX();}extern "C" void ImportDirectX(){ hM_dinput8 = LoadLibrary(dinput8_dll); if (hM_dinput8 == NULL) { DXLoadError(); } pDirectInput8Create = (lpDirectInput8Create) GetProcAddress(hM_dinput8, dinput8_imp); if (pDirectInput8Create == NULL) { char err[256]; wsprintf(err,"Failed to import %s:%s", dinput8_dll, dinput8_imp); MessageBox(NULL, err, "Error", MB_ICONERROR); DXLoadError(); } hM_ddraw = LoadLibrary(ddraw_dll); if (hM_ddraw == NULL) { char err[256]; wsprintf(err,"Failed to import %s",ddraw_dll); MessageBox(NULL, err,"Error",MB_ICONERROR); DXLoadError(); } pDirectDrawCreateEx = (lpDirectDrawCreateEx) GetProcAddress(hM_ddraw, ddraw_imp); if (pDirectDrawCreateEx == NULL) { char err[256]; wsprintf(err,"Failed to import %s:%s", ddraw_dll, ddraw_imp); MessageBox(NULL, err, "Error", MB_ICONERROR); DXLoadError(); } hM_dsound = LoadLibrary(dsound_dll); if (hM_dsound == NULL) { char err[256]; wsprintf(err,"Failed to import %s",dsound_dll); MessageBox(NULL, err,"Error",MB_ICONERROR); DXLoadError(); } pDirectSoundCreate8 = (lpDirectSoundCreate8) GetProcAddress(hM_dsound, dsound_imp); if (pDirectSoundCreate8 == NULL) { char err[256]; wsprintf(err,"Failed to import %s:%s", dsound_dll, dsound_imp); MessageBox(NULL, err, "Error", MB_ICONERROR); DXLoadError(); }}// milliseconds 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)double start, end, freq, update_ticks_pc, start2, end2, update_ticks_pc2;void ReleaseDirectDraw();void ReleaseDirectSound();void ReleaseDirectInput();int InitDirectDraw();int ReInitSound();extern "C"{ void drawscreenwin(void); DWORD LastUsedPos=0; DWORD CurMode=~0; void reInitSound() { ReInitSound(); }}void DDrawError(){ char message1[256]; sprintf(message1,"Error drawing to the screen\nMake sure the device is not being used by another process "); MessageBox (NULL, message1, "DirectDraw Error" , MB_ICONERROR );}extern "C" BYTE curblank;extern "C" WORD totlines;void DrawScreen(){ if (FullScreen == 1) { if (TripleBufferWin == 1 || KitchenSync == 1 || (KitchenSyncPAL == 1 && totlines == 314)) { if (DD_BackBuffer->Blt(&rcWindow, DD_CFB, &BlitArea, DDBLT_WAIT, NULL) == DDERR_SURFACELOST) DD_Primary->Restore(); if (DD_Primary->Flip(NULL, DDFLIP_WAIT) == DDERR_SURFACELOST) DD_Primary->Restore(); if (KitchenSync == 1 || (KitchenSyncPAL == 1 && totlines == 314)) { if (DD_BackBuffer->Blt(&rcWindow, DD_CFB, &BlitArea, DDBLT_WAIT, NULL) == DDERR_SURFACELOST) DD_Primary->Restore(); if (DD_Primary->Flip(NULL, DDFLIP_WAIT) == DDERR_SURFACELOST) DD_Primary->Restore(); } } else { if (vsyncon == 1 && curblank != 0x40) { if (lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL) != DD_OK) { DDrawError(); } } DD_Primary->Blt(&rcWindow, DD_CFB, &BlitArea, DDBLT_WAIT, NULL); DD_Primary->Restore(); } } else { if (vsyncon == 1) { if (lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL) != DD_OK) { DDrawError(); } } DD_Primary->Blt(&rcWindow, AltSurface == 0 ? DD_CFB : DD_CFB16, &BlitArea, DDBLT_WAIT, NULL); }}extern "C" {void MultiMouseInit();void MultiMouseShutdown();extern BYTE device1,device2;extern BYTE GUIOn;extern BYTE GUIOn2;DWORD InputEn=0;}BOOL InputAcquire(void){ if (JoystickInput[0]) JoystickInput[0]->Acquire(); if (JoystickInput[1]) JoystickInput[1]->Acquire(); if (JoystickInput[2]) JoystickInput[2]->Acquire(); if (JoystickInput[3]) JoystickInput[3]->Acquire(); if (JoystickInput[4]) JoystickInput[4]->Acquire(); if (device1 && device2 && !GUIOn2) MultiMouseInit(); else if (MouseInput && GUIOn2) MouseInput->Acquire(); if (KeyboardInput) KeyboardInput->Acquire(); InputEn = 1; return TRUE;}BOOL InputDeAcquire(void){ if (KeyboardInput) KeyboardInput->Unacquire(); if (JoystickInput[0]) JoystickInput[0]->Unacquire(); if (JoystickInput[1]) JoystickInput[1]->Unacquire(); if (JoystickInput[2]) JoystickInput[2]->Unacquire(); if (JoystickInput[3]) JoystickInput[3]->Unacquire(); if (JoystickInput[4]) JoystickInput[4]->Unacquire(); if (device1 && device2 && !GUIOn2) MultiMouseShutdown(); else if (MouseInput) MouseInput->Unacquire(); InputEn = 0; return TRUE;}extern "C" {void initwinvideo();void DosExit(void);extern BYTE EMUPause;extern int CurKeyPos;extern int CurKeyReadPos;extern int KeyBuffer[16];extern BYTE debugger;}extern "C" void CheckPriority(){ if (HighPriority == 1) { if(!SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS)) SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } else { SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); }}extern "C" void CheckAlwaysOnTop(){ if (AlwaysOnTop == 1) SetWindowPos(hMainWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); else SetWindowPos(hMainWindow, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);}extern "C" void CheckScreenSaver(){ if (DisableScreenSaver == 1 && IsActivated == 1) { SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, 0, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETLOWPOWERACTIVE, FALSE, 0, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETPOWEROFFACTIVE, FALSE, 0, SPIF_SENDCHANGE); } else { SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETLOWPOWERACTIVE, TRUE, 0, SPIF_SENDCHANGE); SystemParametersInfo(SPI_SETPOWEROFFACTIVE, TRUE, 0, SPIF_SENDCHANGE); }}extern "C" void MinimizeWindow(){ ShowWindow(hMainWindow, SW_MINIMIZE); IsActivated = 0;}BOOL InputRead(void){ static int PrevZ=0; MouseMoveX=0; MouseMoveY=0; if (MouseInput&&InputEn==1) { DIMOUSESTATE dims; HRESULT hr; hr=MouseInput->GetDeviceState(sizeof(DIMOUSESTATE),&dims); if (SUCCEEDED(hr)) { MouseMoveX=(float)dims.lX; MouseMoveY=(float)dims.lY; if (MouseWheel == 1) { long zDelta = dims.lZ-PrevZ; if (!dims.lZ) zDelta=0; while (zDelta>0){ zDelta-=40; if (!((CurKeyPos+1==CurKeyReadPos) || ((CurKeyPos+1==16) && (CurKeyReadPos==0)))){ KeyBuffer[CurKeyPos]=72+256; CurKeyPos++; if (CurKeyPos==16) CurKeyPos=0; } } while (zDelta<0){ zDelta+=40; if (!((CurKeyPos+1==CurKeyReadPos) || ((CurKeyPos+1==16) && (CurKeyReadPos==0)))){ KeyBuffer[CurKeyPos]=80+256; CurKeyPos++; if (CurKeyPos==16) CurKeyPos=0; } } PrevZ=dims.lZ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -