-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplatform_win32.cpp
More file actions
199 lines (162 loc) · 5.46 KB
/
platform_win32.cpp
File metadata and controls
199 lines (162 loc) · 5.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#if _WIN32
#include "platform.h"
#include "main.h"
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <shobjidl.h>
using namespace MRT;
static HDC DC;
static BITMAPINFO bmpInfo;
static HWND mainWindow;
static ITaskbarList3 *taskBar;
static uint32 G_windowWidth;
static uint32 G_windowHeight;
static uint32 G_bufferWidth;
static uint32 G_bufferHeight;
static double freq;
uint64_t MRT_GetTime() {
LARGE_INTEGER t;
QueryPerformanceCounter(&t);
return t.QuadPart;
}
float MRT_TimeDelta(uint64_t start, uint64_t stop) {
return float((stop - start) / freq);
}
void MRT_PlatformInit() {
LARGE_INTEGER f;
QueryPerformanceFrequency(&f);
freq = double(f.QuadPart);
DWORD dwProcessList[2];
DWORD count = GetConsoleProcessList(dwProcessList, 2);
if (count == 1) { // we are the only process using this console, just close it
FreeConsole();
}
}
LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam) {
LRESULT result = 0;
int32 mouseX = ((short*)&lParam)[0];
int32 mouseY = ((short*)&lParam)[1];
switch (uMsg) {
case WM_KEYDOWN: {
KeyState prevState = (lParam & (1 << 30)) ? MRT_DOWN : MRT_UP;
KeyboardCallback(int(wParam), MRT_DOWN, prevState);
} break;
case WM_KEYUP:
KeyboardCallback(int(wParam), MRT_UP, MRT_DOWN);
break;
case WM_LBUTTONUP:
MouseCallback(mouseX, mouseY, MRT_UP, MRT_NONE);
break;
case WM_LBUTTONDOWN:
MouseCallback(mouseX, mouseY, MRT_DOWN, MRT_NONE);
break;
case WM_RBUTTONUP:
MouseCallback(mouseX, mouseY, MRT_NONE, MRT_UP);
break;
case WM_RBUTTONDOWN:
MouseCallback(mouseX, mouseY, MRT_NONE, MRT_DOWN);
break;
case WM_DESTROY:
case WM_CLOSE:
WindowCallback(MRT_CLOSE);
break;
default:
result = DefWindowProc(hWindow, uMsg, wParam, lParam);
}
return result;
}
void MRT_SetWindowTitle(const char *str) {
SetWindowTextA(mainWindow, str);
}
void MRT_CreateWindow(uint32_t windowWidth, uint32_t windowHeight, uint32_t bufferWidth, uint32_t bufferHeight) {
HMODULE hInstance = GetModuleHandle(NULL);
WNDCLASSEX windowClass = { sizeof(windowClass) };
windowClass.lpfnWndProc = MainWndProc;
windowClass.hInstance = hInstance;
windowClass.lpszClassName = "MiniRayTracerMain";
if (!RegisterClassEx(&windowClass)) {
DebugBreak();
exit(1);
}
DWORD windowStyle = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_VISIBLE;
DWORD windowStyleEx = 0;
// adjust window so that drawable area is exactly the size we want
RECT r = { 0, 0, LONG(windowWidth), LONG(windowHeight) };
AdjustWindowRectEx(&r, windowStyle, FALSE, windowStyleEx);
mainWindow = CreateWindowEx(windowStyleEx, windowClass.lpszClassName, "MiniRayTracer", windowStyle, 5, 35,
(r.right - r.left), (r.bottom - r.top), NULL, NULL, hInstance, 0);
DC = GetDC(mainWindow);
// set stretch mode in case buffer size != window size
// NOTE: stretch mode is reset if we release the DC
//SetStretchBltMode(DC, HALFTONE); // bicubic-like, blurry. comment out if undesired
//SetBrushOrgEx(DC, 0, 0, NULL); // required after setting HALFTONE according to MSDN
// tell Windows how to interpret our backbuffer
bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader);
bmpInfo.bmiHeader.biWidth = bufferWidth;
bmpInfo.bmiHeader.biHeight = bufferHeight; // y axis up
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 32;
bmpInfo.bmiHeader.biCompression = BI_RGB;
G_windowWidth = windowWidth;
G_windowHeight = windowHeight;
G_bufferWidth = bufferWidth;
G_bufferHeight = bufferHeight;
CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&taskBar);
taskBar->SetProgressState(mainWindow, TBPF_NORMAL);
}
void MRT_HandleMessages() {
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
void MRT_ReportProgress(uint64_t done, uint64_t total) {
if ((done == total) && (taskBar != NULL)) {
taskBar->SetProgressState(mainWindow, TBPF_NOPROGRESS);
taskBar->Release();
taskBar = NULL;
}
else {
if (taskBar == NULL) {
CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **)&taskBar);
taskBar->SetProgressState(mainWindow, TBPF_NORMAL);
}
taskBar->SetProgressValue(mainWindow, done, total);
}
}
void MRT_DrawToWindow(const uint32_t* backBuffer) {
StretchDIBits(DC, 0, 0, G_windowWidth, G_windowHeight, 0, 0, G_bufferWidth, G_bufferHeight, backBuffer, &bmpInfo, DIB_RGB_COLORS, SRCCOPY);
}
void MRT_DebugPrint(const char *format, ...) {
static char buffer[16384];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
fputs(buffer, stderr);
OutputDebugStringA(buffer);
}
void MRT_Assert(bool cond) {
if (!cond) DebugBreak();
}
void MRT_Assert(bool cond, const char *msg) {
if (!cond) {
MRT_DebugPrint(msg);
DebugBreak();
}
}
void MRT_LowerThreadPriority() {
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
}
void MRT_PlatformDestroy() {
ReleaseDC(mainWindow, DC);
FreeConsole();
}
void MRT_Sleep(uint32_t ms) {
Sleep(ms);
}
#endif