Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions include/app/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
#ifndef APP_H
#define APP_H

int bgem_app_init(void);
#include "system/config.h"

#endif // APP_H
/**
* @brief
* Run the application.
*
* @param[in] cfg
* Struct containing the settings
*
* @return
* EXIT_SUCCESS if all the shutdown and clean up routines have been
* completed. EXIT_FAILURE if an error occurred in the middle of
* execution.
*/
int bgem_app_run(bgem_config* cfg);

#endif /* APP_H */
19 changes: 19 additions & 0 deletions include/bgem_defaults.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* MIT License
* Copyright (c) 2026 Cătălin Gabriel Drăghiță
*/

#ifndef BGEM_DEFAULTS_H
#define BGEM_DEFAULTS_H

/* Rendering */
#define BGEM_DEFAULT_RENDER_WIDTH 1920
#define BGEM_DEFAULT_RENDER_HEIGHT 1080

/* Frame pacing */
#define BGEM_DEFAULT_FRAME_LIMIT 60

/* Window mode */
#define BGEM_DEFAULT_WINDOW_MODE 0 /* 0 - Windowed | 1 - Borderless */

#endif /* BGEM_DEFAULTS_H */
71 changes: 71 additions & 0 deletions include/core/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,88 @@
#define DEBUG_PRINT(fmt, ...) do {} while (0)
#endif

/**
* @brief
* List of error codes returned by bgem's functions for error handling
*/
typedef enum {
BGEM_OK = 0, /**< Executed successfully */
BGEM_ERROR_GPU, /**< Graphics or rendering error */
BGEM_ERROR_PLATFORM, /**< Operating system function error */
BGEM_ERROR_OOM, /**< Out of memory error */
BGEM_ERROR_IO, /**< File operation error */
BGEM_ERROR_NOT_FOUND /**< An asset or file is not available */
} bgem_result;

#ifdef __cplusplus
extern "C" {
#endif

#ifdef DEBUG
/**
* @brief
* Initialize the Imgui debug UI
*
* @param[in] window
* The window created by SDL. Must be the main Bluegem window
*
*/
void bgem_debug_init(SDL_Window *window);

/**
* @brief
* Destroy the Imgui context
*
* Must be called after bgem_debug_init()
*/
void bgem_debug_shutdown(void);

/**
* @brief
* On/Off switch to show the UI or not
*/
void bgem_debug_toggle(void);

/**
* @brief
* Show the UI
*
* PROTOTYPE! Just displays Hello world
*/
void bgem_debug_newFrame(void);

/**
* @brief
* Render the debug UI
*/
void bgem_debug_render(void);

/**
* @brief
* Returns the status set by bgem_debug_toggle()
*
* @return
* TRUE if enabled. FALSE if disabled.
*/
int bgem_debug_isActive(void);

#define BGEM_DEBUG_INIT(window) bgem_debug_init(window)
#define BGEM_DEBUG_SHUTDOWN() bgem_debug_shutdown()
#define BGEM_DEBUG_TOGGLE() bgem_debug_toggle()
#define BGEM_DEBUG_NEWFRAME() bgem_debug_newFrame()
#define BGEM_DEBUG_RENDER() bgem_debug_render()
#define BGEM_DEBUG_ISACTIVE() bgem_debug_isActive()

#else
#define BGEM_DEBUG_INIT(window) ((void)0)
#define BGEM_DEBUG_SHUTDOWN() ((void)0)
#define BGEM_DEBUG_TOGGLE() ((void)0)
#define BGEM_DEBUG_NEWFRAME() ((void)0)
#define BGEM_DEBUG_RENDER() ((void)0)
#define BGEM_DEBUG_ISACTIVE() ((void)0)

#endif

#ifdef __cplusplus
}
#endif
Expand Down
59 changes: 59 additions & 0 deletions include/core/frame_limiter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* MIT License
* Copyright (c) 2026 Cătălin Gabriel Drăghiță
*/

#ifndef FRAME_LIMITER_H
#define FRAME_LIMITER_H

#include <SDL3/SDL.h>

typedef struct {
Uint32 target_fps;
double frame_budget; /* seconds per frame (1.0 / target_fps) */
double app_start; /* timestamp at limiter init */
double frame_start; /* timestamp at last bgem_frame_limiter_begin() */
float dt_ms; /* actual duration of the previous frame */
double elapsed; /* seconds since app_start */
} bgem_frame_limiter;

/**
* @brief
* Initialize the frame limiter.
*
* @param[out] fl
* Fill in the struct members.
*
* @param[in] target_fps
* The framerate number to not go above.
*/
void bgem_frame_limiterInit(bgem_frame_limiter *fl, Uint32 target_fps);

/**
* @brief
* The beginning of the frame.
*
* Placed at the start of the rendering pipepline. It will create a reference point
* to compare to when bgem_frame_limiterEnd() is called.
*
* A `BGEM_MAX_DT_SECONDS` of 100ms is used to avoid comparing big time differences
* bugs after suspend or debug breaks.
*
* @param[in, out] fl
* The struct that contains the current frame time information.
*/
void bgem_frame_limiterBegin(bgem_frame_limiter *fl);

/**
* @brief
* The end of the frame.
*
* Placed at the end of the rendering pipeline. It will compare with the information
* set from bgem_frame_limiterBegin(), and sleep until it reaches the frame time.
*
* @param[in] fl
* The struct that contains the frame time to compare to.
*/
void bgem_frame_limiterEnd(bgem_frame_limiter *fl);

#endif /* FRAME_LIMITER_H */
46 changes: 46 additions & 0 deletions include/core/path.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* MIT License
* Copyright (c) 2026 Cătălin Gabriel Drăghiță
*/

#ifndef PATH_H
#define PATH_H

#include <stdlib.h>
#include <stdbool.h>

#include "core/debug.h"

/**
* @brief
* Converts the relative path into full path
*
* @param[out] out
* Where to store the full path
*
* @param[in] size
* Size of the character buffer where to store the
* full path
*
* @param[in] relative_path
* The relative path
*
* @return
* BGEM_ERROR_BUFFER if the output is bigger than the buffer (size).
* BGEM_OK if the output fits in the buffer.
*/
bgem_result bgem_path_relativeToFull(char *out, size_t size, const char *relative_path);

#if defined(_WIN32)
#include <windows.h>
#define BGEM_PATH_MAX MAX_PATH
#else
#include <limits.h>
#if defined(PATH_MAX)
#define BGEM_PATH_MAX PATH_MAX
#else
#define BGEM_PATH_MAX 4096 /* POSIX fallback for filesystems without a fixed limit */
#endif
#endif

#endif /* PATH_H */
19 changes: 19 additions & 0 deletions include/core/timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* MIT License
* Copyright (c) 2026 Cătălin Gabriel Drăghiță
*/

#ifndef TIMER_H
#define TIMER_H

/**
* @brief
* High precision timer in seconds.
*
* @return
* Time elapsed in seconds. Integer part is the whole seconds,
* and the fractional part are the subsecond reminder.
*/
double bgem_timer_seconds(void);

#endif /* TIMER_H */
58 changes: 56 additions & 2 deletions include/platform/platform_egl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,67 @@
#define PLATFORM_EGL_H

#include <SDL3/SDL.h>
#include <EGL/egl.h>

#include "core/debug.h"

typedef struct bgem_platform_windowContext bgem_platform_windowContext;

/* Create graphics context attached to SDL window */

/**
* @brief
* Create an EGL context and attach it to the provided window.
*
* @param[in] window
* The window created by SDL to attatch the EGL context.
*
* @return
* Returns a struct with all the members initialized, ready to be controlled
* by future EGL calls. NULL if a failure occurred.
*/
bgem_platform_windowContext* bgem_platform_createContext(SDL_Window *window);
void bgem_platform_swapBuffers(bgem_platform_windowContext *platformContext);

/**
* @brief
* Call EGL's swap buffer function.
*
* @param[in] platformContext
* The valid window context structure to read from and execute the EGL's swap
* buffer function.
*
* @return
* EGL_SUCCESS if performed successfully.
*
* TODO: Handle more errors
*/
EGLint bgem_platform_swapBuffers(bgem_platform_windowContext *platformContext);

/**
* @brief
* Resize the context created by the Wayland compositor
*
* @param[in] platformContext
* If the window context has a non-null wl_win member, it will be read by the
* Wayland specific function and apply it to the appropriate context to resize.
*
* @param[in] w
* Width in pixels
*
* @param[in] h
* Height in pixels
*/
void bgem_platform_waylandResizeSurface(bgem_platform_windowContext *platformContext, int w, int h);

/**
* @brief
* Destroy the context.
*
* Must be called after a successful bgem_platform_createContext()
*
* @param[in] platformContext
* The struct to clear up.
*/
void bgem_platform_destroyContext(bgem_platform_windowContext *platformContext);

#endif //PLATFORM_EGL_H
#endif /* PLATFORM_EGL_H */
19 changes: 18 additions & 1 deletion include/platform/platform_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,24 @@ typedef enum {
BGEM_INSTANCE_LOCK_ERROR,
} bgem_instance_lockStatus;

/**
* @brief
* Lock the instance so only one at a time can be opened
*
* @return
* `BGEM_INSTANCE_LOCK_OK` if the lock has been executed successfully.
* `BGEM_INSTANCE_LOCK_ALREADY_RUNNING` if the new instance detects
* there is already another one opened, and `BGEM_INSTANCE_LOCK_ERROR`
* if the instance lock could not be set.
*/
bgem_instance_lockStatus bgem_platform_instanceLock(void);

/**
* @brief
* Unlock the instance.
*
* This is done during termination and cleanup procedures.
*/
void bgem_platform_instanceUnlock(void);

#endif // PLATFORM_INIT_H
#endif /* PLATFORM_INIT_H */
15 changes: 14 additions & 1 deletion include/platform/platform_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@
#ifndef PLATFORM_WINDOW_H
#define PLATFORM_WINDOW_H

/**
* @brief
* Brings the window forward.
*
* This only works in Windows. macOS already handles this with Launch
* Services. Wayland cannot control window status for now.
*
* NOTE: This is paired with the instance locking mechanism, hence the
* MessageBox in Linux will warn about the windows being "already opened"
* which is not really consistent with what the function is intended to do,
* at least on Linux
*
*/
void bgem_platform_windowBringForward(void);

#endif // PLATFORM_WINDOW_H
#endif /* PLATFORM_WINDOW_H */
Loading
Loading