📄 hardware.c
字号:
/* hardware.c, HAWK game engine
*
* This is the main file where the hardware, or OS specific code goes.
*
* Copyright 1997-1998 by Phil Frisbie, Jr.
* for Hawk Software
*
* All hardware specific code goes here
*
*/
#include <windows.h>
#include "hardware.h"
#include "hawk.h"
#include "internal.h"
#include <largeint.h>
#include "sound.h"
int Done = FALSE;
void cleanup(void);
/* Timer functions */
static unsigned int hardwareCounterFreq = 0;
static int counterFreq = 0;
void initTimer(int rate) /* Init a simulated game timer */
{
LARGE_INTEGER CounterFreq;
QueryPerformanceFrequency(&CounterFreq);
hardwareCounterFreq = CounterFreq.LowPart;
if (rate > 0)
counterFreq = rate;
else
counterFreq = 1000;
}
unsigned int readTimer(void) /* Read from the simulated timer */
{
LARGE_INTEGER time;
ULONG remainder;
if(!hardwareCounterFreq) /* timer not yet init */
return 0;
QueryPerformanceCounter(&time);
time = ExtendedIntegerMultiply(time, counterFreq);
time = ExtendedLargeIntegerDivide(time, hardwareCounterFreq, &remainder);
return time.LowPart;
}
unsigned int getTime(void) /* Get the current time in milliseconds */
{
LARGE_INTEGER time;
ULONG remainder;
if(!hardwareCounterFreq) /* timer not yet init */
return 0;
QueryPerformanceCounter(&time);
time = ExtendedIntegerMultiply(time, 1000);
time = ExtendedLargeIntegerDivide(time, hardwareCounterFreq, &remainder);
return time.LowPart;
}
unsigned int getElapsedTime(void)/* Get the elapsed milliseconds since last call */
{
LARGE_INTEGER time;
ULONG remainder;
unsigned int elapsed;
static LARGE_INTEGER last;
if(!hardwareCounterFreq) /* timer not yet init */
return 0;
QueryPerformanceCounter(&time);
time = ExtendedIntegerMultiply(time, 1000);
time = ExtendedLargeIntegerDivide(time, hardwareCounterFreq, &remainder);
time = LargeIntegerSubtract(time, last);
elapsed = time.LowPart;
last = time;
return elapsed;
}
void Mpause(unsigned int ms)/* pause for ms milliseconds */
{
unsigned int start;
if(!hardwareCounterFreq) /* timer not yet init */
return;
start = getTime();
while((getTime() - start)<ms);
}
/* Graphics/window functions */
int WINAPI MainWndProc (HWND, UINT, WPARAM, LPARAM);
int SetupPixelFormat(void);
CHAR szAppName[]="HAWK demo";
HWND hwnd;
HDC hdc;
HGLRC glrc;
int cmdshow;
HINSTANCE instance;
HINSTANCE prevInstance;
int resizable;
void setWindowVars(void *i, void *p, int s)
{
instance = i;
prevInstance = p;
cmdshow = s;
}
int createWindow(unsigned int w, unsigned int h)
{
WNDCLASS wndclass;
resizable = TRUE;
/* Register the frame class */
wndclass.style = CS_OWNDC;
wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = instance;
wndclass.hIcon = 0;
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
return FALSE;
if(Engine.mode&EN_FULL_SCREEN) /* full screen mode */
{
DEVMODE dmode;
int modenum;
BOOL modeswitch;
LONG changeResult;
/* set the screen size/depth */
modenum = 0;
do
{
modeswitch = !EnumDisplaySettings(NULL, modenum, &dmode );
if(dmode.dmBitsPerPel == Engine.colorbits &&
dmode.dmPelsWidth == w &&
dmode.dmPelsHeight == h) break;
modenum++;
} while(!modeswitch);
if(modeswitch) /* didn't find mode */
{
ChangeDisplaySettings (NULL, 0);
MessageBox (NULL, "Didn't find good fullscreen mode", "Error", MB_OK | MB_ICONERROR);
return 0;
}
dmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
changeResult = ChangeDisplaySettings (&dmode, CDS_TEST);
switch (changeResult)
{
case DISP_CHANGE_SUCCESSFUL:
ChangeDisplaySettings (&dmode, CDS_FULLSCREEN);
break;
case DISP_CHANGE_FAILED:
MessageBox (NULL, "Failed to change to desired settings", "Error", MB_OK | MB_ICONERROR);
return 0;
case DISP_CHANGE_BADMODE:
MessageBox (NULL, "That fullscreen mode is not supported", "Error", MB_OK | MB_ICONERROR);
return 0;
case DISP_CHANGE_RESTART:
MessageBox (NULL, "Must restart to get that Fullscreen setting", "Error", MB_OK | MB_ICONERROR);
return 0;
}
/* Create the frame */
hwnd = CreateWindowEx(
WS_EX_TOPMOST,
szAppName,
szAppName,
WS_POPUP | WS_MAXIMIZE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0,
Engine.w,
Engine.h,
NULL,
NULL,
instance,
NULL );
/* make sure window was created */
if(!hwnd)
return FALSE;
/* show and update main window */
ShowWindow(hwnd, cmdshow);
UpdateWindow(hwnd);
}
else
{
/* adust the w and h for a windowed app */
h += GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME) * 2;
w += GetSystemMetrics(SM_CXDLGFRAME) * 2;
/* Create the frame */
hwnd = CreateWindow (szAppName,
szAppName,
WS_BORDER | WS_DLGFRAME | WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
w,
h,
NULL,
NULL,
instance,
NULL);
/* make sure window was created */
if(!hwnd)
return FALSE;
/* show and update main window */
ShowWindow (hwnd, cmdshow);
UpdateWindow (hwnd);
}
if (!SetupPixelFormat())
PostQuitMessage(0);
SetFocus(hwnd);
return TRUE;
}
void swapBuffers(void)
{
SwapBuffers(hdc);
}
int messageLoop(void)
{
MSG msg;
while (1)
{
if(Done)
PostMessage(hwnd, WM_DESTROY, 0, 0);
/* Poll events without blocking */
while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0))
{
/* time to exit */
cleanup();
return(0);
}
/* TranslateMessage(&msg); */
DispatchMessage(&msg);
}
HAWK_Update();
swapBuffers();
}
return(0);
}
int WINAPI MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 1;
PAINTSTRUCT ps;
RECT rect;
int w, h;
static BOOL Right = TRUE;
switch (uMsg)
{
case WM_CREATE:
hdc = GetDC(hWnd);
break;
case WM_ACTIVATE:
if ( LOWORD(wParam)==WA_INACTIVE )
wglMakeCurrent(hdc, NULL);
else
wglMakeCurrent(hdc, glrc);
break;
case WM_SIZE:
GetClientRect(hWnd, &rect);
w = rect.right - rect.left;
h = rect.bottom - rect.top;
if(w && h && resizable)
reshape(w, h);
InvalidateRect(hWnd,NULL,TRUE);
break;
case WM_PAINT:
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
if(glrc)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(glrc);
glrc = NULL;
}
if(hdc)
{
ReleaseDC(hWnd, hdc);
hdc = NULL;
}
if(Engine.mode&EN_FULL_SCREEN)
ChangeDisplaySettings(NULL, 0);
PostQuitMessage(0);
break;
default:
lRet = DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return lRet;
}
int SetupPixelFormat(void)
{
PIXELFORMATDESCRIPTOR *ppfd;
int pixelformat;
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
1, /* version number */
PFD_DRAW_TO_WINDOW | /* support window */
PFD_SUPPORT_OPENGL | /* support OpenGL */
PFD_DOUBLEBUFFER, /* double buffered */
PFD_TYPE_RGBA, /* RGBA type */
Engine.colorbits, /* color depth */
0, 0, 0, 0, 0, 0, /* color bits ignored */
0, /* no alpha buffer */
0, /* shift bit ignored */
0, /* no accumulation buffer */
0, 0, 0, 0, /* accum bits ignored */
Engine.zbufferbits, /* z-buffer depth */
0, /* no stencil buffer */
0, /* no auxiliary buffer */
PFD_MAIN_PLANE, /* main layer */
0, /* reserved */
0, 0, 0 /* layer masks ignored */
};
pfd.cColorBits = GetDeviceCaps(hdc,BITSPIXEL);
ppfd = &pfd;
if((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0)
{
MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
return FALSE;
}
if(SetPixelFormat(hdc, pixelformat, ppfd) == FALSE)
{
MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
return FALSE;
}
glrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, glrc);
return TRUE;
}
/* Input functions */
JOYCAPS joycaps;
void initInput(void) /* Init all the input devices */
{
JOYINFOEX joyinfo;
MMRESULT result;
/* check to see if a joystick driver is loaded */
memset(&Joyinfo, 0, sizeof(JOYSTICKINFO));
Joyinfo.numjoy = (int)joyGetNumDevs();
if(Joyinfo.numjoy)
{
/* make sure a joystick is plugged in */
joyinfo.dwSize = sizeof(JOYINFOEX);
joyinfo.dwFlags = JOY_RETURNALL;
result = joyGetPosEx(JOYSTICKID1, &joyinfo);
if(result != JOYERR_NOERROR)
{
Joyinfo.numjoy = 0;
return;
}
/* find out what the joystick can do */
result = joyGetDevCaps(JOYSTICKID1, &joycaps, sizeof(JOYCAPS));
if(result == JOYERR_NOERROR)
{
Joyinfo.numbuttons = joycaps.wNumButtons;
Joyinfo.name = TagMalloc(strlen(joycaps.szPname) + 1, TAG_GAME);
strcpy(Joyinfo.name, joycaps.szPname);
Joyinfo.hat = (BOOL)(joycaps.wCaps & JOYCAPS_HASPOV);
}
}
}
void getKeys(unsigned char *keys) /* Get the current key status */
{
int i;
GetKeyboardState(keys);
/* convert to BOOL */
for(i=0;i<256;i++)
{
if(keys[i] & 0x80)
keys[i] = 1;
else keys[i] = 0;
}
}
void getMouse(MOUSE *mouse) /* Get current mouse status */
{
POINT point;
static int visable = TRUE;
GetCursorPos(&point);
ScreenToClient(hwnd, &point);
if(point.y < 10) /* cursor is outside our window */
{
if(!visable)
{
ShowCursor(TRUE);
visable = TRUE;
}
}
else
if(visable)
{
ShowCursor(FALSE);
visable = FALSE;
}
mouse->x = max(0, min(point.x, Engine.w));
mouse->y = max(0, min(point.y, Engine.h));
mouse->lbutton = (Keys[VK_LBUTTON] & 0x80);
mouse->mbutton = (Keys[VK_MBUTTON] & 0x80);
mouse->rbutton = (Keys[VK_RBUTTON] & 0x80);
}
#define JOY_POLL GAME_TICKS/10
void getJoy(JOY *joy)
{
static lastpoll = 0;
JOYINFOEX joyinfo;
MMRESULT result;
if(!lastpoll)/* first time through */
{
lastpoll = Engine.gameframes;
return;
}
/* only poll joystick 10 times per second */
if(lastpoll + JOY_POLL > Engine.gameframes)
return;
/* clear out the old info */
memset(joy, 0, sizeof(JOY));
/* return if no joystick */
if(Joyinfo.numjoy < 1)
return;
/* get the current status */
joyinfo.dwSize = sizeof(JOYINFOEX);
joyinfo.dwFlags = JOY_RETURNALL;
result = joyGetPosEx(JOYSTICKID1, &joyinfo);
if(result != JOYERR_NOERROR)
return;
/* convert to our format */
if(joyinfo.dwXpos < 16384)
joy->joyleft = TRUE;
else if(joyinfo.dwXpos > 65535-16384)
joy->joyright = TRUE;
if(joyinfo.dwYpos < 16384)
joy->joyforward = TRUE;
else if(joyinfo.dwYpos > 65535-16384)
joy->joyback = TRUE;
if(joyinfo.dwPOV == JOY_POVLEFT)
joy->hatleft = TRUE;
if(joyinfo.dwPOV == JOY_POVRIGHT)
joy->hatright = TRUE;
if(joyinfo.dwPOV == JOY_POVFORWARD)
joy->hatforward = TRUE;
if(joyinfo.dwPOV == JOY_POVBACKWARD)
joy->hatback = TRUE;
joy->button1 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON1);
joy->button2 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON2);
joy->button3 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON3);
joy->button4 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON4);
joy->button5 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON5);
joy->button6 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON6);
joy->button7 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON7);
joy->button8 = (BOOL)(joyinfo.dwButtons & JOY_BUTTON8);
}
/* misc. functions */
BOOL initSound(void)
{
if(!sndEnable(hwnd))
return FALSE;
return TRUE;
}
void printdebug(char *string, ...)
{
char buffer[256];
va_list args;
OutputDebugString("***HAWK Info: ");
va_start(args, string);
vsprintf(buffer, string, args);
va_end(args);
OutputDebugString(buffer);
}
/* Anything you want to do at exit goes here */
void cleanup(void)
{
logf("\n\nNormal shutdown in progress\n");
memShutdown();
closePAKfile();
}
void fatalError(char *error, ...)
{
va_list argptr;
char text[1024];
va_start(argptr, error);
vsprintf(text, error, argptr);
va_end(argptr);
logf(text);
MessageBox(NULL, text, "Error", 0 /* MB_OK */ );
exit(1);
}
/* this is optional, but good for debugging when logging is enabled */
void systemInfo(void)
{
OSVERSIONINFO os;
MEMORYSTATUS mem;
DWORD totalmem, freemem;
char *env;
/* get the OS info */
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&os);
switch(os.dwPlatformId)
{
case VER_PLATFORM_WIN32s:
logf("Windows 3.1 with Win32s version %d.%d\n\n", os.dwMajorVersion, os.dwMinorVersion);
break;
case VER_PLATFORM_WIN32_WINDOWS:
logf("Windows 95/98 version %d.%d build %d %s\n\n", os.dwMajorVersion,
os.dwMinorVersion, LOWORD(os.dwBuildNumber), os.szCSDVersion);
break;
case VER_PLATFORM_WIN32_NT:
logf("Windows NT version %d.%d build %d %s\n\n", os.dwMajorVersion,
os.dwMinorVersion, LOWORD(os.dwBuildNumber), os.szCSDVersion);
break;
}
/* get the memory info */
mem.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&mem);
totalmem = (mem.dwTotalPhys + mem.dwTotalPageFile>>20);
freemem = (mem.dwAvailPhys + mem.dwAvailPageFile)>>20;
logf("Total physical memory %d MB, free physical memory %d MB\n",
mem.dwTotalPhys>>20, mem.dwAvailPhys>>20);
logf("Total virtual memory %d MB, free virtual memory %d MB\n\n", totalmem, freemem);
if(0)
{
/* get the environment strings */
env = (char *)GetEnvironmentStrings();
if(env)
{
logf("Environment strings:\n");
while(env[0])
{
logf("%s\n", env);
env += (strlen(env) + 1);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -