mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-12-21 22:14:43 -08:00
Day 40 complete
This commit is contained in:
parent
193b71ff92
commit
fa28d401ef
14
README.md
14
README.md
@ -33,7 +33,7 @@ Module build order:
|
|||||||
|
|
||||||
## Milestone
|
## Milestone
|
||||||
|
|
||||||
Day 39 : Basic Bitmap Rendering Cleanup
|
Day 40 : Cursor Hiding and Fullscreen Support
|
||||||
|
|
||||||
Features Done so far:
|
Features Done so far:
|
||||||
|
|
||||||
@ -44,14 +44,17 @@ Features Done so far:
|
|||||||
* Will automatically not run if app process is found (for engine module).
|
* Will automatically not run if app process is found (for engine module).
|
||||||
* Can emit exported mangled symbols for the engine module for hot-reload with the platform module without needing to use C linkage symbols or a complex hot-reload library (Live++, etc).
|
* Can emit exported mangled symbols for the engine module for hot-reload with the platform module without needing to use C linkage symbols or a complex hot-reload library (Live++, etc).
|
||||||
* Platform Layer:
|
* Platform Layer:
|
||||||
|
* Block Memory allocation via VirtualAlloc for engine module
|
||||||
|
* Memory mapped files for engine & game snapshots.
|
||||||
|
* Instantaneous hot reload of engine module
|
||||||
|
* Software rendering via Win32 GDI
|
||||||
* Direct Sound audio
|
* Direct Sound audio
|
||||||
* Keyboard & Mouse Input via GetAsyncKeyState & Win32 window messagng
|
* Keyboard & Mouse Input via GetAsyncKeyState & Win32 window messagng
|
||||||
* XInput controller support
|
* XInput controller support
|
||||||
* Dualsense controller support via joyshock library
|
* Dualsense controller support via joyshock library
|
||||||
* Software rendering via Win32 GDI
|
* Fullscreen toggle
|
||||||
* Instantaneous hot reload of engine module
|
* Can't change refresh rate
|
||||||
* Block Memory allocation via VirtualAlloc for engine module
|
* Auto-hide cursor in client region (painted surface), not using editor tools
|
||||||
* Memory mapped files for engine & game snapshots.
|
|
||||||
* Engine Layer:
|
* Engine Layer:
|
||||||
* Take & load snapshots of either the engine's or game's memory state.
|
* Take & load snapshots of either the engine's or game's memory state.
|
||||||
* Allows for engine or game state to be restored even if a crash occurs to exact memory state it was before.
|
* Allows for engine or game state to be restored even if a crash occurs to exact memory state it was before.
|
||||||
@ -68,6 +71,7 @@ Features Done so far:
|
|||||||
|
|
||||||
## Gallery
|
## Gallery
|
||||||
|
|
||||||
|
![img](docs/imgs/10x_2023-10-22_01-44-21.gif)
|
||||||
![img](docs/imgs/handmade_win32_2023-10-21_22-18-47.gif)
|
![img](docs/imgs/handmade_win32_2023-10-21_22-18-47.gif)
|
||||||
![img](docs/imgs/handmade_win32_2023-10-21_02-16-43.png)
|
![img](docs/imgs/handmade_win32_2023-10-21_02-16-43.png)
|
||||||
![img](docs/imgs/handmade_win32_2023-10-20_23-14-37.png)
|
![img](docs/imgs/handmade_win32_2023-10-20_23-14-37.png)
|
||||||
|
BIN
docs/imgs/10x_2023-10-22_01-44-21.gif
Normal file
BIN
docs/imgs/10x_2023-10-22_01-44-21.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 MiB |
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning( disable: 4201 ) // Support for non-standard nameless struct or union extesnion
|
#pragma warning( disable: 4201 ) // Support for non-standard nameless struct or union extesnion
|
||||||
#pragma warning( disable: 4100 ) // Support for unreferenced formal parameters
|
#pragma warning( disable: 4100 ) // Support for unreferenced formal parameters
|
||||||
|
@ -59,7 +59,7 @@ enum CS : UINT
|
|||||||
CS_Horizontal_Redraw = CS_HREDRAW,
|
CS_Horizontal_Redraw = CS_HREDRAW,
|
||||||
CS_Vertical_Redraw = CS_VREDRAW,
|
CS_Vertical_Redraw = CS_VREDRAW,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CW : s32
|
enum CW : s32
|
||||||
{
|
{
|
||||||
CW_Use_Default = CW_USEDEFAULT,
|
CW_Use_Default = CW_USEDEFAULT,
|
||||||
|
@ -14,10 +14,7 @@
|
|||||||
- Asset loading path
|
- Asset loading path
|
||||||
- Threading (launch a thread)
|
- Threading (launch a thread)
|
||||||
- Raw Input (support for multiple keyboards)
|
- Raw Input (support for multiple keyboards)
|
||||||
- Sleep / timeBeginPeriod
|
|
||||||
- ClipCursor() (for multimonitor support)
|
- ClipCursor() (for multimonitor support)
|
||||||
- Fullscreen support
|
|
||||||
- WM_SETCURSOR (control cursor visibility)
|
|
||||||
- QueryCancelAutoplay
|
- QueryCancelAutoplay
|
||||||
- WM_ACTIVATEAPP (for when not active)
|
- WM_ACTIVATEAPP (for when not active)
|
||||||
- Blit speed improvemnts (BitBlt)
|
- Blit speed improvemnts (BitBlt)
|
||||||
@ -64,6 +61,10 @@ global StrPath Path_Scratch;
|
|||||||
// TODO(Ed) : This is a global for now.
|
// TODO(Ed) : This is a global for now.
|
||||||
global b32 Running = false;
|
global b32 Running = false;
|
||||||
|
|
||||||
|
global b32 Show_Windows_Cursor;
|
||||||
|
global HCURSOR Windows_Cursor;
|
||||||
|
global WINDOWPLACEMENT Window_Position;
|
||||||
|
|
||||||
global WinDimensions Window_Dimensions;
|
global WinDimensions Window_Dimensions;
|
||||||
global OffscreenBuffer Surface_Back_Buffer;
|
global OffscreenBuffer Surface_Back_Buffer;
|
||||||
|
|
||||||
@ -145,6 +146,37 @@ NS_PLATFORM_END
|
|||||||
NS_PLATFORM_BEGIN
|
NS_PLATFORM_BEGIN
|
||||||
#pragma region Windows Sandbox Interface
|
#pragma region Windows Sandbox Interface
|
||||||
|
|
||||||
|
internal
|
||||||
|
void toggle_fullscreen( HWND window_handle )
|
||||||
|
{
|
||||||
|
// Note(Ed) : Follows: https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
|
||||||
|
DWORD style = GetWindowLongA( window_handle, GWL_STYLE );
|
||||||
|
if ( style & WS_OVERLAPPEDWINDOW )
|
||||||
|
{
|
||||||
|
MONITORINFO info = { sizeof(MONITORINFO) };
|
||||||
|
HMONITOR monitor_handle = MonitorFromWindow( window_handle, MONITOR_DEFAULTTOPRIMARY );
|
||||||
|
|
||||||
|
if ( GetWindowPlacement( window_handle, & Window_Position )
|
||||||
|
&& GetMonitorInfoA( monitor_handle, & info ) )
|
||||||
|
{
|
||||||
|
SetWindowLongA( window_handle, GWL_STYLE, style & ~WS_OVERLAPPEDWINDOW );
|
||||||
|
SetWindowPos( window_handle, HWND_TOP
|
||||||
|
, info.rcMonitor.left, info.rcMonitor.top
|
||||||
|
, info.rcWork.right - info.rcMonitor.left, info.rcMonitor.bottom - info.rcMonitor.top
|
||||||
|
, SWP_NOOWNERZORDER | SWP_FRAMECHANGED
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetWindowLongA( window_handle, GWL_STYLE , style | WS_OVERLAPPEDWINDOW );
|
||||||
|
SetWindowPlacement( window_handle, & Window_Position );
|
||||||
|
SetWindowPos( window_handle, NULL
|
||||||
|
, 0, 0, 0, 0
|
||||||
|
, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal WinDimensions
|
internal WinDimensions
|
||||||
get_window_dimensions( HWND window_handle )
|
get_window_dimensions( HWND window_handle )
|
||||||
{
|
{
|
||||||
@ -161,6 +193,19 @@ display_buffer_in_window( HDC device_context, s32 window_width, s32 window_heigh
|
|||||||
, s32 x, s32 y
|
, s32 x, s32 y
|
||||||
, s32 width, s32 height )
|
, s32 width, s32 height )
|
||||||
{
|
{
|
||||||
|
if ( (window_width % buffer->width ) == 0
|
||||||
|
&& (window_height % buffer->height) == 0 )
|
||||||
|
{
|
||||||
|
// TODO(Ed) : Aspect ratio correction
|
||||||
|
StretchDIBits( device_context
|
||||||
|
, 0, 0, window_width, window_height
|
||||||
|
, 0, 0, buffer->width, buffer->height
|
||||||
|
, buffer->memory, & buffer->info
|
||||||
|
, DIB_ColorTable_RGB, RO_Source_To_Dest );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
s32 offset_x = 0;
|
s32 offset_x = 0;
|
||||||
s32 offset_y = 0;
|
s32 offset_y = 0;
|
||||||
|
|
||||||
@ -259,7 +304,7 @@ main_window_callback( HWND handle
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// SetLayeredWindowAttributes( handle, RGB(0, 0, 0), 120, LWA_Alpha );
|
// SetLayeredWindowAttributes( handle, RGB(0, 0, 0), 120, LWA_Alpha );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -296,21 +341,31 @@ main_window_callback( HWND handle
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// TODO(Ed) : Expose cursor toggling to engine via platform api (lets game control it for its ux purposes)
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
{
|
{
|
||||||
RECT rect;
|
|
||||||
POINT pt = { LOWORD(l_param), HIWORD(l_param) };
|
|
||||||
|
|
||||||
GetClientRect(handle, &rect);
|
while (ShowCursor(FALSE) >= 0);
|
||||||
if (PtInRect(&rect, pt))
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_NCMOUSEMOVE:
|
||||||
|
{
|
||||||
|
// Show the cursor when it's outside the window's client area (i.e., on the frame or elsewhere)
|
||||||
|
while (ShowCursor(TRUE) < 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_SETCURSOR:
|
||||||
|
{
|
||||||
|
if ( Show_Windows_Cursor )
|
||||||
{
|
{
|
||||||
// Hide the cursor when it's inside the window
|
// SetCursor( Windows_Cursor );
|
||||||
// while (ShowCursor(FALSE) >= 0);
|
result = DefWindowProc( handle, system_messages, w_param, l_param );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Show the cursor when it's outside the window
|
SetCursor(NULL);
|
||||||
// while (ShowCursor(TRUE) < 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -330,7 +385,7 @@ main_window_callback( HWND handle
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
process_pending_window_messages( engine::KeyboardState* keyboard, engine::MousesState* mouse )
|
process_pending_window_messages( HWND window_handle, engine::KeyboardState* keyboard, engine::MousesState* mouse )
|
||||||
{
|
{
|
||||||
MSG window_msg_info;
|
MSG window_msg_info;
|
||||||
while ( PeekMessageA( & window_msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) )
|
while ( PeekMessageA( & window_msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) )
|
||||||
@ -342,7 +397,7 @@ process_pending_window_messages( engine::KeyboardState* keyboard, engine::Mouses
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard input handling
|
// Keyboard input handling
|
||||||
switch (window_msg_info.message)
|
switch (window_msg_info.message)
|
||||||
{
|
{
|
||||||
// I rather do this with GetAsyncKeyState...
|
// I rather do this with GetAsyncKeyState...
|
||||||
case WM_SYSKEYDOWN:
|
case WM_SYSKEYDOWN:
|
||||||
@ -361,6 +416,13 @@ process_pending_window_messages( engine::KeyboardState* keyboard, engine::Mouses
|
|||||||
Running = false;
|
Running = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VK_F10:
|
||||||
|
{
|
||||||
|
// TODO(Ed) : Expose this feature via platform_api to engine. Let the game toggle via the its action binds.
|
||||||
|
if ( is_down )
|
||||||
|
toggle_fullscreen( window_handle );
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -622,10 +684,14 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
|
|||||||
// window_class.cbWndExtra = ;
|
// window_class.cbWndExtra = ;
|
||||||
window_class.hInstance = instance;
|
window_class.hInstance = instance;
|
||||||
// window_class.hIcon = ;
|
// window_class.hIcon = ;
|
||||||
// window_class.hCursor = ;
|
window_class.hCursor = LoadCursorW( 0, IDC_ARROW );
|
||||||
// window_class.hbrBackground = ;
|
// window_class.hbrBackground = ;
|
||||||
window_class.lpszMenuName = L"Handmade Hero!";
|
window_class.lpszMenuName = L"Handmade Hero!";
|
||||||
window_class.lpszClassName = L"HandmadeHeroWindowClass";
|
window_class.lpszClassName = L"HandmadeHeroWindowClass";
|
||||||
|
|
||||||
|
Show_Windows_Cursor = true;
|
||||||
|
Windows_Cursor = LoadCursorW( 0, IDC_CROSS );
|
||||||
|
Window_Position = {sizeof(WINDOWPLACEMENT)};
|
||||||
|
|
||||||
if ( ! RegisterClassW( & window_class ) )
|
if ( ! RegisterClassW( & window_class ) )
|
||||||
{
|
{
|
||||||
@ -895,7 +961,7 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_pending_window_messages( new_keyboard, new_mouse );
|
process_pending_window_messages( window_handle, new_keyboard, new_mouse );
|
||||||
|
|
||||||
// f32 delta_time = timing_get_seconds_elapsed( last_frame_clock, timing_get_wall_clock() );
|
// f32 delta_time = timing_get_seconds_elapsed( last_frame_clock, timing_get_wall_clock() );
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ function check-FileForChanges
|
|||||||
return $false
|
return $false
|
||||||
}
|
}
|
||||||
$file_name = Split-Path $path_file -Leaf
|
$file_name = Split-Path $path_file -Leaf
|
||||||
$path_csv = Join-Path $path_build ($file_name + "_file_hash.csv")
|
$path_csv = Join-Path $path_build ($file_name + "_file_hash.csv")
|
||||||
|
|
||||||
$csv_file_hash = $null
|
$csv_file_hash = $null
|
||||||
if (Test-Path $path_csv) {
|
if (Test-Path $path_csv) {
|
||||||
@ -385,6 +385,9 @@ function build-platform
|
|||||||
}
|
}
|
||||||
write-host "Building Platform Module" -ForegroundColor Green
|
write-host "Building Platform Module" -ForegroundColor Green
|
||||||
|
|
||||||
|
$local:includes = $script:includes
|
||||||
|
$includes += $path_platform
|
||||||
|
|
||||||
# CodeGen Pre-Build
|
# CodeGen Pre-Build
|
||||||
$path_engine_symbols = Join-Path $path_engine_gen 'engine_symbols.gen.hpp'
|
$path_engine_symbols = Join-Path $path_engine_gen 'engine_symbols.gen.hpp'
|
||||||
$unit = Join-Path $path_codegen 'platform_gen.cpp'
|
$unit = Join-Path $path_codegen 'platform_gen.cpp'
|
||||||
@ -404,9 +407,6 @@ function build-platform
|
|||||||
New-Item $path_platform_gen -ItemType Directory > $null
|
New-Item $path_platform_gen -ItemType Directory > $null
|
||||||
}
|
}
|
||||||
|
|
||||||
$local:includes = $script:includes
|
|
||||||
$includes += $path_platform
|
|
||||||
|
|
||||||
$local:compiler_args = @()
|
$local:compiler_args = @()
|
||||||
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user