HandmadeHero/project/handmade_win32.cpp

314 lines
7.6 KiB
C++
Raw Normal View History

2023-09-08 18:08:57 -07:00
#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
#include "grime.h"
#include "macros.h"
#include "types.h"
#include <stdio.h>
2023-09-08 14:50:22 -07:00
#include "win32.h"
2023-09-08 21:01:53 -07:00
NS_WIN32_BEGIN
2023-09-08 18:08:57 -07:00
2023-09-08 21:01:53 -07:00
// TODO(Ed) : This is a global for now.
global bool Running;
global BITMAPINFO ScreenBitmapInfo;
global void* ScreenBitmapMemory; // Lets use directly mess with the "pixel's memory buffer"
global u32 BitmapWidth;
global u32 BitmapHeight;
constexpr u32 BytesPerPixel = 4;
internal void
render_weird_graident( u32 x_offset, u32 y_offset )
{
struct Pixel {
u8 Blue;
u8 Green;
u8 Red;
u8 Alpha;
};
u32 pitch = BitmapWidth * BytesPerPixel;
u8* row = rcast( u8*, ScreenBitmapMemory);
local_persist float wildcard = 0;
for ( u32 y = 0; y < BitmapHeight; ++ y )
{
// u8* pixel = rcast(u8*, row);
// Pixel* pixel = rcast( Pixel*, row );
u32* pixel = rcast(u32*, row);
for ( u32 x = 0; x < BitmapWidth; ++ x )
{
/* Pixel in memory:
-----------------------------------------------
Pixel + 0 Pixel + 1 Pixel + 2 Pixel + 3
RR GG GG XX
-----------------------------------------------
x86-64 : Little Endian Arch
0x XX BB GG RR
*/
// pixel[0] = scast(u8, x + x_offset);
// pixel[1] = scast(u8, y + y_offset);
// pixel[2] = 0;
// pixel[3] = 0;
// pixel->Blue = scast(u8, x + x_offset * u8(wildcard) % 256);
// pixel->Green = scast(u8, y + y_offset - u8(wildcard) % 128);
// pixel->Red = scast(u8, wildcard) % 256 - x * 0.1f;
// pixel->Alpha = 0;
// ++pixel;
// pixel += BytesPerPixel;
u8 blue = scast(u8, x + x_offset * u8(wildcard) % 256);
u8 green = scast(u8, y + y_offset - u8(wildcard) % 128);
u8 red = scast(u8, wildcard) % 256 - x * 0.4f;
*pixel++ = (red << 16) | (green << 8) | blue;
}
// wildcard += 0.001f;
wildcard += .25f * 0.5;
row += pitch;
}
}
2023-09-08 21:01:53 -07:00
internal void
resize_dib_section( u32 width, u32 height )
{
// TODO(Ed) : Bulletproof memory handling here for the bitmap memory
// TODO(Ed) : Free DIB section
if ( ScreenBitmapMemory )
2023-09-08 21:01:53 -07:00
{
VirtualFree( ScreenBitmapMemory, 0, MEM_RELEASE );
2023-09-08 21:01:53 -07:00
}
BitmapWidth = width;
BitmapHeight = height;
// Negative means top-down in the context of the biHeight
# define Top_Down -
constexpr BITMAPINFOHEADER&
header = ScreenBitmapInfo.bmiHeader;
ScreenBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
ScreenBitmapInfo.bmiHeader.biWidth = BitmapWidth;
ScreenBitmapInfo.bmiHeader.biHeight = Top_Down BitmapHeight;
ScreenBitmapInfo.bmiHeader.biPlanes = 1;
ScreenBitmapInfo.bmiHeader.biBitCount = 32; // Need 24, but want 32 ( alignment )
ScreenBitmapInfo.bmiHeader.biCompression = BI_RGB_Uncompressed;
// ScreenBitmapInfo.bmiHeader.biSizeImage = 0;
// ScreenBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
// ScreenBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
// ScreenBitmapInfo.bmiHeader.biClrUsed = 0;
// ScreenBitmapInfo.bmiHeader.biClrImportant = 0;
# undef Top_Down
#if 0
2023-09-08 21:01:53 -07:00
ScreenBitmapHandle = CreateDIBSection( ScreenDeviceContext, & ScreenBitmapInfo
, DIB_ColorTable_RGB, & ScreenBitmapMemory
// Ignoring these last two
, 0, 0 );
#endif
2023-09-08 21:01:53 -07:00
// ReleaseContext( 0, ScreenDeviceContext );
// We want to "touch" a pixel on every 4-byte boundary
u32 BitmapMemorySize = (BitmapWidth * BitmapHeight) * BytesPerPixel;
ScreenBitmapMemory = VirtualAlloc( NULL, BitmapMemorySize, MEM_COMMIT, PAGE_READWRITE );
// TODO(Ed) : Clear to black
2023-09-08 21:01:53 -07:00
}
internal void
update_window( HDC device_context, RECT* WindowRect
2023-09-08 21:01:53 -07:00
, u32 x, u32 y
, u32 width, u32 height )
{
#if 0
BitBlt( device_context
, x, y, width, height
, ScreenDeviceContext
, x, y, RO_Source_To_Dest
);
#else
u32 window_width = WindowRect->right - WindowRect->left;
u32 window_height = WindowRect->bottom - WindowRect->top;
2023-09-08 21:01:53 -07:00
StretchDIBits( device_context
#if 0
2023-09-08 21:01:53 -07:00
, x, y, width, height
, x, y, width, height
#endif
, 0, 0, BitmapWidth, BitmapHeight
, 0, 0, window_width, window_height
2023-09-08 21:01:53 -07:00
, ScreenBitmapMemory, & ScreenBitmapInfo
, DIB_ColorTable_RGB, RO_Source_To_Dest );
#endif
2023-09-08 21:01:53 -07:00
}
LRESULT CALLBACK
main_window_callback(
2023-09-08 18:08:57 -07:00
HWND handle,
UINT system_messages,
WPARAM w_param,
LPARAM l_param
)
{
LRESULT result;
switch ( system_messages )
{
case WM_ACTIVATEAPP:
{
OutputDebugStringA( "WM_ACTIVATEAPP\n" );
}
break;
case WM_CLOSE:
{
2023-09-08 21:01:53 -07:00
// TODO(Ed) : Handle with a message to the user
Running = false;
2023-09-08 18:08:57 -07:00
}
break;
case WM_DESTROY:
{
2023-09-08 21:01:53 -07:00
// TODO(Ed) : Handle with as an error and recreate the window
Running = false;
2023-09-08 18:08:57 -07:00
}
break;
case WM_PAINT:
{
PAINTSTRUCT info;
HDC device_context = BeginPaint( handle, & info );
u32 x = info.rcPaint.left;
u32 y = info.rcPaint.top;
u32 width = info.rcPaint.right - info.rcPaint.left;
u32 height = info.rcPaint.bottom - info.rcPaint.top;
RECT client_rect;
GetClientRect( handle, & client_rect );
2023-09-08 18:08:57 -07:00
update_window( device_context, & client_rect
2023-09-08 18:08:57 -07:00
, x, y
2023-09-08 21:01:53 -07:00
, width, height );
2023-09-08 18:08:57 -07:00
EndPaint( handle, & info );
}
break;
case WM_SIZE:
{
2023-09-08 21:01:53 -07:00
RECT client_rect;
GetClientRect( handle, & client_rect );
u32 width = client_rect.right - client_rect.left;
u32 height = client_rect.bottom - client_rect.top;
resize_dib_section( width, height );
2023-09-08 18:08:57 -07:00
}
break;
default:
{
result = DefWindowProc( handle, system_messages, w_param, l_param );
}
}
return result;
}
2023-09-08 21:01:53 -07:00
NS_WIN32_END
2023-09-08 21:01:53 -07:00
int CALLBACK
WinMain(
2023-09-08 18:08:57 -07:00
HINSTANCE instance,
HINSTANCE prev_instance,
LPSTR commandline,
int show_command
2023-09-08 14:50:22 -07:00
)
{
2023-09-08 21:01:53 -07:00
using namespace win32;
// MessageBox( 0, L"First message!", L"Handmade Hero", MB_Ok_Btn | MB_Icon_Information );
2023-09-08 18:08:57 -07:00
WNDCLASS window_class {};
window_class.style = CS_Own_Device_Context | CS_Horizontal_Redraw | CS_Vertical_Redraw;
2023-09-08 21:01:53 -07:00
window_class.lpfnWndProc = main_window_callback;
2023-09-08 18:08:57 -07:00
// 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 ) )
2023-09-08 18:08:57 -07:00
{
HWND window_handle = CreateWindowExW(
0,
window_class.lpszClassName,
L"Handmade Hero",
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 )
{
2023-09-08 21:01:53 -07:00
Running = true;
2023-09-08 18:08:57 -07:00
MSG msg_info;
u32 x_offset = 0;
u32 y_offset = 0;
2023-09-08 21:01:53 -07:00
while( Running )
2023-09-08 18:08:57 -07:00
{
if ( PeekMessageW( & msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) )
2023-09-08 18:08:57 -07:00
{
if ( msg_info.message == WM_QUIT )
{
OutputDebugStringA("WM_QUIT\n");
Running = false;
}
TranslateMessage( & msg_info );
DispatchMessage( & msg_info );
2023-09-08 18:08:57 -07:00
}
render_weird_graident( x_offset, y_offset );
RECT window_rect;
GetClientRect( window_handle, & window_rect );
HDC device_context = GetDC( window_handle );
u32 window_width = window_rect.right - window_rect.left;
u32 window_height = window_rect.bottom - window_rect.top;
update_window( device_context, & window_rect, 0, 0, window_width, window_height );
++ x_offset;
++ y_offset;
2023-09-08 18:08:57 -07:00
}
}
else
{
2023-09-08 21:01:53 -07:00
// TODO(Ed) : Logging
2023-09-08 18:08:57 -07:00
}
}
else
{
// TODO(Ed) : Logging
}
2023-09-08 15:54:16 -07:00
return 0;
}