Initial commit
This commit is contained in:
commit
7f62ce23d0
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
bin/
|
||||||
|
.vs/
|
||||||
|
ctime.exe
|
||||||
|
tags
|
29
drenderer.sln
Normal file
29
drenderer.sln
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.26403.3
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "drenderer", "bin\drenderer.exe", "{25476A47-63FF-426D-A4A2-73AB789B9916}"
|
||||||
|
ProjectSection(DebuggerProjectSystem) = preProject
|
||||||
|
PortSupplier = 00000000-0000-0000-0000-000000000000
|
||||||
|
Executable = C:\git\drenderer\bin\drenderer.exe
|
||||||
|
RemoteMachine = THAI-PC
|
||||||
|
StartingDirectory = C:\git\drenderer\bin
|
||||||
|
Environment = Default
|
||||||
|
LaunchingEngine = 00000000-0000-0000-0000-000000000000
|
||||||
|
UseLegacyDebugEngines = No
|
||||||
|
LaunchSQLEngine = No
|
||||||
|
AttachLaunchAction = No
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{25476A47-63FF-426D-A4A2-73AB789B9916}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
46
src/.clang-format
Normal file
46
src/.clang-format
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
ColumnLimit: 80,
|
||||||
|
TabWidth: 4,
|
||||||
|
IndentWidth: 4, # 1 tab
|
||||||
|
UseTab: ForIndentation,
|
||||||
|
BreakBeforeBraces: Allman,
|
||||||
|
PointerBindsToType: false,
|
||||||
|
###
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: false,
|
||||||
|
AlwaysBreakTemplateDeclarations: true,
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true,
|
||||||
|
IndentFunctionDeclarationAfterType: false,
|
||||||
|
#
|
||||||
|
AccessModifierOffset: -4, # 1 tab
|
||||||
|
AlignAfterOpenBracket: true,
|
||||||
|
AlignConsecutiveAssignments: true,
|
||||||
|
AlignTrailingComments: true,
|
||||||
|
#
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true,
|
||||||
|
AllowShortBlocksOnASingleLine: false,
|
||||||
|
AllowShortIfStatementsOnASingleLine: true,
|
||||||
|
AllowShortLoopsOnASingleLine: false,
|
||||||
|
#
|
||||||
|
BinPackArguments: true,
|
||||||
|
BinPackParameters: true,
|
||||||
|
#
|
||||||
|
BreakConstructorInitializersBeforeComma: true,
|
||||||
|
ConstructorInitializerIndentWidth: 0,
|
||||||
|
#
|
||||||
|
IndentCaseLabels: true,
|
||||||
|
#
|
||||||
|
MaxEmptyLinesToKeep: 1,
|
||||||
|
NamespaceIndentation: None,
|
||||||
|
#
|
||||||
|
SpaceBeforeAssignmentOperators: true,
|
||||||
|
SpaceInEmptyParentheses: false,
|
||||||
|
SpacesBeforeTrailingComments: 1,
|
||||||
|
SpacesInAngles: false,
|
||||||
|
SpacesInCStyleCastParentheses: false,
|
||||||
|
SpacesInParentheses: false,
|
||||||
|
SpacesInSquareBrackets: false,
|
||||||
|
#
|
||||||
|
Cpp11BracedListStyle: true,
|
||||||
|
Standard: Cpp11,
|
||||||
|
#
|
||||||
|
}
|
6
src/DRenderer.cpp
Normal file
6
src/DRenderer.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "DRendererPlatform.h"
|
||||||
|
|
||||||
|
void DR_Update(PlatformRenderBuffer *const renderBuffer,
|
||||||
|
PlatformInput *const input, PlatformMemory *const memory)
|
||||||
|
{
|
||||||
|
}
|
8
src/DRenderer.h
Normal file
8
src/DRenderer.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef DRENDERER_H
|
||||||
|
#define DRENDERER_H
|
||||||
|
|
||||||
|
void DR_Update(struct PlatformRenderBuffer *const renderBuffer,
|
||||||
|
struct PlatformInput *const input,
|
||||||
|
struct PlatformMemory *const memory);
|
||||||
|
|
||||||
|
#endif
|
97
src/DRendererPlatform.h
Normal file
97
src/DRendererPlatform.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#ifndef DRENDERER_PLATFORM_H
|
||||||
|
#define DRENDERER_PLATFORM_H
|
||||||
|
|
||||||
|
#include "dqn.h"
|
||||||
|
|
||||||
|
enum Key
|
||||||
|
{
|
||||||
|
key_up,
|
||||||
|
key_down,
|
||||||
|
key_left,
|
||||||
|
key_right,
|
||||||
|
key_escape,
|
||||||
|
|
||||||
|
key_1,
|
||||||
|
key_2,
|
||||||
|
key_3,
|
||||||
|
key_4,
|
||||||
|
|
||||||
|
key_q,
|
||||||
|
key_w,
|
||||||
|
key_e,
|
||||||
|
key_r,
|
||||||
|
|
||||||
|
key_a,
|
||||||
|
key_s,
|
||||||
|
key_d,
|
||||||
|
key_f,
|
||||||
|
|
||||||
|
key_z,
|
||||||
|
key_x,
|
||||||
|
key_c,
|
||||||
|
key_v,
|
||||||
|
|
||||||
|
key_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct KeyState
|
||||||
|
{
|
||||||
|
bool endedDown;
|
||||||
|
u32 halfTransitionCount;
|
||||||
|
} KeyState;
|
||||||
|
|
||||||
|
typedef struct PlatformInput
|
||||||
|
{
|
||||||
|
f32 deltaForFrame;
|
||||||
|
|
||||||
|
bool loadNewRom;
|
||||||
|
wchar_t rom[260];
|
||||||
|
|
||||||
|
union {
|
||||||
|
KeyState key[key_count];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
KeyState up;
|
||||||
|
KeyState down;
|
||||||
|
KeyState left;
|
||||||
|
KeyState right;
|
||||||
|
KeyState escape;
|
||||||
|
|
||||||
|
KeyState key_1;
|
||||||
|
KeyState key_2;
|
||||||
|
KeyState key_3;
|
||||||
|
KeyState key_4;
|
||||||
|
|
||||||
|
KeyState key_q;
|
||||||
|
KeyState key_w;
|
||||||
|
KeyState key_e;
|
||||||
|
KeyState key_r;
|
||||||
|
|
||||||
|
KeyState key_a;
|
||||||
|
KeyState key_s;
|
||||||
|
KeyState key_d;
|
||||||
|
KeyState key_f;
|
||||||
|
|
||||||
|
KeyState key_z;
|
||||||
|
KeyState key_x;
|
||||||
|
KeyState key_c;
|
||||||
|
KeyState key_v;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} PlatformInput;
|
||||||
|
|
||||||
|
typedef struct PlatformMemory
|
||||||
|
{
|
||||||
|
DqnMemBuffer permanentBuffer;
|
||||||
|
DqnMemBuffer transientBuffer;
|
||||||
|
} PlatformMemory;
|
||||||
|
|
||||||
|
typedef struct PlatformRenderBuffer
|
||||||
|
{
|
||||||
|
i32 width;
|
||||||
|
i32 height;
|
||||||
|
i32 bytesPerPixel;
|
||||||
|
void *memory;
|
||||||
|
} PlatformRenderBuffer;
|
||||||
|
|
||||||
|
#endif
|
2
src/UnityBuild/UnityBuild.cpp
Normal file
2
src/UnityBuild/UnityBuild.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#include "..\DRenderer.cpp"
|
||||||
|
#include "..\Win32DRenderer.cpp"
|
393
src/Win32DRenderer.cpp
Normal file
393
src/Win32DRenderer.cpp
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
#include "DRenderer.h"
|
||||||
|
#include "DRendererPlatform.h"
|
||||||
|
|
||||||
|
#define DQN_IMPLEMENTATION
|
||||||
|
#define DQN_WIN32_IMPLEMENTATION
|
||||||
|
#include "dqn.h"
|
||||||
|
|
||||||
|
#define UNICODE
|
||||||
|
#define _UNICODE
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
typedef struct Win32RenderBitmap
|
||||||
|
{
|
||||||
|
BITMAPINFO info;
|
||||||
|
HBITMAP handle;
|
||||||
|
i32 width;
|
||||||
|
i32 height;
|
||||||
|
i32 bytesPerPixel;
|
||||||
|
void *memory;
|
||||||
|
} Win32RenderBitmap;
|
||||||
|
|
||||||
|
FILE_SCOPE Win32RenderBitmap globalRenderBitmap;
|
||||||
|
FILE_SCOPE bool globalRunning;
|
||||||
|
|
||||||
|
FILE_SCOPE void Win32DisplayRenderBitmap(Win32RenderBitmap renderBitmap,
|
||||||
|
HDC deviceContext, LONG width,
|
||||||
|
LONG height)
|
||||||
|
{
|
||||||
|
HDC stretchDC = CreateCompatibleDC(deviceContext);
|
||||||
|
SelectObject(stretchDC, renderBitmap.handle);
|
||||||
|
DQN_ASSERT(renderBitmap.width == width);
|
||||||
|
DQN_ASSERT(renderBitmap.height == height);
|
||||||
|
StretchBlt(deviceContext, 0, 0, width, height, stretchDC, 0, 0,
|
||||||
|
renderBitmap.width, renderBitmap.height, SRCCOPY);
|
||||||
|
|
||||||
|
// NOTE: Win32 AlphaBlend requires the RGB components to be premultiplied
|
||||||
|
// with alpha.
|
||||||
|
#if 0
|
||||||
|
BLENDFUNCTION blend = {};
|
||||||
|
blend.BlendOp = AC_SRC_OVER;
|
||||||
|
blend.SourceConstantAlpha = 255;
|
||||||
|
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||||
|
|
||||||
|
if (!AlphaBlend(deviceContext, 0, 0, width, height, deviceContext, 0, 0,
|
||||||
|
width, height, blend))
|
||||||
|
{
|
||||||
|
OutputDebugString(L"AlphaBlend() failed.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
DeleteDC(stretchDC);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Win32Menu
|
||||||
|
{
|
||||||
|
Win32Menu_FileOpen = 4,
|
||||||
|
Win32Menu_FileExit,
|
||||||
|
};
|
||||||
|
|
||||||
|
FILE_SCOPE void Win32CreateMenu(HWND window)
|
||||||
|
{
|
||||||
|
HMENU menuBar = CreateMenu();
|
||||||
|
{ // File Menu
|
||||||
|
HMENU menu = CreatePopupMenu();
|
||||||
|
AppendMenu(menuBar, MF_STRING | MF_POPUP, (UINT_PTR)menu, "File");
|
||||||
|
AppendMenu(menu, MF_STRING, Win32Menu_FileOpen, "Open");
|
||||||
|
AppendMenu(menu, MF_STRING, Win32Menu_FileExit, "Exit");
|
||||||
|
}
|
||||||
|
SetMenu(window, menuBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_SCOPE LRESULT CALLBACK Win32MainProcCallback(HWND window, UINT msg,
|
||||||
|
WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
LRESULT result = 0;
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case WM_CREATE:
|
||||||
|
{
|
||||||
|
Win32CreateMenu(window);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
globalRunning = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
PAINTSTRUCT paint;
|
||||||
|
HDC deviceContext = BeginPaint(window, &paint);
|
||||||
|
|
||||||
|
LONG renderWidth, renderHeight;
|
||||||
|
DqnWin32_GetClientDim(window, &renderWidth, &renderHeight);
|
||||||
|
|
||||||
|
DqnV2 ratio = DqnV2_2i(globalRenderBitmap.width, globalRenderBitmap.height);
|
||||||
|
DqnV2 newDim = DqnV2_ConstrainToRatio(DqnV2_2i(renderWidth, renderHeight), ratio);
|
||||||
|
renderWidth = (LONG)newDim.w;
|
||||||
|
renderHeight = (LONG)newDim.h;
|
||||||
|
|
||||||
|
Win32DisplayRenderBitmap(globalRenderBitmap, deviceContext,
|
||||||
|
renderWidth, renderHeight);
|
||||||
|
EndPaint(window, &paint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
result = DefWindowProcW(window, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_SCOPE inline void Win32UpdateKey(KeyState *key, bool isDown)
|
||||||
|
{
|
||||||
|
if (key->endedDown != isDown)
|
||||||
|
{
|
||||||
|
key->endedDown = isDown;
|
||||||
|
key->halfTransitionCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_SCOPE void Win32HandleMenuMessages(HWND window, MSG msg,
|
||||||
|
PlatformInput *input)
|
||||||
|
{
|
||||||
|
switch (LOWORD(msg.wParam))
|
||||||
|
{
|
||||||
|
case Win32Menu_FileExit:
|
||||||
|
{
|
||||||
|
globalRunning = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Win32Menu_FileOpen:
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
wchar_t fileBuffer[MAX_PATH] = {};
|
||||||
|
OPENFILENAME openDialogInfo = {};
|
||||||
|
openDialogInfo.lStructSize = sizeof(OPENFILENAME);
|
||||||
|
openDialogInfo.hwndOwner = window;
|
||||||
|
openDialogInfo.lpstrFile = fileBuffer;
|
||||||
|
openDialogInfo.nMaxFile = DQN_ARRAY_COUNT(fileBuffer);
|
||||||
|
openDialogInfo.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
||||||
|
|
||||||
|
if (GetOpenFileName(&openDialogInfo) != 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_SCOPE void Win32ProcessMessages(HWND window, PlatformInput *input)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, window, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
switch (msg.message)
|
||||||
|
{
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
Win32HandleMenuMessages(window, msg, input);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
case WM_KEYUP:
|
||||||
|
{
|
||||||
|
bool isDown = (msg.message == WM_KEYDOWN);
|
||||||
|
switch (msg.wParam)
|
||||||
|
{
|
||||||
|
case VK_UP: Win32UpdateKey(&input->up, isDown); break;
|
||||||
|
case VK_DOWN: Win32UpdateKey(&input->down, isDown); break;
|
||||||
|
case VK_LEFT: Win32UpdateKey(&input->left, isDown); break;
|
||||||
|
case VK_RIGHT: Win32UpdateKey(&input->right, isDown); break;
|
||||||
|
|
||||||
|
case '1': Win32UpdateKey(&input->key_1, isDown); break;
|
||||||
|
case '2': Win32UpdateKey(&input->key_2, isDown); break;
|
||||||
|
case '3': Win32UpdateKey(&input->key_3, isDown); break;
|
||||||
|
case '4': Win32UpdateKey(&input->key_4, isDown); break;
|
||||||
|
|
||||||
|
case 'Q': Win32UpdateKey(&input->key_q, isDown); break;
|
||||||
|
case 'W': Win32UpdateKey(&input->key_w, isDown); break;
|
||||||
|
case 'E': Win32UpdateKey(&input->key_e, isDown); break;
|
||||||
|
case 'R': Win32UpdateKey(&input->key_r, isDown); break;
|
||||||
|
|
||||||
|
case 'A': Win32UpdateKey(&input->key_a, isDown); break;
|
||||||
|
case 'S': Win32UpdateKey(&input->key_s, isDown); break;
|
||||||
|
case 'D': Win32UpdateKey(&input->key_d, isDown); break;
|
||||||
|
case 'F': Win32UpdateKey(&input->key_f, isDown); break;
|
||||||
|
|
||||||
|
case 'Z': Win32UpdateKey(&input->key_z, isDown); break;
|
||||||
|
case 'X': Win32UpdateKey(&input->key_x, isDown); break;
|
||||||
|
case 'C': Win32UpdateKey(&input->key_c, isDown); break;
|
||||||
|
case 'V': Win32UpdateKey(&input->key_v, isDown); break;
|
||||||
|
|
||||||
|
case VK_ESCAPE:
|
||||||
|
{
|
||||||
|
Win32UpdateKey(&input->escape, isDown);
|
||||||
|
if (input->escape.endedDown) globalRunning = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
|
LPWSTR lpCmdLine, int nShowCmd)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Initialise Win32 Window
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
WNDCLASSEXW wc =
|
||||||
|
{
|
||||||
|
sizeof(WNDCLASSEX),
|
||||||
|
CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||||
|
Win32MainProcCallback,
|
||||||
|
0, // int cbClsExtra
|
||||||
|
0, // int cbWndExtra
|
||||||
|
hInstance,
|
||||||
|
LoadIcon(NULL, IDI_APPLICATION),
|
||||||
|
LoadCursor(NULL, IDC_ARROW),
|
||||||
|
GetSysColorBrush(COLOR_3DFACE),
|
||||||
|
L"", // LPCTSTR lpszMenuName
|
||||||
|
L"DRendererClass",
|
||||||
|
NULL, // HICON hIconSm
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!RegisterClassExW(&wc))
|
||||||
|
{
|
||||||
|
DqnWin32_DisplayLastError("RegisterClassEx() failed.");
|
||||||
|
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.
|
||||||
|
const u32 MIN_WIDTH = 800;
|
||||||
|
const u32 MIN_HEIGHT = 600;
|
||||||
|
RECT rect = {};
|
||||||
|
rect.right = MIN_WIDTH;
|
||||||
|
rect.bottom = MIN_HEIGHT;
|
||||||
|
DWORD windowStyle =
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||||
|
AdjustWindowRect(&rect, windowStyle, true);
|
||||||
|
|
||||||
|
HWND mainWindow = CreateWindowExW(
|
||||||
|
WS_EX_COMPOSITED, wc.lpszClassName, L"DRenderer", windowStyle,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
|
||||||
|
rect.bottom - rect.top, nullptr, nullptr, hInstance, nullptr);
|
||||||
|
|
||||||
|
if (!mainWindow)
|
||||||
|
{
|
||||||
|
DqnWin32_DisplayLastError("CreateWindowEx() failed.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Initialise the renderbitmap
|
||||||
|
BITMAPINFOHEADER header = {};
|
||||||
|
header.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
header.biWidth = MIN_WIDTH;
|
||||||
|
header.biHeight = MIN_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;
|
||||||
|
|
||||||
|
globalRenderBitmap.info.bmiHeader = header;
|
||||||
|
globalRenderBitmap.width = header.biWidth;
|
||||||
|
globalRenderBitmap.height = header.biHeight;
|
||||||
|
globalRenderBitmap.bytesPerPixel = header.biBitCount / 8;
|
||||||
|
DQN_ASSERT(globalRenderBitmap.bytesPerPixel >= 1);
|
||||||
|
|
||||||
|
HDC deviceContext = GetDC(mainWindow);
|
||||||
|
globalRenderBitmap.handle = CreateDIBSection(
|
||||||
|
deviceContext, &globalRenderBitmap.info, DIB_RGB_COLORS,
|
||||||
|
&globalRenderBitmap.memory, NULL, NULL);
|
||||||
|
ReleaseDC(mainWindow, deviceContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!globalRenderBitmap.memory)
|
||||||
|
{
|
||||||
|
DqnWin32_DisplayLastError("CreateDIBSection() failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Update Loop
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
PlatformMemory platformMemory = {};
|
||||||
|
DQN_ASSERT(DqnMemBuffer_Init(&platformMemory.permanentBuffer, DQN_MEGABYTE(1), true, 4) &&
|
||||||
|
DqnMemBuffer_Init(&platformMemory.transientBuffer, DQN_MEGABYTE(1), true, 4));
|
||||||
|
|
||||||
|
const f32 TARGET_FRAMES_PER_S = 60.0f;
|
||||||
|
f32 targetSecondsPerFrame = 1 / TARGET_FRAMES_PER_S;
|
||||||
|
f64 frameTimeInS = 0.0f;
|
||||||
|
globalRunning = true;
|
||||||
|
|
||||||
|
SetWindowTextA(mainWindow, "test");
|
||||||
|
while (globalRunning)
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Update State
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
f64 startFrameTimeInS = DqnTime_NowInS();
|
||||||
|
{
|
||||||
|
PlatformInput platformInput = {};
|
||||||
|
platformInput.deltaForFrame = (f32)frameTimeInS;
|
||||||
|
Win32ProcessMessages(mainWindow, &platformInput);
|
||||||
|
|
||||||
|
PlatformRenderBuffer platformBuffer = {};
|
||||||
|
platformBuffer.memory = globalRenderBitmap.memory;
|
||||||
|
platformBuffer.height = globalRenderBitmap.height;
|
||||||
|
platformBuffer.width = globalRenderBitmap.width;
|
||||||
|
platformBuffer.bytesPerPixel = globalRenderBitmap.bytesPerPixel;
|
||||||
|
DR_Update(&platformBuffer, &platformInput, &platformMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Rendering
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
LONG renderWidth, renderHeight;
|
||||||
|
DqnWin32_GetClientDim(mainWindow, &renderWidth, &renderHeight);
|
||||||
|
|
||||||
|
DqnV2 ratio = DqnV2_2i(globalRenderBitmap.width, globalRenderBitmap.height);
|
||||||
|
DqnV2 newDim = DqnV2_ConstrainToRatio(DqnV2_2i(renderWidth, renderHeight), ratio);
|
||||||
|
renderWidth = (LONG)newDim.w;
|
||||||
|
renderHeight = (LONG)newDim.h;
|
||||||
|
|
||||||
|
HDC deviceContext = GetDC(mainWindow);
|
||||||
|
Win32DisplayRenderBitmap(globalRenderBitmap, deviceContext,
|
||||||
|
renderWidth, renderHeight);
|
||||||
|
ReleaseDC(mainWindow, deviceContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Frame Limiting
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
{
|
||||||
|
f64 workTimeInS = DqnTime_NowInS() - startFrameTimeInS;
|
||||||
|
if (workTimeInS < targetSecondsPerFrame)
|
||||||
|
{
|
||||||
|
DWORD remainingTimeInMs =
|
||||||
|
(DWORD)((targetSecondsPerFrame - workTimeInS) * 1000);
|
||||||
|
Sleep(remainingTimeInMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frameTimeInS = DqnTime_NowInS() - startFrameTimeInS;
|
||||||
|
f32 msPerFrame = 1000.0f * (f32)frameTimeInS;
|
||||||
|
|
||||||
|
char windowTitleBuffer[128] = {};
|
||||||
|
Dqn_sprintf(windowTitleBuffer, "drenderer - dev - %5.2f ms/f",
|
||||||
|
msPerFrame);
|
||||||
|
SetWindowTextA(mainWindow, windowTitleBuffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
65
src/build.bat
Normal file
65
src/build.bat
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
REM Build for Visual Studio compiler. Run your copy of vcvarsall.bat to setup command-line compiler.
|
||||||
|
|
||||||
|
REM Check if build tool is on path
|
||||||
|
REM >nul, 2>nul will remove the output text from the where command
|
||||||
|
where /q cl.exe
|
||||||
|
if %errorlevel%==1 (
|
||||||
|
echo MSVC CL not on path, please add it to path to build by command line.
|
||||||
|
goto end
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Build tags file
|
||||||
|
ctags -R
|
||||||
|
|
||||||
|
set ProjectName=drenderer
|
||||||
|
ctime -begin ..\src\%ProjectName%.ctm
|
||||||
|
|
||||||
|
IF NOT EXIST ..\bin mkdir ..\bin
|
||||||
|
pushd ..\bin
|
||||||
|
|
||||||
|
REM ////////////////////////////////////////////////////////////////////////////
|
||||||
|
REM Compile Switches
|
||||||
|
REM ////////////////////////////////////////////////////////////////////////////
|
||||||
|
REM EHa- disable exception handling (we don't use)
|
||||||
|
REM GR- disable c runtime type information (we don't use)
|
||||||
|
REM MD use dynamic runtime library
|
||||||
|
REM MT use static runtime library, so build and link it into exe
|
||||||
|
REM Od disables optimisations
|
||||||
|
REM Oi enable intrinsics optimisation, let us use CPU intrinsics if there is one
|
||||||
|
REM instead of generating a call to external library (i.e. CRT).
|
||||||
|
REM Zi enables debug data, Z7 combines the debug files into one.
|
||||||
|
REM W4 warning level 4
|
||||||
|
REM WX treat warnings as errors
|
||||||
|
REM wd4100 unused argument parameters
|
||||||
|
REM wd4201 nonstandard extension used: nameless struct/union
|
||||||
|
REM wd4189 local variable is initialised but not referenced
|
||||||
|
REM wd4505 unreferenced local function not used will be removed
|
||||||
|
set CompileFlags=-EHa- -GR- -Oi -MT -Z7 -W4 -wd4100 -wd4201 -wd4189 -wd4505 -Od -FAsc
|
||||||
|
set Defines=
|
||||||
|
|
||||||
|
REM ////////////////////////////////////////////////////////////////////////////
|
||||||
|
REM Include Directories/Link Libraries
|
||||||
|
REM ////////////////////////////////////////////////////////////////////////////
|
||||||
|
set IncludeFiles=
|
||||||
|
|
||||||
|
REM Link libraries
|
||||||
|
set LinkLibraries=user32.lib kernel32.lib gdi32.lib
|
||||||
|
|
||||||
|
REM incremental:no, turn incremental builds off
|
||||||
|
REM opt:ref, try to remove functions from libs that are not referenced at all
|
||||||
|
set LinkFlags=-incremental:no -opt:ref -subsystem:WINDOWS -machine:x64 -nologo
|
||||||
|
|
||||||
|
REM ////////////////////////////////////////////////////////////////////////////
|
||||||
|
REM Compile
|
||||||
|
REM ////////////////////////////////////////////////////////////////////////////
|
||||||
|
cl %CompileFlags% %Defines% ..\src\UnityBuild\UnityBuild.cpp %IncludeFiles% /link %LinkLibraries% %LinkFlags% /out:%ProjectName%.exe
|
||||||
|
REM cl %CompileFlags% /P %Defines% ..\src\UnityBuild\UnityBuild.cpp %IncludeFiles%
|
||||||
|
|
||||||
|
popd
|
||||||
|
set LastError=%ERRORLEVEL%
|
||||||
|
ctime -end %ProjectName%.ctm %LastError%
|
||||||
|
|
||||||
|
:end
|
||||||
|
exit /b %LastError%
|
BIN
src/drenderer.ctm
Normal file
BIN
src/drenderer.ctm
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user