📄 winlink.cpp
字号:
//Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later
//version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define DIRECTINPUT_VERSION 0x0800
#define DIRECTSOUND_VERSION 0x0800
extern "C" {
#include <windows.h>
#include <stdio.h>
#include <ddraw.h>
#include <initguid.h>
#include <mmsystem.h>
#include <time.h>
}
#include <math.h>
#include <dsound.h>
#include <dinput.h>
#include <winuser.h>
#include "resource.h"
#include <fstream.h>
DWORD WindowWidth = 256;
DWORD WindowHeight = 224;
DWORD FullScreen=0;
DWORD Moving=0;
DWORD SoundBufferSize=1024*18;
DWORD FirstSound=1;
int AllowDefault=0;
int SoundEnabled=1;
DWORD FirstActivate = 1;
#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned long
HWND hMainWindow;
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_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;
int MouseMove2X;
int MouseMove2Y;
DWORD SurfaceX=0;
DWORD SurfaceY=0;
BYTE IsActivated = 1;
BYTE AltTimer = 0;
extern "C" {
DWORD MouseButton;
}
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 ImportDirectX()
{
hM_dinput8 = LoadLibrary(dinput8_dll);
if (hM_dinput8 == NULL)
{
if (MessageBox(NULL, "Sorry, you need DirectX v8.0 or higher to use\nZSNESW. Would 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();
}
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);
FreeDirectX();
}
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);
FreeDirectX();
}
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);
FreeDirectX();
}
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);
FreeDirectX();
}
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);
FreeDirectX();
}
}
#define UPDATE_TICKS_GAME 1000.855001760297741789468390082/60 // milliseconds per world update
#define UPDATE_TICKS_GAMEPAL 1000/50 // milliseconds per world update
#define UPDATE_TICKS_GUI 1000/36 // milliseconds per world update
#define UPDATE_TICKS_UDP 1000/60 // milliseconds per world update
_int64 start, end, freq, update_ticks_pc, start2, end2, update_ticks_pc2;
void ReleaseDirectDraw();
void ReleaseDirectSound();
void ReleaseDirectInput();
extern "C"
{
void drawscreenwin(void);
DWORD LastUsedPos=0;
DWORD CurMode=-1;
}
void DDrawError(){
char message1[256];
sprintf(message1,"Error drawing to the screen\nMake sure the device is not being used by another process \0");
MessageBox (NULL, message1, "DirectDraw Error" , MB_ICONERROR );
}
extern "C" BYTE vsyncon;
extern "C" BYTE TripleBufferWin;
void DrawScreen()
{
if (FullScreen == 1)
{
if (TripleBufferWin == 1)
{
DD_BackBuffer->Blt(NULL, DD_CFB, NULL, DDBLT_WAIT, NULL);
DD_Primary->Flip(NULL, DDFLIP_WAIT);
}
else
{
if (vsyncon == 1)
{
if (lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL) != DD_OK)
{
DDrawError();
}
}
DD_Primary->Blt(&rcWindow, DD_CFB, NULL, DDBLT_WAIT, NULL);
}
}
else
{
if (vsyncon == 1)
{
if (lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL) != DD_OK)
{
DDrawError();
}
}
DD_Primary->Blt(&rcWindow, DD_CFB, NULL, DDBLT_WAIT, NULL);
}
}
DWORD InputEn=0;
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 (MouseInput) MouseInput->Acquire();
if (KeyboardInput) KeyboardInput->Acquire();
InputEn=1;
return TRUE;
}
BOOL InputDeAcquire(void)
{
if (MouseInput) { MouseInput->Unacquire(); }
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();
InputEn=0;
return TRUE;
}
extern "C" {
unsigned char keyboardhit=0;
void initwinvideo();
void DosExit();
extern BYTE StereoSound;
extern DWORD SoundQuality;
extern BYTE LargeSoundBuf;
extern BYTE ExclusiveSound;
extern BYTE HighPriority;
extern BYTE AlwaysOnTop;
extern BYTE SaveMainWindowPos;
extern BYTE AlternateTimer;
extern BYTE AllowMultipleInst;
extern BYTE DisableScreenSaver;
extern signed short int MainWindowX;
extern signed short int MainWindowY;
extern int CurKeyPos;
extern int CurKeyReadPos;
extern int KeyBuffer[16];
}
extern "C" void CheckPriority()
{
if (HighPriority == 1) 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);
else SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, TRUE, 0, SPIF_SENDCHANGE);
}
extern "C" void MinimizeWindow()
{
ShowWindow(hMainWindow, SW_MINIMIZE);
IsActivated = 0;
}
extern "C" BYTE MouseWheel;
BOOL InputRead(void)
{
static PrevZ=0;
MouseMoveX=0;
MouseMoveY=0;
if (MouseInput&&InputEn==1)
{
DIMOUSESTATE dims;
HRESULT hr;
aquireagain:;
hr=MouseInput->GetDeviceState(sizeof(DIMOUSESTATE),&dims);
if (hr==DIERR_INPUTLOST)
{
hr=MouseInput->Acquire();
if (SUCCEEDED(hr))
{
goto aquireagain;
}
}
if (SUCCEEDED(hr))
{
MouseMoveX=dims.lX;
MouseMoveY=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;
}
MouseButton=(dims.rgbButtons[0]>>7)|(dims.rgbButtons[1]>>6)|(dims.rgbButtons[2]>>5)|(dims.rgbButtons[3]>>4);
}
else
{
return FALSE;
}
}
return TRUE;
}
void ExitFunction()
{
IsActivated = 0;
CheckScreenSaver();
ReleaseDirectInput();
ReleaseDirectSound();
ReleaseDirectDraw();
DestroyWindow(hMainWindow);
}
LRESULT CALLBACK Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static bool shiftpr;
bool accept;
int vkeyval;
short zDelta;
switch (uMsg)
{
case WM_KEYDOWN: // sent when user presses a key
if (!((CurKeyPos+1==CurKeyReadPos) || ((CurKeyPos+1==16)
&& (CurKeyReadPos==0)))){
accept=false;
if (wParam==16)
shiftpr=true;
if (((wParam>='A') && (wParam<='Z')) ||
((wParam>='a') && (wParam<='z')) || (wParam==27) ||
(wParam==32) || (wParam==8) || (wParam==13) || (wParam==9)) {
accept=true; vkeyval=wParam;
}
if ((wParam>='0') && (wParam<='9')) {
accept=true; vkeyval=wParam;
if (shiftpr) {
switch (wParam) {
case '1': vkeyval='!'; break;
case '2': vkeyval='@'; break;
case '3': vkeyval='#'; break;
case '4': vkeyval='$'; break;
case '5': vkeyval='%'; break;
case '6': vkeyval='^'; break;
case '7': vkeyval='&'; break;
case '8': vkeyval='*'; break;
case '9': vkeyval='('; break;
case '0': vkeyval=')'; break;
}
}
}
if ((wParam>=VK_NUMPAD0) && (wParam<=VK_NUMPAD9)) {
accept=true; vkeyval=wParam-VK_NUMPAD0+'0';
}
if (!shiftpr){
switch (wParam) {
case 189: vkeyval='-'; accept=true; break;
case 187: vkeyval='='; accept=true; break;
case 219: vkeyval='['; accept=true; break;
case 221: vkeyval=']'; accept=true; break;
case 186: vkeyval=';'; accept=true; break;
case 222: vkeyval=39; accept=true; break;
case 188: vkeyval=','; accept=true; break;
case 190: vkeyval='.'; accept=true; break;
case 191: vkeyval='/'; accept=true; break;
case 192: vkeyval='`'; accept=true; break;
case 220: vkeyval=92; accept=true; break;
}
} else {
switch (wParam) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -