Fixed window positioning on Windows. TODO: Test again on Linux and MacOS.
This commit is contained in:
+52
-16
@@ -138,27 +138,56 @@ void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory)
|
|||||||
free(Memory); // TODO: Should we accept debug_read_file_result instead of just memory.
|
free(Memory); // TODO: Should we accept debug_read_file_result instead of just memory.
|
||||||
}
|
}
|
||||||
|
|
||||||
static sdl_window_size SDLGetWindowSize(SDL_Window *Window)
|
static sdl_border_size SDLGetWindowBorderSizes(SDL_Window *Window)
|
||||||
{
|
{
|
||||||
|
sdl_border_size Result;
|
||||||
|
SDL_GetWindowBordersSize(Window, &Result.Top, &Result.Left, &Result.Bottom, &Result.Right);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: All SDL window functions (SDL_GetWindowSize, SDL_GetWindowPosition, SDL_SetWindowPosition, SDL_SetWindowSize)
|
||||||
|
// work ONLY with client area. This has some weird behavior with SDL_SetWindowPosition where SDLGetWindowBorderSizes
|
||||||
|
// reports left border (of 8 in our case), however it does not have that border in reality, so we ignore left and right borders.
|
||||||
|
// As a result, we ignore left and right borders, for now.
|
||||||
|
static sdl_window_size SDLGetBorderedWindowSize(SDL_Window *Window)
|
||||||
|
{
|
||||||
|
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
|
||||||
|
|
||||||
sdl_window_size Dimension;
|
sdl_window_size Dimension;
|
||||||
SDL_GetWindowSize(Window, &Dimension.Width, &Dimension.Height);
|
SDL_GetWindowSize(Window, &Dimension.Width, &Dimension.Height);
|
||||||
|
Dimension.Height += Border.Top + Border.Bottom;
|
||||||
|
// Dimension.Width += Border.Left + Border.Right;
|
||||||
|
|
||||||
return Dimension;
|
return Dimension;
|
||||||
}
|
}
|
||||||
|
|
||||||
static sdl_window_position SDLGetWindowPosition(SDL_Window *Window)
|
static sdl_window_position SDLGetBorderedWindowPosition(SDL_Window *Window)
|
||||||
{
|
{
|
||||||
// NOTE: SDL_GetWindowPosition returns the client area position.
|
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
|
||||||
S32 top, left;
|
|
||||||
SDL_GetWindowBordersSize(Window, &top, &left, 0, 0);
|
|
||||||
|
|
||||||
sdl_window_position Position;
|
sdl_window_position Position;
|
||||||
SDL_GetWindowPosition(Window, &Position.X, &Position.Y);
|
SDL_GetWindowPosition(Window, &Position.X, &Position.Y);
|
||||||
Position.X -= left;
|
// Position.X -= Border.Left;
|
||||||
Position.Y -= top;
|
Position.Y -= Border.Top;
|
||||||
|
|
||||||
return Position;
|
return Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SDLSetBorderedWindowPosition(SDL_Window *Window, S32 X, S32 Y)
|
||||||
|
{
|
||||||
|
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
|
||||||
|
|
||||||
|
SDL_SetWindowPosition(Window, X, Y + Border.Top);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SDLSetBorderedWindowSize(SDL_Window *Window, S32 Width, S32 Height)
|
||||||
|
{
|
||||||
|
sdl_border_size Border = SDLGetWindowBorderSizes(Window);
|
||||||
|
|
||||||
|
// SDL_SetWindowSize(Window, Width - (Border.Left + Border.Right), Height - (Border.Top + Border.Bottom));
|
||||||
|
SDL_SetWindowSize(Window, Width, Height - (Border.Top + Border.Bottom));
|
||||||
|
}
|
||||||
|
|
||||||
static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, int Width, int Height)
|
static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, int Width, int Height)
|
||||||
{
|
{
|
||||||
if(Buffer->Texture)
|
if(Buffer->Texture)
|
||||||
@@ -191,7 +220,7 @@ static void SDLDisplayBufferInWindow(offscreen_buffer *Buffer, SDL_Window *Windo
|
|||||||
|
|
||||||
/* TODO: We temporarily introduce the target rectangle to avoid stretching the canvas. */
|
/* TODO: We temporarily introduce the target rectangle to avoid stretching the canvas. */
|
||||||
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
|
/* SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0); */
|
||||||
sdl_window_size WinSize = SDLGetWindowSize(Window);
|
sdl_window_size WinSize = SDLGetBorderedWindowSize(Window);
|
||||||
if(WinSize.Width >= Buffer->Width*2 && WinSize.Height >= Buffer->Height*2) {
|
if(WinSize.Width >= Buffer->Width*2 && WinSize.Height >= Buffer->Height*2) {
|
||||||
SDL_Rect dest_rect = { OffsetX, OffsetY, Buffer->Width*2, Buffer->Height*2 };
|
SDL_Rect dest_rect = { OffsetX, OffsetY, Buffer->Width*2, Buffer->Height*2 };
|
||||||
SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect));
|
SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect));
|
||||||
@@ -315,16 +344,16 @@ static void SDLToggleFullscreen(SDL_Window *Window)
|
|||||||
{
|
{
|
||||||
if(IsFullscreen) {
|
if(IsFullscreen) {
|
||||||
if(SDL_SetWindowFullscreen(Window, 0) == 0) {
|
if(SDL_SetWindowFullscreen(Window, 0) == 0) {
|
||||||
SDL_SetWindowSize(Window, WindowSize.Width, WindowSize.Height);
|
SDLSetBorderedWindowSize(Window, WindowSize.Width, WindowSize.Height);
|
||||||
SDL_SetWindowPosition(Window, WindowPosition.X, WindowPosition.Y);
|
SDLSetBorderedWindowPosition(Window, WindowPosition.X, WindowPosition.Y);
|
||||||
|
|
||||||
IsFullscreen = FALSE;
|
IsFullscreen = FALSE;
|
||||||
} else {
|
} else {
|
||||||
/* TODO: This didn't work . . . SDL_GetError() */
|
/* TODO: This didn't work . . . SDL_GetError() */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
WindowSize = SDLGetWindowSize(Window);
|
WindowSize = SDLGetBorderedWindowSize(Window);
|
||||||
WindowPosition = SDLGetWindowPosition(Window);
|
WindowPosition = SDLGetBorderedWindowPosition(Window);
|
||||||
|
|
||||||
if(SDL_SetWindowFullscreen(Window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
|
if(SDL_SetWindowFullscreen(Window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
|
||||||
IsFullscreen = TRUE;
|
IsFullscreen = TRUE;
|
||||||
@@ -773,7 +802,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
|
|
||||||
if(Window) {
|
if(Window) {
|
||||||
SDL_DisplayMode display_mode;
|
SDL_DisplayMode display_mode;
|
||||||
SDL_GetCurrentDisplayMode(0, &display_mode);
|
SDL_GetCurrentDisplayMode(0, &display_mode); // Various display information.
|
||||||
|
|
||||||
SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
|
SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC);
|
||||||
|
|
||||||
@@ -789,6 +818,10 @@ S32 main(S32 argc, char *argv[])
|
|||||||
thread_context TempContext; // TODO:
|
thread_context TempContext; // TODO:
|
||||||
memset(&TempContext, 0, sizeof(TempContext));
|
memset(&TempContext, 0, sizeof(TempContext));
|
||||||
|
|
||||||
|
// TODO: It should be in the handmade layer. Expose the SDLSetProgramIcon to handmade layer the same way we expose file writing.
|
||||||
|
// This way, we can use all the drawing functions of handmade.
|
||||||
|
// https://learn.microsoft.com/en-us/windows/apps/design/iconography/app-icon-construction
|
||||||
|
// Probably, the icon size should be 256x256, so windows scales it properly. This buffer should be allocated into the arena.
|
||||||
loaded_bitmap ProgramIcon = DEBUGLoadBMPP(&TempContext, DEBUGPlatformReadEntireFile, "data/program_icon.bmp");
|
loaded_bitmap ProgramIcon = DEBUGLoadBMPP(&TempContext, DEBUGPlatformReadEntireFile, "data/program_icon.bmp");
|
||||||
game_offscreen_buffer ProgramIconBuffer;
|
game_offscreen_buffer ProgramIconBuffer;
|
||||||
ProgramIconBuffer.Memory = malloc((ProgramIcon.Width * ProgramIcon.Height) * 4);
|
ProgramIconBuffer.Memory = malloc((ProgramIcon.Width * ProgramIcon.Height) * 4);
|
||||||
@@ -809,7 +842,11 @@ S32 main(S32 argc, char *argv[])
|
|||||||
/* TODO: This didn't work . . . SDL_GetError() */
|
/* TODO: This didn't work . . . SDL_GetError() */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
SDL_SetWindowPosition(Window, (display_mode.w - RESOLUTION_WIDTH-20), (display_mode.h - RESOLUTION_HEIGHT-20));
|
|
||||||
|
SDL_Rect UsableDisplayRect;
|
||||||
|
SDL_GetDisplayUsableBounds(0, &UsableDisplayRect);
|
||||||
|
sdl_window_size CurrentWindowSize = SDLGetBorderedWindowSize(Window);
|
||||||
|
SDLSetBorderedWindowPosition(Window, (UsableDisplayRect.x + UsableDisplayRect.w - CurrentWindowSize.Width), (UsableDisplayRect.y + UsableDisplayRect.h - CurrentWindowSize.Height));
|
||||||
|
|
||||||
GlobalRunning = TRUE;
|
GlobalRunning = TRUE;
|
||||||
|
|
||||||
@@ -828,8 +865,7 @@ S32 main(S32 argc, char *argv[])
|
|||||||
SDL_PauseAudio(0); // TODO: This should be paused until we have some actual sound to play.
|
SDL_PauseAudio(0); // TODO: This should be paused until we have some actual sound to play.
|
||||||
|
|
||||||
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
|
SoundOutput.Samples = calloc(SoundOutput.SamplesPerSecond, SoundOutput.BytesPerSample);
|
||||||
/* SoundOutput.Samples =
|
/* SoundOutput.Samples = malloc(SoundOutput.SecondaryBufferSize); */
|
||||||
* malloc(SoundOutput.SecondaryBufferSize); */
|
|
||||||
/* NOTE: calloc auto clears to zero */
|
/* NOTE: calloc auto clears to zero */
|
||||||
/* SDLClearSoundBuffer(&SoundOutput); */
|
/* SDLClearSoundBuffer(&SoundOutput); */
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,13 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "handmade.h"
|
#include "handmade.h"
|
||||||
|
|
||||||
|
typedef struct sdl_border_size {
|
||||||
|
S32 Top;
|
||||||
|
S32 Bottom;
|
||||||
|
S32 Left;
|
||||||
|
S32 Right;
|
||||||
|
} sdl_border_size;
|
||||||
|
|
||||||
typedef struct sdl_window_size {
|
typedef struct sdl_window_size {
|
||||||
S32 Width;
|
S32 Width;
|
||||||
S32 Height;
|
S32 Height;
|
||||||
|
|||||||
Reference in New Issue
Block a user