Skip to content

Instantly share code, notes, and snippets.

@ChlorUpload
Last active October 8, 2024 18:17
Show Gist options
  • Save ChlorUpload/8c560f72cbd4222bdaff90a99db6ff40 to your computer and use it in GitHub Desktop.
Save ChlorUpload/8c560f72cbd4222bdaff90a99db6ff40 to your computer and use it in GitHub Desktop.
A Game loop using PeekMessage function
// Set project as empty windows project.
// A game loop using PeekMessage function.
// Uses double buffering.
#include <Windows.h>
#include <time.h>
#include <math.h>
#pragma comment(lib, "winmm.lib")
#define __FPS 60
int FRAMES;
void Update();
void Render();
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
WCHAR lpszName[MAX_PATH] = L"Gravity Simulation";
int sw, sh;
int window;
HDC hScreenDC;
HDC hRenderDC;
HBITMAP hBitmap;
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow
)
{
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance = hInstance;
WndClass.lpfnWndProc = (WNDPROC)WndProc;
WndClass.lpszClassName = lpszName;
WndClass.lpszMenuName = NULL;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd = CreateWindow(lpszName, lpszName, WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
window = sh * 2 / 3;
hScreenDC = GetDC(hWnd);
hRenderDC = CreateCompatibleDC(hScreenDC);
hBitmap = CreateBitmap(window, window, 1, 32, NULL);
SelectObject(hRenderDC, hBitmap);
PatBlt(hRenderDC, 0, 0, window, window, WHITENESS);
FRAMES = 0;
const int TICKS_PER_SECOND = __FPS;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
timeBeginPeriod(1);
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
DWORD next_game_tick = timeGetTime();
srand((unsigned int)time(NULL));
while (true)
{
if (PeekMessage(&Message, 0, 0, 0, PM_REMOVE))
{
if (Message.message == WM_QUIT) break;
TranslateMessage(&Message);
DispatchMessage(&Message);
}
else
{
Sleep(1);
if (timeGetTime() > next_game_tick)
{
FRAMES++;
Update();
Render();
next_game_tick += SKIP_TICKS;
}
}
}
timeEndPeriod(1);
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage)
{
case WM_CREATE:
sw = GetSystemMetrics(SM_CXSCREEN);
sh = GetSystemMetrics(SM_CYSCREEN);
MoveWindow(hWnd, sw / 2 - sh / 3, sh / 6, sh * 2 / 3, sh * 2 / 3, TRUE);
break;
case WM_RBUTTONUP:
MessageBox(hWnd, L"Quit Program", L"Simulation Notice", MB_OK);
case WM_DESTROY:
DeleteDC(hScreenDC);
DeleteDC(hRenderDC);
DeleteObject(hBitmap);
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
int x = 100, y = 100, r = 10;
void Update()
{
PatBlt(hRenderDC, 0, 0, window, window, WHITENESS);
SelectObject(hRenderDC, GetStockObject(LTGRAY_BRUSH));
x = (int)(window / 2 + window / 5 * cos(4 * 3.14 * FRAMES / 1000));
y = (int)(window / 2 + window / 3 * sin(4 * 3.14 * FRAMES / 1000));
Ellipse(hRenderDC, x - r, y - r, x + r, y + r);
}
WCHAR framestr[MAX_PATH];
void Render()
{
BitBlt(hScreenDC, 0, 0, window, window, hRenderDC, 0, 0, SRCCOPY);
wsprintf(framestr, L"FRAME : %d", FRAMES);
TextOut(hScreenDC, 4, 0, framestr, wcslen(framestr));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment