diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index f4f13cf..5375bbf 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -10,6 +10,7 @@
"UNICODE",
"_UNICODE",
"GEN_TIME",
+ "Build_Debug",
],
"windowsSdkVersion": "10.0.22621.0",
"compilerPath": "cl.exe",
diff --git a/HandmadeHero.10x b/HandmadeHero.10x
index 610cfe0..6bdde83 100644
--- a/HandmadeHero.10x
+++ b/HandmadeHero.10x
@@ -38,6 +38,8 @@
C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um
+ UNICODE
+ _UNICODE
GEN_TIME
diff --git a/handmade-hero-notes b/handmade-hero-notes
index 0a6995a..6b43c05 160000
--- a/handmade-hero-notes
+++ b/handmade-hero-notes
@@ -1 +1 @@
-Subproject commit 0a6995a2cb6217d01b463bb4416c5d30c075333b
+Subproject commit 6b43c05d4800c498eb3c9b24e976f9a7eddf3301
diff --git a/project/handmade_win32.cpp b/project/handmade_win32.cpp
index 8b25d37..a08e7db 100644
--- a/project/handmade_win32.cpp
+++ b/project/handmade_win32.cpp
@@ -1,13 +1,172 @@
-#include "win32.h"
+#if __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-const-variable"
+#pragma clang diagnostic ignored "-Wswitch"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#pragma clang diagnostic ignored "-Wvarargs"
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
-int CALLBACK WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nShowCmd
+#include "grime.h"
+#include "macros.h"
+#include "types.h"
+
+#include "win32.h"
+// using namespace win32;
+
+// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc
+// https://learn.microsoft.com/en-us/windows/win32/winmsg/about-messages-and-message-queues#system-defined-messages
+LRESULT CALLBACK MainWindowCallback(
+ HWND handle,
+ UINT system_messages,
+ WPARAM w_param,
+ LPARAM l_param
)
{
- MessageBox( 0, L"First message!", L"Handmade Hero", MB_OK | MB_ICONINFORMATION );
+ LRESULT result;
+
+ // https://learn.microsoft.com/en-us/windows/win32/winmsg/window-notifications
+ switch ( system_messages )
+ {
+ case WM_ACTIVATEAPP:
+ {
+ OutputDebugStringA( "WM_ACTIVATEAPP\n" );
+ }
+ break;
+
+ case WM_CLOSE:
+ {
+ OutputDebugStringA( "WM_CLOSE\n" );
+ }
+ break;
+
+ case WM_DESTROY:
+ {
+ OutputDebugStringA( "WM_DESTROY\n" );
+ }
+ break;
+
+ case WM_PAINT:
+ {
+ PAINTSTRUCT info;
+ HDC device_context = BeginPaint( handle, & info );
+
+ u32 x = info.rcPaint.left;
+ u32 y = info.rcPaint.top;
+ u32 height = info.rcPaint.bottom - info.rcPaint.top;
+ u32 width = info.rcPaint.right - info.rcPaint.left;
+
+ global DWORD operation = RO_Whiteness;
+
+ PatBlt( device_context
+ , x, y
+ , width, height
+ , operation );
+
+ operation == RO_Whiteness ?
+ operation = RO_Blackness
+ : operation = RO_Whiteness;
+
+ EndPaint( handle, & info );
+ }
+ break;
+
+ case WM_SIZE:
+ {
+ OutputDebugStringA( "WM_SIZE\n" );
+ }
+ break;
+
+ default:
+ {
+ OutputDebugStringA( "default\n" );
+ result = DefWindowProc( handle, system_messages, w_param, l_param );
+ }
+ }
+
+ return result;
+}
+
+int CALLBACK WinMain(
+ HINSTANCE instance,
+ HINSTANCE prev_instance,
+ LPSTR commandline,
+ int show_command
+)
+{
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messagebox
+ // MessageBox( 0, L"First message!", L"Handmade Hero", MB_Ok_Btn | MB_Icon_Information );
+
+ // https://en.wikibooks.org/wiki/Windows_Programming/Window_Creation
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassa
+ WNDCLASS window_class {};
+ // window_class.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ window_class.style = CS_Own_Device_Context | CS_Horizontal_Redraw | CS_Vertical_Redraw;
+ window_class.lpfnWndProc = MainWindowCallback;
+ // window_class.cbClsExtra = ;
+ // window_class.cbWndExtra = ;
+ window_class.hInstance = instance;
+ // window_class.hIcon = ;
+ // window_class.hCursor = ;
+ // window_class.hbrBackground = ;
+ window_class.lpszMenuName = L"Handmade Hero!";
+ window_class.lpszClassName = L"HandmadeHeroWindowClass";
+
+ if ( RegisterClassW( &window_class ) )
+ {
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexa
+ // https://learn.microsoft.com/en-us/windows/win32/winmsg/window-styles
+ HWND window_handle = CreateWindowExW(
+ 0,
+ window_class.lpszClassName,
+ L"Handmade Hero",
+ // WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ WS_Overlapped_Window | WS_Initially_Visible,
+ CW_USEDEFAULT, CW_USEDEFAULT, // x, y
+ CW_USEDEFAULT, CW_USEDEFAULT, // width, height
+ 0, 0, // parent, menu
+ instance, 0 // instance, param
+ );
+
+ if ( window_handle )
+ {
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
+ // ShowWindow( window_handle, show_command );
+
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-updatewindow
+ // UpdateWindow( window_handle );
+
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage
+ MSG message;
+ for (;;)
+ {
+ BOOL msg_result = GetMessage( & message, 0, 0, 0 );
+ if ( msg_result > 0 )
+ {
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-translatemessage
+ TranslateMessage( & message );
+
+ // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-dispatchmessage
+ DispatchMessage( & message );
+ // break;
+ }
+ else
+ {
+ // TODO (Ed) : Logging
+ break;
+ }
+ }
+ }
+ else
+ {
+ // TODO (Ed) : Logging
+ }
+ }
+ else
+ {
+ // TODO(Ed) : Logging
+ }
return 0;
}
diff --git a/project/platform/grime.h b/project/platform/grime.h
new file mode 100644
index 0000000..77f1c17
--- /dev/null
+++ b/project/platform/grime.h
@@ -0,0 +1,111 @@
+#pragma region Platform Detection
+
+/* Platform architecture */
+
+#if defined( _WIN64 ) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( __64BIT__ ) || defined( __powerpc64__ ) || defined( __ppc64__ ) || defined( __aarch64__ )
+# ifndef GEN_ARCH_64_BIT
+# define GEN_ARCH_64_BIT 1
+# endif
+#else
+# ifndef GEN_ARCH_32_BItxt_StrCaT
+# define GEN_ARCH_32_BIT 1
+# endif
+#endif
+
+/* Platform OS */
+
+#if defined( _WIN32 ) || defined( _WIN64 )
+# ifndef GEN_SYSTEM_WINDOWS
+# define GEN_SYSTEM_WINDOWS 1
+# endif
+#elif defined( __APPLE__ ) && defined( __MACH__ )
+# ifndef GEN_SYSTEM_OSX
+# define GEN_SYSTEM_OSX 1
+# endif
+# ifndef GEN_SYSTEM_MACOS
+# define GEN_SYSTEM_MACOS 1
+# endif
+# include
+# if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1
+# ifndef GEN_SYSTEM_IOS
+# define GEN_SYSTEM_IOS 1
+# endif
+# endif
+#elif defined( __unix__ )
+# ifndef GEN_SYSTEM_UNIX
+# define GEN_SYSTEM_UNIX 1
+# endif
+# if defined( ANDROID ) || defined( __ANDROID__ )
+# ifndef GEN_SYSTEM_ANDROID
+# define GEN_SYSTEM_ANDROID 1
+# endif
+# ifndef GEN_SYSTEM_LINUX
+# define GEN_SYSTEM_LINUX 1
+# endif
+# elif defined( __linux__ )
+# ifndef GEN_SYSTEM_LINUX
+# define GEN_SYSTEM_LINUX 1
+# endif
+# elif defined( __FreeBSD__ ) || defined( __FreeBSD_kernel__ )
+# ifndef GEN_SYSTEM_FREEBSD
+# define GEN_SYSTEM_FREEBSD 1
+# endif
+# elif defined( __OpenBSD__ )
+# ifndef GEN_SYSTEM_OPENBSD
+# define GEN_SYSTEM_OPENBSD 1
+# endif
+# elif defined( __EMSCRIPTEN__ )
+# ifndef GEN_SYSTEM_EMSCRIPTEN
+# define GEN_SYSTEM_EMSCRIPTEN 1
+# endif
+# elif defined( __CYGWIN__ )
+# ifndef GEN_SYSTEM_CYGWIN
+# define GEN_SYSTEM_CYGWIN 1
+# endif
+# else
+# error This UNIX operating system is not supported
+# endif
+#else
+# error This operating system is not supported
+#endif
+
+/* Platform compiler */
+
+#if defined( _MSC_VER )
+# define GEN_COMPILER_MSVC 1
+#elif defined( __GNUC__ )
+# define GEN_COMPILER_GCC 1
+#elif defined( __clang__ )
+# define GEN_COMPILER_CLANG 1
+#elif defined( __MINGW32__ )
+# define GEN_COMPILER_MINGW 1
+# error Unknown compiler
+#endif
+
+#if defined( __has_attribute )
+# define GEN_HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
+#else
+# define GEN_HAS_ATTRIBUTE( attribute ) ( 0 )
+#endif
+
+#if defined(GEN_GCC_VERSION_CHECK)
+# undef GEN_GCC_VERSION_CHECK
+#endif
+#if defined(GEN_GCC_VERSION)
+# define GEN_GCC_VERSION_CHECK(major,minor,patch) (GEN_GCC_VERSION >= GEN_VERSION_ENCODE(major, minor, patch))
+#else
+# define GEN_GCC_VERSION_CHECK(major,minor,patch) (0)
+#endif
+
+#pragma endregion Platform Detection
+
+#pragma region Mandatory Includes
+
+# include
+# include
+
+# if defined( GEN_SYSTEM_WINDOWS )
+# include
+# endif
+
+#pragma endregion Mandatory Includes
diff --git a/project/platform/macros.h b/project/platform/macros.h
new file mode 100644
index 0000000..faace17
--- /dev/null
+++ b/project/platform/macros.h
@@ -0,0 +1,5 @@
+// Keywords
+
+#define global static // Global variables
+#define internal static // Internal linkage
+#define local_persist static // Local Persisting variables
diff --git a/project/platform/types.h b/project/platform/types.h
new file mode 100644
index 0000000..693db15
--- /dev/null
+++ b/project/platform/types.h
@@ -0,0 +1,120 @@
+#pragma region Basic Types
+
+#define U8_MIN 0u
+#define U8_MAX 0xffu
+#define I8_MIN ( -0x7f - 1 )
+#define I8_MAX 0x7f
+
+#define U16_MIN 0u
+#define U16_MAX 0xffffu
+#define I16_MIN ( -0x7fff - 1 )
+#define I16_MAX 0x7fff
+
+#define U32_MIN 0u
+#define U32_MAX 0xffffffffu
+#define I32_MIN ( -0x7fffffff - 1 )
+#define I32_MAX 0x7fffffff
+
+#define U64_MIN 0ull
+#define U64_MAX 0xffffffffffffffffull
+#define I64_MIN ( -0x7fffffffffffffffll - 1 )
+#define I64_MAX 0x7fffffffffffffffll
+
+#if defined( GEN_ARCH_32_BIT )
+# define USIZE_MIN GEN_U32_MIN
+# define USIZE_MAX GEN_U32_MAX
+# define ISIZE_MIN GEN_S32_MIN
+# define ISIZE_MAX GEN_S32_MAX
+#elif defined( GEN_ARCH_64_BIT )
+# define USIZE_MIN GEN_U64_MIN
+# define USIZE_MAX GEN_U64_MAX
+# define ISIZE_MIN GEN_I64_MIN
+# define ISIZE_MAX GEN_I64_MAX
+#else
+# error Unknown architecture size. This library only supports 32 bit and 64 bit architectures.
+#endif
+
+#define F32_MIN 1.17549435e-38f
+#define F32_MAX 3.40282347e+38f
+#define F64_MIN 2.2250738585072014e-308
+#define F64_MAX 1.7976931348623157e+308
+
+#if defined( GEN_COMPILER_MSVC )
+# if _MSC_VER < 1300
+typedef unsigned char u8;
+typedef signed char s8;
+typedef unsigned short u16;
+typedef signed short s16;
+typedef unsigned int u32;
+typedef signed int s32;
+# else
+typedef unsigned __int8 u8;
+typedef signed __int8 s8;
+typedef unsigned __int16 u16;
+typedef signed __int16 s16;
+typedef unsigned __int32 u32;
+typedef signed __int32 s32;
+# endif
+typedef unsigned __int64 u64;
+typedef signed __int64 s64;
+#else
+# include
+
+typedef uint8_t u8;
+typedef int8_t s8;
+typedef uint16_t u16;
+typedef int16_t s16;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint64_t u64;
+typedef int64_t s64;
+#endif
+
+static_assert( sizeof( u8 ) == sizeof( s8 ), "sizeof(u8) != sizeof(s8)" );
+static_assert( sizeof( u16 ) == sizeof( s16 ), "sizeof(u16) != sizeof(s16)" );
+static_assert( sizeof( u32 ) == sizeof( s32 ), "sizeof(u32) != sizeof(s32)" );
+static_assert( sizeof( u64 ) == sizeof( s64 ), "sizeof(u64) != sizeof(s64)" );
+
+static_assert( sizeof( u8 ) == 1, "sizeof(u8) != 1" );
+static_assert( sizeof( u16 ) == 2, "sizeof(u16) != 2" );
+static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" );
+static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" );
+
+typedef size_t uw;
+typedef ptrdiff_t sw;
+
+static_assert( sizeof( uw ) == sizeof( sw ), "sizeof(uw) != sizeof(sw)" );
+
+// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
+#if defined( _WIN64 )
+typedef signed __int64 sptr;
+typedef unsigned __int64 uptr;
+#elif defined( _WIN32 )
+// NOTE; To mark types changing their size, e.g. zpl_intptr
+# ifndef _W64
+# if ! defined( __midl ) && ( defined( _X86_ ) || defined( _M_IX86 ) ) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+# endif
+typedef _W64 signed int sptr;
+typedef _W64 unsigned int uptr;
+#else
+typedef uintptr_t uptr;
+typedef intptr_t sptr;
+#endif
+
+static_assert( sizeof( uptr ) == sizeof( sptr ), "sizeof(uptr) != sizeof(sptr)" );
+
+typedef float f32;
+typedef double f64;
+
+static_assert( sizeof( f32 ) == 4, "sizeof(f32) != 4" );
+static_assert( sizeof( f64 ) == 8, "sizeof(f64) != 8" );
+
+typedef s8 b8;
+typedef s16 b16;
+typedef s32 b32;
+
+#pragma endregion Basic Types
diff --git a/project/platform/win32.h b/project/platform/win32.h
index e4c48d3..064a8e5 100644
--- a/project/platform/win32.h
+++ b/project/platform/win32.h
@@ -5,8 +5,121 @@ Alternative header for windows.h
#include "windows/windows_base.h"
#include "windows/window.h"
-#ifdef UNICODE
-constexpr auto MessageBox = MessageBoxW;
+// #ifdef Build_Debug
+# include "windows/dbghelp.h"
+// #endif
+
+#if Build_DLL
+# define WIN_LIBRARY_API extern "C" __declspec(dllexport)
#else
-constexpr auto MessageBox = MessageBoxA;
+# define WIN_LIBRARY_API extern "C"
+#endif
+
+#ifndef CONST
+# define CONST const
+#endif
+
+#define WM_ACTIVATEAPP 0x001C
+
+
+// namespace win32 {
+
+#ifdef UNICODE
+ constexpr auto CreateWindowEx = CreateWindowExW;
+#else
+ constexpr auto CreateWindowEx = CreateWindowExA;
#endif // !UNICODE
+
+#ifdef UNICODE
+ constexpr auto DefWindowProc = DefWindowProcW;
+#else
+ constexpr auto DefWindowProc = DefWindowProcA;
+#endif // !UNICODE
+
+#ifdef UNICODE
+ constexpr auto DispatchMessage = DispatchMessageW;
+#else
+ constexpr auto DispatchMessage = DispatchMessageA;
+#endif // !UNICODE
+
+#pragma region Message Function Templates
+// From WinUser.h, modular headers lib doesn't have.
+
+WIN_LIBRARY_API BOOL WINAPI GetMessageA(
+ LPMSG lpMsg,
+ HWND hWnd,
+ UINT wMsgFilterMin,
+ UINT wMsgFilterMax);
+WIN_LIBRARY_API BOOL WINAPI GetMessageW(
+ LPMSG lpMsg,
+ HWND hWnd,
+ UINT wMsgFilterMin,
+ UINT wMsgFilterMax);
+#ifdef UNICODE
+ constexpr auto GetMessage = GetMessageW;
+#else
+ constexpr auto GetMessage = GetMessageA;
+#endif // !UNICODE
+
+#ifdef UNICODE
+ constexpr auto MessageBox = MessageBoxW;
+#else
+ constexpr auto MessageBox = MessageBoxA;
+#endif // !UNICODE
+
+#ifdef UNICODE
+ constexpr auto RegisterClass = RegisterClassW;
+#else
+ constexpr auto RegisterClass = RegisterClassA;
+#endif // !UNICODE
+#pragma endregion Message Function Templates
+
+#pragma region Window PAINT
+typedef struct tagPAINTSTRUCT {
+ HDC hdc;
+ BOOL fErase;
+ RECT rcPaint;
+ BOOL fRestore;
+ BOOL fIncUpdate;
+ BYTE rgbReserved[32];
+} PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;
+
+WIN_LIBRARY_API HDC WINAPI
+BeginPaint( HWND hWnd, LPPAINTSTRUCT lpPaint );
+
+WIN_LIBRARY_API BOOL WINAPI
+EndPaint( HWND hWnd, CONST PAINTSTRUCT *lpPaint );
+
+WIN_LIBRARY_API BOOL WINAPI PatBlt( HDC hdc, int x, int y, int w, int h, DWORD rop );
+#pragma endregion Window PAINT
+
+// Class Style Constants
+// https://learn.microsoft.com/en-us/windows/win32/winmsg/about-window-classes
+// https://learn.microsoft.com/en-us/windows/win32/winmsg/window-class-styles
+
+enum CS : UINT
+{
+ CS_Own_Device_Context = CS_OWNDC,
+ CS_Horizontal_Redraw = CS_HREDRAW,
+ CS_Vertical_Redraw = CS_VREDRAW,
+};
+
+enum MB : UINT
+{
+ MB_Ok_Btn = MB_OK,
+ MB_Icon_Information = MB_ICONINFORMATION,
+};
+
+enum WS : UINT
+{
+ WS_Overlapped_Window = WS_OVERLAPPEDWINDOW,
+ WS_Initially_Visible = WS_VISIBLE,
+};
+
+enum RasterOps : DWORD
+{
+ RO_Blackness = (DWORD)0x00000042,
+ RO_Whiteness = (DWORD)0x00FF0062,
+};
+
+// }
diff --git a/scripts/build.ps1 b/scripts/build.ps1
index d67f04a..9e13bf0 100644
--- a/scripts/build.ps1
+++ b/scripts/build.ps1
@@ -319,23 +319,26 @@ $linker_args = @(
)
#region Handmade Generate
-$unit = Join-Path $path_gen 'handmade_gen.cpp'
-$executable = Join-Path $path_build 'handmade_gen.exe'
-
-build-simple $includes $compiler_args $linker_args $unit $executable
-write-host
-
-& $executable
-write-host
-
if ( $false ) {
- Remove-Item (Get-ChildItem -Path $path_build -Recurse -Force)
+ $unit = Join-Path $path_gen 'handmade_gen.cpp'
+ $executable = Join-Path $path_build 'handmade_gen.exe'
+
+ build-simple $includes $compiler_args $linker_args $unit $executable
+ write-host
+
+ & $executable
+ write-host
+
+ if ( $false ) {
+ Remove-Item (Get-ChildItem -Path $path_build -Recurse -Force)
+ }
}
#endregion Handmade Generate
#region Handmade Runtime
$lib_user32 = 'User32.lib'
+$lib_gdi32 = 'Gdi32.lib'
$unit = Join-Path $path_project 'handmade_win32.cpp'
$executable = Join-Path $path_build 'handmade_win32.exe'
@@ -343,6 +346,7 @@ $executable = Join-Path $path_build 'handmade_win32.exe'
$compiler_args = @()
$linker_args = @(
+ $lib_gdi32,
$lib_user32,
$flag_link_win_subsystem_windows
)