diff --git a/project/handmade_win32.cpp b/project/handmade_win32.cpp index c1cf2b2..31261fb 100644 --- a/project/handmade_win32.cpp +++ b/project/handmade_win32.cpp @@ -1,8 +1,11 @@ -#include +#include "win32.h" -int main() +int CALLBACK WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nShowCmd +) { - puts("Handmade Hero!"); - return 0; } diff --git a/project/platform/win32.h b/project/platform/win32.h new file mode 100644 index 0000000..7c670f9 --- /dev/null +++ b/project/platform/win32.h @@ -0,0 +1,6 @@ +/* +Alternative header for windows.h +*/ + +#include "windows/windows_base.h" + diff --git a/project/platform/windows/windows_base.h b/project/platform/windows/windows_base.h new file mode 100644 index 0000000..bfc1205 --- /dev/null +++ b/project/platform/windows/windows_base.h @@ -0,0 +1,392 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Copyright (c) Arvid Gerstmann. All rights reserved. + */ +#ifndef _WINDOWS_ +#ifndef WINDOWS_BASE_H +#define WINDOWS_BASE_H + +/* Disable all warnings */ +#if defined(_MSC_VER) + #pragma warning(push, 0) +#endif +#if defined(__cplusplus) +extern "C" { +#endif + +/* size_t */ +/* #include */ + + +/* + * Windows Version requirements: Vista + * See here for more information regarding this define: + * https://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx + */ +#ifndef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 +#endif + +/* Magic: */ +#define _CRTALLOC(x) __declspec(allocate(x)) +#define DECLSPEC_ALIGN(x) __declspec(align(x)) + +/* Basic Defines: */ +#define NTAPI __stdcall +#define WINAPI __stdcall +#define APIENTRY __stdcall +#define CALLBACK __stdcall +#define TRUE (1) +#define FALSE (0) +#ifndef NULL +# ifdef __cplusplus +# define NULL __nullptr +# else +# define NULL ((void *)0) +# endif +#endif +#ifndef FORCEINLINE +#define FORCEINLINE __forceinline +#endif +#ifdef UNICODE +#define __TEXT(x) L ## x +#define TEXT(x) __TEXT(x) +#else +#define TEXT(x) x +#endif +#define PATH_MAX 260 +#define MAX_PATH 260 + +#define MAKEWORD(a, b) \ + ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | \ + ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8)) +#define MAKELONG(a, b) \ + ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | \ + ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16)) +#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff)) +#define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff)) +#define LOBYTE(w) ((BYTE)(((DWORD_PTR)(w)) & 0xff)) +#define HIBYTE(w) ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff)) + +#if !defined(_68K_) \ + && !defined(_MPPC_) \ + && !defined(_X86_) \ + && !defined(_IA64_) \ + && !defined(_AMD64_) \ + && defined(_M_AMD64) +#define _AMD64_ +#endif + +/* + * Windows uses the `interface` define to create interfaces for both C and C++. + * Only the C version is defined here and not the C++ version. + * Both can be found in BaseTyps.h + */ +#define STDMETHODCALLTYPE __stdcall +#define STDMETHODVCALLTYPE __cdecl +#define STDAPICALLTYPE __stdcall +#define STDAPIVCALLTYPE __cdecl + +#define interface struct +#define PURE +#define THIS_ INTERFACE * This, +#define THIS INTERFACE * This +#define STDMETHOD(method) HRESULT (STDMETHODCALLTYPE * method) +#define STDMETHOD_(type, method) type (STDMETHODCALLTYPE * method) +#define STDMETHODV(method) HRESULT (STDMETHODVCALLTYPE * method) +#define STDMETHODV_(type, method) type (STDMETHODVCALLTYPE * method) + +#define IFACEMETHOD(method) __override STDMETHOD(method) +#define IFACEMETHOD_(type, method) __override STDMETHOD_(type,method) +#define IFACEMETHODV(method) __override STDMETHODV(method) +#define IFACEMETHODV_(type, method) __override STDMETHODV_(type,method) + +#define BEGIN_INTERFACE +#define END_INTERFACE + +#ifdef CONST_VTABLE +#undef CONST_VTBL +#define CONST_VTBL const +#define DECLARE_INTERFACE(iface) \ + typedef interface iface { \ + const struct iface##Vtbl * lpVtbl; \ + } iface; \ + typedef const struct iface##Vtbl iface##Vtbl; \ + const struct iface##Vtbl + +#else + +#undef CONST_VTBL +#define CONST_VTBL +#define DECLARE_INTERFACE(iface) \ + typedef interface iface { \ + struct iface##Vtbl * lpVtbl; \ + } iface; \ + typedef struct iface##Vtbl iface##Vtbl; \ + struct iface##Vtbl + +#endif /* CONST_VTABLE */ + +#define DECLARE_INTERFACE_(iface, baseiface) DECLARE_INTERFACE(iface) + + +#define HRESULT_IS_WIN32(x) \ + ((((x) >> 16) & 0xFFFF) == 0x8) +#define HRESULT_IS_FAILURE(x) \ + ((((x) >> 31) & 0x1) == 0x1) +#define HRESULT_FACILITY(x) \ + (((x) >> 16) & 0xFFFF) +#define HRESULT_CODE(x) \ + ((x) & 0xFFFF) +#define HRESULT_FROM_WIN32(x) \ + (0x80070000 | (x)) + + +/* ========================================================================== */ +/* Basic Types: */ +/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx */ +/* ========================================================================== */ + +#if defined(_MSC_VER) + /* 1300 == VC 6.0 */ + #if _MSC_VER < 1300 + typedef signed char int8_t; + typedef unsigned char uint8_t; + typedef signed short int16_t; + typedef unsigned short uint16_t; + typedef signed int int32_t; + typedef unsigned int uint32_t; + #else + typedef signed __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef signed __int16 int16_t; + typedef unsigned __int16 uint16_t; + typedef signed __int32 int32_t; + typedef unsigned __int32 uint32_t; + #endif + typedef signed __int64 int64_t; + typedef unsigned __int64 uint64_t; +#else + #include +#endif + + +typedef int BOOL; +typedef char CHAR; +typedef short SHORT; +typedef int INT; +typedef long LONG; +typedef unsigned char UCHAR; +typedef unsigned short USHORT; +typedef unsigned int UINT; +typedef unsigned long ULONG; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef float FLOAT; +typedef unsigned long DWORD; +#ifndef HAVE_WCHAR_T +#define HAVE_WCHAR_T +#if !defined(__cplusplus) +typedef unsigned short wchar_t; +#endif +#endif +typedef wchar_t WCHAR; +typedef wchar_t * PWCHAR; +typedef WORD ATOM; +typedef unsigned int ULONG32; +typedef uint64_t DWORD64; +typedef uint64_t ULONG64; +typedef signed int INT32; +typedef signed __int64 INT64; +typedef uint64_t DWORDLONG; + +typedef CHAR * PCHAR; +typedef ULONG * PULONG; +typedef BYTE * PBYTE; +typedef ULONG64 * PULONG64; +typedef DWORD64 * PDWORD64; + +#if !defined(_M_IX86) +typedef int64_t LONGLONG; +typedef uint64_t ULONGLONG; +#else +typedef double LONGLONG; +typedef double ULONGLONG; +#endif + +typedef void VOID; +typedef void * PVOID; +typedef void * LPVOID; +typedef BOOL * PBOOL; +typedef BOOL * LPBOOL; +typedef WORD * PWORD; +typedef LONG * PLONG; +typedef LONG * LPLONG; +typedef DWORD * PDWORD; + +typedef LPVOID HANDLE; +typedef HANDLE HINSTANCE; +typedef HANDLE HWND; +typedef HINSTANCE HMODULE; +typedef HANDLE HDC; +typedef HANDLE HGLRC; +typedef HANDLE HMENU; +typedef HANDLE * PHANDLE; +typedef HANDLE * LPHANDLE; + +#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name + +typedef WCHAR * PWSTR; +typedef BYTE * LPBYTE; +typedef long * LPLONG; +typedef DWORD * LPDWORD; +typedef const void * LPCVOID; + +#if defined(_WIN64) +typedef int64_t INT_PTR; +typedef int64_t LONG_PTR; +typedef uint64_t UINT_PTR; +typedef uint64_t ULONG_PTR; +#else +typedef int INT_PTR; +typedef long LONG_PTR; +typedef unsigned int UINT_PTR; +typedef unsigned long ULONG_PTR; +#endif +typedef ULONG_PTR DWORD_PTR; +typedef DWORD_PTR * PDWORD_PTR; + +typedef ULONG_PTR SIZE_T; +typedef LONG_PTR SSIZE_T; + +typedef CHAR * LPSTR; +typedef WCHAR * LPWSTR; +typedef const CHAR * LPCSTR; +typedef const WCHAR * LPCWSTR; +#if defined(UNICODE) +typedef WCHAR TCHAR; +typedef WCHAR TBYTE; +typedef LPCWSTR LPCTSTR; +typedef LPWSTR LPTSTR; +#else +typedef char TCHAR; +typedef unsigned char TBYTE; +typedef LPCSTR LPCTSTR; +typedef LPSTR LPTSTR; +#endif + +#define MINCHAR 0x80 +#define MAXCHAR 0x7f +#define MINSHORT 0x8000 +#define MAXSHORT 0x7fff +#define MINLONG 0x80000000 +#define MAXLONG 0x7fffffff +#define MAXBYTE 0xff +#define MAXWORD 0xffff +#define MAXDWORD 0xffffffff + +#if defined(_WIN64) +typedef INT_PTR (WINAPI *FARPROC)(void); +typedef INT_PTR (WINAPI *NEARPROC)(void); +typedef INT_PTR (WINAPI *PROC)(void); +#else +typedef int (WINAPI *FARPROC)(void); +typedef int (WINAPI *NEARPROC)(void); +typedef int (WINAPI *PROC)(void); +#endif + +typedef DWORD ACCESS_MASK; +typedef ACCESS_MASK * PACCESS_MASK; + +typedef HANDLE HICON; +typedef HANDLE HBRUSH; +typedef HICON HCURSOR; + +typedef LONG HRESULT; +typedef LONG_PTR LRESULT; +typedef LONG_PTR LPARAM; +typedef UINT_PTR WPARAM; + +typedef void * HGDIOBJ; + +typedef HANDLE HKEY; +typedef HKEY * PHKEY; +typedef ACCESS_MASK REGSAM; + + +/* ========================================================================== */ +/* Errors: */ +/* ========================================================================== */ +#define ERROR_SUCCESS 0L +#define ERROR_FILE_NOT_FOUND 2L +#define ERROR_PATH_NOT_FOUND 3L +#define ERROR_TOO_MANY_OPEN_FILES 4L +#define ERROR_ACCESS_DENIED 5L +#define ERROR_NO_MORE_FILES 18L +#define ERROR_SHARING_VIOLATION 32L +#define ERROR_FILE_EXISTS 80L +#define ERROR_INSUFFICIENT_BUFFER 122L +#define ERROR_ALREADY_EXISTS 183L +#define ERROR_MORE_DATA 234L + + +/* ========================================================================== */ +/* Enums */ +/* ========================================================================== */ +/* DllMain Reason: */ +#define DLL_PROCESS_ATTACH (1) +#define DLL_PROCESS_DETACH (0) +#define DLL_THREAD_ATTACH (2) +#define DLL_THREAD_DETACH (3) + + +/* ========================================================================== */ +/* Structures: */ +/* ========================================================================== */ +typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + LPVOID lpSecurityDescriptor; + BOOL bInheritHandle; +} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + +typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + }; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; +} LARGE_INTEGER, *PLARGE_INTEGER; + +typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + }; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; +} ULARGE_INTEGER, *PULARGE_INTEGER; + +/* Filetime: */ +typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *PFILETIME, *LPFILETIME; + + +#if defined(__cplusplus) +} +#endif +/* Enable all warnings */ +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + +#endif /* WINDOWS_BASE_H */ +#endif /* _WINDOWS_ */ diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 56b037c..da725c2 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -149,13 +149,13 @@ if ( $vendor -match "clang" ) function build-simple { - param( $includes, $unit, $executable ) + param( [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$executable ) Write-Host "build-simple: clang" $object = $executable -replace '\.exe', '.obj' $pdb = $executable -replace '\.exe', '.pdb' - $compiler_args = @( + $compiler_args += @( $flag_no_color_diagnostics, $flag_target_arch, $target_arch, $flag_wall, @@ -179,8 +179,7 @@ if ( $vendor -match "clang" ) $compiler_args += $flag_compile, $unit run-compiler $compiler $unit $compiler_args - $linker_args = @( - $flag_link_win_subsystem_console, + $linker_args += @( $flag_link_win_machine_64, $( $flag_link_win_path_output + $executable ) ) @@ -206,37 +205,37 @@ if ( $vendor -match "clang" ) if ( $vendor -match "msvc" ) { # https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 - $flag_compile = '/c' - $flag_debug = '/Zi' - $flag_define = '/D' - $flag_include = '/I' - $flag_full_src_path = '/FC' - $flag_nologo = '/nologo' - $flag_dll = '/LD' - $flag_dll_debug = '/LDd' - $flag_linker = '/link' - $flag_link_debug = '/DEBUG' - $flag_link_pdb = '/PDB:' - $flag_link_machine_32 = '/MACHINE:X86' - $flag_link_machine_64 = '/MACHINE:X64' - $flag_link_path_output = '/OUT:' - $flag_link_rt_dll = '/MD' - $flag_link_rt_dll_debug = '/MDd' - $flag_link_rt_static = '/MT' - $flag_link_rt_static_debug = '/MTd' - $flag_link_subsystem_console = '/SUBSYSTEM:CONSOLE' - $flag_link_subsystem_windows = '/SUBSYSTEM:WINDOWS' - $flag_no_optimization = '/Od' - $flag_out_name = '/OUT:' - $flag_path_interm = '/Fo' - $flag_path_debug = '/Fd' - $flag_path_output = '/Fe' - $flag_preprocess_conform = '/Zc:preprocessor' + $flag_compile = '/c' + $flag_debug = '/Zi' + $flag_define = '/D' + $flag_include = '/I' + $flag_full_src_path = '/FC' + $flag_nologo = '/nologo' + $flag_dll = '/LD' + $flag_dll_debug = '/LDd' + $flag_linker = '/link' + $flag_link_win_debug = '/DEBUG' + $flag_link_win_pdb = '/PDB:' + $flag_link_win_machine_32 = '/MACHINE:X86' + $flag_link_win_machine_64 = '/MACHINE:X64' + $flag_link_win_path_output = '/OUT:' + $flag_link_win_rt_dll = '/MD' + $flag_link_win_rt_dll_debug = '/MDd' + $flag_link_win_rt_static = '/MT' + $flag_link_win_rt_static_debug = '/MTd' + $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' + $flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' + $flag_no_optimization = '/Od' + $flag_out_name = '/OUT:' + $flag_path_interm = '/Fo' + $flag_path_debug = '/Fd' + $flag_path_output = '/Fe' + $flag_preprocess_conform = '/Zc:preprocessor' # This works because this project uses a single unit to build function build-simple { - param( [array]$includes, [array]$compiler_args, [string]$unit, [string]$executable ) + param( [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$executable ) Write-Host "build-simple: msvc" $object = $executable -replace '\.exe', '.obj' @@ -245,33 +244,32 @@ if ( $vendor -match "msvc" ) $compiler_args += @( $flag_nologo, $flag_preprocess_conform, - $flag_debug, $flag_full_src_path, ( $flag_path_interm + $path_build + '\' ), ( $flag_path_output + $path_build + '\' ) ) if ( $release -eq $false ) { + $compiler_args += $flag_debug $compiler_args += ( $flag_define + 'Build_Debug' ) $compiler_args += ( $flag_path_debug + $path_build + '\' ) - $compiler_args += $flag_link_rt_static_debug + $compiler_args += $flag_link_win_rt_static_debug $compiler_args += $flag_no_optimization } else { - $compiler_args += $flag_link_rt_static + $compiler_args += $flag_link_win_rt_static } $compiler_args += $includes | ForEach-Object { $flag_include + $_ } $compiler_args += $flag_compile, $unit run-compiler $compiler $unit $compiler_args - $linker_args = @( + $linker_args += @( $flag_nologo, - $flag_link_machine_64, - $flag_link_subsystem_console, - ( $flag_link_path_output + $executable ) + $flag_link_win_machine_64, + ( $flag_link_win_path_output + $executable ) ) if ( $release -eq $false ) { - $linker_args += $flag_link_debug - $linker_args += $flag_link_pdb + $pdb + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb } else { } @@ -285,10 +283,11 @@ if ( $vendor -match "msvc" ) } #endregion Configuration -$path_project = Join-Path $path_root 'project' -$path_build = Join-Path $path_root 'build' -$path_deps = Join-Path $path_project 'dependencies' -$path_gen = Join-Path $path_project 'gen' +$path_project = Join-Path $path_root 'project' +$path_build = Join-Path $path_root 'build' +$path_deps = Join-Path $path_project 'dependencies' +$path_gen = Join-Path $path_project 'gen' +$path_platform = Join-Path $path_project 'platform' $update_deps = Join-Path $PSScriptRoot 'update_deps.ps1' @@ -301,20 +300,25 @@ if ( (Test-Path $path_deps) -eq $false ) { } $includes = @( - $path_gen, $path_project, - $path_deps + $path_gen, + $path_deps, + $path_platform ) -$compiler_args = @( - ($flag_define + 'GEN_TIME') +$compiler_args = @() +$compiler_args += ( $flag_define + 'GEN_TIME' ) + +$linker_args = @( + $flag_link_win_subsystem_console ) #region Handmade Generate -$unit = Join-Path $path_gen 'gen_handmade.cpp' -$executable = Join-Path $path_build 'gen_handmade.exe' +$unit = Join-Path $path_gen 'handmade_gen.cpp' +$executable = Join-Path $path_build 'handmade_gen.exe' -build-simple $includes $compiler_args $unit $executable +build-simple $includes $compiler_args $linker_args $unit $executable +write-host & $executable write-host @@ -329,10 +333,13 @@ if ( $false ) { $unit = Join-Path $path_project 'handmade_win32.cpp' $executable = Join-Path $path_build 'handmade_win32.exe' -$compile_args = @( +$compiler_args = @() + +$linker_args = @( + $flag_link_win_subsystem_windows ) -build-simple $includes $compiler_args $unit $executable +build-simple $includes $compiler_args $linker_args $unit $executable #endregion Handmade Runtime Pop-Location