210 lines
3.7 KiB
C
210 lines
3.7 KiB
C
#include "doomkeys.h"
|
|
|
|
#include "doomgeneric.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <Windows.h>
|
|
|
|
static BITMAPINFO s_Bmi = { sizeof(BITMAPINFOHEADER), DOOMGENERIC_RESX, -DOOMGENERIC_RESY, 1, 32 };
|
|
static HWND s_Hwnd = 0;
|
|
static HDC s_Hdc = 0;
|
|
|
|
|
|
#define KEYQUEUE_SIZE 16
|
|
|
|
static unsigned short s_KeyQueue[KEYQUEUE_SIZE];
|
|
static unsigned int s_KeyQueueWriteIndex = 0;
|
|
static unsigned int s_KeyQueueReadIndex = 0;
|
|
|
|
static unsigned char convertToDoomKey(unsigned char key)
|
|
{
|
|
switch (key)
|
|
{
|
|
case VK_RETURN:
|
|
key = KEY_ENTER;
|
|
break;
|
|
case VK_ESCAPE:
|
|
key = KEY_ESCAPE;
|
|
break;
|
|
case VK_LEFT:
|
|
key = KEY_LEFTARROW;
|
|
break;
|
|
case VK_RIGHT:
|
|
key = KEY_RIGHTARROW;
|
|
break;
|
|
case VK_UP:
|
|
key = KEY_UPARROW;
|
|
break;
|
|
case VK_DOWN:
|
|
key = KEY_DOWNARROW;
|
|
break;
|
|
case VK_CONTROL:
|
|
key = KEY_FIRE;
|
|
break;
|
|
case VK_SPACE:
|
|
key = KEY_USE;
|
|
break;
|
|
case VK_SHIFT:
|
|
key = KEY_RSHIFT;
|
|
break;
|
|
default:
|
|
key = tolower(key);
|
|
break;
|
|
}
|
|
|
|
return key;
|
|
}
|
|
|
|
static void addKeyToQueue(int pressed, unsigned char keyCode)
|
|
{
|
|
unsigned char key = convertToDoomKey(keyCode);
|
|
|
|
unsigned short keyData = (pressed << 8) | key;
|
|
|
|
s_KeyQueue[s_KeyQueueWriteIndex] = keyData;
|
|
s_KeyQueueWriteIndex++;
|
|
s_KeyQueueWriteIndex %= KEYQUEUE_SIZE;
|
|
}
|
|
|
|
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_CLOSE:
|
|
DestroyWindow(hwnd);
|
|
break;
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
ExitProcess(0);
|
|
break;
|
|
case WM_KEYDOWN:
|
|
addKeyToQueue(1, wParam);
|
|
break;
|
|
case WM_KEYUP:
|
|
addKeyToQueue(0, wParam);
|
|
break;
|
|
default:
|
|
return DefWindowProcA(hwnd, msg, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void DG_Init()
|
|
{
|
|
// window creation
|
|
const char windowClassName[] = "DoomWindowClass";
|
|
const char windowTitle[] = "Doom";
|
|
WNDCLASSEXA wc;
|
|
|
|
wc.cbSize = sizeof(WNDCLASSEXA);
|
|
wc.style = 0;
|
|
wc.lpfnWndProc = wndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = 0;
|
|
wc.hIcon = 0;
|
|
wc.hCursor = 0;
|
|
wc.hbrBackground = 0;
|
|
wc.lpszMenuName = 0;
|
|
wc.lpszClassName = windowClassName;
|
|
wc.hIconSm = 0;
|
|
|
|
if (!RegisterClassExA(&wc))
|
|
{
|
|
printf("Window Registration Failed!");
|
|
|
|
exit(-1);
|
|
}
|
|
|
|
RECT rect;
|
|
rect.left = rect.top = 0;
|
|
rect.right = DOOMGENERIC_RESX;
|
|
rect.bottom = DOOMGENERIC_RESY;
|
|
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
|
|
|
|
HWND hwnd = CreateWindowExA(0, windowClassName, windowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
|
|
if (hwnd)
|
|
{
|
|
s_Hwnd = hwnd;
|
|
|
|
s_Hdc = GetDC(hwnd);
|
|
ShowWindow(hwnd, SW_SHOW);
|
|
}
|
|
else
|
|
{
|
|
printf("Window Creation Failed!");
|
|
|
|
exit(-1);
|
|
}
|
|
|
|
memset(s_KeyQueue, 0, KEYQUEUE_SIZE * sizeof(unsigned short));
|
|
}
|
|
|
|
void DG_DrawFrame()
|
|
{
|
|
MSG msg;
|
|
memset(&msg, 0, sizeof(msg));
|
|
|
|
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) > 0)
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessageA(&msg);
|
|
}
|
|
|
|
StretchDIBits(s_Hdc, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY, 0, 0, DOOMGENERIC_RESX, DOOMGENERIC_RESY, DG_ScreenBuffer, &s_Bmi, 0, SRCCOPY);
|
|
|
|
SwapBuffers(s_Hdc);
|
|
}
|
|
|
|
void DG_SleepMs(uint32_t ms)
|
|
{
|
|
Sleep(ms);
|
|
}
|
|
|
|
uint32_t DG_GetTicksMs()
|
|
{
|
|
return GetTickCount();
|
|
}
|
|
|
|
int DG_GetKey(int* pressed, unsigned char* doomKey)
|
|
{
|
|
if (s_KeyQueueReadIndex == s_KeyQueueWriteIndex)
|
|
{
|
|
//key queue is empty
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
unsigned short keyData = s_KeyQueue[s_KeyQueueReadIndex];
|
|
s_KeyQueueReadIndex++;
|
|
s_KeyQueueReadIndex %= KEYQUEUE_SIZE;
|
|
|
|
*pressed = keyData >> 8;
|
|
*doomKey = keyData & 0xFF;
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
void DG_SetWindowTitle(const char * title)
|
|
{
|
|
if (s_Hwnd)
|
|
{
|
|
SetWindowTextA(s_Hwnd, title);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
doomgeneric_Create(argc, argv);
|
|
|
|
for (int i = 0; ; i++)
|
|
{
|
|
doomgeneric_Tick();
|
|
}
|
|
|
|
|
|
return 0;
|
|
} |