fixed gitignore

This commit is contained in:
Anton Ljungdahl 2025-05-17 21:51:10 +02:00
parent 8c26c11e0d
commit 68404e7535
2 changed files with 287 additions and 0 deletions

View File

@ -0,0 +1,256 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//~
#pragma comment(lib, "kernel32")
#pragma comment(lib, "user32")
#pragma comment(lib, "gdi32")
#define OS_W32_MSG_CREATE_WINDOW (WM_USER + 0x1337)
#define OS_W32_MSG_DESTROY_WINDOW (WM_USER + 0x1338)
global DWORD MainThreadID;
global HWND g_service_window_handle;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//~
internal void *
os_reserve(U64 size)
{
void *result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE);
return result;
}
internal B32
os_commit(void *ptr, U64 size)
{
B32 result = (VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE) != 0);
return result;
}
internal void
os_decommit(void *ptr, U64 size)
{
VirtualFree(ptr, size, MEM_DECOMMIT);
}
internal void
os_release(void *ptr, U64 size)
{
// NOTE(anton): Don't need to use size for freeing on Win32, but the API
// should have it for other platforms.
VirtualFree(ptr, 0, MEM_RELEASE);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//~
internal LRESULT CALLBACK
ServiceWndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam)
{
/* NOTE(casey): This is not really a window handler per se, it's actually just
a remote thread call handler. Windows only really has blocking remote thread
calls if you register a WndProc for them, so that's what we do.
This handles CREATE_DANGEROUS_WINDOW and DESTROY_DANGEROUS_WINDOW, which are
just calls that do CreateWindow and DestroyWindow here on this thread when
some other thread wants that to happen.
*/
LRESULT result = 0;
switch(Message)
{
case OS_W32_MSG_CREATE_WINDOW:
{
OS_W32_WndParam *wndParam = (OS_W32_WndParam *)WParam;
result = (LRESULT)CreateWindowExW(wndParam->dwExStyle,
wndParam->lpClassName,
wndParam->lpWindowName,
wndParam->dwStyle,
wndParam->X,
wndParam->Y,
wndParam->nWidth,
wndParam->nHeight,
wndParam->hWndParent,
wndParam->hMenu,
wndParam->hInstance,
wndParam->lpParam);
} break;
case OS_W32_MSG_DESTROY_WINDOW:
{
DestroyWindow((HWND)WParam);
} break;
default:
{
result = DefWindowProcW(Window, Message, WParam, LParam);
} break;
}
return result;
}
internal LRESULT CALLBACK
DisplayWndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam)
{
/* NOTE(casey): This is an example of an actual window procedure. It doesn't do anything
but forward things to the main thread, because again, all window messages now occur
on the message thread, and presumably we would rather handle everything there. You
don't _have_ to do that - you could choose to handle some of the messages here.
But if you did, you would have to actually think about whether there are race conditions
with your main thread and all that. So just PostThreadMessageW()'ing everything gets
you out of having to think about it.
*/
LRESULT Result = 0;
switch (Message)
{
// NOTE(casey): Mildly annoying, if you want to specify a window, you have
// to snuggle the params yourself, because Windows doesn't let you forward
// a god damn window message even though the program IS CALLED WINDOWS. It's
// in the name! Let me pass it!
case WM_CLOSE:
{
PostThreadMessageW(MainThreadID, Message, (WPARAM)Window, LParam);
} break;
// NOTE(casey): Anything you want the application to handle, forward to the main thread
// here.
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_DESTROY:
case WM_CHAR:
{
PostThreadMessageW(MainThreadID, Message, WParam, LParam);
} break;
default:
{
Result = DefWindowProcW(Window, Message, WParam, LParam);
} break;
}
return Result;
}
internal DWORD WINAPI
MainThreadEntryPoint(LPVOID Param)
{
/* NOTE(Casey): This is your app code. Basically you just do everything the same,
but instead of calling CreateWindow/DestroyWindow, you use SendMessage to
do it on the other thread, using the CREATE_DANGEROUS_WINDOW and DESTROY_DANGEROUS_WINDOW
user messages. Otherwise, everything proceeds as normal.
*/
HWND ServiceWindow = (HWND)Param;
g_service_window_handle = ServiceWindow;
WNDCLASSEXW WindowClass = {0};
WindowClass.cbSize = sizeof(WindowClass);
WindowClass.lpfnWndProc = &DisplayWndProc;
WindowClass.hInstance = GetModuleHandleW(NULL);
WindowClass.hIcon = LoadIconA(NULL, IDI_APPLICATION);
WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
WindowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WindowClass.lpszClassName = L"Dangerous Class";
RegisterClassExW(&WindowClass);
OS_W32_WndParam wndParam = {0};
wndParam.dwExStyle = 0;;
wndParam.lpClassName = WindowClass.lpszClassName;
wndParam.lpWindowName = L"Dangerous Window";
wndParam.dwStyle = WS_OVERLAPPEDWINDOW|WS_VISIBLE;
wndParam.X = CW_USEDEFAULT;
wndParam.Y = CW_USEDEFAULT;
wndParam.nWidth = CW_USEDEFAULT;
wndParam.nHeight = CW_USEDEFAULT;
wndParam.hInstance = WindowClass.hInstance;
// Create initial window
HWND ThisWouldBeTheHandleIfYouCared = (HWND)SendMessageW(ServiceWindow,
OS_W32_MSG_CREATE_WINDOW,
(WPARAM)&wndParam,
0);
entry_point();
LOG("Exited main program. Terminating \n");
ExitProcess(0);
}
int
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
/* NOTE(casey): At startup, you create one hidden window used to handle requests
to create or destroy windows. There's nothing special about this window; it
only exists because Windows doesn't have a way to do a remote thread call without
a window handler. You could instead just do this with your own synchronization
primitives if you wanted - this is just the easiest way to do it on Windows
because they've already built it for you.
*/
LOG("Entered WinMain\n");
WNDCLASSEXW WindowClass = {0};
WindowClass.cbSize = sizeof(WindowClass);
WindowClass.lpfnWndProc = &ServiceWndProc;
WindowClass.hInstance = GetModuleHandleW(NULL);
WindowClass.hIcon = LoadIconA(NULL, IDI_APPLICATION);
WindowClass.hCursor = LoadCursorA(NULL, IDC_ARROW);
WindowClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WindowClass.lpszClassName = L"DTCClass";
RegisterClassExW(&WindowClass);
HWND ServiceWindow = CreateWindowExW(0, WindowClass.lpszClassName, L"DTCService", 0,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
0, 0, WindowClass.hInstance, 0);
// NOTE(casey): Once the service window is created, you can start the main thread,
// which is where all your app code would actually happen.
CreateThread(0, 0, MainThreadEntryPoint, ServiceWindow, 0, &MainThreadID);
// NOTE(casey): This thread can just idle for the rest of the run, forwarding
// messages to the main thread that it thinks the main thread wants.
DWORD exitCode;
for(;;)
{
MSG Message;
GetMessageW(&Message, 0, 0, 0);
TranslateMessage(&Message);
if((Message.message == WM_CHAR) ||
(Message.message == WM_KEYDOWN) ||
(Message.message == WM_QUIT) ||
(Message.message == WM_SIZE))
{
PostThreadMessageW(MainThreadID, Message.message, Message.wParam, Message.lParam);
}
else
{
DispatchMessageW(&Message);
}
}
return 0;
}
internal void
OS_W32_log_debug(const char *fmt_string, ...)
{
char buffer[1024];
va_list args;
va_start(args, fmt_string);
_vsnprintf(buffer, sizeof(buffer) / sizeof(char), fmt_string, args);
va_end(args);
OutputDebugStringA(buffer);
}

View File

@ -0,0 +1,31 @@
#ifndef OS_CORE_WIN32_H
#define OS_CORE_WIN32_H
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//~
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Temp struct for launching window on separate thread.
// Trying to learn from https://github.com/cmuratori/dtc/blob/main/dtc.cpp
typedef struct OS_W32_WndParam OS_W32_WndParam;
struct OS_W32_WndParam
{
DWORD dwExStyle;
LPCWSTR lpClassName;
LPCWSTR lpWindowName;
DWORD dwStyle;
S32 X;
S32 Y;
S32 nWidth;
S32 nHeight;
HWND hWndParent;
HMENU hMenu;
HINSTANCE hInstance;
LPVOID lpParam;
};
internal void OS_W32_log_debug(const char *fmt_string, ...);
#endif /* OS_CORE_WIN32_H */