Got OpenGL kind of working again. Lots of other work recreating functionality as well, but none of its done yet.
This commit is contained in:
parent
134a0a1e20
commit
0f220c608d
|
@ -0,0 +1,39 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
set ProjectDevRoot=C:\projects
|
||||||
|
set ProjectName=foldhaus
|
||||||
|
set ProjectDevPath=%ProjectDevRoot%\%ProjectName%
|
||||||
|
|
||||||
|
pushd %ProjectDevPath%
|
||||||
|
|
||||||
|
IF NOT EXIST .\build\ mkdir .\build
|
||||||
|
|
||||||
|
C:\programs\ctime\ctime.exe -begin %ProjectDevPath%\build\win32_foldhaus_build_time.ctm
|
||||||
|
|
||||||
|
set CommonCompilerFlags=-nologo -DDEBUG=1 -DPLATFORM_WINDOWS -FC -WX -W4 -Z7 -Oi -GR- -EHsc -EHa- -MTd -fp:fast -fp:except-
|
||||||
|
set CommonCompilerFlags=-wd4127 -wd4702 -wd4101 -wd4505 -wd4100 -wd4189 -wd4244 -wd4201 -wd4996 -I%CommonLibs% -O2 %CommonCompilerFlags%
|
||||||
|
set CommonLinkerFlags= -opt:ref
|
||||||
|
|
||||||
|
pushd build
|
||||||
|
|
||||||
|
del *.pdb > NUL 2> NUL
|
||||||
|
|
||||||
|
REM Compile and Run the Preprocessor
|
||||||
|
REM cl %CommonCompilerFlags% ..\meta\foldhaus_meta.cpp /link %CommonLinkerFlags%
|
||||||
|
pushd ..\src\
|
||||||
|
REM ..\build\foldhaus_meta.exe C:\projects\foldhaus\src\
|
||||||
|
popd
|
||||||
|
|
||||||
|
REM cl %CommonCompilerFlags% F:\src\foldhaus_util_radialumia_file_converter.cpp /link %CommonLinkerFlags%
|
||||||
|
REM foldhaus_util_radialumia_file_converter.exe
|
||||||
|
|
||||||
|
echo WAITING FOR PDB TO WRITE > lock.tmp
|
||||||
|
cl %CommonCompilerFlags% ..\src\foldhaus_app.cpp /Fefoldhaus.dll /LD /link %CommonLinkerFlags% /EXPORT:InitializeApplication /EXPORT:UpdateAndRender /EXPORT:CleanupApplication /EXPORT:ReloadStaticData
|
||||||
|
set LastError=%ERRORLEVEL%
|
||||||
|
del lock.tmp
|
||||||
|
|
||||||
|
cl %CommonCompilerFlags% ..\src\win32_foldhaus.cpp /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib opengl32.lib dsound.lib Ws2_32.lib Comdlg32.lib -incremental:no
|
||||||
|
|
||||||
|
C:\programs\ctime\ctime.exe -end C:\projects\foldhaus\build\win32_foldhaus_build_time.ctm %LastError%
|
||||||
|
C:\programs\ctime\ctime.exe -stats C:\projects\foldhaus\build\win32_foldhaus_build_time.ctm
|
||||||
|
popd
|
|
@ -249,8 +249,8 @@ DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData)
|
||||||
v4 P2 = ModelMatrix * P2_In;
|
v4 P2 = ModelMatrix * P2_In;
|
||||||
v4 P3 = ModelMatrix * P3_In;
|
v4 P3 = ModelMatrix * P3_In;
|
||||||
|
|
||||||
PushTri3DOnBatch(Data->Batch, P0, P1, P2, UV0, UV1, UV2, Color);
|
PushTri3DOnBatch(Data->Batch, P0, P1, P2, UV0, UV1, UV2, Color, Color, Color);
|
||||||
PushTri3DOnBatch(Data->Batch, P0, P2, P3, UV0, UV2, UV3, Color);
|
PushTri3DOnBatch(Data->Batch, P0, P2, P3, UV0, UV2, UV3, Color, Color, Color);
|
||||||
|
|
||||||
LED++;
|
LED++;
|
||||||
}
|
}
|
||||||
|
@ -418,11 +418,49 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
if (stbtt_InitFont(&StbFont, FontFile.Base, stbtt_GetFontOffsetForIndex(FontFile.Base, 0)))
|
if (stbtt_InitFont(&StbFont, FontFile.Base, stbtt_GetFontOffsetForIndex(FontFile.Base, 0)))
|
||||||
{
|
{
|
||||||
bitmap_font* Font = PushStruct(State->Permanent, bitmap_font);
|
bitmap_font* Font = PushStruct(State->Permanent, bitmap_font);
|
||||||
Font->Atlas = PushTexture(State);
|
|
||||||
RenderStbttToBitmapFont(Font, StbFont, FontSize, 512, State->Permanent, State->Transient );
|
|
||||||
|
Font->BitmapWidth = 512;
|
||||||
|
Font->BitmapHeight = 512;
|
||||||
|
Font->BitmapBytesPerPixel = 4;
|
||||||
|
Font->BitmapMemory = PushArray(State->Permanent, u8, Font->BitmapWidth * Font->BitmapHeight * Font->BitmapBytesPerPixel);;
|
||||||
|
Font->BitmapStride = Font->BitmapWidth * Font->BitmapBytesPerPixel;
|
||||||
|
|
||||||
|
platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", 14);
|
||||||
|
Font->PixelHeight = FontInfo.PixelHeight;
|
||||||
|
Font->Ascent = FontInfo.Ascent;
|
||||||
|
Font->Descent = FontInfo.Descent;
|
||||||
|
Font->Leading = FontInfo.Leading;
|
||||||
|
Font->MaxCharWidth = FontInfo.MaxCharWidth;
|
||||||
|
|
||||||
|
Font->CodepointDictionarySize = (FontInfo.CodepointOnePastLast - FontInfo.CodepointStart);
|
||||||
|
Font->CodepointDictionaryCount = 0;
|
||||||
|
Font->CodepointKeys = PushArray(State->Permanent, char, Font->CodepointDictionarySize);
|
||||||
|
Font->CodepointValues = PushArray(State->Permanent, codepoint_bitmap, Font->CodepointDictionarySize);
|
||||||
|
|
||||||
|
for (s32 Codepoint = FontInfo.CodepointStart;
|
||||||
|
Codepoint < FontInfo.CodepointOnePastLast;
|
||||||
|
Codepoint++)
|
||||||
|
{
|
||||||
|
u32 CodepointX, CodepointY;
|
||||||
|
GetNextCodepointOffset(Font, &CodepointX, &CodepointY);
|
||||||
|
|
||||||
|
u32 CodepointW, CodepointH;
|
||||||
|
Context.PlatformDrawFontCodepoint(
|
||||||
|
Font->BitmapMemory,
|
||||||
|
Font->BitmapWidth,
|
||||||
|
Font->BitmapHeight,
|
||||||
|
CodepointX, CodepointY,
|
||||||
|
(char)Codepoint, FontInfo,
|
||||||
|
&CodepointW, &CodepointH);
|
||||||
|
|
||||||
|
AddCodepointToFont(Font, Codepoint, 0, 0, CodepointW, CodepointH, CodepointX, CodepointY);
|
||||||
|
}
|
||||||
|
|
||||||
State->Interface.Font = Font;
|
State->Interface.Font = Font;
|
||||||
State->Font = Font;
|
State->Font = Font;
|
||||||
Font->Atlas->Handle = Context.PlatformGetGPUTextureHandle(Font->Atlas->Memory, Font->Atlas->Width, Font->Atlas->Height);
|
Font->BitmapTextureHandle = Context.PlatformGetGPUTextureHandle(Font->BitmapMemory,
|
||||||
|
Font->BitmapWidth, Font->BitmapHeight);
|
||||||
}
|
}
|
||||||
} else {}
|
} else {}
|
||||||
}
|
}
|
||||||
|
@ -570,12 +608,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
m44 ModelViewMatrix = GetCameraModelViewMatrix(State->Camera);
|
m44 ModelViewMatrix = GetCameraModelViewMatrix(State->Camera);
|
||||||
m44 ProjectionMatrix = GetCameraPerspectiveProjectionMatrix(State->Camera);
|
m44 ProjectionMatrix = GetCameraPerspectiveProjectionMatrix(State->Camera);
|
||||||
|
|
||||||
RenderBuffer->ViewWidth = Context.WindowWidth;
|
|
||||||
RenderBuffer->ViewHeight = Context.WindowHeight;
|
|
||||||
|
|
||||||
r32 LEDHalfWidth = .5f;
|
r32 LEDHalfWidth = .5f;
|
||||||
|
|
||||||
PushRenderPerspective(RenderBuffer, Context.WindowWidth, Context.WindowHeight, State->Camera);
|
PushRenderPerspective(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight, State->Camera);
|
||||||
PushRenderClearScreen(RenderBuffer);
|
PushRenderClearScreen(RenderBuffer);
|
||||||
|
|
||||||
DEBUG_IF(GlobalDebugServices->Interface.RenderSculpture) // DebugServices RenderSculpture Toggle
|
DEBUG_IF(GlobalDebugServices->Interface.RenderSculpture) // DebugServices RenderSculpture Toggle
|
||||||
|
@ -634,7 +669,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
|
|
||||||
DEBUG_TRACK_SCOPE(DrawInterface);
|
DEBUG_TRACK_SCOPE(DrawInterface);
|
||||||
|
|
||||||
PushRenderOrthographic(RenderBuffer, Context.WindowWidth, Context.WindowHeight);
|
PushRenderOrthographic(RenderBuffer, 0, 0, Context.WindowWidth, Context.WindowHeight);
|
||||||
|
|
||||||
// Universe Data View
|
// Universe Data View
|
||||||
if (State->DrawUniverseOutputDisplay)
|
if (State->DrawUniverseOutputDisplay)
|
||||||
|
@ -698,7 +733,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
v2{Context.WindowWidth, Context.WindowHeight},
|
v2{Context.WindowWidth, Context.WindowHeight},
|
||||||
0, State->Interface, Input);
|
0, State->Interface, Input);
|
||||||
|
|
||||||
v2 ButtonDim = v2{200, State->Interface.Font->NewLineYOffset + 10};
|
v2 ButtonDim = v2{200, (r32)NewLineYOffset(*State->Interface.Font) + 10};
|
||||||
v2 ButtonPos = v2{State->Interface.Margin.x, Context.WindowHeight - (ButtonDim.y + 10)};
|
v2 ButtonPos = v2{State->Interface.Margin.x, Context.WindowHeight - (ButtonDim.y + 10)};
|
||||||
button_result LoadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
button_result LoadAssemblyBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
||||||
MakeStringLiteral("Load Assembly"),
|
MakeStringLiteral("Load Assembly"),
|
||||||
|
|
|
@ -3,7 +3,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(DrawDebugInterface);
|
DEBUG_TRACK_SCOPE(DrawDebugInterface);
|
||||||
|
|
||||||
v2 TopOfDebugView = v2{StartX, WindowHeight - (Interface.Font->NewLineYOffset + 5)};
|
v2 TopOfDebugView = v2{StartX, WindowHeight - (NewLineYOffset(*Interface.Font) + 5)};
|
||||||
v2 TopOfScreenLinePos = TopOfDebugView;
|
v2 TopOfScreenLinePos = TopOfDebugView;
|
||||||
|
|
||||||
arena_snapshot StartTempMemory = TakeSnapshotOfArena(*Transient);
|
arena_snapshot StartTempMemory = TakeSnapshotOfArena(*Transient);
|
||||||
|
@ -24,7 +24,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
(u32)FramesPerSecond);
|
(u32)FramesPerSecond);
|
||||||
DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, WhiteV4);
|
DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, WhiteV4);
|
||||||
|
|
||||||
v2 ButtonDim = v2{200, Interface.Font->NewLineYOffset + 10};
|
v2 ButtonDim = v2{200, (r32)NewLineYOffset(*Interface.Font) + 10};
|
||||||
TopOfScreenLinePos.y -= ButtonDim.y + 10;
|
TopOfScreenLinePos.y -= ButtonDim.y + 10;
|
||||||
v2 ButtonPos = TopOfScreenLinePos;
|
v2 ButtonPos = TopOfScreenLinePos;
|
||||||
button_result CameraBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
button_result CameraBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
||||||
|
@ -52,7 +52,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
button_result SendSACNDataBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
button_result SendSACNDataBtn = EvaluateButton(RenderBuffer, ButtonPos, ButtonPos + ButtonDim,
|
||||||
SACNButtonString, Interface, Input);
|
SACNButtonString, Interface, Input);
|
||||||
|
|
||||||
TopOfScreenLinePos.y -= Interface.Font->NewLineYOffset + 10;
|
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font) + 10;
|
||||||
|
|
||||||
if (CameraBtn.Pressed)
|
if (CameraBtn.Pressed)
|
||||||
{
|
{
|
||||||
|
@ -85,7 +85,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
3, Camera.LookAt.y,
|
3, Camera.LookAt.y,
|
||||||
3, Camera.LookAt.z);
|
3, Camera.LookAt.z);
|
||||||
DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, v4{1.0f, 1.0f, 1.0f, 1.0f});
|
DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, v4{1.0f, 1.0f, 1.0f, 1.0f});
|
||||||
TopOfScreenLinePos.y -= Interface.Font->NewLineYOffset;
|
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GlobalDebugServices->Interface.ShowTrackedScopes)
|
if (GlobalDebugServices->Interface.ShowTrackedScopes)
|
||||||
|
@ -127,7 +127,7 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
Register, WhiteV4).x;
|
Register, WhiteV4).x;
|
||||||
Register.x += GSMax(ColumnFourX - Register.x, 200.f);
|
Register.x += GSMax(ColumnFourX - Register.x, 200.f);
|
||||||
|
|
||||||
TopOfScreenLinePos.y -= Interface.Font->NewLineYOffset;
|
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,14 @@ typedef CLEANUP_APPLICATION(cleanup_application);
|
||||||
|
|
||||||
// Platform Functions
|
// Platform Functions
|
||||||
|
|
||||||
|
typedef struct platform_font_info platform_font_info;
|
||||||
|
|
||||||
|
#define GET_FONT_INFO(name) platform_font_info name(char* FontName, s32 PixelHeight)
|
||||||
|
typedef GET_FONT_INFO(platform_get_font_info);
|
||||||
|
|
||||||
|
#define DRAW_FONT_CODEPOINT(name) void name(u8* DestBuffer, s32 DestBufferWidth, s32 DestBufferHeight, u32 XOffset, u32 YOffset, char Codepoint, platform_font_info FontInfo, u32* OutWidth, u32* OutHeight)
|
||||||
|
typedef DRAW_FONT_CODEPOINT(platform_draw_font_codepoint);
|
||||||
|
|
||||||
// Worker Threads
|
// Worker Threads
|
||||||
|
|
||||||
#define THREADED_WORK_PROC(name) void name(s32 ThreadID, void* Data)
|
#define THREADED_WORK_PROC(name) void name(s32 ThreadID, void* Data)
|
||||||
|
@ -106,7 +114,8 @@ struct context
|
||||||
platform_write_entire_file* PlatformWriteEntireFile;
|
platform_write_entire_file* PlatformWriteEntireFile;
|
||||||
platform_get_file_path* PlatformGetFilePath;
|
platform_get_file_path* PlatformGetFilePath;
|
||||||
platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle;
|
platform_get_gpu_texture_handle* PlatformGetGPUTextureHandle;
|
||||||
|
platform_get_font_info* PlatformGetFontInfo;
|
||||||
|
platform_draw_font_codepoint* PlatformDrawFontCodepoint;
|
||||||
platform_get_socket_handle* PlatformGetSocketHandle;
|
platform_get_socket_handle* PlatformGetSocketHandle;
|
||||||
platform_get_send_address* PlatformGetSendAddress;
|
platform_get_send_address* PlatformGetSendAddress;
|
||||||
platform_set_socket_option* PlatformSetSocketOption;
|
platform_set_socket_option* PlatformSetSocketOption;
|
||||||
|
|
|
@ -18,7 +18,7 @@ Render3DQuadBatch (u8* CommandData, s32 TriCount)
|
||||||
v4* Colors = (v4*)(CommandData + BATCH_3D_COLORS_OFFSET(TriCount));
|
v4* Colors = (v4*)(CommandData + BATCH_3D_COLORS_OFFSET(TriCount));
|
||||||
|
|
||||||
#if IMMEDIATE_MODE_RENDERING
|
#if IMMEDIATE_MODE_RENDERING
|
||||||
glBegin(GL_TRIANGLES);
|
|
||||||
for (s32 Tri = 0; Tri < TriCount; Tri++)
|
for (s32 Tri = 0; Tri < TriCount; Tri++)
|
||||||
{
|
{
|
||||||
v4 P0 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 0)];
|
v4 P0 = Vertecies[BATCH_3D_VERTEX_INDEX(Tri, 0)];
|
||||||
|
@ -33,9 +33,8 @@ Render3DQuadBatch (u8* CommandData, s32 TriCount)
|
||||||
|
|
||||||
OpenGLDraw3DTri(P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
OpenGLDraw3DTri(P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
||||||
}
|
}
|
||||||
glEnd();
|
|
||||||
#else
|
#else
|
||||||
OpenGLRenderTriBuffer((u8*)Vertecies, 4, UVs, 2, Colors, 4, TriCount * 3);
|
OpenGLRenderTriBuffer((u8*)Vertecies, 4, (u8*)UVs, 2, (u8*)Colors, 4, TriCount * 3);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ Render2DQuadBatch (u8* CommandData, s32 QuadCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
OpenGLRenderTriBuffer((u8*)Vertecies, 2, UVs, 2, Colors, 4, QuadCount * 2 * 3);
|
OpenGLRenderTriBuffer((u8*)Vertecies, 2, (u8*)UVs, 2, (u8*)Colors, 4, QuadCount * 2 * 3);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +75,6 @@ RenderCommandBuffer (render_command_buffer CommandBuffer)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_FUNCTION;
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
glViewport(0, 0, CommandBuffer.ViewWidth, CommandBuffer.ViewHeight);
|
|
||||||
|
|
||||||
glMatrixMode(GL_TEXTURE_2D);
|
glMatrixMode(GL_TEXTURE_2D);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
|
@ -100,6 +97,9 @@ RenderCommandBuffer (render_command_buffer CommandBuffer)
|
||||||
{
|
{
|
||||||
render_command_set_render_mode* Command = (render_command_set_render_mode*)(CommandHeader + 1);
|
render_command_set_render_mode* Command = (render_command_set_render_mode*)(CommandHeader + 1);
|
||||||
|
|
||||||
|
glViewport(Command->ViewOffsetX, Command->ViewOffsetY,
|
||||||
|
Command->ViewWidth, Command->ViewHeight);
|
||||||
|
|
||||||
LoadModelView(Command->ModelView.E);
|
LoadModelView(Command->ModelView.E);
|
||||||
LoadProjection(Command->Projection.E);
|
LoadProjection(Command->Projection.E);
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,7 @@ struct render_command_set_render_mode
|
||||||
{
|
{
|
||||||
m44 ModelView;
|
m44 ModelView;
|
||||||
m44 Projection;
|
m44 Projection;
|
||||||
|
r32 ViewOffsetX, ViewOffsetY;
|
||||||
r32 ViewWidth, ViewHeight;
|
r32 ViewWidth, ViewHeight;
|
||||||
b32 UseDepthBuffer;
|
b32 UseDepthBuffer;
|
||||||
};
|
};
|
||||||
|
@ -280,7 +281,10 @@ ThreadSafeIncrementQuadConstructorCount (render_quad_batch_constructor* Construc
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
PushTri3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v2 UV0, v2 UV1, v2 UV2, v4 Color)
|
PushTri3DOnBatch (render_quad_batch_constructor* Constructor,
|
||||||
|
v4 P0, v4 P1, v4 P2,
|
||||||
|
v2 UV0, v2 UV1, v2 UV2,
|
||||||
|
v4 C0, v4 C1, v4 C2)
|
||||||
{
|
{
|
||||||
s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor);
|
s32 Tri = ThreadSafeIncrementQuadConstructorCount(Constructor);
|
||||||
// Vertecies
|
// Vertecies
|
||||||
|
@ -292,17 +296,28 @@ PushTri3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4
|
||||||
Constructor->UVs[BATCH_3D_UV_INDEX(Tri, 1)] = UV1;
|
Constructor->UVs[BATCH_3D_UV_INDEX(Tri, 1)] = UV1;
|
||||||
Constructor->UVs[BATCH_3D_UV_INDEX(Tri, 2)] = UV1;
|
Constructor->UVs[BATCH_3D_UV_INDEX(Tri, 2)] = UV1;
|
||||||
// Color V0
|
// Color V0
|
||||||
Constructor->ColorsV[BATCH_3D_COLOR_INDEX(Tri, 0)] = Color;
|
Constructor->ColorsV[BATCH_3D_COLOR_INDEX(Tri, 0)] = C0;
|
||||||
Constructor->ColorsV[BATCH_3D_COLOR_INDEX(Tri, 1)] = Color;
|
Constructor->ColorsV[BATCH_3D_COLOR_INDEX(Tri, 1)] = C1;
|
||||||
Constructor->ColorsV[BATCH_3D_COLOR_INDEX(Tri, 2)] = Color;
|
Constructor->ColorsV[BATCH_3D_COLOR_INDEX(Tri, 2)] = C2;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color)
|
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor, v4 P0, v4 P1, v4 P2, v4 P3, v2 UVMin, v2 UVMax, v4 Color)
|
||||||
{
|
{
|
||||||
Assert(Constructor->Count < Constructor->Max);
|
Assert(Constructor->Count < Constructor->Max);
|
||||||
PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color);
|
PushTri3DOnBatch(Constructor, P0, P1, P2, UVMin, v2{UVMax.x, UVMin.y}, UVMax, Color, Color, Color);
|
||||||
PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color);
|
PushTri3DOnBatch(Constructor, P0, P2, P3, UVMin, UVMax, v2{UVMin.x, UVMax.y}, Color, Color, Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
PushQuad3DOnBatch (render_quad_batch_constructor* Constructor,
|
||||||
|
v4 P0, v4 P1, v4 P2, v4 P3,
|
||||||
|
v2 UV0, v2 UV1, v2 UV2, v2 UV3,
|
||||||
|
v4 C0, v4 C1, v4 C2, v4 C3)
|
||||||
|
{
|
||||||
|
Assert(Constructor->Count < Constructor->Max);
|
||||||
|
PushTri3DOnBatch(Constructor, P0, P1, P2, UV0, UV1, UV2, C0, C1, C2);
|
||||||
|
PushTri3DOnBatch(Constructor, P0, P2, P3, UV0, UV2, UV3, C0, C2, C3);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -418,19 +433,26 @@ PushRenderCommand_ (render_command_buffer* CommandBuffer, render_command_type Co
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal render_command_set_render_mode*
|
||||||
PushRenderPerspective (render_command_buffer* Buffer, s32 ViewWidth, s32 ViewHeight, camera Camera)
|
PushRenderPerspective (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight, camera Camera)
|
||||||
{
|
{
|
||||||
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
||||||
|
|
||||||
Command->ModelView = GetCameraModelViewMatrix(Camera);
|
Command->ModelView = GetCameraModelViewMatrix(Camera);
|
||||||
Command->Projection = GetCameraPerspectiveProjectionMatrix(Camera);
|
Command->Projection = GetCameraPerspectiveProjectionMatrix(Camera);
|
||||||
Command->ViewWidth;
|
|
||||||
Command->ViewHeight;
|
Command->ViewOffsetX = (r32)OffsetX;
|
||||||
|
Command->ViewOffsetY = (r32)OffsetY;
|
||||||
|
Command->ViewWidth = (r32)ViewWidth;
|
||||||
|
Command->ViewHeight = (r32)ViewHeight;
|
||||||
|
|
||||||
Command->UseDepthBuffer = true;
|
Command->UseDepthBuffer = true;
|
||||||
|
|
||||||
|
return Command;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushRenderOrthographic (render_command_buffer* Buffer, s32 ViewWidth, s32 ViewHeight)
|
PushRenderOrthographic (render_command_buffer* Buffer, s32 OffsetX, s32 OffsetY, s32 ViewWidth, s32 ViewHeight)
|
||||||
{
|
{
|
||||||
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
render_command_set_render_mode* Command = PushRenderCommand(Buffer, render_command_set_render_mode);
|
||||||
Command->ModelView = m44{
|
Command->ModelView = m44{
|
||||||
|
@ -448,8 +470,12 @@ PushRenderOrthographic (render_command_buffer* Buffer, s32 ViewWidth, s32 ViewHe
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
-1, -1, 0, 1
|
-1, -1, 0, 1
|
||||||
};
|
};
|
||||||
Command->ViewWidth;
|
|
||||||
Command->ViewHeight;
|
Command->ViewOffsetX = (r32)OffsetX;
|
||||||
|
Command->ViewOffsetY = (r32)OffsetY;
|
||||||
|
Command->ViewWidth = ViewWidth;
|
||||||
|
Command->ViewHeight = ViewHeight;
|
||||||
|
|
||||||
Command->UseDepthBuffer = false;;
|
Command->UseDepthBuffer = false;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,6 +557,21 @@ PushRenderTexture2DBatch(render_command_buffer* Buffer, s32 QuadCount,
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal render_quad_batch_constructor
|
||||||
|
PushRenderTexture2DBatch (render_command_buffer* Buffer, s32 QuadCount,
|
||||||
|
u8* TextureMemory, s32 TextureHandle, s32 TextureWidth, s32 TextureHeight,
|
||||||
|
s32 TextureBytesPerPixel, s32 TextureStride)
|
||||||
|
{
|
||||||
|
render_texture Texture = render_texture{
|
||||||
|
TextureMemory,
|
||||||
|
TextureHandle,
|
||||||
|
TextureWidth,
|
||||||
|
TextureHeight,
|
||||||
|
TextureBytesPerPixel,
|
||||||
|
TextureStride};
|
||||||
|
return PushRenderTexture2DBatch(Buffer, QuadCount, Texture);
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
PushRenderTexture2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 Color,
|
PushRenderTexture2D (render_command_buffer* Buffer, v2 Min, v2 Max, v4 Color,
|
||||||
v2 UVMin, v2 UVMax,
|
v2 UVMin, v2 UVMax,
|
||||||
|
|
101
gs_font.h
101
gs_font.h
|
@ -1,6 +1,107 @@
|
||||||
#ifndef GS_FONT_H
|
#ifndef GS_FONT_H
|
||||||
|
|
||||||
|
struct codepoint_bitmap
|
||||||
|
{
|
||||||
|
s32 XOffset, YOffset;
|
||||||
|
s32 Width, Height;
|
||||||
|
s32 BitmapX, BitmapY;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bitmap_font
|
||||||
|
{
|
||||||
|
char* Name;
|
||||||
|
s32 PixelHeight;
|
||||||
|
s32 Ascent;
|
||||||
|
s32 Descent;
|
||||||
|
s32 Leading;
|
||||||
|
s32 MaxCharWidth;
|
||||||
|
|
||||||
|
u32 CodepointDictionarySize;
|
||||||
|
u32 CodepointDictionaryCount;
|
||||||
|
char* CodepointKeys;
|
||||||
|
codepoint_bitmap* CodepointValues;
|
||||||
|
|
||||||
|
u8* BitmapMemory;
|
||||||
|
u32 BitmapWidth;
|
||||||
|
u32 BitmapHeight;
|
||||||
|
u32 BitmapBytesPerPixel;
|
||||||
|
u32 BitmapStride;
|
||||||
|
s32 BitmapTextureHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal bitmap_font
|
||||||
|
InitializeTextFont (s32 CodepointCount, u8* CodepointMemory, s32 CodepointMemorySize)
|
||||||
|
{
|
||||||
|
bitmap_font Result = {};
|
||||||
|
|
||||||
|
Result.CodepointDictionarySize = CodepointCount;
|
||||||
|
Result.CodepointDictionaryCount = 0;
|
||||||
|
Assert(CodepointMemorySize >= (sizeof(char) + sizeof(codepoint_bitmap)) * CodepointCount);
|
||||||
|
Result.CodepointKeys = (char*)CodepointMemory;
|
||||||
|
Result.CodepointValues = (codepoint_bitmap*)(CodepointMemory + (sizeof(char) * CodepointCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GLYPH_SKIRT 1
|
||||||
|
internal void
|
||||||
|
GetNextCodepointOffset (bitmap_font* Font, u32* X, u32* Y)
|
||||||
|
{
|
||||||
|
s32 LastCodepointIndex = Font->CodepointDictionaryCount - 1;
|
||||||
|
if (LastCodepointIndex >= 0)
|
||||||
|
{
|
||||||
|
codepoint_bitmap BitmapInfo = Font->CodepointValues[LastCodepointIndex];
|
||||||
|
u32 TempX = BitmapInfo.XOffset + BitmapInfo.Width + GLYPH_SKIRT;
|
||||||
|
u32 TempY = BitmapInfo.YOffset;
|
||||||
|
if (TempX + Font->MaxCharWidth > Font->BitmapWidth)
|
||||||
|
{
|
||||||
|
TempX = 0;
|
||||||
|
TempY -= BitmapInfo.Height + GLYPH_SKIRT;
|
||||||
|
}
|
||||||
|
*X = TempX;
|
||||||
|
*Y = TempY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*X = 0;
|
||||||
|
*Y = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
AddCodepointToFont (bitmap_font* Font, char Codepoint,
|
||||||
|
s32 XOffset, s32 YOffset, s32 Width, s32 Height,
|
||||||
|
s32 BitmapX, s32 BitmapY)
|
||||||
|
{
|
||||||
|
Assert(Font->CodepointDictionaryCount < Font->CodepointDictionarySize);
|
||||||
|
|
||||||
|
char* Key = Font->CodepointKeys + Font->CodepointDictionaryCount;
|
||||||
|
codepoint_bitmap* Value = Font->CodepointValues + Font->CodepointDictionaryCount;
|
||||||
|
Font->CodepointDictionaryCount++;
|
||||||
|
|
||||||
|
*Key = Codepoint;
|
||||||
|
*Value = {XOffset, YOffset, Width, Height, BitmapX, BitmapY};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal s32
|
||||||
|
GetIndexForCodepoint (bitmap_font Font, char Codepoint)
|
||||||
|
{
|
||||||
|
s32 Result = -1;
|
||||||
|
for (u32 i = 0; i < Font.CodepointDictionaryCount; i++)
|
||||||
|
{
|
||||||
|
if (Font.CodepointKeys[i] == Codepoint)
|
||||||
|
{
|
||||||
|
Result = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s32
|
||||||
|
NewLineYOffset (bitmap_font Font)
|
||||||
|
{
|
||||||
|
s32 Result = Font.Ascent - Font.Descent;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
#define GS_FONT_H
|
#define GS_FONT_H
|
||||||
#endif
|
#endif
|
|
@ -1,4 +0,0 @@
|
||||||
#ifndef GS_INPUT_H
|
|
||||||
|
|
||||||
#define GS_INPUT_H
|
|
||||||
#endif
|
|
100
gs_platform.h
100
gs_platform.h
|
@ -1,5 +1,51 @@
|
||||||
#ifndef GS_PLATFORM_H
|
#ifndef GS_PLATFORM_H
|
||||||
|
|
||||||
|
#ifndef GS_LANGUAGE_H
|
||||||
|
// Types
|
||||||
|
typedef signed char b8;
|
||||||
|
typedef short int b16;
|
||||||
|
typedef int b32;
|
||||||
|
typedef long long int b64;
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short int u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned long long int u64;
|
||||||
|
|
||||||
|
typedef signed char s8;
|
||||||
|
typedef short int s16;
|
||||||
|
typedef int s32;
|
||||||
|
typedef long long int s64;
|
||||||
|
|
||||||
|
typedef float r32;
|
||||||
|
typedef double r64;
|
||||||
|
|
||||||
|
#define internal static
|
||||||
|
#define local_persist static
|
||||||
|
#define global_variable static
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define Assert(condition) if(!(condition)) { *((int *)0) = 5; }
|
||||||
|
#define InvalidCodePath Assert(0)
|
||||||
|
#define InvalidDefaultCase default: { InvalidCodePath; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
#include "gs_win32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct window_info
|
||||||
|
{
|
||||||
|
char* Name;
|
||||||
|
s32 Width;
|
||||||
|
s32 Height;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct window window;
|
||||||
|
|
||||||
|
#define PLATFORM_MEMORY_NO_ERROR 0
|
||||||
struct platform_memory_result
|
struct platform_memory_result
|
||||||
{
|
{
|
||||||
u8* Base;
|
u8* Base;
|
||||||
|
@ -7,7 +53,21 @@ struct platform_memory_result
|
||||||
s32 Error;
|
s32 Error;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PLATFORM_MEMORY_NO_ERROR 0
|
struct texture_buffer
|
||||||
|
{
|
||||||
|
u8* Memory;
|
||||||
|
s32 Width;
|
||||||
|
s32 Height;
|
||||||
|
s32 Pitch;
|
||||||
|
s32 BytesPerPixel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct system_path
|
||||||
|
{
|
||||||
|
char* Path;
|
||||||
|
s32 PathLength;
|
||||||
|
s32 IndexOfLastSlash;
|
||||||
|
};
|
||||||
|
|
||||||
#define PLATFORM_ALLOC(name) platform_memory_result name(s32 Size)
|
#define PLATFORM_ALLOC(name) platform_memory_result name(s32 Size)
|
||||||
typedef PLATFORM_ALLOC(platform_alloc);
|
typedef PLATFORM_ALLOC(platform_alloc);
|
||||||
|
@ -21,28 +81,32 @@ typedef PLATFORM_READ_ENTIRE_FILE(platform_read_entire_file);
|
||||||
#define PLATFORM_WRITE_ENTIRE_FILE(name) b32 name(char* Path, u8* Contents, s32 Size)
|
#define PLATFORM_WRITE_ENTIRE_FILE(name) b32 name(char* Path, u8* Contents, s32 Size)
|
||||||
typedef PLATFORM_WRITE_ENTIRE_FILE(platform_write_entire_file);
|
typedef PLATFORM_WRITE_ENTIRE_FILE(platform_write_entire_file);
|
||||||
|
|
||||||
#define PLATFORM_GET_FILE_PATH(name)
|
#define PLATFORM_GET_FILE_PATH(name) b32 name(char* PathBuffer, s32 BufferLength)
|
||||||
typedef PLATFORM_GET_FILE_PATH(platform_get_file_path);
|
typedef PLATFORM_GET_FILE_PATH(platform_get_file_path);
|
||||||
|
|
||||||
#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name)
|
#define PLATFORM_GET_GPU_TEXTURE_HANDLE(name) s32 name(u8* Memory, s32 Width, s32 Height)
|
||||||
typedef PLATFORM_GET_GPU_TEXTURE_HANDLE(platform_get_gpu_texture_handle);
|
typedef PLATFORM_GET_GPU_TEXTURE_HANDLE(platform_get_gpu_texture_handle);
|
||||||
|
|
||||||
#define PLATFORM_GET_SOCKET_HANDLE(name)
|
typedef s32 platform_socket_handle;
|
||||||
|
typedef s32 platform_network_address_handle;
|
||||||
|
|
||||||
|
#define PLATFORM_GET_SOCKET_HANDLE(name) platform_socket_handle name(s32 AddressFamily, s32 Type, s32 Protocol)
|
||||||
typedef PLATFORM_GET_SOCKET_HANDLE(platform_get_socket_handle);
|
typedef PLATFORM_GET_SOCKET_HANDLE(platform_get_socket_handle);
|
||||||
|
|
||||||
#define PLATFORM_GET_SEND_ADDRESS(name)
|
#define PLATFORM_GET_SEND_ADDRESS_HANDLE(name) platform_network_address_handle name(s32 AddressFamily, u16 Port, u32 Address)
|
||||||
typedef PLATFORM_GET_SEND_ADDRESS(platform_get_send_address);
|
typedef PLATFORM_GET_SEND_ADDRESS_HANDLE(platform_get_send_address);
|
||||||
|
|
||||||
#define PLATFORM_SET_SOCKET_OPTION(name)
|
#define PLATFORM_SET_SOCKET_OPTION(name) s32 name(platform_socket_handle SocketHandle, s32 Level, s32 Option, const char* OptionValue, s32 OptionLength)
|
||||||
typedef PLATFORM_SET_SOCKET_OPTION(platform_set_socket_option);
|
typedef PLATFORM_SET_SOCKET_OPTION(platform_set_socket_option);
|
||||||
|
|
||||||
#define PLATFORM_SEND_TO(name)
|
#define PLATFORM_SEND_TO(name) s32 name(platform_socket_handle SocketHandle, platform_network_address_handle AddressHandle, const char* Buffer, s32 BufferLength, s32 Flags)
|
||||||
typedef PLATFORM_SEND_TO(platform_send_to);
|
typedef PLATFORM_SEND_TO(platform_send_to);
|
||||||
|
|
||||||
#define PLATFORM_CLOSE_SOCKET(name)
|
#define PLATFORM_CLOSE_SOCKET(name) void name(platform_socket_handle SocketHandle)
|
||||||
typedef PLATFORM_CLOSE_SOCKET(platform_close_socket);
|
typedef PLATFORM_CLOSE_SOCKET(platform_close_socket);
|
||||||
|
|
||||||
|
#ifndef GS_INPUT
|
||||||
|
#define GS_INPUT
|
||||||
enum key_code
|
enum key_code
|
||||||
{
|
{
|
||||||
KeyCode_Invalid,
|
KeyCode_Invalid,
|
||||||
|
@ -119,6 +183,7 @@ struct input_frame
|
||||||
b32 KeysDown[(int)KeyCode_Count];
|
b32 KeysDown[(int)KeyCode_Count];
|
||||||
s32 StringInputUsed;
|
s32 StringInputUsed;
|
||||||
char StringInput[INPUT_FRAME_STRING_LENGTH];
|
char StringInput[INPUT_FRAME_STRING_LENGTH];
|
||||||
|
s32 MouseX, MouseY, MouseScroll;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct input
|
struct input
|
||||||
|
@ -126,6 +191,7 @@ struct input
|
||||||
input_frame Frames[2];
|
input_frame Frames[2];
|
||||||
input_frame* New;
|
input_frame* New;
|
||||||
input_frame* Old;
|
input_frame* Old;
|
||||||
|
s32 MouseDownX, MouseDownY;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal void InitializeInput (input* Input);
|
internal void InitializeInput (input* Input);
|
||||||
|
@ -167,5 +233,19 @@ KeyTransitionedUp (input Input, key_code Key)
|
||||||
{
|
{
|
||||||
return !Input.New->KeysDown[Key] && Input.Old->KeysDown[Key];
|
return !Input.New->KeysDown[Key] && Input.Old->KeysDown[Key];
|
||||||
}
|
}
|
||||||
|
#endif // GS_INPUT
|
||||||
|
|
||||||
|
internal window PlatformCreateWindow (char* Name, s32 Width, s32 Height);
|
||||||
|
|
||||||
|
|
||||||
|
// Time
|
||||||
|
|
||||||
|
internal r32
|
||||||
|
GetSecondsElapsed (s64 Start, s64 End, s64 PerformanceCountFrequency)
|
||||||
|
{
|
||||||
|
r32 Result = ((r32)(End - Start) / (r32) PerformanceCountFrequency);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
#define GS_PLATFORM_H
|
#define GS_PLATFORM_H
|
||||||
#endif // GS_PLATFORM_H
|
#endif // GS_PLATFORM_H
|
13
gs_string.h
13
gs_string.h
|
@ -244,8 +244,7 @@ static float ParseFloat (char* String, s32 Length);
|
||||||
static s32 FloatToString(float Float, char *String, s32 Length, s32 AfterPoint);
|
static s32 FloatToString(float Float, char *String, s32 Length, s32 AfterPoint);
|
||||||
|
|
||||||
// PrintF
|
// PrintF
|
||||||
|
static s32 PrintF(string* String, char* Format, ...);
|
||||||
#define PrintString(str, format, ...) snprintf(str.Memory, str.Max, format, __VA_ARGS__); str.Length = CharArrayLength(str.Memory);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// String Memory Function Declarations
|
// String Memory Function Declarations
|
||||||
|
@ -1278,11 +1277,12 @@ FloatToString(float Float, char *String, s32 Length, s32 AfterPoint)
|
||||||
|
|
||||||
|
|
||||||
internal s32
|
internal s32
|
||||||
PrintStringF(char* Format, char* Destination, s32 DestLength, ...)
|
PrintF (string* String, char* Format, ...)
|
||||||
{
|
{
|
||||||
va_list Args;
|
va_list Args;
|
||||||
va_start(Args, DestLength);
|
va_start(Args, Format);
|
||||||
|
|
||||||
|
#if 0
|
||||||
s32 LengthPrinted = 0;
|
s32 LengthPrinted = 0;
|
||||||
char* DestChar = Destination;
|
char* DestChar = Destination;
|
||||||
|
|
||||||
|
@ -1334,9 +1334,10 @@ PrintStringF(char* Format, char* Destination, s32 DestLength, ...)
|
||||||
}
|
}
|
||||||
*(Destination + LengthPrinted) = 0;
|
*(Destination + LengthPrinted) = 0;
|
||||||
|
|
||||||
va_end(Args);
|
#endif
|
||||||
|
|
||||||
return LengthPrinted;
|
va_end(Args);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,15 @@ union v4
|
||||||
r32 E[4];
|
r32 E[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define WhiteV4 v4{1, 1, 1, 1}
|
||||||
|
#define BlackV4 v4{0, 0, 0, 1}
|
||||||
|
#define RedV4 v4{1, 0, 0, 1}
|
||||||
|
#define GreenV4 v4{0, 1, 0, 1}
|
||||||
|
#define BlueV4 v4{0, 0, 1, 1}
|
||||||
|
#define YellowV4 v4{1, 1, 0, 1}
|
||||||
|
#define TealV4 v4{0, 1, 1, 1}
|
||||||
|
#define PinkV4 v4{1, 0, 1, 1}
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
// MATRIX
|
// MATRIX
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
|
@ -99,8 +108,8 @@ union m44
|
||||||
|
|
||||||
struct rect
|
struct rect
|
||||||
{
|
{
|
||||||
v2 LowerLeft;
|
v2 Min;
|
||||||
v2 UpperRight;
|
v2 Max;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -187,6 +196,19 @@ V4OpV4Def(*)
|
||||||
#undef V3OpV3Def
|
#undef V3OpV3Def
|
||||||
#undef V4OpV4Def
|
#undef V4OpV4Def
|
||||||
|
|
||||||
|
#define V2RefOpV2Def(op) v2 operator##op (v2& A, v2 B) { return v2{ A.x op B.x, A.y op B.y };}
|
||||||
|
#define V3RefOpV3Def(op) v3 operator##op (v3& A, v3 B) { return v3{ A.x op B.x, A.y op B.y, A.z op B.z };}
|
||||||
|
#define V4RefOpScalarDef(op) v4 operator##op (v4& A, v4 B) { return v4{ A.x op B.x, A.y op B.y, A.z op B.z, A.w op B.w };}
|
||||||
|
V2RefOpV2Def(+=)
|
||||||
|
V2RefOpV2Def(-=)
|
||||||
|
V3RefOpV3Def(+=)
|
||||||
|
V3RefOpV3Def(-=)
|
||||||
|
V4RefOpScalarDef(+=)
|
||||||
|
V4RefOpScalarDef(-=)
|
||||||
|
#undef V2RefOpV2Def
|
||||||
|
#undef V3RefOpV3Def
|
||||||
|
#undef V4RefOpV4Def
|
||||||
|
|
||||||
#define V2OpScalarDef(op) v2 operator##op (v2 A, r32 B) { return v2{ A.x op B, A.y op B };}
|
#define V2OpScalarDef(op) v2 operator##op (v2 A, r32 B) { return v2{ A.x op B, A.y op B };}
|
||||||
#define V3OpScalarDef(op) v3 operator##op (v3 A, r32 B) { return v3{ A.x op B, A.y op B, A.z op B };}
|
#define V3OpScalarDef(op) v3 operator##op (v3 A, r32 B) { return v3{ A.x op B, A.y op B, A.z op B };}
|
||||||
#define V4OpScalarDef(op) v4 operator##op (v4 A, r32 B) { return v4{ A.x op B, A.y op B, A.z op B, A.w op B };}
|
#define V4OpScalarDef(op) v4 operator##op (v4 A, r32 B) { return v4{ A.x op B, A.y op B, A.z op B, A.w op B };}
|
||||||
|
@ -201,9 +223,9 @@ V4OpScalarDef(/)
|
||||||
#undef V4POpScalarDef
|
#undef V4POpScalarDef
|
||||||
|
|
||||||
|
|
||||||
#define V2POpScalarDef(op) v2 operator##op (v2* A, r32 B) { return v2{ A->x op B, A->y op B };}
|
#define V2POpScalarDef(op) v2 operator##op (v2& A, r32 B) { return v2{ A->x op B, A->y op B };}
|
||||||
#define V3POpScalarDef(op) v3 operator##op (v3* A, r32 B) { return v3{ A->x op B, A->y op B, A->z op B };}
|
#define V3POpScalarDef(op) v3 operator##op (v3& A, r32 B) { return v3{ A->x op B, A->y op B, A->z op B };}
|
||||||
#define V4POpScalarDef(op) v4 operator##op (v4* A, r32 B) { return v4{ A->x op B, A->y op B, A->z op B, A->w op B };}
|
#define V4POpScalarDef(op) v4 operator##op (v4& A, r32 B) { return v4{ A->x op B, A->y op B, A->z op B, A->w op B };}
|
||||||
V2OpScalarDef(*=)
|
V2OpScalarDef(*=)
|
||||||
V2OpScalarDef(/=)
|
V2OpScalarDef(/=)
|
||||||
V3OpScalarDef(*=)
|
V3OpScalarDef(*=)
|
||||||
|
@ -613,6 +635,39 @@ PointToPercentRange (v2 P, v2 Min, v2 Max)
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////
|
||||||
|
// RECT
|
||||||
|
//////////////////////////////////////
|
||||||
|
|
||||||
|
inline r32
|
||||||
|
Width (rect Rect)
|
||||||
|
{
|
||||||
|
s32 Result = Rect.Max.x - Rect.Min.x;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32
|
||||||
|
Height (rect Rect)
|
||||||
|
{
|
||||||
|
s32 Result = Rect.Max.y - Rect.Min.y;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2
|
||||||
|
CalculateRectCenter (rect Rect)
|
||||||
|
{
|
||||||
|
v2 Result = (Rect.Min + Rect.Max) / 2.0f;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
PointIsInRect (v2 Point, rect Rect)
|
||||||
|
{
|
||||||
|
b32 Result = ((Point.x >= Rect.Min.x && Point.x <= Rect.Max.x) &&
|
||||||
|
(Point.y >= Rect.Min.y && Point.y <= Rect.Max.y));
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
// MATRIX
|
// MATRIX
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
@ -778,8 +833,6 @@ Transpose (m44 M)
|
||||||
static m44
|
static m44
|
||||||
GetPositionM44 (v4 Position)
|
GetPositionM44 (v4 Position)
|
||||||
{
|
{
|
||||||
DEBUG_TRACK_SCOPE(GetPositionM44);
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
return m44{
|
return m44{
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
|
|
|
@ -0,0 +1,974 @@
|
||||||
|
#ifndef GS_WIN32_CPP
|
||||||
|
|
||||||
|
struct win32_state
|
||||||
|
{
|
||||||
|
b32 Initialized;
|
||||||
|
b32 Running;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct win32_opengl_window_info
|
||||||
|
{
|
||||||
|
s32 ColorBits;
|
||||||
|
s32 AlphaBits;
|
||||||
|
s32 DepthBits;
|
||||||
|
HGLRC RenderContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct window
|
||||||
|
{
|
||||||
|
char* Name;
|
||||||
|
char* ClassName;
|
||||||
|
s32 Width;
|
||||||
|
s32 Height;
|
||||||
|
WNDPROC WindowEventHandler;
|
||||||
|
|
||||||
|
WNDCLASS Class;
|
||||||
|
HWND Handle;
|
||||||
|
HDC DeviceContext;
|
||||||
|
|
||||||
|
// TODO(peter): Make this a union?
|
||||||
|
win32_opengl_window_info OpenGLInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct handle_window_msg_result
|
||||||
|
{
|
||||||
|
b32 NeedsUpdate;
|
||||||
|
#ifdef DEBUG
|
||||||
|
char MessageType[128];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
global_variable win32_state GlobalWin32State;
|
||||||
|
|
||||||
|
// Utility
|
||||||
|
internal s32 Win32StringLength(char* String);
|
||||||
|
internal s32 Win32ConcatStrings(s32 ALen, char* A, s32 BLen, char* B, s32 DestLen, char* Dest);
|
||||||
|
|
||||||
|
// Windowing & Graphics
|
||||||
|
struct win32_offscreen_buffer
|
||||||
|
{
|
||||||
|
texture_buffer Buffer;
|
||||||
|
BITMAPINFO Info;
|
||||||
|
};
|
||||||
|
|
||||||
|
LRESULT CALLBACK Win32HandleWindowsEvents (HWND WindowHandle, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
internal handle_window_msg_result HandleWindowsMessage (HWND WindowHandle, MSG Message);
|
||||||
|
internal void Win32UpdateWindowDimension(window* Window);
|
||||||
|
internal void Win32ResizeDIBSection(win32_offscreen_buffer *Buffer, int Width, int Height);
|
||||||
|
internal void Win32DisplayBufferInWindow(win32_offscreen_buffer* Buffer, window Window);
|
||||||
|
|
||||||
|
// Memory
|
||||||
|
|
||||||
|
internal PLATFORM_ALLOC(Win32Alloc);
|
||||||
|
internal PLATFORM_FREE(Win32Free);
|
||||||
|
|
||||||
|
// File IO
|
||||||
|
internal PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile);
|
||||||
|
internal PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile);
|
||||||
|
internal FILETIME Win32GetFileLastWriteTime;
|
||||||
|
|
||||||
|
// DLL
|
||||||
|
struct win32_dll_refresh
|
||||||
|
{
|
||||||
|
FILETIME LastWriteTime;
|
||||||
|
HMODULE DLL;
|
||||||
|
|
||||||
|
b32 IsValid;
|
||||||
|
|
||||||
|
char SourceDLLPath[MAX_PATH];
|
||||||
|
char WorkingDLLPath[MAX_PATH];
|
||||||
|
char LockFilePath[MAX_PATH];
|
||||||
|
};
|
||||||
|
|
||||||
|
internal b32 LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult);
|
||||||
|
internal void UnloadApplicationDLL(win32_dll_refresh* DLL);
|
||||||
|
internal win32_dll_refresh InitializeDLLHotReloading(char* SourceDLLName, char* WorkingDLLFileName, char* LockFileName);
|
||||||
|
internal b32 HotLoadDLL(win32_dll_refresh* DLL);
|
||||||
|
|
||||||
|
// Networking
|
||||||
|
|
||||||
|
///
|
||||||
|
// Utils
|
||||||
|
///
|
||||||
|
|
||||||
|
internal s32
|
||||||
|
Win32StringLength(char* String)
|
||||||
|
{
|
||||||
|
char* At = String;
|
||||||
|
while (*At) { At++; };
|
||||||
|
return At - String;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal s32
|
||||||
|
Win32ConcatStrings(s32 ALen, char* A, s32 BLen, char* B, s32 DestLen, char* Dest)
|
||||||
|
{
|
||||||
|
char* Dst = Dest;
|
||||||
|
char* AAt = A;
|
||||||
|
for (s32 a = 0; a < ALen; a++)
|
||||||
|
{
|
||||||
|
*Dst++ = *AAt++;
|
||||||
|
}
|
||||||
|
char* BAt = B;
|
||||||
|
for (s32 b = 0; b < BLen; b++)
|
||||||
|
{
|
||||||
|
*Dst++ = *BAt++;
|
||||||
|
}
|
||||||
|
return Dst - Dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
// Windowing
|
||||||
|
///
|
||||||
|
|
||||||
|
internal window
|
||||||
|
Win32CreateWindow (HINSTANCE HInstance, char* WindowName, s32 Width, s32 Height,
|
||||||
|
WNDPROC WindowEventHandler)
|
||||||
|
{
|
||||||
|
window Result = {};
|
||||||
|
Result.Name = WindowName;
|
||||||
|
Result.ClassName = WindowName;
|
||||||
|
Result.Width = Width;
|
||||||
|
Result.Height = Height;
|
||||||
|
Result.WindowEventHandler = WindowEventHandler;
|
||||||
|
|
||||||
|
Result.Class = {};
|
||||||
|
Result.Class.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
Result.Class.lpfnWndProc = WindowEventHandler;
|
||||||
|
Result.Class.hInstance = HInstance;
|
||||||
|
Result.Class.lpszClassName = WindowName;
|
||||||
|
|
||||||
|
if (RegisterClass(&Result.Class))
|
||||||
|
{
|
||||||
|
Result.Handle = CreateWindowEx(
|
||||||
|
0,
|
||||||
|
Result.Class.lpszClassName,
|
||||||
|
WindowName,
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
Width,
|
||||||
|
Height,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
HInstance,
|
||||||
|
0);
|
||||||
|
Result.DeviceContext = GetDC(Result.Handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal window
|
||||||
|
PlatformCreateWindow (char* WindowName, s32 Width, s32 Height)
|
||||||
|
{
|
||||||
|
HINSTANCE HInstance = GetModuleHandle(NULL);
|
||||||
|
return Win32CreateWindow(HInstance, WindowName, Width, Height, Win32HandleWindowsEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
CreateOpenGLWindowContext (win32_opengl_window_info Info, window* Window)
|
||||||
|
{
|
||||||
|
// Setup pixel format
|
||||||
|
{
|
||||||
|
PIXELFORMATDESCRIPTOR PixelFormatDesc = { 0 };
|
||||||
|
// TODO: Program seems to work perfectly fine without all other params except dwFlags.
|
||||||
|
// Can we skip other params for the sake of brevity?
|
||||||
|
PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||||
|
PixelFormatDesc.nVersion = 1;
|
||||||
|
PixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
|
||||||
|
PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;// TODO(Peter): include this in win32_opengl_window_info?
|
||||||
|
PixelFormatDesc.cColorBits = Info.ColorBits;
|
||||||
|
PixelFormatDesc.cAlphaBits = Info.AlphaBits;
|
||||||
|
PixelFormatDesc.cDepthBits = Info.DepthBits;
|
||||||
|
PixelFormatDesc.dwLayerMask = PFD_MAIN_PLANE; // TODO(Peter): include this in win32_opengl_window_info?
|
||||||
|
//
|
||||||
|
|
||||||
|
s32 PixelFormat = ChoosePixelFormat(Window->DeviceContext, &PixelFormatDesc);
|
||||||
|
if (!PixelFormat) { InvalidCodePath; } // TODO: Log: Choose pixel format failed
|
||||||
|
if (!SetPixelFormat(Window->DeviceContext, PixelFormat, &PixelFormatDesc)) { InvalidCodePath; } // TODO: Log: Set pixel format failed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create rendering context
|
||||||
|
{
|
||||||
|
// TODO: Create "proper" context?
|
||||||
|
// https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation
|
||||||
|
|
||||||
|
Info.RenderContext = wglCreateContext(Window->DeviceContext);
|
||||||
|
wglMakeCurrent(Window->DeviceContext, Info.RenderContext);
|
||||||
|
|
||||||
|
// TODO(Peter): do we want this?
|
||||||
|
/*
|
||||||
|
glGetIntegerv(GL_MAJOR_VERSION, );
|
||||||
|
glGetIntegerv(GL_MINOR_VERSION, );
|
||||||
|
(char*)glGetString(GL_VENDOR);
|
||||||
|
(char*)glGetString(GL_RENDERER);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Window->OpenGLInfo = Info;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct handle_window_event_result
|
||||||
|
{
|
||||||
|
LRESULT Result;
|
||||||
|
b32 Handled;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32UpdateInputFrameMouseButtonState (input_frame* InputFrame, key_code KeyCode, int Win32VirtualKey)
|
||||||
|
{
|
||||||
|
InputFrame->KeysDown[KeyCode] = (GetKeyState(Win32VirtualKey) & (1 << 15)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32UpdateInputFrameMouseState (input_frame* InputFrame)
|
||||||
|
{
|
||||||
|
Win32UpdateInputFrameMouseButtonState(InputFrame, KeyCode_MouseLeftButton, VK_LBUTTON);
|
||||||
|
Win32UpdateInputFrameMouseButtonState(InputFrame, KeyCode_MouseMiddleButton, VK_MBUTTON);
|
||||||
|
Win32UpdateInputFrameMouseButtonState(InputFrame, KeyCode_MouseRightButton, VK_RBUTTON);
|
||||||
|
// NOTE(Peter): If you decide to support extra mouse buttons, on windows the key codes are
|
||||||
|
// VK_XBUTTON1 and VK_XBUTTON2
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32UpdateInputFrameMouseWheelDelta (input_frame* InputFrame, MSG Message)
|
||||||
|
{
|
||||||
|
int MouseWheel = GET_WHEEL_DELTA_WPARAM(Message.wParam);
|
||||||
|
InputFrame->MouseScroll = MouseWheel;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal handle_window_event_result
|
||||||
|
HandleWindowEventUnlessWouldUseDefault (HWND WindowHandle, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
handle_window_event_result Result = {};
|
||||||
|
Result.Handled = false;
|
||||||
|
|
||||||
|
switch (Msg)
|
||||||
|
{
|
||||||
|
case WM_SIZE:
|
||||||
|
{
|
||||||
|
|
||||||
|
Result.Handled = true;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
{
|
||||||
|
Result.Result = DefWindowProc(WindowHandle, Msg, wParam, lParam);
|
||||||
|
Result.Handled = true;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_DESTROY:
|
||||||
|
{
|
||||||
|
GlobalWin32State.Running = false;
|
||||||
|
Result.Handled = true;
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_PAINT:
|
||||||
|
{
|
||||||
|
PAINTSTRUCT PaintStruct;
|
||||||
|
HDC DeviceContext;
|
||||||
|
b32 PaintResult;
|
||||||
|
|
||||||
|
DeviceContext = BeginPaint(WindowHandle, &PaintStruct);
|
||||||
|
PaintResult = EndPaint(WindowHandle, &PaintStruct);
|
||||||
|
Result.Handled = true;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK
|
||||||
|
Win32HandleWindowsEvents (
|
||||||
|
HWND WindowHandle,
|
||||||
|
UINT Msg,
|
||||||
|
WPARAM wParam,
|
||||||
|
LPARAM lParam
|
||||||
|
)
|
||||||
|
{
|
||||||
|
handle_window_event_result EventResult = HandleWindowEventUnlessWouldUseDefault(
|
||||||
|
WindowHandle,
|
||||||
|
Msg,
|
||||||
|
wParam,
|
||||||
|
lParam);
|
||||||
|
|
||||||
|
if (!EventResult.Handled)
|
||||||
|
{
|
||||||
|
EventResult.Result = DefWindowProc(WindowHandle, Msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
return EventResult.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WIN32_SHOULD_TRANSLATE_TO_CHAR -1
|
||||||
|
|
||||||
|
static int
|
||||||
|
Win32GetKeyIndex (int Win32VirtualKey, bool NumpadValid, bool TranslateToChar)
|
||||||
|
{
|
||||||
|
int Result = WIN32_SHOULD_TRANSLATE_TO_CHAR;
|
||||||
|
|
||||||
|
if (Win32VirtualKey == VK_ESCAPE) { Result = (int)KeyCode_Esc; }
|
||||||
|
|
||||||
|
if (!TranslateToChar)
|
||||||
|
{
|
||||||
|
if (Win32VirtualKey == VK_SPACE) { Result = (int)KeyCode_Space; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Win32VirtualKey == VK_CAPITAL) { Result = (int)KeyCode_CapsLock; }
|
||||||
|
else if (Win32VirtualKey == VK_TAB) { Result = (int)KeyCode_Tab; }
|
||||||
|
else if (Win32VirtualKey == VK_LSHIFT) { Result = (int)KeyCode_LeftShift; }
|
||||||
|
else if (Win32VirtualKey == VK_RSHIFT) { Result = (int)KeyCode_RightShift; }
|
||||||
|
else if (Win32VirtualKey == VK_LCONTROL) { Result = (int)KeyCode_LeftCtrl; }
|
||||||
|
else if (Win32VirtualKey == VK_RCONTROL) { Result = (int)KeyCode_RightCtrl; }
|
||||||
|
|
||||||
|
// TODO(Peter): support the function key?
|
||||||
|
//else if (Win32VirtualKey == VK_) { Result = (int)KeyCode_Fn; }
|
||||||
|
|
||||||
|
else if (Win32VirtualKey == VK_MENU) { Result = (int)KeyCode_Alt; }
|
||||||
|
else if (Win32VirtualKey == VK_PRIOR) { Result = (int)KeyCode_PageUp; }
|
||||||
|
else if (Win32VirtualKey == VK_NEXT) { Result = (int)KeyCode_PageDown; }
|
||||||
|
else if (Win32VirtualKey == VK_BACK) { Result = (int)KeyCode_Backspace; }
|
||||||
|
else if (Win32VirtualKey == VK_DELETE) { Result = (int)KeyCode_Delete; }
|
||||||
|
else if (Win32VirtualKey == VK_RETURN) { Result = (int)KeyCode_Enter; }
|
||||||
|
|
||||||
|
else if (Win32VirtualKey == VK_F1) { Result = (int)KeyCode_F1; }
|
||||||
|
else if (Win32VirtualKey == VK_F2) { Result = (int)KeyCode_F2; }
|
||||||
|
else if (Win32VirtualKey == VK_F3) { Result = (int)KeyCode_F3; }
|
||||||
|
else if (Win32VirtualKey == VK_F4) { Result = (int)KeyCode_F4; }
|
||||||
|
else if (Win32VirtualKey == VK_F5) { Result = (int)KeyCode_F5; }
|
||||||
|
else if (Win32VirtualKey == VK_F6) { Result = (int)KeyCode_F6; }
|
||||||
|
else if (Win32VirtualKey == VK_F7) { Result = (int)KeyCode_F7; }
|
||||||
|
else if (Win32VirtualKey == VK_F8) { Result = (int)KeyCode_F8; }
|
||||||
|
else if (Win32VirtualKey == VK_F9) { Result = (int)KeyCode_F9; }
|
||||||
|
else if (Win32VirtualKey == VK_F10) { Result = (int)KeyCode_F10; }
|
||||||
|
else if (Win32VirtualKey == VK_F11) { Result = (int)KeyCode_F11; }
|
||||||
|
else if (Win32VirtualKey == VK_F12) { Result = (int)KeyCode_F12; }
|
||||||
|
|
||||||
|
if (!TranslateToChar)
|
||||||
|
{
|
||||||
|
if (Win32VirtualKey == 0x30) { Result = (int)KeyCode_0; }
|
||||||
|
else if (Win32VirtualKey == 0x31) { Result = (int)KeyCode_1; }
|
||||||
|
else if (Win32VirtualKey == 0x32) { Result = (int)KeyCode_2; }
|
||||||
|
else if (Win32VirtualKey == 0x33) { Result = (int)KeyCode_3; }
|
||||||
|
else if (Win32VirtualKey == 0x34) { Result = (int)KeyCode_4; }
|
||||||
|
else if (Win32VirtualKey == 0x35) { Result = (int)KeyCode_5; }
|
||||||
|
else if (Win32VirtualKey == 0x36) { Result = (int)KeyCode_6; }
|
||||||
|
else if (Win32VirtualKey == 0x37) { Result = (int)KeyCode_7; }
|
||||||
|
else if (Win32VirtualKey == 0x38) { Result = (int)KeyCode_8; }
|
||||||
|
else if (Win32VirtualKey == 0x39) { Result = (int)KeyCode_9; }
|
||||||
|
|
||||||
|
else if (Win32VirtualKey == 0x41) { Result = (int)KeyCode_A; }
|
||||||
|
else if (Win32VirtualKey == 0x42) { Result = (int)KeyCode_B; }
|
||||||
|
else if (Win32VirtualKey == 0x43) { Result = (int)KeyCode_C; }
|
||||||
|
else if (Win32VirtualKey == 0x44) { Result = (int)KeyCode_D; }
|
||||||
|
else if (Win32VirtualKey == 0x45) { Result = (int)KeyCode_E; }
|
||||||
|
else if (Win32VirtualKey == 0x46) { Result = (int)KeyCode_F; }
|
||||||
|
else if (Win32VirtualKey == 0x47) { Result = (int)KeyCode_G; }
|
||||||
|
else if (Win32VirtualKey == 0x48) { Result = (int)KeyCode_H; }
|
||||||
|
else if (Win32VirtualKey == 0x49) { Result = (int)KeyCode_I; }
|
||||||
|
else if (Win32VirtualKey == 0x4A) { Result = (int)KeyCode_J; }
|
||||||
|
else if (Win32VirtualKey == 0x4B) { Result = (int)KeyCode_K; }
|
||||||
|
else if (Win32VirtualKey == 0x4C) { Result = (int)KeyCode_L; }
|
||||||
|
else if (Win32VirtualKey == 0x4D) { Result = (int)KeyCode_M; }
|
||||||
|
else if (Win32VirtualKey == 0x4E) { Result = (int)KeyCode_N; }
|
||||||
|
else if (Win32VirtualKey == 0x4F) { Result = (int)KeyCode_O; }
|
||||||
|
else if (Win32VirtualKey == 0x50) { Result = (int)KeyCode_P; }
|
||||||
|
else if (Win32VirtualKey == 0x51) { Result = (int)KeyCode_Q; }
|
||||||
|
else if (Win32VirtualKey == 0x52) { Result = (int)KeyCode_R; }
|
||||||
|
else if (Win32VirtualKey == 0x53) { Result = (int)KeyCode_S; }
|
||||||
|
else if (Win32VirtualKey == 0x54) { Result = (int)KeyCode_T; }
|
||||||
|
else if (Win32VirtualKey == 0x55) { Result = (int)KeyCode_U; }
|
||||||
|
else if (Win32VirtualKey == 0x56) { Result = (int)KeyCode_V; }
|
||||||
|
else if (Win32VirtualKey == 0x57) { Result = (int)KeyCode_W; }
|
||||||
|
else if (Win32VirtualKey == 0x58) { Result = (int)KeyCode_X; }
|
||||||
|
else if (Win32VirtualKey == 0x59) { Result = (int)KeyCode_Y; }
|
||||||
|
else if (Win32VirtualKey == 0x5A) { Result = (int)KeyCode_Z; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NumpadValid)
|
||||||
|
{
|
||||||
|
if (Win32VirtualKey == VK_NUMPAD0) { Result = (int)KeyCode_Num0; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD1) { Result = (int)KeyCode_Num1; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD2) { Result = (int)KeyCode_Num2; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD3) { Result = (int)KeyCode_Num3; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD4) { Result = (int)KeyCode_Num4; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD5) { Result = (int)KeyCode_Num5; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD6) { Result = (int)KeyCode_Num6; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD7) { Result = (int)KeyCode_Num7; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD8) { Result = (int)KeyCode_Num8; }
|
||||||
|
else if (Win32VirtualKey == VK_NUMPAD9) { Result = (int)KeyCode_Num9; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Win32VirtualKey == VK_UP) { Result = (int)KeyCode_UpArrow; }
|
||||||
|
else if (Win32VirtualKey == VK_DOWN) { Result = (int)KeyCode_DownArrow; }
|
||||||
|
else if (Win32VirtualKey == VK_LEFT) { Result = (int)KeyCode_LeftArrow; }
|
||||||
|
else if (Win32VirtualKey == VK_RIGHT) { Result = (int)KeyCode_RightArrow; }
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal handle_window_msg_result
|
||||||
|
HandleWindowsMessage (
|
||||||
|
HWND WindowHandle,
|
||||||
|
MSG Message)
|
||||||
|
{
|
||||||
|
handle_window_msg_result Result = {};
|
||||||
|
Result.NeedsUpdate = 0;
|
||||||
|
|
||||||
|
switch (Message.message)
|
||||||
|
{
|
||||||
|
case WM_HOTKEY:
|
||||||
|
{
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_MOUSEWHEEL:
|
||||||
|
{
|
||||||
|
int MouseWheel = GET_WHEEL_DELTA_WPARAM(Message.wParam);
|
||||||
|
/*
|
||||||
|
Input.New->MouseScroll = MouseWheel;
|
||||||
|
Result.NeedsUpdate = true;
|
||||||
|
*/
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
case WM_MBUTTONDOWN:
|
||||||
|
case WM_MBUTTONUP:
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
case WM_RBUTTONUP:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Input.New->KeyStates[KeyCode_MouseLeftButton] = (GetKeyState(VK_LBUTTON) & (1 << 15)) != 0;
|
||||||
|
Input.New->KeyStates[KeyCode_MouseMiddleButton] = (GetKeyState(VK_MBUTTON) & (1 << 15)) != 0;
|
||||||
|
Input.New->KeyStates[KeyCode_MouseRightButton] = (GetKeyState(VK_RBUTTON) & (1 << 15)) != 0;
|
||||||
|
// NOTE(Peter): If you decide to support extra mouse buttons, on windows the key codes are
|
||||||
|
// VK_XBUTTON1 and VK_XBUTTON2
|
||||||
|
|
||||||
|
if (KeyTransitionedDown(KeyCode_MouseLeftButton, Input))
|
||||||
|
{
|
||||||
|
Input.MouseDownX = Input.New->MouseX;
|
||||||
|
Input.MouseDownY = Input.New->MouseY;
|
||||||
|
}
|
||||||
|
Result.NeedsUpdate = true;*/
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
{
|
||||||
|
POINT MousePos;
|
||||||
|
GetCursorPos(&MousePos);
|
||||||
|
ScreenToClient(WindowHandle, &MousePos);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Input.New->MouseX = MousePos.x;
|
||||||
|
Input.New->MouseY = App.WindowHeight - MousePos.y;
|
||||||
|
|
||||||
|
Result.NeedsUpdate = true;
|
||||||
|
*/
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
case WM_SYSKEYUP:
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
case WM_KEYUP:
|
||||||
|
{
|
||||||
|
int VirtualKey = (int)Message.wParam;
|
||||||
|
bool KeyDown = (Message.lParam & (1 << 31)) == 0;
|
||||||
|
int KeyIndex = Win32GetKeyIndex(VirtualKey, true, true);
|
||||||
|
/*
|
||||||
|
if (KeyIndex >= 0)
|
||||||
|
{
|
||||||
|
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_KEYEvent ");
|
||||||
|
Input.New->KeyStates[KeyIndex] = KeyDown;
|
||||||
|
Result.NeedsUpdate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Input.TranslateInputToCharValues && KeyDown)
|
||||||
|
{
|
||||||
|
// NOTE(Peter): Took this out b/c we're translating the WM_CHAR messages
|
||||||
|
// in the message pump, and if we do it here as well, character producing
|
||||||
|
// key messages get put on the message queue twice
|
||||||
|
TranslateMessage(&Message);
|
||||||
|
DispatchMessage(&Message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_KEYEvent ");
|
||||||
|
// NOTE(Peter): This is so that when you lift up a key that was generating a WM_CHAR,
|
||||||
|
// the app still has a chance to respond to it.
|
||||||
|
Result.NeedsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case WM_CHAR:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
char TranslatedChar = (char)Message.wParam;
|
||||||
|
int KeyIndex = GetKeyIndexFromChar(TranslatedChar);
|
||||||
|
|
||||||
|
if (KeyIndex >= 0)
|
||||||
|
{
|
||||||
|
// NOTE(Peter): Always setting this to true becuase windows is stupid and doesn't
|
||||||
|
// pass the press/release bit through correctly. So now the KEYDOWN/KEYUP Messages above
|
||||||
|
// only translate the message to a WM_CHAR message if its a key down. Since we clear all
|
||||||
|
// keystates to false at the beginning of an input frame, this will make transitions
|
||||||
|
// get registered correctly.
|
||||||
|
Input.New->KeyStates[KeyIndex] = true;
|
||||||
|
Result.NeedsUpdate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Translated Char Not Recognized: %c\n", TranslatedChar);
|
||||||
|
//InvalidCodePath;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
TranslateMessage(&Message);
|
||||||
|
DispatchMessage(&Message);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32UpdateWindowDimension(window* Window)
|
||||||
|
{
|
||||||
|
RECT ClientRect;
|
||||||
|
GetClientRect(Window->Handle, &ClientRect);
|
||||||
|
Window->Width = ClientRect.right - ClientRect.left;
|
||||||
|
Window->Height = ClientRect.bottom - ClientRect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32ResizeDIBSection(win32_offscreen_buffer *Win32Buffer, int Width, int Height)
|
||||||
|
{
|
||||||
|
if(Win32Buffer->Buffer.Memory)
|
||||||
|
{
|
||||||
|
VirtualFree(Win32Buffer->Buffer.Memory, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
Win32Buffer->Buffer.Width = Width;
|
||||||
|
Win32Buffer->Buffer.Height = Height;
|
||||||
|
|
||||||
|
int BytesPerPixel = 4;
|
||||||
|
Win32Buffer->Buffer.BytesPerPixel = BytesPerPixel;
|
||||||
|
|
||||||
|
Win32Buffer->Info.bmiHeader.biSize = sizeof(Win32Buffer->Info.bmiHeader);
|
||||||
|
Win32Buffer->Info.bmiHeader.biWidth = Win32Buffer->Buffer.Width;
|
||||||
|
Win32Buffer->Info.bmiHeader.biHeight = -Win32Buffer->Buffer.Height; // Top down, not bottom up
|
||||||
|
Win32Buffer->Info.bmiHeader.biPlanes = 1;
|
||||||
|
Win32Buffer->Info.bmiHeader.biBitCount = 32;
|
||||||
|
Win32Buffer->Info.bmiHeader.biCompression = BI_RGB;
|
||||||
|
|
||||||
|
int BitmapMemorySize = (Win32Buffer->Buffer.Width * Win32Buffer->Buffer.Height)*BytesPerPixel;
|
||||||
|
Win32Buffer->Buffer.Memory = (u8*)VirtualAlloc(0, BitmapMemorySize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
Win32Buffer->Buffer.Pitch = Width*BytesPerPixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
Win32DisplayBufferInWindow(win32_offscreen_buffer* Win32Buffer, window Window)
|
||||||
|
{
|
||||||
|
StretchDIBits(Window.DeviceContext,
|
||||||
|
0, 0, Win32Buffer->Buffer.Width, Win32Buffer->Buffer.Height,
|
||||||
|
0, 0, Win32Buffer->Buffer.Width, Win32Buffer->Buffer.Height,
|
||||||
|
Win32Buffer->Buffer.Memory,
|
||||||
|
&Win32Buffer->Info,
|
||||||
|
DIB_RGB_COLORS, SRCCOPY);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
// Memory
|
||||||
|
///
|
||||||
|
|
||||||
|
internal u8*
|
||||||
|
Win32BasicAlloc (s32 Size)
|
||||||
|
{
|
||||||
|
return (u8*)VirtualAlloc(NULL, Size,
|
||||||
|
MEM_COMMIT | MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
PLATFORM_ALLOC(Win32Alloc)
|
||||||
|
{
|
||||||
|
platform_memory_result Result = {};
|
||||||
|
Result.Error = PLATFORM_MEMORY_NO_ERROR;
|
||||||
|
|
||||||
|
Result.Base = Win32BasicAlloc(Size);
|
||||||
|
if (Result.Base)
|
||||||
|
{
|
||||||
|
Result.Size = Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result.Error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLATFORM_FREE(Win32Free)
|
||||||
|
{
|
||||||
|
b32 Result = VirtualFree(Base, Size, MEM_RELEASE);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// File IO
|
||||||
|
PLATFORM_READ_ENTIRE_FILE(Win32ReadEntireFile)
|
||||||
|
{
|
||||||
|
platform_memory_result Result = {};
|
||||||
|
Result.Error = PLATFORM_MEMORY_NO_ERROR;
|
||||||
|
|
||||||
|
HANDLE FileHandle = CreateFileA (
|
||||||
|
Path,
|
||||||
|
GENERIC_READ,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD FileSize = GetFileSize(FileHandle, NULL);
|
||||||
|
Result.Base = (u8*)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE,
|
||||||
|
PAGE_EXECUTE_READWRITE);
|
||||||
|
if (Result.Base)
|
||||||
|
{
|
||||||
|
Result.Size = FileSize;
|
||||||
|
|
||||||
|
s32 BytesRead = 0;
|
||||||
|
if (ReadFile(FileHandle, (LPVOID)Result.Base, FileSize, (LPDWORD)(&BytesRead), NULL))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result.Size = 0;
|
||||||
|
Result.Error = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(FileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO(Peter): failure
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLATFORM_WRITE_ENTIRE_FILE(Win32WriteEntireFile)
|
||||||
|
{
|
||||||
|
b32 Result = false;
|
||||||
|
HANDLE FileHandle = CreateFileA (
|
||||||
|
Path,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
DWORD BytesWritten = 0;
|
||||||
|
|
||||||
|
b32 WriteSuccess = WriteFile(FileHandle,
|
||||||
|
Contents, Size,
|
||||||
|
&BytesWritten,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (WriteSuccess && BytesWritten == (u32)Size)
|
||||||
|
{
|
||||||
|
CloseHandle(FileHandle);
|
||||||
|
Result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal FILETIME
|
||||||
|
GetFileLastWriteTime(char* Path)
|
||||||
|
{
|
||||||
|
FILETIME Result = {};
|
||||||
|
|
||||||
|
WIN32_FIND_DATA FindData = {};
|
||||||
|
HANDLE FileHandle = FindFirstFileA(Path, &FindData);
|
||||||
|
|
||||||
|
if (FileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
Result = FindData.ftLastWriteTime;
|
||||||
|
FindClose(FileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO(Peter): Error handling
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLATFORM_GET_FILE_PATH(Win32SystemDialogueOpenFile)
|
||||||
|
{
|
||||||
|
b32 Result = false;
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
// DLL
|
||||||
|
///
|
||||||
|
|
||||||
|
internal void
|
||||||
|
GetApplicationPath(system_path* Result)
|
||||||
|
{
|
||||||
|
Assert(Result->Path);
|
||||||
|
Result->PathLength = GetModuleFileNameA(0, Result->Path, Result->PathLength);
|
||||||
|
|
||||||
|
u32 CharactersScanned = 0;
|
||||||
|
u32 IndexOfLastSlash = 0;
|
||||||
|
char *Scan = Result->Path;
|
||||||
|
while(*Scan)
|
||||||
|
{
|
||||||
|
if (*Scan == '\\')
|
||||||
|
{
|
||||||
|
Result->IndexOfLastSlash = CharactersScanned + 1;
|
||||||
|
}
|
||||||
|
Scan++;
|
||||||
|
CharactersScanned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult)
|
||||||
|
{
|
||||||
|
b32 Success = false;
|
||||||
|
Assert(DLLResult->DLL == 0);
|
||||||
|
|
||||||
|
DLLResult->DLL = LoadLibraryA(DLLName); // TODO(Peter): Error checking
|
||||||
|
if (DLLResult->DLL)
|
||||||
|
{
|
||||||
|
Success = true;
|
||||||
|
DLLResult->IsValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
UnloadApplicationDLL(win32_dll_refresh* DLL)
|
||||||
|
{
|
||||||
|
if (DLL->DLL)
|
||||||
|
{
|
||||||
|
FreeLibrary(DLL->DLL);
|
||||||
|
}
|
||||||
|
DLL->DLL = 0;
|
||||||
|
DLL->IsValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal win32_dll_refresh
|
||||||
|
InitializeDLLHotReloading(char* SourceDLLName,
|
||||||
|
char* WorkingDLLFileName,
|
||||||
|
char* LockFileName)
|
||||||
|
{
|
||||||
|
win32_dll_refresh Result = {};
|
||||||
|
Result.IsValid = false;
|
||||||
|
|
||||||
|
system_path ExePath = {};
|
||||||
|
ExePath.PathLength = MAX_PATH;
|
||||||
|
ExePath.Path = (char*)Win32BasicAlloc(ExePath.PathLength);
|
||||||
|
GetApplicationPath(&ExePath);
|
||||||
|
|
||||||
|
Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
||||||
|
Win32StringLength(SourceDLLName), SourceDLLName,
|
||||||
|
MAX_PATH, Result.SourceDLLPath);
|
||||||
|
Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
||||||
|
Win32StringLength(WorkingDLLFileName), WorkingDLLFileName,
|
||||||
|
MAX_PATH, Result.WorkingDLLPath);
|
||||||
|
Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
||||||
|
Win32StringLength(LockFileName), LockFileName,
|
||||||
|
MAX_PATH, Result.LockFilePath);
|
||||||
|
|
||||||
|
Win32Free((u8*)ExePath.Path, ExePath.PathLength);
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
HotLoadDLL(win32_dll_refresh* DLL)
|
||||||
|
{
|
||||||
|
b32 DidReload = false;
|
||||||
|
|
||||||
|
FILETIME UpdatedLastWriteTime = GetFileLastWriteTime(DLL->SourceDLLPath);
|
||||||
|
if (CompareFileTime(&UpdatedLastWriteTime, &DLL->LastWriteTime))
|
||||||
|
{
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA Ignored;
|
||||||
|
if (!GetFileAttributesEx(DLL->LockFilePath, GetFileExInfoStandard, &Ignored))
|
||||||
|
{
|
||||||
|
UnloadApplicationDLL(DLL);
|
||||||
|
CopyFileA(DLL->SourceDLLPath, DLL->WorkingDLLPath, FALSE);
|
||||||
|
LoadApplicationDLL(DLL->WorkingDLLPath, DLL);
|
||||||
|
DLL->LastWriteTime = UpdatedLastWriteTime;
|
||||||
|
DidReload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DidReload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Timing
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
internal s64
|
||||||
|
GetPerformanceFrequency ()
|
||||||
|
{
|
||||||
|
LARGE_INTEGER Frequency;
|
||||||
|
if (!QueryPerformanceFrequency(&Frequency))
|
||||||
|
{
|
||||||
|
s32 Error = GetLastError();
|
||||||
|
InvalidCodePath;
|
||||||
|
}
|
||||||
|
return (s64)Frequency.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal s64
|
||||||
|
GetWallClock ()
|
||||||
|
{
|
||||||
|
LARGE_INTEGER Time;
|
||||||
|
if (!QueryPerformanceCounter(&Time))
|
||||||
|
{
|
||||||
|
s32 Error = GetLastError();
|
||||||
|
InvalidCodePath;
|
||||||
|
}
|
||||||
|
return (s64)Time.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Open GL
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
internal void
|
||||||
|
OpenGLRenderTriBuffer (u8* Vertecies, s32 VertexElements,
|
||||||
|
u8* UVs, s32 UVElements,
|
||||||
|
u8* Colors, s32 ColorsElements,
|
||||||
|
s32 TriCount)
|
||||||
|
{
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glVertexPointer(VertexElements, GL_FLOAT, VertexElements * sizeof(r32), Vertecies);
|
||||||
|
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(UVElements, GL_FLOAT, UVElements * sizeof(r32), UVs);
|
||||||
|
|
||||||
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
glColorPointer(ColorsElements, GL_FLOAT, ColorsElements * sizeof(r32), Colors);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, TriCount);
|
||||||
|
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
OpenGLDraw3DTri (v4 P0, v4 P1, v4 P2,
|
||||||
|
v2 UV0, v2 UV1, v2 UV2,
|
||||||
|
v4 C0, v4 C1, v4 C2)
|
||||||
|
{
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
glTexCoord2f(UV0.x, UV0.y);
|
||||||
|
glColor4f(C0.r, C0.g, C0.b, C0.a);
|
||||||
|
glVertex4f(P0.x, P0.y, P0.z, P0.w);
|
||||||
|
|
||||||
|
glTexCoord2f(UV1.x, UV1.y);
|
||||||
|
glColor4f(C1.r, C1.g, C1.b, C1.a);
|
||||||
|
glVertex4f(P1.x, P1.y, P1.z, P1.w);
|
||||||
|
|
||||||
|
glTexCoord2f(UV2.x, UV2.y);
|
||||||
|
glColor4f(C2.r, C2.g, C2.b, C2.a);
|
||||||
|
glVertex4f(P2.x, P2.y, P2.z, P2.w);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
OpenGLDraw2DTri (v2 P0, v2 P1, v2 P2,
|
||||||
|
v2 UV0, v2 UV1, v2 UV2,
|
||||||
|
v4 C0, v4 C1, v4 C2)
|
||||||
|
{
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
glTexCoord2f(UV0.x, UV0.y);
|
||||||
|
glColor4f(C0.r, C0.g, C0.b, C0.a);
|
||||||
|
glVertex2f(P0.x, P0.y);
|
||||||
|
|
||||||
|
glTexCoord2f(UV1.x, UV1.y);
|
||||||
|
glColor4f(C1.r, C1.g, C1.b, C1.a);
|
||||||
|
glVertex2f(P1.x, P1.y);
|
||||||
|
|
||||||
|
glTexCoord2f(UV2.x, UV2.y);
|
||||||
|
glColor4f(C2.r, C2.g, C2.b, C2.a);
|
||||||
|
glVertex2f(P2.x, P2.y);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
LoadModelView (r32 Matrix[16])
|
||||||
|
{
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadMatrixf(Matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
LoadProjection (r32 Matrix[16])
|
||||||
|
{
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadMatrixf(Matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
ClearRenderBuffer ()
|
||||||
|
{
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 NextTextureHandle = 1;
|
||||||
|
internal s32
|
||||||
|
SubmitTexture (u8* Memory, s32 Width, s32 Height)
|
||||||
|
{
|
||||||
|
s32 TextureHandle = NextTextureHandle++;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, TextureHandle);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, Memory);
|
||||||
|
return TextureHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BindTexture (s32 TextureHandle)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, TextureHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GS_WIN32_CPP
|
||||||
|
#endif // GS_WIN32_CPP
|
834
gs_win32.h
834
gs_win32.h
|
@ -1,831 +1,17 @@
|
||||||
#ifndef GS_WIN32_H
|
#ifndef GS_WIN32_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
struct platform_font_info
|
||||||
#define DEBUG_GET_MESSAGE_NAME(string, message) sprintf(string, message);
|
|
||||||
#else
|
|
||||||
#define DEBUG_GET_MESSAGE_NAME(string, message)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct win32_state
|
|
||||||
{
|
{
|
||||||
b32 Initialized;
|
s32 PixelHeight;
|
||||||
b32 Running;
|
s32 Ascent, Descent, Leading;
|
||||||
|
s32 MaxCharWidth;
|
||||||
|
s32 CodepointStart;
|
||||||
|
s32 CodepointOnePastLast;
|
||||||
|
|
||||||
|
HDC DrawingDC;
|
||||||
|
HBITMAP Bitmap;
|
||||||
|
HFONT Font;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct win32_window_info
|
|
||||||
{
|
|
||||||
char* Name;
|
|
||||||
char* ClassName;
|
|
||||||
s32 Width;
|
|
||||||
s32 Height;
|
|
||||||
WNDPROC WindowEventsHandler; // If this is left null, Win32HandleWindowsEvents will be used
|
|
||||||
};
|
|
||||||
|
|
||||||
struct win32_opengl_window_info
|
|
||||||
{
|
|
||||||
s32 ColorBits;
|
|
||||||
s32 AlphaBits;
|
|
||||||
s32 DepthBits;
|
|
||||||
HGLRC RenderContext;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct win32_window
|
|
||||||
{
|
|
||||||
win32_window_info Info;
|
|
||||||
|
|
||||||
WNDCLASS Class;
|
|
||||||
HWND Handle;
|
|
||||||
HDC DeviceContext;
|
|
||||||
|
|
||||||
// TODO(peter): Make this a union?
|
|
||||||
win32_opengl_window_info OpenGLInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct handle_window_msg_result
|
|
||||||
{
|
|
||||||
b32 NeedsUpdate;
|
|
||||||
#ifdef DEBUG
|
|
||||||
char MessageType[128];
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
global_variable win32_state GlobalWin32State;
|
|
||||||
|
|
||||||
// Utility
|
|
||||||
internal s32 Win32StringLength(char* String);
|
|
||||||
internal s32 Win32ConcatStrings(s32 ALen, char* A, s32 BLen, char* B, s32 DestLen, char* Dest);
|
|
||||||
|
|
||||||
// Windowing & Graphics
|
|
||||||
struct win32_offscreen_buffer
|
|
||||||
{
|
|
||||||
u8* Memory;
|
|
||||||
s32 Width;
|
|
||||||
s32 Height;
|
|
||||||
s32 Pitch;
|
|
||||||
s32 BytesPerPixel;
|
|
||||||
BITMAPINFO Info;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void InitializeWin32();
|
|
||||||
internal win32_window CreateWin32Window (char* WindowName, char* WindowClassName, s32 Width, s32 Height);
|
|
||||||
LRESULT CALLBACK Win32HandleWindowsEvents (HWND WindowHandle, UINT Msg, WPARAM wParam, LPARAM lParam);
|
|
||||||
internal handle_window_msg_result HandleWindowsMessage (HWND WindowHandle, MSG Message);
|
|
||||||
internal void Win32UpdateWindowDimension(win32_window* Window);
|
|
||||||
internal void Win32ResizeDIBSection(win32_offscreen_buffer *Buffer, int Width, int Height);
|
|
||||||
internal void Win32DisplayBufferInWindow(win32_offscreen_buffer* Buffer, win32_window Window);
|
|
||||||
|
|
||||||
// Memory
|
|
||||||
|
|
||||||
internal platform_memory_result Win32Alloc(s32 Size);
|
|
||||||
internal b32 Win32Free(u8* Base, s32 Size);
|
|
||||||
|
|
||||||
// File IO
|
|
||||||
internal platform_memory_result ReadEntireFile(char* Path);
|
|
||||||
internal b32 WriteEntireFile(char* Path, u8* Contents, s32 Size);
|
|
||||||
internal FILETIME GetFileLastWriteTime(char* Path);
|
|
||||||
|
|
||||||
// DLL
|
|
||||||
struct win32_dll_refresh
|
|
||||||
{
|
|
||||||
FILETIME LastWriteTime;
|
|
||||||
HMODULE DLL;
|
|
||||||
|
|
||||||
b32 IsValid;
|
|
||||||
|
|
||||||
char SourceDLLPath[MAX_PATH];
|
|
||||||
char WorkingDLLPath[MAX_PATH];
|
|
||||||
char LockFilePath[MAX_PATH];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct executable_path
|
|
||||||
{
|
|
||||||
char Path[MAX_PATH];
|
|
||||||
s32 PathLength;
|
|
||||||
s32 IndexOfLastSlash;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal executable_path GetApplicationPath();
|
|
||||||
internal b32 LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult);
|
|
||||||
internal void UnloadApplicationDLL(win32_dll_refresh* DLL);
|
|
||||||
internal win32_dll_refresh InitializeDLLHotReloading(char* SourceDLLName, char* WorkingDLLFileName, char* LockFileName);
|
|
||||||
internal b32 HotLoadDLL(win32_dll_refresh* DLL);
|
|
||||||
|
|
||||||
///
|
|
||||||
// Utils
|
|
||||||
///
|
|
||||||
|
|
||||||
internal s32
|
|
||||||
Win32StringLength(char* String)
|
|
||||||
{
|
|
||||||
char* At = String;
|
|
||||||
while (*At) { At++; };
|
|
||||||
return At - String;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal s32
|
|
||||||
Win32ConcatStrings(s32 ALen, char* A, s32 BLen, char* B, s32 DestLen, char* Dest)
|
|
||||||
{
|
|
||||||
char* Dst = Dest;
|
|
||||||
char* AAt = A;
|
|
||||||
for (s32 a = 0; a < ALen; a++)
|
|
||||||
{
|
|
||||||
*Dst++ = *AAt++;
|
|
||||||
}
|
|
||||||
char* BAt = B;
|
|
||||||
for (s32 b = 0; b < BLen; b++)
|
|
||||||
{
|
|
||||||
*Dst++ = *BAt++;
|
|
||||||
}
|
|
||||||
return Dst - Dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
// Windowing
|
|
||||||
///
|
|
||||||
|
|
||||||
internal void
|
|
||||||
InitializeWin32 ()
|
|
||||||
{
|
|
||||||
GlobalWin32State = {};
|
|
||||||
GlobalWin32State.Running = false;
|
|
||||||
GlobalWin32State.Initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal win32_window
|
|
||||||
CreateWin32Window (HINSTANCE HInstance, win32_window_info Info)
|
|
||||||
{
|
|
||||||
win32_window Result = {};
|
|
||||||
Result.Info = Info;
|
|
||||||
|
|
||||||
Result.Class = {};
|
|
||||||
Result.Class.style = CS_HREDRAW | CS_VREDRAW;
|
|
||||||
if (Info.WindowEventsHandler)
|
|
||||||
{
|
|
||||||
Result.Class.lpfnWndProc = Info.WindowEventsHandler;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result.Class.lpfnWndProc = Win32HandleWindowsEvents;
|
|
||||||
}
|
|
||||||
Result.Class.hInstance = HInstance;
|
|
||||||
Result.Class.lpszClassName = Info.ClassName;
|
|
||||||
|
|
||||||
if (RegisterClass(&Result.Class))
|
|
||||||
{
|
|
||||||
Result.Handle = CreateWindowEx(
|
|
||||||
0,
|
|
||||||
Result.Class.lpszClassName,
|
|
||||||
Info.Name,
|
|
||||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
CW_USEDEFAULT,
|
|
||||||
Info.Width,
|
|
||||||
Info.Height,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
HInstance,
|
|
||||||
0);
|
|
||||||
Result.DeviceContext = GetDC(Result.Handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
CreateOpenGLWindowContext (win32_opengl_window_info Info, win32_window* Window)
|
|
||||||
{
|
|
||||||
// Setup pixel format
|
|
||||||
{
|
|
||||||
PIXELFORMATDESCRIPTOR PixelFormatDesc = { 0 };
|
|
||||||
// TODO: Program seems to work perfectly fine without all other params except dwFlags.
|
|
||||||
// Can we skip other params for the sake of brevity?
|
|
||||||
PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
||||||
PixelFormatDesc.nVersion = 1;
|
|
||||||
PixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
|
|
||||||
PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;// TODO(Peter): include this in win32_opengl_window_info?
|
|
||||||
PixelFormatDesc.cColorBits = Info.ColorBits;
|
|
||||||
PixelFormatDesc.cAlphaBits = Info.AlphaBits;
|
|
||||||
PixelFormatDesc.cDepthBits = Info.DepthBits;
|
|
||||||
PixelFormatDesc.dwLayerMask = PFD_MAIN_PLANE; // TODO(Peter): include this in win32_opengl_window_info?
|
|
||||||
//
|
|
||||||
|
|
||||||
s32 PixelFormat = ChoosePixelFormat(Window->DeviceContext, &PixelFormatDesc);
|
|
||||||
if (!PixelFormat) { InvalidCodePath; } // TODO: Log: Choose pixel format failed
|
|
||||||
if (!SetPixelFormat(Window->DeviceContext, PixelFormat, &PixelFormatDesc)) { InvalidCodePath; } // TODO: Log: Set pixel format failed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create rendering context
|
|
||||||
{
|
|
||||||
// TODO: Create "proper" context?
|
|
||||||
// https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation
|
|
||||||
|
|
||||||
Info.RenderContext = wglCreateContext(Window->DeviceContext);
|
|
||||||
wglMakeCurrent(Window->DeviceContext, Info.RenderContext);
|
|
||||||
|
|
||||||
// TODO(Peter): do we want this?
|
|
||||||
/*
|
|
||||||
glGetIntegerv(GL_MAJOR_VERSION, );
|
|
||||||
glGetIntegerv(GL_MINOR_VERSION, );
|
|
||||||
(char*)glGetString(GL_VENDOR);
|
|
||||||
(char*)glGetString(GL_RENDERER);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
Window->OpenGLInfo = Info;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct handle_window_event_result
|
|
||||||
{
|
|
||||||
LRESULT Result;
|
|
||||||
b32 Handled;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal handle_window_event_result
|
|
||||||
HandleWindowEventUnlessWouldUseDefault (HWND WindowHandle, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
handle_window_event_result Result = {};
|
|
||||||
Result.Handled = false;
|
|
||||||
|
|
||||||
switch (Msg)
|
|
||||||
{
|
|
||||||
case WM_SIZE:
|
|
||||||
{
|
|
||||||
//ResizeDIBSection();
|
|
||||||
Result.Handled = true;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_CLOSE:
|
|
||||||
{
|
|
||||||
Result.Result = DefWindowProc(WindowHandle, Msg, wParam, lParam);
|
|
||||||
Result.Handled = true;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_DESTROY:
|
|
||||||
{
|
|
||||||
GlobalWin32State.Running = false;
|
|
||||||
Result.Handled = true;
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_PAINT:
|
|
||||||
{
|
|
||||||
PAINTSTRUCT PaintStruct;
|
|
||||||
HDC DeviceContext;
|
|
||||||
b32 PaintResult;
|
|
||||||
|
|
||||||
DeviceContext = BeginPaint(WindowHandle, &PaintStruct);
|
|
||||||
PaintResult = EndPaint(WindowHandle, &PaintStruct);
|
|
||||||
Result.Handled = true;
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK
|
|
||||||
Win32HandleWindowsEvents (
|
|
||||||
HWND WindowHandle,
|
|
||||||
UINT Msg,
|
|
||||||
WPARAM wParam,
|
|
||||||
LPARAM lParam
|
|
||||||
)
|
|
||||||
{
|
|
||||||
handle_window_event_result EventResult = HandleWindowEventUnlessWouldUseDefault(
|
|
||||||
WindowHandle,
|
|
||||||
Msg,
|
|
||||||
wParam,
|
|
||||||
lParam);
|
|
||||||
|
|
||||||
if (!EventResult.Handled)
|
|
||||||
{
|
|
||||||
EventResult.Result = DefWindowProc(WindowHandle, Msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EventResult.Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WIN32_SHOULD_TRANSLATE_TO_CHAR -1
|
|
||||||
|
|
||||||
static int
|
|
||||||
Win32GetKeyIndex (int Win32VirtualKey, bool NumpadValid, bool TranslateToChar)
|
|
||||||
{
|
|
||||||
int Result = WIN32_SHOULD_TRANSLATE_TO_CHAR;
|
|
||||||
|
|
||||||
if (Win32VirtualKey == VK_ESCAPE) { Result = (int)KeyCode_Esc; }
|
|
||||||
|
|
||||||
if (!TranslateToChar)
|
|
||||||
{
|
|
||||||
if (Win32VirtualKey == VK_SPACE) { Result = (int)KeyCode_Space; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Win32VirtualKey == VK_CAPITAL) { Result = (int)KeyCode_CapsLock; }
|
|
||||||
else if (Win32VirtualKey == VK_TAB) { Result = (int)KeyCode_Tab; }
|
|
||||||
else if (Win32VirtualKey == VK_LSHIFT) { Result = (int)KeyCode_LeftShift; }
|
|
||||||
else if (Win32VirtualKey == VK_RSHIFT) { Result = (int)KeyCode_RightShift; }
|
|
||||||
else if (Win32VirtualKey == VK_LCONTROL) { Result = (int)KeyCode_LeftCtrl; }
|
|
||||||
else if (Win32VirtualKey == VK_RCONTROL) { Result = (int)KeyCode_RightCtrl; }
|
|
||||||
|
|
||||||
// TODO(Peter): support the function key?
|
|
||||||
//else if (Win32VirtualKey == VK_) { Result = (int)KeyCode_Fn; }
|
|
||||||
|
|
||||||
else if (Win32VirtualKey == VK_MENU) { Result = (int)KeyCode_Alt; }
|
|
||||||
else if (Win32VirtualKey == VK_PRIOR) { Result = (int)KeyCode_PageUp; }
|
|
||||||
else if (Win32VirtualKey == VK_NEXT) { Result = (int)KeyCode_PageDown; }
|
|
||||||
else if (Win32VirtualKey == VK_BACK) { Result = (int)KeyCode_Backspace; }
|
|
||||||
else if (Win32VirtualKey == VK_DELETE) { Result = (int)KeyCode_Delete; }
|
|
||||||
else if (Win32VirtualKey == VK_RETURN) { Result = (int)KeyCode_Enter; }
|
|
||||||
|
|
||||||
else if (Win32VirtualKey == VK_F1) { Result = (int)KeyCode_F1; }
|
|
||||||
else if (Win32VirtualKey == VK_F2) { Result = (int)KeyCode_F2; }
|
|
||||||
else if (Win32VirtualKey == VK_F3) { Result = (int)KeyCode_F3; }
|
|
||||||
else if (Win32VirtualKey == VK_F4) { Result = (int)KeyCode_F4; }
|
|
||||||
else if (Win32VirtualKey == VK_F5) { Result = (int)KeyCode_F5; }
|
|
||||||
else if (Win32VirtualKey == VK_F6) { Result = (int)KeyCode_F6; }
|
|
||||||
else if (Win32VirtualKey == VK_F7) { Result = (int)KeyCode_F7; }
|
|
||||||
else if (Win32VirtualKey == VK_F8) { Result = (int)KeyCode_F8; }
|
|
||||||
else if (Win32VirtualKey == VK_F9) { Result = (int)KeyCode_F9; }
|
|
||||||
else if (Win32VirtualKey == VK_F10) { Result = (int)KeyCode_F10; }
|
|
||||||
else if (Win32VirtualKey == VK_F11) { Result = (int)KeyCode_F11; }
|
|
||||||
else if (Win32VirtualKey == VK_F12) { Result = (int)KeyCode_F12; }
|
|
||||||
|
|
||||||
if (!TranslateToChar)
|
|
||||||
{
|
|
||||||
if (Win32VirtualKey == 0x30) { Result = (int)KeyCode_0; }
|
|
||||||
else if (Win32VirtualKey == 0x31) { Result = (int)KeyCode_1; }
|
|
||||||
else if (Win32VirtualKey == 0x32) { Result = (int)KeyCode_2; }
|
|
||||||
else if (Win32VirtualKey == 0x33) { Result = (int)KeyCode_3; }
|
|
||||||
else if (Win32VirtualKey == 0x34) { Result = (int)KeyCode_4; }
|
|
||||||
else if (Win32VirtualKey == 0x35) { Result = (int)KeyCode_5; }
|
|
||||||
else if (Win32VirtualKey == 0x36) { Result = (int)KeyCode_6; }
|
|
||||||
else if (Win32VirtualKey == 0x37) { Result = (int)KeyCode_7; }
|
|
||||||
else if (Win32VirtualKey == 0x38) { Result = (int)KeyCode_8; }
|
|
||||||
else if (Win32VirtualKey == 0x39) { Result = (int)KeyCode_9; }
|
|
||||||
|
|
||||||
else if (Win32VirtualKey == 0x41) { Result = (int)KeyCode_A; }
|
|
||||||
else if (Win32VirtualKey == 0x42) { Result = (int)KeyCode_B; }
|
|
||||||
else if (Win32VirtualKey == 0x43) { Result = (int)KeyCode_C; }
|
|
||||||
else if (Win32VirtualKey == 0x44) { Result = (int)KeyCode_D; }
|
|
||||||
else if (Win32VirtualKey == 0x45) { Result = (int)KeyCode_E; }
|
|
||||||
else if (Win32VirtualKey == 0x46) { Result = (int)KeyCode_F; }
|
|
||||||
else if (Win32VirtualKey == 0x47) { Result = (int)KeyCode_G; }
|
|
||||||
else if (Win32VirtualKey == 0x48) { Result = (int)KeyCode_H; }
|
|
||||||
else if (Win32VirtualKey == 0x49) { Result = (int)KeyCode_I; }
|
|
||||||
else if (Win32VirtualKey == 0x4A) { Result = (int)KeyCode_J; }
|
|
||||||
else if (Win32VirtualKey == 0x4B) { Result = (int)KeyCode_K; }
|
|
||||||
else if (Win32VirtualKey == 0x4C) { Result = (int)KeyCode_L; }
|
|
||||||
else if (Win32VirtualKey == 0x4D) { Result = (int)KeyCode_M; }
|
|
||||||
else if (Win32VirtualKey == 0x4E) { Result = (int)KeyCode_N; }
|
|
||||||
else if (Win32VirtualKey == 0x4F) { Result = (int)KeyCode_O; }
|
|
||||||
else if (Win32VirtualKey == 0x50) { Result = (int)KeyCode_P; }
|
|
||||||
else if (Win32VirtualKey == 0x51) { Result = (int)KeyCode_Q; }
|
|
||||||
else if (Win32VirtualKey == 0x52) { Result = (int)KeyCode_R; }
|
|
||||||
else if (Win32VirtualKey == 0x53) { Result = (int)KeyCode_S; }
|
|
||||||
else if (Win32VirtualKey == 0x54) { Result = (int)KeyCode_T; }
|
|
||||||
else if (Win32VirtualKey == 0x55) { Result = (int)KeyCode_U; }
|
|
||||||
else if (Win32VirtualKey == 0x56) { Result = (int)KeyCode_V; }
|
|
||||||
else if (Win32VirtualKey == 0x57) { Result = (int)KeyCode_W; }
|
|
||||||
else if (Win32VirtualKey == 0x58) { Result = (int)KeyCode_X; }
|
|
||||||
else if (Win32VirtualKey == 0x59) { Result = (int)KeyCode_Y; }
|
|
||||||
else if (Win32VirtualKey == 0x5A) { Result = (int)KeyCode_Z; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NumpadValid)
|
|
||||||
{
|
|
||||||
if (Win32VirtualKey == VK_NUMPAD0) { Result = (int)KeyCode_Num0; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD1) { Result = (int)KeyCode_Num1; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD2) { Result = (int)KeyCode_Num2; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD3) { Result = (int)KeyCode_Num3; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD4) { Result = (int)KeyCode_Num4; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD5) { Result = (int)KeyCode_Num5; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD6) { Result = (int)KeyCode_Num6; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD7) { Result = (int)KeyCode_Num7; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD8) { Result = (int)KeyCode_Num8; }
|
|
||||||
else if (Win32VirtualKey == VK_NUMPAD9) { Result = (int)KeyCode_Num9; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Win32VirtualKey == VK_UP) { Result = (int)KeyCode_UpArrow; }
|
|
||||||
else if (Win32VirtualKey == VK_DOWN) { Result = (int)KeyCode_DownArrow; }
|
|
||||||
else if (Win32VirtualKey == VK_LEFT) { Result = (int)KeyCode_LeftArrow; }
|
|
||||||
else if (Win32VirtualKey == VK_RIGHT) { Result = (int)KeyCode_RightArrow; }
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal handle_window_msg_result
|
|
||||||
HandleWindowsMessage (
|
|
||||||
HWND WindowHandle,
|
|
||||||
MSG Message)
|
|
||||||
{
|
|
||||||
handle_window_msg_result Result = {};
|
|
||||||
Result.NeedsUpdate = 0;
|
|
||||||
|
|
||||||
switch (Message.message)
|
|
||||||
{
|
|
||||||
case WM_HOTKEY:
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_HOTKEY ");
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_MOUSEWHEEL:
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_MOUSEWHEEL ");
|
|
||||||
int MouseWheel = GET_WHEEL_DELTA_WPARAM(Message.wParam);
|
|
||||||
/*
|
|
||||||
Input.New->MouseScroll = MouseWheel;
|
|
||||||
Result.NeedsUpdate = true;
|
|
||||||
*/
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
case WM_MBUTTONDOWN:
|
|
||||||
case WM_MBUTTONUP:
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
case WM_RBUTTONUP:
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_MOUSEBUTTON ");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Input.New->KeyStates[KeyCode_MouseLeftButton] = (GetKeyState(VK_LBUTTON) & (1 << 15)) != 0;
|
|
||||||
Input.New->KeyStates[KeyCode_MouseMiddleButton] = (GetKeyState(VK_MBUTTON) & (1 << 15)) != 0;
|
|
||||||
Input.New->KeyStates[KeyCode_MouseRightButton] = (GetKeyState(VK_RBUTTON) & (1 << 15)) != 0;
|
|
||||||
// NOTE(Peter): If you decide to support extra mouse buttons, on windows the key codes are
|
|
||||||
// VK_XBUTTON1 and VK_XBUTTON2
|
|
||||||
|
|
||||||
if (KeyTransitionedDown(KeyCode_MouseLeftButton, Input))
|
|
||||||
{
|
|
||||||
Input.MouseDownX = Input.New->MouseX;
|
|
||||||
Input.MouseDownY = Input.New->MouseY;
|
|
||||||
}
|
|
||||||
Result.NeedsUpdate = true;*/
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_MOUSEMOVE ");
|
|
||||||
POINT MousePos;
|
|
||||||
GetCursorPos(&MousePos);
|
|
||||||
ScreenToClient(WindowHandle, &MousePos);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Input.New->MouseX = MousePos.x;
|
|
||||||
Input.New->MouseY = App.WindowHeight - MousePos.y;
|
|
||||||
|
|
||||||
Result.NeedsUpdate = true;
|
|
||||||
*/
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_SYSKEYDOWN:
|
|
||||||
case WM_SYSKEYUP:
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
case WM_KEYUP:
|
|
||||||
{
|
|
||||||
int VirtualKey = (int)Message.wParam;
|
|
||||||
bool KeyDown = (Message.lParam & (1 << 31)) == 0;
|
|
||||||
int KeyIndex = Win32GetKeyIndex(VirtualKey, true, true);
|
|
||||||
/*
|
|
||||||
if (KeyIndex >= 0)
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_KEYEvent ");
|
|
||||||
Input.New->KeyStates[KeyIndex] = KeyDown;
|
|
||||||
Result.NeedsUpdate = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Input.TranslateInputToCharValues && KeyDown)
|
|
||||||
{
|
|
||||||
// NOTE(Peter): Took this out b/c we're translating the WM_CHAR messages
|
|
||||||
// in the message pump, and if we do it here as well, character producing
|
|
||||||
// key messages get put on the message queue twice
|
|
||||||
TranslateMessage(&Message);
|
|
||||||
DispatchMessage(&Message);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_KEYEvent ");
|
|
||||||
// NOTE(Peter): This is so that when you lift up a key that was generating a WM_CHAR,
|
|
||||||
// the app still has a chance to respond to it.
|
|
||||||
Result.NeedsUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case WM_CHAR:
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "WM_CHAR ");
|
|
||||||
/*
|
|
||||||
char TranslatedChar = (char)Message.wParam;
|
|
||||||
int KeyIndex = GetKeyIndexFromChar(TranslatedChar);
|
|
||||||
|
|
||||||
if (KeyIndex >= 0)
|
|
||||||
{
|
|
||||||
// NOTE(Peter): Always setting this to true becuase windows is stupid and doesn't
|
|
||||||
// pass the press/release bit through correctly. So now the KEYDOWN/KEYUP Messages above
|
|
||||||
// only translate the message to a WM_CHAR message if its a key down. Since we clear all
|
|
||||||
// keystates to false at the beginning of an input frame, this will make transitions
|
|
||||||
// get registered correctly.
|
|
||||||
Input.New->KeyStates[KeyIndex] = true;
|
|
||||||
Result.NeedsUpdate = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Translated Char Not Recognized: %c\n", TranslatedChar);
|
|
||||||
//InvalidCodePath;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
DEBUG_GET_MESSAGE_NAME(Result.MessageType, "Unhandled WM Event ");
|
|
||||||
TranslateMessage(&Message);
|
|
||||||
DispatchMessage(&Message);
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Win32UpdateWindowDimension(win32_window* Window)
|
|
||||||
{
|
|
||||||
RECT ClientRect;
|
|
||||||
GetClientRect(Window->Handle, &ClientRect);
|
|
||||||
Window->Info.Width = ClientRect.right - ClientRect.left;
|
|
||||||
Window->Info.Height = ClientRect.bottom - ClientRect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Win32ResizeDIBSection(win32_offscreen_buffer *Buffer, int Width, int Height)
|
|
||||||
{
|
|
||||||
if(Buffer->Memory)
|
|
||||||
{
|
|
||||||
VirtualFree(Buffer->Memory, 0, MEM_RELEASE);
|
|
||||||
}
|
|
||||||
|
|
||||||
Buffer->Width = Width;
|
|
||||||
Buffer->Height = Height;
|
|
||||||
|
|
||||||
int BytesPerPixel = 4;
|
|
||||||
Buffer->BytesPerPixel = BytesPerPixel;
|
|
||||||
|
|
||||||
Buffer->Info.bmiHeader.biSize = sizeof(Buffer->Info.bmiHeader);
|
|
||||||
Buffer->Info.bmiHeader.biWidth = Buffer->Width;
|
|
||||||
Buffer->Info.bmiHeader.biHeight = -Buffer->Height; // Top down, not bottom up
|
|
||||||
Buffer->Info.bmiHeader.biPlanes = 1;
|
|
||||||
Buffer->Info.bmiHeader.biBitCount = 32;
|
|
||||||
Buffer->Info.bmiHeader.biCompression = BI_RGB;
|
|
||||||
|
|
||||||
int BitmapMemorySize = (Buffer->Width*Buffer->Height)*BytesPerPixel;
|
|
||||||
Buffer->Memory = (u8*)VirtualAlloc(0, BitmapMemorySize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
|
||||||
Buffer->Pitch = Width*BytesPerPixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
Win32DisplayBufferInWindow(win32_offscreen_buffer* Buffer, win32_window Window)
|
|
||||||
{
|
|
||||||
StretchDIBits(Window.DeviceContext,
|
|
||||||
0, 0, Buffer->Width, Buffer->Height,
|
|
||||||
0, 0, Buffer->Width, Buffer->Height,
|
|
||||||
Buffer->Memory,
|
|
||||||
&Buffer->Info,
|
|
||||||
DIB_RGB_COLORS, SRCCOPY);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
// Memory
|
|
||||||
///
|
|
||||||
|
|
||||||
internal win32_memory_op_result
|
|
||||||
Win32Alloc(s32 Size)
|
|
||||||
{
|
|
||||||
win32_memory_op_result Result = {};
|
|
||||||
Result.Success = false;
|
|
||||||
|
|
||||||
Result.Base = (u8*)VirtualAlloc(NULL, Size,
|
|
||||||
MEM_COMMIT | MEM_RESERVE,
|
|
||||||
PAGE_EXECUTE_READWRITE);
|
|
||||||
if (Result.Base)
|
|
||||||
{
|
|
||||||
Result.Size = Size;
|
|
||||||
Result.Success = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
Win32Free(u8* Base, s32 Size)
|
|
||||||
{
|
|
||||||
b32 Result = VirtualFree(Base, Size, MEM_RELEASE);
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// File IO
|
|
||||||
internal win32_memory_op_result
|
|
||||||
ReadEntireFile(char* Path)
|
|
||||||
{
|
|
||||||
win32_memory_op_result Result = {};
|
|
||||||
Result.Success = false;
|
|
||||||
|
|
||||||
HANDLE FileHandle = CreateFileA (
|
|
||||||
Path,
|
|
||||||
GENERIC_READ,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
OPEN_EXISTING,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (FileHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
DWORD FileSize = GetFileSize(FileHandle, NULL);
|
|
||||||
Result.Base = (u8*)VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE,
|
|
||||||
PAGE_EXECUTE_READWRITE);
|
|
||||||
if (Result.Base)
|
|
||||||
{
|
|
||||||
Result.Size = FileSize;
|
|
||||||
|
|
||||||
s32 BytesRead = 0;
|
|
||||||
if (ReadFile(FileHandle, (LPVOID)Result.Base, FileSize, (LPDWORD)(&BytesRead), NULL))
|
|
||||||
{
|
|
||||||
Result.Success = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result.Size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CloseHandle(FileHandle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO(Peter): failure
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
WriteEntireFile (char* Path, u8* Contents, s32 Size)
|
|
||||||
{
|
|
||||||
b32 Result = false;
|
|
||||||
HANDLE FileHandle = CreateFileA (
|
|
||||||
Path,
|
|
||||||
GENERIC_WRITE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
CREATE_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (FileHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
DWORD BytesWritten = 0;
|
|
||||||
|
|
||||||
b32 WriteSuccess = WriteFile(FileHandle,
|
|
||||||
Contents, Size,
|
|
||||||
&BytesWritten,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (WriteSuccess && BytesWritten == (u32)Size)
|
|
||||||
{
|
|
||||||
CloseHandle(FileHandle);
|
|
||||||
Result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal FILETIME
|
|
||||||
GetFileLastWriteTime(char* Path)
|
|
||||||
{
|
|
||||||
FILETIME Result = {};
|
|
||||||
|
|
||||||
WIN32_FIND_DATA FindData = {};
|
|
||||||
HANDLE FileHandle = FindFirstFileA(Path, &FindData);
|
|
||||||
|
|
||||||
if (FileHandle != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
Result = FindData.ftLastWriteTime;
|
|
||||||
FindClose(FileHandle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO(Peter): Error handling
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
// DLL
|
|
||||||
///
|
|
||||||
|
|
||||||
internal executable_path
|
|
||||||
GetApplicationPath()
|
|
||||||
{
|
|
||||||
executable_path ExePath = {};
|
|
||||||
ExePath.PathLength = GetModuleFileNameA(0, ExePath.Path, MAX_PATH);
|
|
||||||
|
|
||||||
u32 CharactersScanned = 0;
|
|
||||||
u32 IndexOfLastSlash = 0;
|
|
||||||
char *Scan = ExePath.Path;
|
|
||||||
while(*Scan)
|
|
||||||
{
|
|
||||||
if (*Scan == '\\')
|
|
||||||
{
|
|
||||||
ExePath.IndexOfLastSlash = CharactersScanned + 1;
|
|
||||||
}
|
|
||||||
Scan++;
|
|
||||||
CharactersScanned++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ExePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
LoadApplicationDLL(char* DLLName, win32_dll_refresh* DLLResult)
|
|
||||||
{
|
|
||||||
b32 Success = false;
|
|
||||||
Assert(DLLResult->DLL == 0);
|
|
||||||
|
|
||||||
DLLResult->DLL = LoadLibraryA(DLLName); // TODO(Peter): Error checking
|
|
||||||
if (DLLResult->DLL)
|
|
||||||
{
|
|
||||||
Success = true;
|
|
||||||
DLLResult->IsValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
UnloadApplicationDLL(win32_dll_refresh* DLL)
|
|
||||||
{
|
|
||||||
if (DLL->DLL)
|
|
||||||
{
|
|
||||||
FreeLibrary(DLL->DLL);
|
|
||||||
}
|
|
||||||
DLL->DLL = 0;
|
|
||||||
DLL->IsValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal win32_dll_refresh
|
|
||||||
InitializeDLLHotReloading(char* SourceDLLName,
|
|
||||||
char* WorkingDLLFileName,
|
|
||||||
char* LockFileName)
|
|
||||||
{
|
|
||||||
win32_dll_refresh Result = {};
|
|
||||||
Result.IsValid = false;
|
|
||||||
|
|
||||||
executable_path ExePath = GetApplicationPath();
|
|
||||||
|
|
||||||
Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
|
||||||
Win32StringLength(SourceDLLName), SourceDLLName,
|
|
||||||
MAX_PATH, Result.SourceDLLPath);
|
|
||||||
Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
|
||||||
Win32StringLength(WorkingDLLFileName), WorkingDLLFileName,
|
|
||||||
MAX_PATH, Result.WorkingDLLPath);
|
|
||||||
Win32ConcatStrings(ExePath.IndexOfLastSlash, ExePath.Path,
|
|
||||||
Win32StringLength(LockFileName), LockFileName,
|
|
||||||
MAX_PATH, Result.LockFilePath);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
HotLoadDLL(win32_dll_refresh* DLL)
|
|
||||||
{
|
|
||||||
b32 DidReload = false;
|
|
||||||
|
|
||||||
FILETIME UpdatedLastWriteTime = GetFileLastWriteTime(DLL->SourceDLLPath);
|
|
||||||
if (CompareFileTime(&UpdatedLastWriteTime, &DLL->LastWriteTime))
|
|
||||||
{
|
|
||||||
WIN32_FILE_ATTRIBUTE_DATA Ignored;
|
|
||||||
if (!GetFileAttributesEx(DLL->LockFilePath, GetFileExInfoStandard, &Ignored))
|
|
||||||
{
|
|
||||||
UnloadApplicationDLL(DLL);
|
|
||||||
CopyFileA(DLL->SourceDLLPath, DLL->WorkingDLLPath, FALSE);
|
|
||||||
LoadApplicationDLL(DLL->WorkingDLLPath, DLL);
|
|
||||||
DLL->LastWriteTime = UpdatedLastWriteTime;
|
|
||||||
DidReload = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DidReload;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GS_WIN32_H
|
#define GS_WIN32_H
|
||||||
#endif // GS_WIN32_H
|
#endif // GS_WIN32_H
|
||||||
|
|
31
interface.h
31
interface.h
|
@ -110,24 +110,31 @@ DrawString (render_command_buffer* RenderBuffer, string String, bitmap_font* Fon
|
||||||
v2 LowerRight = Position;
|
v2 LowerRight = Position;
|
||||||
|
|
||||||
render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, String.Length,
|
render_quad_batch_constructor BatchConstructor = PushRenderTexture2DBatch(RenderBuffer, String.Length,
|
||||||
*Font->Atlas);
|
Font->BitmapMemory,
|
||||||
|
Font->BitmapTextureHandle,
|
||||||
|
Font->BitmapWidth,
|
||||||
|
Font->BitmapHeight,
|
||||||
|
Font->BitmapBytesPerPixel,
|
||||||
|
Font->BitmapStride);
|
||||||
|
|
||||||
r32 FontScale = (r32)PointSize / Font->PixelHeight;
|
r32 FontScale = (r32)PointSize / Font->PixelHeight;
|
||||||
v2 RegisterPosition = Position;
|
v2 RegisterPosition = Position;
|
||||||
char* C = String.Memory;
|
char* C = String.Memory;
|
||||||
for (s32 i = 0; i < String.Length; i++)
|
for (s32 i = 0; i < String.Length; i++)
|
||||||
{
|
{
|
||||||
s32 GlyphDataIndex = GetCharacterIndexInFont(*C, Font);
|
s32 GlyphDataIndex = GetIndexForCodepoint(*Font, *C);
|
||||||
character_data Data = Font->CharacterLUT_Values[GlyphDataIndex];
|
codepoint_bitmap CodepointInfo = Font->CodepointValues[GlyphDataIndex];
|
||||||
|
|
||||||
r32 MinX = RegisterPosition.x + Data.RegisterXOffset * FontScale;
|
r32 MinX = RegisterPosition.x + CodepointInfo.XOffset * FontScale;
|
||||||
r32 MinY = RegisterPosition.y + Data.BaselineYOffset * FontScale;
|
r32 MinY = RegisterPosition.y + CodepointInfo.YOffset * FontScale;
|
||||||
r32 MaxX = MinX + (Data.X1 - Data.X0) * FontScale;
|
r32 MaxX = MinX + (CodepointInfo.Width) * FontScale;
|
||||||
r32 MaxY = MinY + (Data.Y1 - Data.Y0) * FontScale;
|
r32 MaxY = MinY + (CodepointInfo.Height) * FontScale;
|
||||||
|
|
||||||
PushQuad2DOnBatch(&BatchConstructor, v2{MinX, MinY}, v2{MaxX, MinY}, v2{MaxX, MaxY}, v2{MinX, MaxY}, Data.AtlasMinUV, Data.AtlasMaxUV, Color);
|
v2 MinUV = v2{(r32)CodepointInfo.BitmapX, (r32)CodepointInfo.BitmapY};
|
||||||
|
v2 MaxUV = MinUV + v2{(r32)CodepointInfo.Width, (r32)CodepointInfo.Height};
|
||||||
|
PushQuad2DOnBatch(&BatchConstructor, v2{MinX, MinY}, v2{MaxX, MinY}, v2{MaxX, MaxY}, v2{MinX, MaxY}, MinUV, MaxUV, Color);
|
||||||
|
|
||||||
RegisterPosition.x += Data.Advance * Font->FontScale * FontScale;
|
RegisterPosition.x += CodepointInfo.Width * FontScale;
|
||||||
C++;
|
C++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +359,7 @@ EvaluatePanel (render_command_buffer* RenderBuffer, v2 Min, v2 Max, string Label
|
||||||
|
|
||||||
v2 TextPos = v2{
|
v2 TextPos = v2{
|
||||||
Min.x + Config.Margin.x,
|
Min.x + Config.Margin.x,
|
||||||
Max.y - (Config.Font->NewLineYOffset + Config.Margin.y)
|
Max.y - ((r32)NewLineYOffset(*Config.Font) + Config.Margin.y)
|
||||||
};
|
};
|
||||||
DrawString(RenderBuffer, Label, Config.Font, 14, TextPos, Config.TextColor);
|
DrawString(RenderBuffer, Label, Config.Font, 14, TextPos, Config.TextColor);
|
||||||
Result.ChildMax = v2{Max.x, TextPos.y} - Config.Margin;
|
Result.ChildMax = v2{Max.x, TextPos.y} - Config.Margin;
|
||||||
|
@ -396,7 +403,7 @@ DrawOptionsList(render_command_buffer* RenderBuffer, v2 Min, v2 Max,
|
||||||
Result.StartIndex = Start;
|
Result.StartIndex = Start;
|
||||||
Result.Selection = Selection_None;
|
Result.Selection = Selection_None;
|
||||||
|
|
||||||
r32 OptionHeight = Config.Font->NewLineYOffset + (2 * Config.Margin.y);
|
r32 OptionHeight = NewLineYOffset(*Config.Font) + (2 * Config.Margin.y);
|
||||||
r32 OptionOffset = OptionHeight + Config.Margin.y;
|
r32 OptionOffset = OptionHeight + Config.Margin.y;
|
||||||
|
|
||||||
s32 OptionsToDisplay = ((Max.y - Min.y) / OptionHeight) - 2;
|
s32 OptionsToDisplay = ((Max.y - Min.y) / OptionHeight) - 2;
|
||||||
|
@ -453,7 +460,7 @@ DrawSelectableOptionsList(render_command_buffer* RenderBuffer, v2 Min, v2 Max,
|
||||||
Result.StartIndex = Start;
|
Result.StartIndex = Start;
|
||||||
Result.Selection = Selection_None;
|
Result.Selection = Selection_None;
|
||||||
|
|
||||||
r32 OptionHeight = Config.Font->NewLineYOffset + (2 * Config.Margin.y);
|
r32 OptionHeight = NewLineYOffset(*Config.Font) + (2 * Config.Margin.y);
|
||||||
r32 OptionOffset = OptionHeight + Config.Margin.y;
|
r32 OptionOffset = OptionHeight + Config.Margin.y;
|
||||||
|
|
||||||
s32 OptionsToDisplay = ((Max.y - Min.y) / OptionHeight) - 2;
|
s32 OptionsToDisplay = ((Max.y - Min.y) / OptionHeight) - 2;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <windows.h>
|
||||||
|
#include "gs_platform.h"
|
||||||
|
#include "gs_win32.h"
|
||||||
|
|
||||||
|
int main (int ArgCount, char** Args)
|
||||||
|
{
|
||||||
|
window MainWindow = PlatformCreateWindow("Test Window", 1024, 768);
|
||||||
|
|
||||||
|
win32_opengl_window_info OpenGLInfo = {};
|
||||||
|
OpenGLInfo.ColorBits = 32;
|
||||||
|
OpenGLInfo.AlphaBits = 8;
|
||||||
|
Win32CreateOpenGLContext(OpenGLInfo, MainWindow);
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
#include <Winsock2.h>
|
#include <Winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#include <gl/gl.h>
|
||||||
|
|
||||||
#include "foldhaus_platform.h"
|
#include "foldhaus_platform.h"
|
||||||
|
|
||||||
#include "gs_win32.h"
|
#include "gs_win32.cpp"
|
||||||
|
|
||||||
#include "gs_opengl.h"
|
|
||||||
#include "foldhaus_renderer.cpp"
|
#include "foldhaus_renderer.cpp"
|
||||||
|
|
||||||
global_variable b32 Running = false;
|
global_variable b32 Running = false;
|
||||||
|
@ -16,7 +16,7 @@ char DLLName[] = "foldhaus.dll";
|
||||||
char WorkingDLLName[] = "foldhaus_temp.dll";
|
char WorkingDLLName[] = "foldhaus_temp.dll";
|
||||||
char DLLLockFileName[] = "lock.tmp";
|
char DLLLockFileName[] = "lock.tmp";
|
||||||
|
|
||||||
win32_window MainWindow;
|
window MainWindow;
|
||||||
|
|
||||||
struct worker_thread_entry
|
struct worker_thread_entry
|
||||||
{
|
{
|
||||||
|
@ -116,7 +116,7 @@ WorkerThreadProc (LPVOID InputThreadInfo)
|
||||||
|
|
||||||
PLATFORM_GET_GPU_TEXTURE_HANDLE(Win32GetGPUTextureHandle)
|
PLATFORM_GET_GPU_TEXTURE_HANDLE(Win32GetGPUTextureHandle)
|
||||||
{
|
{
|
||||||
s32 Handle = SubmitTexture(Width, Height, Memory);
|
s32 Handle = SubmitTexture(Memory, Width, Height);
|
||||||
return Handle;
|
return Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ PLATFORM_GET_SEND_ADDRESS_HANDLE(Win32GetSendAddress)
|
||||||
Assert(Win32NetworkAddressHandleCount < Win32NetworkAddressHandleMax);
|
Assert(Win32NetworkAddressHandleCount < Win32NetworkAddressHandleMax);
|
||||||
s32 NewAddressIndex = Win32NetworkAddressHandleCount++;
|
s32 NewAddressIndex = Win32NetworkAddressHandleCount++;
|
||||||
|
|
||||||
NetworkAddressValues[NewAddressIndex].sin_family = Family;
|
NetworkAddressValues[NewAddressIndex].sin_family = AddressFamily;
|
||||||
NetworkAddressValues[NewAddressIndex].sin_port = HostToNetU16(Port);
|
NetworkAddressValues[NewAddressIndex].sin_port = HostToNetU16(Port);
|
||||||
NetworkAddressValues[NewAddressIndex].sin_addr.s_addr = HostToNetU32(Address);
|
NetworkAddressValues[NewAddressIndex].sin_addr.s_addr = HostToNetU32(Address);
|
||||||
|
|
||||||
|
@ -233,6 +233,50 @@ PLATFORM_CLOSE_SOCKET(Win32CloseSocket)
|
||||||
closesocket(SocketValues[SocketIndex].Socket);
|
closesocket(SocketValues[SocketIndex].Socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GET_FONT_INFO(Win32GetFontInfo)
|
||||||
|
{
|
||||||
|
platform_font_info Result = {};
|
||||||
|
|
||||||
|
Result.DrawingDC = CreateCompatibleDC(NULL);
|
||||||
|
SetBkColor(Result.DrawingDC, RGB(0, 0, 0));
|
||||||
|
SetTextColor(Result.DrawingDC, RGB(255, 255, 255));
|
||||||
|
Result.Bitmap = CreateCompatibleBitmap(NULL, PixelHeight * 2, PixelHeight * 2);
|
||||||
|
SelectObject(Result.DrawingDC, Result.Bitmap);
|
||||||
|
|
||||||
|
Result.Font= CreateFont(PixelHeight, 0, 0, 0,
|
||||||
|
// TODO(Peter): Font weight, need a platform way to request others
|
||||||
|
FW_NORMAL,
|
||||||
|
FALSE, // Italic
|
||||||
|
FALSE, // Underling
|
||||||
|
FALSE, // Strikeout,
|
||||||
|
ANSI_CHARSET,
|
||||||
|
OUT_OUTLINE_PRECIS,
|
||||||
|
CLIP_DEFAULT_PRECIS,
|
||||||
|
PROOF_QUALITY,
|
||||||
|
FIXED_PITCH,
|
||||||
|
FontName);
|
||||||
|
SelectFont(Result.DrawingDC, Result.Font);
|
||||||
|
|
||||||
|
TEXTMETRIC WindowsFontMetrics = {};
|
||||||
|
if (GetTextMetrics(Result.DrawingDC, &WindowsFontMetrics))
|
||||||
|
{
|
||||||
|
Result.PixelHeight = WindowsFontMetrics.tmHeight;
|
||||||
|
Result.Ascent = WindowsFontMetrics.tmAscent;
|
||||||
|
Result.Descent = WindowsFontMetrics.tmDescent;
|
||||||
|
Result.Leading = WindowsFontMetrics.tmExternalLeading;
|
||||||
|
Result.MaxCharWidth = WindowsFontMetrics.tmMaxCharWidth;
|
||||||
|
Result.CodepointStart = WindowsFontMetrics.tmFirstChar;
|
||||||
|
Result.CodepointOnePastLast = WindowsFontMetrics.tmLastChar + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DRAW_FONT_CODEPOINT(Win32DrawFontCodepoint)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK
|
LRESULT CALLBACK
|
||||||
HandleWindowEvents (HWND WindowHandle, UINT Msg, WPARAM WParam, LPARAM LParam)
|
HandleWindowEvents (HWND WindowHandle, UINT Msg, WPARAM WParam, LPARAM LParam)
|
||||||
{
|
{
|
||||||
|
@ -281,14 +325,13 @@ HandleWindowEvents (HWND WindowHandle, UINT Msg, WPARAM WParam, LPARAM LParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
HandleWindowMessage (MSG Message, win32_window* Window, input_frame* InputFrame)
|
HandleWindowMessage (MSG Message, window* Window, input_frame* InputFrame)
|
||||||
{
|
{
|
||||||
switch (Message.message)
|
switch (Message.message)
|
||||||
{
|
{
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
{
|
{
|
||||||
int MouseWheel = GET_WHEEL_DELTA_WPARAM(Message.wParam);
|
Win32UpdateInputFrameMouseWheelDelta(InputFrame, Message);
|
||||||
InputFrame->MouseScroll = MouseWheel;
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
|
@ -298,11 +341,7 @@ HandleWindowMessage (MSG Message, win32_window* Window, input_frame* InputFrame)
|
||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
case WM_RBUTTONUP:
|
case WM_RBUTTONUP:
|
||||||
{
|
{
|
||||||
InputFrame->KeysDown[KeyCode_MouseLeftButton] = (GetKeyState(VK_LBUTTON) & (1 << 15)) != 0;
|
Win32UpdateInputFrameMouseState(InputFrame);
|
||||||
InputFrame->KeysDown[KeyCode_MouseMiddleButton] = (GetKeyState(VK_MBUTTON) & (1 << 15)) != 0;
|
|
||||||
InputFrame->KeysDown[KeyCode_MouseRightButton] = (GetKeyState(VK_RBUTTON) & (1 << 15)) != 0;
|
|
||||||
// NOTE(Peter): If you decide to support extra mouse buttons, on windows the key codes are
|
|
||||||
// VK_XBUTTON1 and VK_XBUTTON2
|
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case WM_SYSKEYDOWN:
|
case WM_SYSKEYDOWN:
|
||||||
|
@ -342,9 +381,10 @@ internal void
|
||||||
DebugPrint (char* Format, ...)
|
DebugPrint (char* Format, ...)
|
||||||
{
|
{
|
||||||
char Buffer[256];
|
char Buffer[256];
|
||||||
|
string StringBuffer = MakeString(Buffer, 256);
|
||||||
va_list Args;
|
va_list Args;
|
||||||
va_start(Args, Format);
|
va_start(Args, Format);
|
||||||
PrintFInternal(Buffer, 256, Format, Args);
|
PrintF(&StringBuffer, Format, Args);
|
||||||
OutputDebugStringA(Buffer);
|
OutputDebugStringA(Buffer);
|
||||||
va_end(Args);
|
va_end(Args);
|
||||||
}
|
}
|
||||||
|
@ -376,14 +416,7 @@ PSTR CmdLineArgs,
|
||||||
INT NCmdShow
|
INT NCmdShow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
win32_window_info MainWindowInfo = {};
|
MainWindow = Win32CreateWindow (HInstance, "Foldhaus", 1440, 768, HandleWindowEvents);
|
||||||
MainWindowInfo.Name = "Foldhaus";
|
|
||||||
MainWindowInfo.ClassName = "Foldhaus Window Class";
|
|
||||||
MainWindowInfo.Width = 1440;
|
|
||||||
MainWindowInfo.Height = 768;
|
|
||||||
MainWindowInfo.WindowEventsHandler = HandleWindowEvents;
|
|
||||||
|
|
||||||
MainWindow = CreateWin32Window (HInstance, MainWindowInfo);
|
|
||||||
Win32UpdateWindowDimension(&MainWindow);
|
Win32UpdateWindowDimension(&MainWindow);
|
||||||
|
|
||||||
win32_opengl_window_info OpenGLWindowInfo = {};
|
win32_opengl_window_info OpenGLWindowInfo = {};
|
||||||
|
@ -393,6 +426,10 @@ INT NCmdShow
|
||||||
CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow);
|
CreateOpenGLWindowContext(OpenGLWindowInfo, &MainWindow);
|
||||||
|
|
||||||
s64 PerformanceCountFrequency = GetPerformanceFrequency();
|
s64 PerformanceCountFrequency = GetPerformanceFrequency();
|
||||||
|
s64 LastFrameEnd = GetWallClock();
|
||||||
|
r32 TargetSecondsPerFrame = 1 / 60.0f;
|
||||||
|
r32 LastFrameSecondsElapsed = 0.0f;
|
||||||
|
|
||||||
GlobalDebugServices = (debug_services*)malloc(sizeof(debug_services));
|
GlobalDebugServices = (debug_services*)malloc(sizeof(debug_services));
|
||||||
InitDebugServices(GlobalDebugServices, (u8*)malloc(Megabytes(8)), Megabytes(8), 1000, PerformanceCountFrequency);
|
InitDebugServices(GlobalDebugServices, (u8*)malloc(Megabytes(8)), Megabytes(8), 1000, PerformanceCountFrequency);
|
||||||
GlobalDebugServices->GetWallClock = GetWallClock;
|
GlobalDebugServices->GetWallClock = GetWallClock;
|
||||||
|
@ -431,21 +468,23 @@ INT NCmdShow
|
||||||
context Context = {};
|
context Context = {};
|
||||||
Context.MemorySize = InitialMemory.Size;
|
Context.MemorySize = InitialMemory.Size;
|
||||||
Context.MemoryBase = InitialMemory.Base;
|
Context.MemoryBase = InitialMemory.Base;
|
||||||
Context.WindowWidth = MainWindow.Info.Width;
|
Context.WindowWidth = MainWindow.Width;
|
||||||
Context.WindowHeight = MainWindow.Info.Height;
|
Context.WindowHeight = MainWindow.Height;
|
||||||
|
|
||||||
// Platform functions
|
// Platform functions
|
||||||
Context.GeneralWorkQueue = &WorkQueue;
|
Context.GeneralWorkQueue = &WorkQueue;
|
||||||
Context.PlatformAlloc = Win32Alloc;
|
Context.PlatformAlloc = Win32Alloc;
|
||||||
Context.PlatformFree = Win32Free;
|
Context.PlatformFree = Win32Free;
|
||||||
Context.PlatformReadEntireFile = ReadEntireFile;
|
Context.PlatformReadEntireFile = Win32ReadEntireFile;
|
||||||
Context.PlatformWriteEntireFile = WriteEntireFile;
|
Context.PlatformWriteEntireFile = Win32WriteEntireFile;
|
||||||
Context.PlatformGetFilePath = Win32SystemDialogOpenFile;
|
Context.PlatformGetFilePath = Win32SystemDialogueOpenFile;
|
||||||
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
Context.PlatformGetGPUTextureHandle = Win32GetGPUTextureHandle;
|
||||||
Context.PlatformGetSocketHandle = Win32GetSocketHandle;
|
Context.PlatformGetSocketHandle = Win32GetSocketHandle;
|
||||||
Context.PlatformGetSendAddress = Win32GetSendAddress;
|
Context.PlatformGetSendAddress = Win32GetSendAddress;
|
||||||
Context.PlatformSetSocketOption = Win32SetSocketOption;
|
Context.PlatformSetSocketOption = Win32SetSocketOption;
|
||||||
Context.PlatformCloseSocket = Win32CloseSocket;
|
Context.PlatformCloseSocket = Win32CloseSocket;
|
||||||
|
Context.PlatformGetFontInfo = Win32GetFontInfo;
|
||||||
|
Context.PlatformDrawFontCodepoint = Win32DrawFontCodepoint;
|
||||||
|
|
||||||
win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName);
|
win32_dll_refresh DLLRefresh = InitializeDLLHotReloading(DLLName, WorkingDLLName, DLLLockFileName);
|
||||||
if (HotLoadDLL(&DLLRefresh))
|
if (HotLoadDLL(&DLLRefresh))
|
||||||
|
@ -490,7 +529,7 @@ INT NCmdShow
|
||||||
GetCursorPos (&MousePos);
|
GetCursorPos (&MousePos);
|
||||||
ScreenToClient(MainWindow.Handle, &MousePos);
|
ScreenToClient(MainWindow.Handle, &MousePos);
|
||||||
Input.New->MouseX = MousePos.x;
|
Input.New->MouseX = MousePos.x;
|
||||||
Input.New->MouseY = MainWindow.Info.Height - MousePos.y;
|
Input.New->MouseY = MainWindow.Height - MousePos.y;
|
||||||
|
|
||||||
if (KeyTransitionedDown(Input, KeyCode_MouseLeftButton))
|
if (KeyTransitionedDown(Input, KeyCode_MouseLeftButton))
|
||||||
{
|
{
|
||||||
|
@ -501,8 +540,8 @@ INT NCmdShow
|
||||||
|
|
||||||
// TODO(Peter): We shouldn't need to do this translation. the platform layer knows about win32_windows. We should just make that the interface
|
// TODO(Peter): We shouldn't need to do this translation. the platform layer knows about win32_windows. We should just make that the interface
|
||||||
// to all windows.
|
// to all windows.
|
||||||
Context.WindowWidth = MainWindow.Info.Width;
|
Context.WindowWidth = MainWindow.Width;
|
||||||
Context.WindowHeight = MainWindow.Info.Height;
|
Context.WindowHeight = MainWindow.Height;
|
||||||
Context.DeltaTime = LastFrameSecondsElapsed;
|
Context.DeltaTime = LastFrameSecondsElapsed;
|
||||||
|
|
||||||
Context.UpdateAndRender(Context, Input, &RenderBuffer);
|
Context.UpdateAndRender(Context, Input, &RenderBuffer);
|
||||||
|
|
Loading…
Reference in New Issue