Separate dchip update from rendering
This commit is contained in:
parent
1c4c6d3dca
commit
de4365126d
@ -18,6 +18,9 @@
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\unity_build.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{01B5A474-4BA5-48A3-B645-7116ADF5585D}</ProjectGuid>
|
||||
<RootNamespace>dchip8</RootNamespace>
|
||||
@ -119,9 +122,6 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\dchip-8.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
@ -15,7 +15,7 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\dchip-8.cpp">
|
||||
<ClCompile Include="src\unity_build.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "stdint.h"
|
||||
|
||||
#define LOCAL_PERSIST static
|
||||
#define GLOBAL_VAR static
|
||||
#define FILE_SCOPE static
|
||||
|
||||
typedef uint32_t u32;
|
||||
|
@ -2,7 +2,8 @@
|
||||
@REM vcvarsall.bat to setup command-line compiler.
|
||||
|
||||
@echo OFF
|
||||
set ProjectName=dchip-8
|
||||
set ProjectName=dchip8
|
||||
set CompileEntryPoint=..\src\unity_build.cpp
|
||||
|
||||
ctime -begin %ProjectName%.ctm
|
||||
|
||||
@ -47,7 +48,7 @@ REM incrmenetal:no, turn incremental builds off
|
||||
REM opt:ref, try to remove functions from libs that are referenced at all
|
||||
set LinkFlags=-incremental:no -opt:ref
|
||||
|
||||
cl %CompileFlags% ..\src\%ProjectName%.cpp %IncludeFlags% /link -subsystem:WINDOWS,5.1 %LinkLibraries% %LinkFlags% /nologo /OUT:"%ProjectName%.exe"
|
||||
cl %CompileFlags% %CompileEntryPoint% %IncludeFlags% /link -subsystem:WINDOWS,5.1 %LinkLibraries% %LinkFlags% /nologo /OUT:"%ProjectName%.exe"
|
||||
|
||||
popd
|
||||
ctime -end %ProjectName%.ctm
|
||||
|
241
src/dchip-8.cpp
241
src/dchip-8.cpp
@ -1,241 +0,0 @@
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
FILE_SCOPE HBITMAP bitmap;
|
||||
FILE_SCOPE BITMAPINFO bitmapInfo;
|
||||
|
||||
const i32 WIDTH = 64;
|
||||
const i32 HEIGHT = 32;
|
||||
const i32 RESOLUTION = WIDTH * HEIGHT;
|
||||
FILE_SCOPE void *bitmapMemory;
|
||||
|
||||
FILE_SCOPE bool globalRunning = false;
|
||||
|
||||
FILE_SCOPE LRESULT CALLBACK mainWindowProcCallback(HWND window, UINT msg,
|
||||
WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
LRESULT result = 0;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
case WM_DESTROY:
|
||||
{
|
||||
globalRunning = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
result = DefWindowProc(window, msg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GLOBAL_VAR LARGE_INTEGER globalQueryPerformanceFrequency;
|
||||
inline FILE_SCOPE f32 getTimeFromQueryPerfCounter(LARGE_INTEGER start,
|
||||
LARGE_INTEGER end)
|
||||
{
|
||||
f32 result = (f32)(end.QuadPart - start.QuadPart) /
|
||||
globalQueryPerformanceFrequency.QuadPart;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE LARGE_INTEGER getWallClock()
|
||||
{
|
||||
LARGE_INTEGER result;
|
||||
QueryPerformanceCounter(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define ErrorBox(text, title) MessageBox(nullptr, text, title, MB_OK);
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
WNDCLASSEX wc =
|
||||
{
|
||||
sizeof(WNDCLASSEX),
|
||||
CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||
mainWindowProcCallback,
|
||||
0, // int cbClsExtra
|
||||
0, // int cbWndExtra
|
||||
hInstance,
|
||||
LoadIcon(NULL, IDI_APPLICATION),
|
||||
LoadCursor(NULL, IDC_ARROW),
|
||||
GetSysColorBrush(COLOR_3DFACE),
|
||||
L"", // LPCTSTR lpszMenuName
|
||||
L"dchip-8Class",
|
||||
NULL, // HICON hIconSm
|
||||
};
|
||||
|
||||
if (!RegisterClassEx(&wc)) {
|
||||
ErrorBox(L"RegisterClassEx() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
globalRunning = true;
|
||||
|
||||
// NOTE: Regarding Window Sizes
|
||||
// If you specify a window size, e.g. 800x600, Windows regards the 800x600
|
||||
// region to be inclusive of the toolbars and side borders. So in actuality,
|
||||
// when you blit to the screen blackness, the area that is being blitted to
|
||||
// is slightly smaller than 800x600. Windows provides a function to help
|
||||
// calculate the size you'd need by accounting for the window style.
|
||||
RECT rect = {};
|
||||
rect.right = 128;
|
||||
rect.bottom = 64;
|
||||
|
||||
DWORD windowStyle =
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
AdjustWindowRect(&rect, windowStyle, FALSE);
|
||||
|
||||
HWND mainWindow = CreateWindowEx(
|
||||
WS_EX_COMPOSITED, wc.lpszClassName, L"dchip-8", windowStyle,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
|
||||
rect.bottom - rect.top, nullptr, nullptr, hInstance, nullptr);
|
||||
|
||||
if (!mainWindow)
|
||||
{
|
||||
ErrorBox(L"CreateWindowEx() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
QueryPerformanceFrequency(&globalQueryPerformanceFrequency);
|
||||
LARGE_INTEGER startFrameTime;
|
||||
const f32 targetFramesPerSecond = 16.0f;
|
||||
f32 targetSecondsPerFrame = 1 / targetFramesPerSecond;
|
||||
f32 frameTimeInS = 0.0f;
|
||||
|
||||
{
|
||||
BITMAPINFOHEADER header = {};
|
||||
header.biSize = sizeof(BITMAPINFOHEADER);
|
||||
header.biWidth = WIDTH;
|
||||
header.biHeight = HEIGHT;
|
||||
header.biPlanes = 1;
|
||||
header.biBitCount = 32;
|
||||
header.biCompression = BI_RGB; // uncompressed bitmap
|
||||
header.biSizeImage = 0;
|
||||
header.biXPelsPerMeter = 0;
|
||||
header.biYPelsPerMeter = 0;
|
||||
header.biClrUsed = 0;
|
||||
header.biClrImportant = 0;
|
||||
|
||||
bitmapInfo.bmiHeader = header;
|
||||
|
||||
const i32 numPixels = header.biWidth * header.biHeight;
|
||||
const i32 bytesPerPixel = header.biBitCount / 8;
|
||||
#if 0
|
||||
bitmapMemory = calloc(1, numPixels * bytesPerPixel);
|
||||
|
||||
if (!bitmapMemory)
|
||||
{
|
||||
ErrorBox(L"malloc() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
HDC deviceContext = GetDC(mainWindow);
|
||||
bitmap = CreateDIBSection(deviceContext, &bitmapInfo, DIB_RGB_COLORS,
|
||||
&bitmapMemory, NULL, NULL);
|
||||
ReleaseDC(mainWindow, deviceContext);
|
||||
|
||||
if (!bitmapMemory)
|
||||
{
|
||||
ErrorBox(L"CreateDIBSection() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
u32 *bitmapBuffer = (u32 *)bitmapMemory;
|
||||
for (i32 i = 0; i < numPixels; i++)
|
||||
{
|
||||
// NOTE: Win32 AlphaBlend requires the RGB components to be
|
||||
// premultiplied with alpha.
|
||||
f32 normA = 1.0f;
|
||||
f32 normR = (normA * 0.0f);
|
||||
f32 normG = (normA * 0.0f);
|
||||
f32 normB = (normA * 1.0f);
|
||||
|
||||
u8 r = (u8)(normR * 255.0f);
|
||||
u8 g = (u8)(normG * 255.0f);
|
||||
u8 b = (u8)(normB * 255.0f);
|
||||
u8 a = (u8)(normA * 255.0f);
|
||||
|
||||
u32 color = (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||
bitmapBuffer[i] = color;
|
||||
}
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
while (globalRunning)
|
||||
{
|
||||
startFrameTime = getWallClock();
|
||||
while (PeekMessage(&msg, mainWindow, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
RECT clientRect = {};
|
||||
GetClientRect(mainWindow, &clientRect);
|
||||
|
||||
LONG clientWidth = clientRect.right - clientRect.left;
|
||||
LONG clientHeight = clientRect.bottom - clientRect.top;
|
||||
|
||||
BLENDFUNCTION blend = {};
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.SourceConstantAlpha = 255;
|
||||
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
HDC deviceContext = GetDC(mainWindow);
|
||||
HDC alphaBlendDC = CreateCompatibleDC(deviceContext);
|
||||
SelectObject(alphaBlendDC, bitmap);
|
||||
|
||||
AlphaBlend(deviceContext, 0, 0, WIDTH, HEIGHT, alphaBlendDC, 0, 0,
|
||||
WIDTH, HEIGHT, blend);
|
||||
StretchBlt(deviceContext, 0, 0, clientWidth, clientHeight,
|
||||
deviceContext, 0, 0, WIDTH, HEIGHT, SRCCOPY);
|
||||
|
||||
DeleteDC(alphaBlendDC);
|
||||
ReleaseDC(mainWindow, deviceContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Frame Limiting
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
LARGE_INTEGER endWorkTime = getWallClock();
|
||||
f32 workTimeInS =
|
||||
getTimeFromQueryPerfCounter(startFrameTime, endWorkTime);
|
||||
if (workTimeInS < targetSecondsPerFrame)
|
||||
{
|
||||
DWORD remainingTimeInMs =
|
||||
(DWORD)((targetSecondsPerFrame - workTimeInS) * 1000);
|
||||
Sleep(remainingTimeInMs);
|
||||
}
|
||||
|
||||
LARGE_INTEGER endFrameTime = getWallClock();
|
||||
frameTimeInS =
|
||||
getTimeFromQueryPerfCounter(startFrameTime, endFrameTime);
|
||||
f32 msPerFrame = 1000.0f * frameTimeInS;
|
||||
|
||||
wchar_t windowTitleBuffer[128] = {};
|
||||
_snwprintf_s(windowTitleBuffer, ARRAY_COUNT(windowTitleBuffer),
|
||||
ARRAY_COUNT(windowTitleBuffer), L"dchip-8 | %5.2f ms/f",
|
||||
msPerFrame);
|
||||
SetWindowText(mainWindow, windowTitleBuffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
27
src/dchip8.cpp
Normal file
27
src/dchip8.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "common.h"
|
||||
#include "dchip8_platform.h"
|
||||
|
||||
void dchip8_update(PlatformRenderBuffer *renderBuffer)
|
||||
{
|
||||
ASSERT(renderBuffer.bytesPerPixel == 4);
|
||||
|
||||
const i32 numPixels = renderBuffer->width * renderBuffer->height;
|
||||
u32 *bitmapBuffer = (u32 *)renderBuffer->memory;
|
||||
for (i32 i = 0; i < numPixels; i++)
|
||||
{
|
||||
// NOTE: Win32 AlphaBlend requires the RGB components to be
|
||||
// premultiplied with alpha.
|
||||
f32 normA = 1.0f;
|
||||
f32 normR = (normA * 0.0f);
|
||||
f32 normG = (normA * 0.0f);
|
||||
f32 normB = (normA * 1.0f);
|
||||
|
||||
u8 r = (u8)(normR * 255.0f);
|
||||
u8 g = (u8)(normG * 255.0f);
|
||||
u8 b = (u8)(normB * 255.0f);
|
||||
u8 a = (u8)(normA * 255.0f);
|
||||
|
||||
u32 color = (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||
bitmapBuffer[i] = color;
|
||||
}
|
||||
}
|
8
src/dchip8.h
Normal file
8
src/dchip8.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef DCHIP8_H
|
||||
#define DCHIP8_H
|
||||
|
||||
#include "dchip8_platform.h"
|
||||
|
||||
void dchip8_update(PlatformRenderBuffer *renderBuffer);
|
||||
|
||||
#endif
|
14
src/dchip8_platform.h
Normal file
14
src/dchip8_platform.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef DCHIP_8_PLATFORM
|
||||
#define DCHIP_8_PLATFORM
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
typedef struct PlatformRenderBuffer
|
||||
{
|
||||
i32 width;
|
||||
i32 height;
|
||||
i32 bytesPerPixel;
|
||||
void *memory;
|
||||
} PlatformRenderBuffer;
|
||||
|
||||
#endif
|
3
src/unity_build.cpp
Normal file
3
src/unity_build.cpp
Normal file
@ -0,0 +1,3 @@
|
||||
#include "win32_dchip8.cpp"
|
||||
|
||||
#include "dchip8.cpp"
|
233
src/win32_dchip8.cpp
Normal file
233
src/win32_dchip8.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "dchip8.h"
|
||||
#include "dchip8_platform.h"
|
||||
|
||||
FILE_SCOPE bool globalRunning = false;
|
||||
FILE_SCOPE LARGE_INTEGER globalQueryPerformanceFrequency;
|
||||
#define win32_error_box(text, title) MessageBox(nullptr, text, title, MB_OK);
|
||||
|
||||
FILE_SCOPE LRESULT CALLBACK win32_main_proc_callback(HWND window, UINT msg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
LRESULT result = 0;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
case WM_DESTROY:
|
||||
{
|
||||
globalRunning = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
result = DefWindowProc(window, msg, wParam, lParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE f32 win32_query_perf_counter_get_time(LARGE_INTEGER start,
|
||||
LARGE_INTEGER end)
|
||||
{
|
||||
f32 result = (f32)(end.QuadPart - start.QuadPart) /
|
||||
globalQueryPerformanceFrequency.QuadPart;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline FILE_SCOPE LARGE_INTEGER win32_query_perf_counter_time()
|
||||
{
|
||||
LARGE_INTEGER result;
|
||||
QueryPerformanceCounter(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct Win32RenderBitmap
|
||||
{
|
||||
BITMAPINFO info;
|
||||
HBITMAP handle;
|
||||
i32 width;
|
||||
i32 height;
|
||||
i32 bytesPerPixel;
|
||||
void *memory;
|
||||
} Win32RenderBitmap;
|
||||
|
||||
FILE_SCOPE void win32_display_render_bitmap(Win32RenderBitmap renderBitmap,
|
||||
HDC deviceContext, LONG width,
|
||||
LONG height)
|
||||
{
|
||||
BLENDFUNCTION blend = {};
|
||||
blend.BlendOp = AC_SRC_OVER;
|
||||
blend.SourceConstantAlpha = 255;
|
||||
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
HDC alphaBlendDC = CreateCompatibleDC(deviceContext);
|
||||
SelectObject(alphaBlendDC, renderBitmap.handle);
|
||||
|
||||
AlphaBlend(deviceContext, 0, 0, width, height, alphaBlendDC, 0, 0,
|
||||
renderBitmap.width, renderBitmap.height, blend);
|
||||
StretchBlt(deviceContext, 0, 0, width, height, deviceContext, 0, 0,
|
||||
renderBitmap.width, renderBitmap.height, SRCCOPY);
|
||||
|
||||
DeleteDC(alphaBlendDC);
|
||||
}
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
WNDCLASSEX wc =
|
||||
{
|
||||
sizeof(WNDCLASSEX),
|
||||
CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||
win32_main_proc_callback,
|
||||
0, // int cbClsExtra
|
||||
0, // int cbWndExtra
|
||||
hInstance,
|
||||
LoadIcon(NULL, IDI_APPLICATION),
|
||||
LoadCursor(NULL, IDC_ARROW),
|
||||
NULL, // GetSysColorBrush(COLOR_3DFACE),
|
||||
L"", // LPCTSTR lpszMenuName
|
||||
L"dchip-8Class",
|
||||
NULL, // HICON hIconSm
|
||||
};
|
||||
|
||||
if (!RegisterClassEx(&wc)) {
|
||||
win32_error_box(L"RegisterClassEx() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// NOTE: Regarding Window Sizes
|
||||
// If you specify a window size, e.g. 800x600, Windows regards the 800x600
|
||||
// region to be inclusive of the toolbars and side borders. So in actuality,
|
||||
// when you blit to the screen blackness, the area that is being blitted to
|
||||
// is slightly smaller than 800x600. Windows provides a function to help
|
||||
// calculate the size you'd need by accounting for the window style.
|
||||
RECT rect = {};
|
||||
rect.right = 128;
|
||||
rect.bottom = 64;
|
||||
|
||||
DWORD windowStyle =
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
AdjustWindowRect(&rect, windowStyle, FALSE);
|
||||
|
||||
HWND mainWindow = CreateWindowEx(
|
||||
WS_EX_COMPOSITED, wc.lpszClassName, L"dchip-8", windowStyle,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
|
||||
rect.bottom - rect.top, nullptr, nullptr, hInstance, nullptr);
|
||||
|
||||
if (!mainWindow)
|
||||
{
|
||||
win32_error_box(L"CreateWindowEx() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Win32RenderBitmap renderBitmap = {};
|
||||
{ // Initialise the renderbitmap
|
||||
BITMAPINFOHEADER header = {};
|
||||
header.biSize = sizeof(BITMAPINFOHEADER);
|
||||
header.biWidth = 64;
|
||||
header.biHeight = 32;
|
||||
header.biPlanes = 1;
|
||||
header.biBitCount = 32;
|
||||
header.biCompression = BI_RGB; // uncompressed bitmap
|
||||
header.biSizeImage = 0;
|
||||
header.biXPelsPerMeter = 0;
|
||||
header.biYPelsPerMeter = 0;
|
||||
header.biClrUsed = 0;
|
||||
header.biClrImportant = 0;
|
||||
|
||||
renderBitmap.info.bmiHeader = header;
|
||||
renderBitmap.width = header.biWidth;
|
||||
renderBitmap.height = header.biHeight;
|
||||
renderBitmap.bytesPerPixel = header.biBitCount / 8;
|
||||
ASSERT(renderBitmap.bytesPerPixel >= 1);
|
||||
|
||||
HDC deviceContext = GetDC(mainWindow);
|
||||
renderBitmap.handle =
|
||||
CreateDIBSection(deviceContext, &renderBitmap.info, DIB_RGB_COLORS,
|
||||
&renderBitmap.memory, NULL, NULL);
|
||||
ReleaseDC(mainWindow, deviceContext);
|
||||
}
|
||||
|
||||
if (!renderBitmap.memory)
|
||||
{
|
||||
win32_error_box(L"CreateDIBSection() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Update Loop
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
QueryPerformanceFrequency(&globalQueryPerformanceFrequency);
|
||||
const f32 TARGET_FRAMES_PER_S = 60.0f;
|
||||
f32 targetSecondsPerFrame = 1 / TARGET_FRAMES_PER_S;
|
||||
f32 frameTimeInS = 0.0f;
|
||||
globalRunning = true;
|
||||
|
||||
while (globalRunning)
|
||||
{
|
||||
LARGE_INTEGER startFrameTime = win32_query_perf_counter_time();
|
||||
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, mainWindow, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Rendering
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
PlatformRenderBuffer renderBuffer = {};
|
||||
renderBuffer.memory = renderBitmap.memory;
|
||||
renderBuffer.height = renderBitmap.height;
|
||||
renderBuffer.width = renderBitmap.width;
|
||||
dchip8_update(&renderBuffer);
|
||||
|
||||
HDC deviceContext = GetDC(mainWindow);
|
||||
win32_display_render_bitmap(renderBitmap, deviceContext, clientWidth,
|
||||
clientHeight);
|
||||
ReleaseDC(mainWindow, deviceContext);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Frame Limiting
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
LARGE_INTEGER endWorkTime = win32_query_perf_counter_time();
|
||||
f32 workTimeInS =
|
||||
win32_query_perf_counter_get_time(startFrameTime, endWorkTime);
|
||||
if (workTimeInS < targetSecondsPerFrame)
|
||||
{
|
||||
DWORD remainingTimeInMs =
|
||||
(DWORD)((targetSecondsPerFrame - workTimeInS) * 1000);
|
||||
Sleep(remainingTimeInMs);
|
||||
}
|
||||
|
||||
LARGE_INTEGER endFrameTime = win32_query_perf_counter_time();
|
||||
frameTimeInS =
|
||||
win32_query_perf_counter_get_time(startFrameTime, endFrameTime);
|
||||
f32 msPerFrame = 1000.0f * frameTimeInS;
|
||||
|
||||
wchar_t windowTitleBuffer[128] = {};
|
||||
_snwprintf_s(windowTitleBuffer, ARRAY_COUNT(windowTitleBuffer),
|
||||
ARRAY_COUNT(windowTitleBuffer), L"dchip-8 | %5.2f ms/f",
|
||||
msPerFrame);
|
||||
SetWindowText(mainWindow, windowTitleBuffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user