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

📄 hardware.c

📁 著名物理引擎Hawk的源代码
💻 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 + -