diff --git a/core.h b/core.h index 8d14c35..edf6e2f 100644 --- a/core.h +++ b/core.h @@ -1,6 +1,16 @@ #ifndef CORE_H_SENTRY #define CORE_H_SENTRY +/* ---- Switches ------------------------------------------------------- */ + +#ifndef BUILD_DEBUG +#define BUILD_DEBUG 1 +#endif + +#ifndef BUILD_INTERNAL +#define BUILD_INTERNAL 1 +#endif + /* ---- Environment Detection ------------------------------------------ */ /* Architecture */ @@ -91,16 +101,6 @@ #error Unknown compiler . . . #endif -/* ---- Switches ------------------------------------------------------- */ - -#ifndef BUILD_DEBUG -#define BUILD_DEBUG 1 -#endif - -#ifndef BUILD_INTERNAL -#define BUILD_INTERNAL 1 -#endif - /* ---- Types ---------------------------------------------------------- */ #ifndef TRUE diff --git a/sdl_handmade.c b/sdl_handmade.c index 00355a3..8a51756 100644 --- a/sdl_handmade.c +++ b/sdl_handmade.c @@ -40,6 +40,10 @@ SDL_GameController *ControllerHandles[MAX_CONTROLLERS]; static offscreen_buffer GlobalBackbuffer; +static B32 IsFullscreen; +static sdl_window_size WindowSize; +static sdl_window_position WindowPosition; + static S32 str_len(char *str) { S32 count = 0; @@ -130,13 +134,20 @@ void DEBUGPlatformFreeFileMemory(thread_context *Thread, void *Memory) free(Memory); } -static sdl_window_dimension SDLGetWindowDimension(SDL_Window *Window) +static sdl_window_size SDLGetWindowSize(SDL_Window *Window) { - sdl_window_dimension Dimension; + sdl_window_size Dimension; SDL_GetWindowSize(Window, &Dimension.Width, &Dimension.Height); return Dimension; } +static sdl_window_position SDLGetWindowPosition(SDL_Window *Window) +{ + sdl_window_position Position; + SDL_GetWindowPosition(Window, &Position.X, &Position.Y); + return Position; +} + static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, int Width, int Height) { if(Buffer->Texture) @@ -155,7 +166,7 @@ static void SDLResizeTexture(offscreen_buffer *Buffer, SDL_Renderer *Renderer, i Buffer->Pitch = Width * BytesPerPixel; } -static void SDLDisplayBufferInWindow(offscreen_buffer Buffer, SDL_Window *Window, SDL_Renderer *Renderer) +static void SDLDisplayBufferInWindow(offscreen_buffer *Buffer, SDL_Window *Window, SDL_Renderer *Renderer) { S32 OffsetX = 10; S32 OffsetY = 10; @@ -163,15 +174,20 @@ static void SDLDisplayBufferInWindow(offscreen_buffer Buffer, SDL_Window *Window SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255); SDL_RenderClear(Renderer); - if(SDL_UpdateTexture(Buffer.Texture, 0, Buffer.Memory, Buffer.Pitch)) { + if(SDL_UpdateTexture(Buffer->Texture, 0, Buffer->Memory, Buffer->Pitch)) { /* TODO: Do something about this error! */ } - /* 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_Rect dest_rect = { OffsetX, OffsetY, RESOLUTION_WIDTH, RESOLUTION_HEIGHT }; - SDL_RenderCopy(Renderer, Buffer.Texture, 0, (const SDL_Rect *)(&dest_rect)); + sdl_window_size WindowSize = SDLGetWindowSize(Window); + if(WindowSize.Width >= Buffer->Width*2 && WindowSize.Height >= 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)); + } else { + SDL_Rect dest_rect = { OffsetX, OffsetY, RESOLUTION_WIDTH, RESOLUTION_HEIGHT }; + SDL_RenderCopy(Renderer, Buffer->Texture, 0, (const SDL_Rect *)(&dest_rect)); + } SDL_RenderPresent(Renderer); } @@ -284,11 +300,38 @@ static void HandleEvent(SDL_Event *Event) } } -static void SDLProcessMessages(sdl_state *SDLState, - game_controller_input *KeyboardController) +// NOTE: On XFCE4 (tested on X11), the window moves slightly lower than the set position, for whatever reason. +// Maybe, we need to redraw inside of the window atleast once before repositioning? +// This issue does not happen on MacOS. +static void SDLToggleFullscreen(SDL_Window *Window) +{ + if(IsFullscreen) { + if(SDL_SetWindowFullscreen(Window, 0) == 0) { + SDL_SetWindowSize(Window, WindowSize.Width, WindowSize.Height); + SDL_SetWindowPosition(Window, WindowPosition.X, WindowPosition.Y); + IsFullscreen = FALSE; + } else { + /* TODO: This didn't work . . . SDL_GetError() */ + } + } else { + WindowSize = SDLGetWindowSize(Window); + WindowPosition = SDLGetWindowPosition(Window); + + if(SDL_SetWindowFullscreen(Window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { + IsFullscreen = TRUE; + } else { + /* TODO: This didn't work . . . SDL_GetError() */ + } + } +} + +static void SDLProcessMessages(sdl_state *SDLState, game_controller_input *KeyboardController) { SDL_Event Event; while(SDL_PollEvent(&Event)) { + SDL_Window *Window = SDL_GetWindowFromID(Event.window.windowID); + SDL_Renderer *Renderer = SDL_GetRenderer(Window); + switch(Event.type) { case SDL_KEYDOWN: case SDL_KEYUP: { @@ -338,12 +381,17 @@ static void SDLProcessMessages(sdl_state *SDLState, * to see SDL_QUIT event occur before our * keybind. */ B32 AltKeyWasDown = (Event.key.keysym.mod & KMOD_ALT); + if(KeyCode == SDLK_F4 && AltKeyWasDown) GlobalRunning = FALSE; #if BUILD_INTERNAL if(KeyCode == SDLK_ESCAPE) GlobalRunning = FALSE; #endif + + if((KeyCode == SDLK_RETURN) && AltKeyWasDown) { + SDLToggleFullscreen(Window); + } } } break; @@ -551,14 +599,16 @@ S32 main(S32 argc, char *argv[]) /* NOTE: Floating windows are not supported oficially by Wayland * protocol. However, SDL_WINDOW_ALWAYS_ON_TOP does work on KDE * under Wayland. I have not tested GNOME. */ - SDL_Window *Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, RESOLUTION_WIDTH+20, RESOLUTION_HEIGHT+20, SDL_WINDOW_RESIZABLE/* | SDL_WINDOW_ALWAYS_ON_TOP*/); + /* NOTE: We create the window hidden at first. This is so that we do not get a window outline + * that shows up whilst it is waiting for the rendered to be created. We want to display + * the window once everything is ready. */ + SDL_Window *Window = SDL_CreateWindow("Handmade Hero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, RESOLUTION_WIDTH+20, RESOLUTION_HEIGHT+20, SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE/* | SDL_WINDOW_ALWAYS_ON_TOP*/); if(Window) { SDL_DisplayMode display_mode; SDL_GetCurrentDisplayMode(0, &display_mode); SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_PRESENTVSYNC); - SDL_SetWindowPosition(Window, (display_mode.w - RESOLUTION_WIDTH-30), (display_mode.h - RESOLUTION_HEIGHT-30)); /* NOTE: For future reference, the custom window bar should use * SDL_SetWindowHitTest to define areas that will be used to @@ -571,18 +621,17 @@ S32 main(S32 argc, char *argv[]) * its actual size. */ /* SDL_RenderPresent(Renderer) is enough to display the window. */ if(Renderer) { -#if BUILD_DEBUG - void *BaseAddress = (void *)TB(2); -#else - void *BaseAddress = (void *)(0); -#endif - SDLSetProgramIcon(Window); -#if 0 + + // TODO: Make it a global. + SDL_Cursor *PointerCursor = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + SDL_SetCursor(PointerCursor); +#if !BUILD_INTERNAL if(SDL_ShowCursor(SDL_DISABLE) < 0) { /* TODO: This didn't work . . . SDL_GetError() */ } #endif + SDL_SetWindowPosition(Window, (display_mode.w - RESOLUTION_WIDTH-20), (display_mode.h - RESOLUTION_HEIGHT-20)); GlobalRunning = TRUE; @@ -595,7 +644,6 @@ S32 main(S32 argc, char *argv[]) SoundOutput.SamplesPerSecond = 48000; SoundOutput.BytesPerSample = sizeof(S16) * 2; SoundOutput.SecondaryBufferSize = SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample; - SoundOutput.tSine = 0; SoundOutput.LatencySampleCount = SoundOutput.SamplesPerSecond / 15; SDLInitSound(SoundOutput.SamplesPerSecond, SoundOutput.SamplesPerSecond * SoundOutput.BytesPerSample / 60); @@ -607,6 +655,12 @@ S32 main(S32 argc, char *argv[]) /* NOTE: calloc auto clears to zero */ /* SDLClearSoundBuffer(&SoundOutput); */ +#if BUILD_DEBUG + void *BaseAddress = (void *)TB(2); +#else + void *BaseAddress = (void *)(0); +#endif + game_memory GameMemory; memset(&GameMemory, 0, sizeof(GameMemory)); GameMemory.PermanentStorageSize = MB(64); @@ -641,6 +695,8 @@ S32 main(S32 argc, char *argv[]) sdl_game_code Game = SDLLoadGameCode(SDLState.DLLPath); + SDL_ShowWindow(Window); // NOTE: Everything is ready; display the window. + while(GlobalRunning) { NewInput->dtForFrame = TargetSecondsPerFrame; @@ -789,7 +845,7 @@ S32 main(S32 argc, char *argv[]) U64 EndCounter = SDLGetWallClock(); - SDLDisplayBufferInWindow(GlobalBackbuffer, Window, Renderer); + SDLDisplayBufferInWindow(&GlobalBackbuffer, Window, Renderer); F64 MSPerFrame = 1000.0 * SDLGetSecondsElapsed(LastCounter, EndCounter); F64 FPS = 1000.0 / MSPerFrame; diff --git a/sdl_handmade.h b/sdl_handmade.h index 7ab2bbd..cfef6db 100644 --- a/sdl_handmade.h +++ b/sdl_handmade.h @@ -6,10 +6,15 @@ #include "core.h" #include "handmade.h" -typedef struct sdl_window_dimension { +typedef struct sdl_window_size { S32 Width; S32 Height; -} sdl_window_dimension; +} sdl_window_size; + +typedef struct sdl_window_position { + S32 X; + S32 Y; +} sdl_window_position; typedef struct offscreen_buffer { /* Pixels are always 32-bit and have the bytes in BGRX @@ -25,7 +30,6 @@ typedef struct sdl_sound_output { S32 SamplesPerSecond; S32 BytesPerSample; S32 SecondaryBufferSize; - F32 tSine; S32 LatencySampleCount; void *Samples; } sdl_sound_output;