Day 40 complete

This commit is contained in:
Edward R. Gonzalez 2023-10-22 01:46:01 -04:00
parent 193b71ff92
commit fa28d401ef
6 changed files with 98 additions and 26 deletions

View File

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 MiB

View File

@ -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

View File

@ -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,11 +684,15 @@ 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 ) )
{ {
// TODO : Diagnostic Logging // TODO : Diagnostic Logging
@ -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() );

View File

@ -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' )