Initial commit

This commit is contained in:
Patrick 2025-10-03 20:16:11 +02:00
commit 56f7cd1875
105 changed files with 22109 additions and 0 deletions

27
include/pgpl.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef PGPL_H
#define PGPL_H
#include <pgpl/gui.h>
#include <pgpl/render.h>
#include <pgpl/thread.h>
#include <pgpl/timer.h>
#include <pgpl/vector.h>
#include <pgpl/window.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This initalizes certain values inside of the pgpl library, call this before
* you call any other pgpl function. */
void pgpl_init(void);
/* This frees any of the resources allocated by pgpl_init. You may call
* pgpl_init again after calling this function. */
void pgpl_deinit(void);
#ifdef __cplusplus
}
#endif
#endif

45
include/pgpl/gui.h Normal file
View file

@ -0,0 +1,45 @@
#ifndef PGPL_GUI_H
#define PGPL_GUI_H
#include <pgpl/gui/helpers.h>
#include <pgpl/gui/predef.h>
#include <pgpl/gui/widgets.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This creates a new GUI instance, the parameters are mostly the same as
* creating a window, however you can also specify a theme which will theme the
* widgets respectively, and app_data, which can be used in callbacks of
* widgets. */
PGPL_Gui *pgpl_gui_create(const char *title, uint32_t width, uint32_t height,
int32_t x, int32_t y, PGPL_GuiTheme *theme,
void *app_data);
/* Destroys the GUI object, including all of its widgets by calling their
* destroy method. The internal boolean must be set to true if this is being
* called from inside of the gui event loop.*/
void pgpl_gui_destroy(PGPL_Gui *gui, bool internal);
/* This shows the GUI window. If wait is true, this will block until the window
* is closed. */
void pgpl_gui_run_and_show(PGPL_Gui *gui, bool wait);
/* Adds the specified widget to be rendered by the GUI. */
void pgpl_gui_widget_add(PGPL_Gui *gui, PGPL_GuiWidget *widget);
/* Removes the widget at the specified index. */
void pgpl_gui_widget_remove(PGPL_Gui *gui, uint32_t index);
/* Get amount of widgets that the gui contains. */
uint32_t pgpl_gui_widget_amount(PGPL_Gui *gui);
/* Gets the widget at the specified index. */
PGPL_GuiWidget *pgpl_gui_widget_get(PGPL_Gui *gui, uint32_t index);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,55 @@
#ifndef PGPL_GUI_HELPERS_H
#define PGPL_GUI_HELPERS_H
#include <pgpl/gui/predef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This function basically subtracts margin, border and padding from the
* max_width and max_height, and then return that through the width and height
* pointers. */
void pgpl_gui_widget_max_content_size(PGPL_GuiWidget *widget,
PGPL_GuiTheme *theme, double *width,
double *height, double max_width,
double max_height);
/* This function lets you configure a theme with just a base_color, which in
* this case is the brightest color that should be used (text, active), a font
* size for the content and a font. This will calculate the other colors,
* margin, border, padding and other font sizes based on those values. */
void pgpl_gui_theme_configure(PGPL_GuiTheme *theme, PGPL_Color base_color,
double content_font_size, PGPL_Font *font);
/* This will do a full render on a widget, it will account for it's offset, if
* it has a border or background, it's margin, border and padding sizes and also
* if it expands on the x and y axis. It then calls the widgets render function
* at the correct x and y offset. */
void pgpl_gui_widget_render_full(PGPL_GuiWidget *widget,
PGPL_Renderer *renderer, PGPL_GuiTheme *theme,
double x, double y, double max_width,
double max_height);
/* Checks if x and y lie within the visible bounds of a widget, accounting for
* margin, border and padding and returns true or false. */
bool pgpl_gui_widget_within_bounds(PGPL_GuiWidget *widget, PGPL_GuiTheme *theme,
double widget_x, double widget_y,
double max_width, double max_height,
double x, double y);
/* This configures all of the widget properties that should be configurable by
* the user. Check the PGPL_GuiWidget struct comment for more info. */
void pgpl_gui_widget_configure(PGPL_GuiWidget *widget, double offset_x,
double offset_y, bool expand_x, bool expand_y,
bool border, bool background,
PGPL_GuiFontSize font_size,
PGPL_GuiTheme *theme_override,
bool use_theme_override, bool ignore_margin,
bool ignore_border, bool ignore_padding);
#ifdef __cplusplus
}
#endif
#endif

131
include/pgpl/gui/predef.h Normal file
View file

@ -0,0 +1,131 @@
#ifndef PGPL_GUI_PREDEF_H
#define PGPL_GUI_PREDEF_H
#include <pgpl/render/predef.h>
#include <pgpl/thread.h>
#include <pgpl/vector.h>
#include <pgpl/window/predef.h>
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Predefinition of some structs. */
typedef struct PGPL_GuiWidget PGPL_GuiWidget;
typedef struct PGPL_Gui PGPL_Gui;
/* These are the enum values for the GUI colors. This helps select a different
* color from the theme if a widget is currently active, hovered over, or in a
* default state. */
typedef enum PGPL_GuiStatusColor {
PGPL_GUI_STATUS_COLOR_NORMAL,
PGPL_GUI_STATUS_COLOR_HOVER,
PGPL_GUI_STATUS_COLOR_ACTIVE
} PGPL_GuiStatusColor;
/* This controls what font size from the theme should be used. There are three
* different types. */
typedef enum PGPL_GuiFontSize {
PGPL_GUI_FONT_SIZE_TITLE,
PGPL_GUI_FONT_SIZE_HEADING,
PGPL_GUI_FONT_SIZE_CONTENT
} PGPL_GuiFontSize;
/* This is the struct for the themes. This controls the colors, font sizes, font
* and many more settings that widgets in a GUI render with. You can use the
* helper function pgpl_gui_theme_configure to easily configure such a theme
* struct. */
typedef struct PGPL_GuiTheme {
/* Color for the text and borders, array of 3 colors to support all values
* from PGPL_GuiStatusColor. */
PGPL_Color text_color[3];
/* Color for the background of widgets, array of 3 colors to support all
* values from PGPL_GuiStatusColor. */
PGPL_Color widget_background_color[3];
/* Color for the background of a GUI. */
PGPL_Color background_color;
/* Controls the margin of the widgets. */
PGPL_Rectangle margin;
/* Controls the border of the widgets. */
PGPL_Rectangle border;
/* Controls the padding of the widgets. */
PGPL_Rectangle padding;
/* Controls the font size of the widgets, this is an array of three so that it
* can support all values from PGPL_GuiFontSize. */
double font_size[3];
/* The font of the theme. */
PGPL_Font *font;
} PGPL_GuiTheme;
/* This is the struct for the individual widgets. This can be used to create
* custom widgets as well. Do note that if you create a custom struct for your
* widget, you need to ensure that the first attribute of said struct is of type
* PGPL_GuiWidget, so that other containers and the gui itself can call its
* methods and read its attributes. */
struct PGPL_GuiWidget {
/* This should be a unique string, often the name of the struct, so that the
* widget type can be identified. */
const char *id;
/* This is the rendering offset of the widget. */
double offset_x, offset_y;
/* expand_x and expand_y determine if the widget should expand in the x and y
* direction when being rendered. */
bool expand_x, expand_y;
/* This determines if the border and background of the widget should be
* rendered or not. */
bool border, background;
/* This picks out which font size from the theme to use. */
PGPL_GuiFontSize font_size;
/* This picks out which color from the theme to use. */
PGPL_GuiStatusColor gui_color;
/* This is the theme that should be used instead of the main theme. Note that
* this theme should propagate to any possible child widgets as well. */
PGPL_GuiTheme theme_override;
/* This determines if the override theme should even be used. If this is
* false, the theme_override is simply ignored. */
bool use_theme_override;
/* These attributes determine whether or not margin, border and padding sizes
* respectively should be ignored when rendering. */
bool ignore_margin, ignore_border, ignore_padding;
/* This returns the size of the content of a widget. This should NOT include
* any margin, padding or border size. */
void (*get_content_size)(PGPL_GuiWidget *widget, PGPL_GuiTheme *theme,
double *width, double *height, double max_width,
double max_height);
/* This renders the content of the widget. Note that the margin, border,
* padding, background and offset of the widget must be accounted for BEFORE
* calling this function. For ease, you can use the
* pgpl_gui_widget_render_full function to automatically take care of all of
* those things for you. */
void (*render_content)(PGPL_GuiWidget *widget, PGPL_Renderer *renderer,
PGPL_GuiTheme *theme, double x, double y,
double max_width, double max_height);
/* This should get called for every event that is not a render or close event.
* Note that the x and y values should be called with the widgets offset
* pre-included. */
void (*event)(PGPL_GuiWidget *widget, PGPL_GuiTheme *theme, PGPL_Gui *gui,
PGPL_WindowEventType event_type,
PGPL_WindowEventData *event_data, double x, double y,
double max_width, double max_height);
/* This should destroy the widget, freeing all of its resources and also call
* the destroy method on all of its potential child widgets. */
void (*destroy)(PGPL_GuiWidget *widget);
};
/* This is the struct for the gui itself. Do not modify it's mutex and the
* widgets vector. The app_data value is used for event callbacks. */
struct PGPL_Gui {
PGPL_WindowThread *window_thread;
PGPL_GuiTheme theme;
PGPL_Vector *widgets;
void *app_data;
PGPL_Mutex *mutex;
};
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,96 @@
#ifndef PGPL_GUI_WIDGETS_H
#define PGPL_GUI_WIDGETS_H
#include <pgpl/gui/predef.h>
#include <pgpl/thread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* These are the two directions a PGPL_GuiContainerLayout can place widgets in.
* You can combine multiple of these to recreate a grid layout. */
typedef enum PGPL_GuiContainerLayoutDirection {
PGPL_GUI_CONTAINER_LAYOUT_DIRECTION_VERTICAL,
PGPL_GUI_CONTAINER_LAYOUT_DIRECTION_HORIZONTAL
} PGPL_GuiContainerLayoutDirection;
/* This is the PGPL_GuiContainerLayout, it places it's widgets along a single
* direction, see PGPL_GuiContainerLayoutDirection for more details on that. Do
* not modify the mutex and widgets vector in this struct. */
typedef struct PGPL_GuiContainerLayout {
PGPL_GuiWidget parent;
PGPL_Vector *widgets;
PGPL_GuiContainerLayoutDirection direction;
PGPL_Mutex *mutex;
} PGPL_GuiContainerLayout;
/* This creates a new container layout instance with the specified direction. */
PGPL_GuiContainerLayout *
pgpl_gui_container_layout_create(PGPL_GuiContainerLayoutDirection direction);
/* This adds a widget to a container layout. */
void pgpl_gui_container_layout_widget_add(
PGPL_GuiContainerLayout *container_layout, PGPL_GuiWidget *widget);
/* This returns a writeable pointer to the widget at the specified index in the
* container_layout. */
PGPL_GuiWidget *
pgpl_gui_container_layout_widget_get(PGPL_GuiContainerLayout *container_layout,
uint32_t index);
/* This deletes the widget at the specified index from the container layout. */
void pgpl_gui_container_layout_widget_delete(
PGPL_GuiContainerLayout *container_layout, uint32_t index);
/* This returns the amount of widgets in a container layout. */
uint32_t pgpl_gui_container_layout_widget_amount(
PGPL_GuiContainerLayout *container_layout);
/* This destroys a container layout, and calls the destroy method on all of it's
* child widgets. */
void pgpl_gui_container_layout_destroy(
PGPL_GuiContainerLayout *container_layout);
/* The struct for a PGPL_GuiTextWidget, the text variable is the string to be
* displayed. */
typedef struct PGPL_GuiTextWidget {
PGPL_GuiWidget parent;
const char *text;
} PGPL_GuiTextWidget;
/* Creates a new text widget. */
PGPL_GuiTextWidget *pgpl_gui_text_widget_create(const char *text);
/* Destroys a text widget. */
void pgpl_gui_text_widget_destroy(PGPL_GuiTextWidget *text_widget);
/* The struct for a PGPL_GuiButtonWidget, the text variable is the string to be
* displayed. The click_callback variable gets called with the gui instances
* app_data parameter. */
typedef struct PGPL_GuiButtonWidget {
PGPL_GuiWidget parent;
const char *text;
void (*click_callback)(void *app_data);
} PGPL_GuiButtonWidget;
/* Creates a new button widget. */
PGPL_GuiButtonWidget *
pgpl_gui_button_widget_create(const char *text,
void (*click_callback)(void *app_data));
/* Destroys a button widget. */
void pgpl_gui_button_widget_destroy(PGPL_GuiButtonWidget *button_widget);
/* Creates a new empty widget. This is very useful to create spacers for
* container layouts. */
PGPL_GuiWidget *pgpl_gui_empty_widget_create(void);
/* Destroys a empty widget. */
void pgpl_gui_empty_widget_destroy(PGPL_GuiWidget *empty_widget);
#ifdef __cplusplus
}
#endif
#endif

8
include/pgpl/render.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef PGPL_RENDER_H
#define PGPL_RENDER_H
#include <pgpl/render/font.h>
#include <pgpl/render/shapes.h>
#include <pgpl/render/texture.h>
#endif

View file

@ -0,0 +1,56 @@
#ifndef PGPL_RENDER_COLOR_H
#define PGPL_RENDER_COLOR_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* PGPL_Color type. This is simply a uint32_t. It contains an RGBA value:
* 0xFF000000 -> Red
* 0x00FF0000 -> Green
* 0x0000FF00 -> Blue
* 0x000000FF -> Alpha */
typedef uint32_t PGPL_Color;
/* Creates a new PGPL_Color with the given parameters. */
static inline PGPL_Color pgpl_color_create(uint8_t red, uint8_t green,
uint8_t blue, uint8_t alpha) {
return ((uint32_t)red << 24) + ((uint32_t)green << 16) +
((uint32_t)blue << 8) + (uint32_t)alpha;
}
/* Gets the red value of the PGPL_Color type. */
static inline uint8_t pgpl_color_get_red(PGPL_Color color) {
return (color >> 24) & 0xFF;
}
/* Gets the green value of the PGPL_Color type. */
static inline uint8_t pgpl_color_get_green(PGPL_Color color) {
return (color >> 16) & 0xFF;
}
/* Gets the blue value of the PGPL_Color type. */
static inline uint8_t pgpl_color_get_blue(PGPL_Color color) {
return (color >> 8) & 0xFF;
}
/* Gets the alpha value of the PGPL_Color type. */
static inline uint8_t pgpl_color_get_alpha(PGPL_Color color) {
return color & 0xFF;
}
/* Divides all color values by the given amount. */
static inline PGPL_Color pgpl_color_divide(PGPL_Color color, double divisor) {
return pgpl_color_create(pgpl_color_get_red(color) / divisor,
pgpl_color_get_green(color) / divisor,
pgpl_color_get_blue(color) / divisor,
pgpl_color_get_alpha(color));
}
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,69 @@
#ifndef PGPL_RENDER_FONT_H
#define PGPL_RENDER_FONT_H
#include <pgpl/render/predef.h>
#include <wchar.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This creates a new font from a .ttf file. See pgpl_font_create for more
* info. */
PGPL_Font *pgpl_font_create_from_file(const char *filename,
uint32_t glyph_size);
/* This bakes a font from a .ttf file which is located somewhere in memory. The
* glyph_size parameter lets you modify the resolution of the baked glyphs. It
* can still be rendered at any size. Note that the data passed here will be
* freed automatically when the font gets destroyed, so do not attempt to free
* it yourself. */
PGPL_Font *pgpl_font_create(uint8_t *data, uint32_t glyph_size);
/* This frees all the resources associated with a font. It can also be with the
* renderer being NULL, this however does not delete the OpenGL texture that was
* created (it still gets deleted upon window destruction). Only use this if the
* window that the font was baked with no longer exists. */
void pgpl_font_destroy(PGPL_Renderer *renderer, PGPL_Font *font);
/* This renders a single glyph on the screen. The c parameter can hold any
* Unicode character value. The values in the xoff and yoff parameters will be
* offset to where the next character should be rendered. The color modulates
* the color of the font texture. */
void pgpl_font_render_glyph(PGPL_Renderer *renderer, PGPL_Font *font, wchar_t c,
PGPL_Color color, double x, double y, double size,
double *xoff, double *yoff);
/* This renders a whole UTF-8 string at a given position. Its parameters work
* similarily to pgpl_render_glyph. */
void pgpl_font_render_string(PGPL_Renderer *renderer, PGPL_Font *font,
const char *str, PGPL_Color color, double x,
double y, double size);
/* Works like pgpl_font_render_string, but takes a wchar_t string instead. */
void pgpl_font_render_wstring(PGPL_Renderer *renderer, PGPL_Font *font,
wchar_t *str, PGPL_Color color, double x,
double y, double size);
/* This calculates the dimensions of a glyph. in the top and left parameters it
* puts the coordinates of the top-left corner, and into the bottom and right
* coordinates those of the bottom-left corner respectively. */
void pgpl_font_glyph_dimensions(PGPL_Font *font, wchar_t c, double size,
double *xoff, double *yoff,
PGPL_Rectangle *rectangle);
/* Works similarily to pgpl_font_glyph_dimensions, however this calculates those
* values for an entire UTF-8 string. */
void pgpl_font_string_dimensions(PGPL_Font *font, const char *str, double size,
PGPL_Rectangle *rectangle);
/* Works like pgpl_font_string_dimensions, but takes a wchar_t string instead.
*/
void pgpl_font_wstring_dimensions(PGPL_Font *font, wchar_t *str, double size,
PGPL_Rectangle *rectangle);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,37 @@
#ifndef PGPL_RENDER_PREDEF_H
#define PGPL_RENDER_PREDEF_H
#include <pgpl/render/color.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* PGPL_Font type. Contains all the data needed to render glyphs on the window.
* None of its members should be accessed directly. */
typedef struct PGPL_Font PGPL_Font;
/* PGPL_Rectangle type. */
typedef struct PGPL_Rectangle {
double top;
double left;
double bottom;
double right;
} PGPL_Rectangle;
/* PGPL_Renderer type. Contains all necessary information for rendering. None of
* its members should be accessed directly. */
typedef struct PGPL_Renderer {
uint32_t width, height;
} PGPL_Renderer;
/* PGPL_Texture type. Contains a texture that can be rendered. None of its
* members should be accessed directly. */
typedef struct PGPL_Texture PGPL_Texture;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,39 @@
#ifndef PGPL_RENDER_SHAPES_H
#define PGPL_RENDER_SHAPES_H
#include <pgpl/render/predef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Renders a basic rectangle with the given parameters. */
void pgpl_render_rectangle(PGPL_Renderer *renderer, PGPL_Color color, double x,
double y, double width, double height);
/* Renders a basic line with the given parameters. Note that this doesn't work
* that well if the scale is not at 1.0. */
void pgpl_render_line(PGPL_Renderer *renderer, PGPL_Color color, double x0,
double y0, double x1, double y1);
/* Renders a basic circle at the given coordinates with the given radius. The
* triangle count defines how many triangles should be rendered, the higher, the
* more accurate the circle will look. */
void pgpl_render_circle(PGPL_Renderer *renderer, PGPL_Color color, double x,
double y, double radius, double triangle_amount);
/* Renders a single dot at the given coordinates. Note that this doesn't work
* that well if the scale is not at 1.0. */
void pgpl_render_point(PGPL_Renderer *renderer, PGPL_Color color, double x,
double y);
/* Renders a basic triangle with the given parameters. */
void pgpl_render_triangle(PGPL_Renderer *renderer, PGPL_Color color, double ax,
double ay, double bx, double by, double cx,
double cy);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,73 @@
#ifndef PGPL_RENDER_TEXTURE_H
#define PGPL_RENDER_TEXTURE_H
#include <pgpl/render/predef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This enum contains all possible texture filtering methods that textures can
* be created with. */
typedef enum PGPL_TextureFilter {
PGPL_TEXTURE_FILTER_LINEAR,
PGPL_TEXTURE_FILTER_NEAREST
} PGPL_TextureFilter;
/* This enum contains all possible texture formats that textures can be created
* from. */
typedef enum PGPL_TextureFormat {
PGPL_TEXTURE_FORMAT_RGBA,
PGPL_TEXTURE_FORMAT_RGB,
PGPL_TEXTURE_FORMAT_BW
} PGPL_TextureFormat;
/* This creates a texture from an image file stored in memory. The file_data is
* a pointer to it, and len is the lenght of the file_data. See
* pgpl_render_create_texture_file for more info. */
PGPL_Texture *pgpl_render_create_texture_file_memory(PGPL_Renderer *renderer,
const uint8_t *file_data,
uint32_t len,
PGPL_TextureFilter filter);
/* This creates a texture from a file. This supports anything that stb_image
* supports. You can also choose the filtering method to be used. */
PGPL_Texture *pgpl_render_create_texture_file(PGPL_Renderer *renderer,
const char *filename,
PGPL_TextureFilter filter);
/* This creates a texture from raw pixel data. The width and height are used to
* determine the size of the data. Note that RGB images are padded to 4 bytes
* per pixel. */
PGPL_Texture *pgpl_render_create_texture(PGPL_Renderer *renderer,
const uint8_t *data, uint32_t width,
uint32_t height,
PGPL_TextureFilter filter,
PGPL_TextureFormat format);
/* This frees any resources associated with a texture. Note that you can call
* this with renderer being NULL, this however doesn't get rid of any OpenGL
* data (it still gets deleted upon window destruction). Only call this with the
* renderer as NULL if the window it was created on is already destroyed. */
void pgpl_render_destroy_texture(PGPL_Renderer *renderer,
PGPL_Texture *texture);
/* This renders a texture at the given position and with the given size. Note
* that you can ONLY render images on the window they were created on. */
void pgpl_render_texture(PGPL_Renderer *renderer, PGPL_Texture *texture,
double x, double y, double width, double height);
/* This renders a texture with extended settings. The color parameter allows you
* to modulate the color of the texture, the s0, s1, t0 and t1 parameters let
* you specify coordinates on a given texture, so that you only render a part of
* the texture. See pgpl_render_texture for more info. */
void pgpl_render_texture_extended(PGPL_Renderer *renderer,
PGPL_Texture *texture, double x, double y,
double width, double height, PGPL_Color color,
double s0, double t0, double s1, double t1);
#ifdef __cplusplus
}
#endif
#endif

46
include/pgpl/thread.h Normal file
View file

@ -0,0 +1,46 @@
#ifndef PGPL_THREAD_H
#define PGPL_THREAD_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* These are the thread and mutex abstraction structs, do not try to modify
* their contents. */
typedef struct PGPL_Thread PGPL_Thread;
typedef struct PGPL_Mutex PGPL_Mutex;
/* This creates a new thread, which executes the given function with the given
* argument. */
PGPL_Thread *pgpl_thread_create(void *(*function)(void *arg), void *arg);
/* This destroys a thread. This doesn't actually stop the execution of the
* thread however, it simply just frees the data. */
void pgpl_thread_destroy(PGPL_Thread *thread);
/* This blocks until the thread finishes executing. */
void pgpl_thread_join(PGPL_Thread *thread);
/* This creates a new mutex. */
PGPL_Mutex *pgpl_mutex_create(void);
/* This destroys a mutex. */
void pgpl_mutex_destroy(PGPL_Mutex *mutex);
/* This locks a mutex, and blocks until said mutex can be locked. */
void pgpl_mutex_lock(PGPL_Mutex *mutex);
/* This attempts to lock a mutex. If it fails, this will return false, else it
* will return true. */
bool pgpl_mutex_try_lock(PGPL_Mutex *mutex);
/* This will unlock a mutex. */
void pgpl_mutex_unlock(PGPL_Mutex *mutex);
#ifdef __cplusplus
}
#endif
#endif

33
include/pgpl/timer.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef PGPL_TIMER_H
#define PGPL_TIMER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* PGPL_Timer was never designed with accuracy in mind. It just serves as an
* easy way to prevent busy wait loops in a cross-platform manner. */
/* The PGPL_Timer type contains all info needed by the pgpl_timer functions. */
typedef struct PGPL_Timer PGPL_Timer;
/* This creates a new PGPL_Timer. */
PGPL_Timer *pgpl_timer_create(void);
/* This gets the time in milliseconds since the last time it was measured. */
uint32_t pgpl_timer_get_delta(PGPL_Timer *timer);
/* This destroys a PGPL_Timer */
void pgpl_timer_destroy(PGPL_Timer *timer);
/* This sleeps for the given amount of milliseconds. This function is not
* guaranteed to be 100% accurate. */
void pgpl_timer_sleep(uint32_t milliseconds);
#ifdef __cplusplus
}
#endif
#endif

68
include/pgpl/vector.h Normal file
View file

@ -0,0 +1,68 @@
#ifndef PGPL_VECTOR_H
#define PGPL_VECTOR_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* PGPL_Vector is NOT thread safe. It can be used from multiple threads, but the
* synchronization is up to the user. */
/* Contents of the PGPL_Vector struct should not be accessed directly. */
typedef struct PGPL_Vector PGPL_Vector;
/* Creates a new Vector which can then store data with the given data_size. */
PGPL_Vector *pgpl_vector_create(uint32_t data_size);
/* This destroys a vector created by pgpl_vector_create. */
void pgpl_vector_destroy(PGPL_Vector *vector);
/* Pushes data of the vectors data_size onto the back of the vector. */
void pgpl_vector_push_back(PGPL_Vector *vector, void *data);
/* Pushes data of the vectors data_size onto the front of the vector. This is
* slower than pushing it onto the back. */
void pgpl_vector_push_front(PGPL_Vector *vector, void *data);
/* Pops data of the vectors data_size from the back of the vector. Do not free
* the returned pointer. The memory becomes invalid after running another pop or
* delete on the array. */
void *pgpl_vector_pop_back(PGPL_Vector *vector);
/* Pops data of the vectors data_size from the back of the vector. Do not free
* the returned pointer. Slower than poping from the back. The memory becomes
* invalid after running another pop or delete on the array. */
void *pgpl_vector_pop_front(PGPL_Vector *vector);
/* Returns the top entry on the back of the vector. The returned pointer points
* to data inside of the vector, and may be used to modify the entry's content.
* Do not free the returned pointer */
void *pgpl_vector_peek_back(PGPL_Vector *vector);
/* Returns the top entry on the front of the vector. The returned pointer points
* to data inside of the vector, and may be used to modify the entry's content.
* Do not free the returned pointer */
void *pgpl_vector_peek_front(PGPL_Vector *vector);
/* Deletes an index from the vector. The returned pointer should not be freed.
* The memory is invalid after running another pop or delete on the array. */
void *pgpl_vector_delete_index(PGPL_Vector *vector, uint32_t index);
/* Inserts data of the vectors data_size after the given index. */
void pgpl_vector_insert_after_index(PGPL_Vector *vector, uint32_t index,
void *data);
/* Returns a pointer to the data at the given index. You may modify the contents
* of this memory, and this will reflect in the vector itself. */
void *pgpl_vector_get_index(PGPL_Vector *vector, uint32_t index);
/* Returns the length of the vector. */
uint32_t pgpl_vector_get_length(PGPL_Vector *vector);
#ifdef __cplusplus
}
#endif
#endif

114
include/pgpl/window.h Normal file
View file

@ -0,0 +1,114 @@
#ifndef PGPL_WINDOW_H
#define PGPL_WINDOW_H
#include <pgpl/render.h>
#include <pgpl/window/predef.h>
#include <pgpl/window/thread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Mouse button event enum. Goes from 1-5. */
typedef enum PGPL_WindowMouseButton {
PGPL_WINDOW_MOUSE_BUTTON_LEFT = 1,
PGPL_WINDOW_MOUSE_BUTTON_MIDDLE,
PGPL_WINDOW_MOUSE_BUTTON_RIGHT,
PGPL_WINDOW_MOUSE_BUTTON_SCROLL_UP,
PGPL_WINDOW_MOUSE_BUTTON_SCROLL_DOWN
} PGPL_WindowMouseButton;
/* Creates a new Window with the given parameters. Do not call free on the
* returned object manually. */
PGPL_Window *pgpl_window_create(const char *title, uint32_t width,
uint32_t height, int32_t x, int32_t y);
/* Destroys the window and frees all its resources. Does not free rendering
* objects. */
void pgpl_window_destroy(PGPL_Window *window);
/* Makes the window visible. */
void pgpl_window_show(PGPL_Window *window);
/* Makes the window invisible. */
void pgpl_window_hide(PGPL_Window *window);
/* Sets a new title for the window. */
void pgpl_window_set_title(PGPL_Window *window, const char *title);
/* Returns the current title of the window. Note that the returned pointer is
* only valid during the windows existance. Changing the title may also change
* what the returned string points to. Do not call free on the
* returned object manually. */
const char *pgpl_window_get_title(PGPL_Window *window);
/* Returns the windows size in the passed pointers. The width and height
* pointers are allowed to be NULL. */
void pgpl_window_get_size(PGPL_Window *window, uint32_t *width,
uint32_t *height);
/* Changes the windows size to the passed width and height */
void pgpl_window_set_size(PGPL_Window *window, uint32_t width, uint32_t height);
/* Returns the windows position in the passed pointers. The x and y pointers are
* allowed to be NULL. */
void pgpl_window_get_position(PGPL_Window *window, int32_t *x, int32_t *y);
/* Changes the windows position to the passed x and y */
void pgpl_window_set_position(PGPL_Window *window, int32_t x, int32_t y);
/* Sets the rendering scale of the window. */
void pgpl_window_set_scale(PGPL_Window *window, double scale);
/* Gets the rendering scale of the window. */
double pgpl_window_get_scale(PGPL_Window *window);
/* This makes the window always display above the parent window. On Windows this
* reparents the window without removing it's borders, so that it still looks
* like a window. On X11 this works just like the respective X11 function. The
* parent pointer must either be of type HWND (on Windows) or of type Window *
* (on X11). */
void pgpl_window_set_transient(PGPL_Window *window, void *parent);
/* This reparents the window to the parent window. On Windows this also removes
* the childs windows borders. The parent pointer must either be of type HWND
* (on Windows) or of type Window * (on X11). */
void pgpl_window_reparent_to(PGPL_Window *window, void *parent);
/* This gets you the raw Window handle. This will be of type HWND (on Windows)
* or of type Window * (on X11). */
void *pgpl_window_get_raw_window(PGPL_Window *window);
/* This fetches all events from the window into an internal queue, and returns
* back data of the first event found. */
PGPL_WindowEventType pgpl_window_fetch_event(PGPL_Window *window,
PGPL_WindowEventData *event_data);
/* This creates a new window event and puts it into the internal queue. */
void pgpl_window_create_event(PGPL_Window *window,
PGPL_WindowEventType event_type,
PGPL_WindowEventData *event_data);
/* This starts a render on a window, and clears it with the given color. Within
* any given program, you can only have one renderer at a time because of
* OpenGL. Any new calls to this function will block until the rendering is
* stopped.
*
* It is recommended to only call this at the beginning of a render event
* on a window, and then finish it at the end of a render event. It is however
* allowed to start a render at any time.
*
* If you need to clean up any rendering resources upon program exit, you are
* allowed to do so without starting a new render. All OpenGL objects are freed
* upon window destruction. */
PGPL_Renderer *pgpl_window_start_render(PGPL_Window *window, PGPL_Color color);
/* This finishes a render, and displays the rendered buffer on the window. See
* the pgpl_window_start_render function for more information. */
void pgpl_window_finish_render(PGPL_Window *window, PGPL_Renderer *renderer);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,50 @@
#ifndef PGPL_WINDOW_PREDEF_H
#define PGPL_WINDOW_PREDEF_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* PGPL_WindowThread type. Contains all the data that is needed by the thread
* loop and a PGPL_Window. None of its members should be accessed directly. */
typedef struct PGPL_WindowThread PGPL_WindowThread;
/* PGPL_Window type. This contains all of the data associated with a window.
* None of its members should be accessed directly. */
typedef struct PGPL_Window PGPL_Window;
/* This is an input event which is returned on PGPL_WINDOW_EVENT_KEY_* and
* PGPL_WINDOW_EVENT_MOUSE_* events. */
typedef struct PGPL_WindowInputEvent {
uint32_t key;
int32_t x;
int32_t y;
} PGPL_WindowInputEvent;
/* This is the event data type, it allows you to access extended information for
* certain window events. */
typedef union PGPL_WindowEventData {
PGPL_WindowInputEvent input_event;
} PGPL_WindowEventData;
/* This is an enum containing all kinds of window events. Further details can be
* read from the PGPL_WindowEventData type. */
typedef enum PGPL_WindowEventType {
PGPL_WINDOW_EVENT_NONE,
PGPL_WINDOW_EVENT_RENDER_REQUEST,
PGPL_WINDOW_EVENT_KEY_PRESS,
PGPL_WINDOW_EVENT_KEY_RELEASE,
PGPL_WINDOW_EVENT_MOUSE_PRESS,
PGPL_WINDOW_EVENT_MOUSE_RELEASE,
PGPL_WINDOW_EVENT_MOUSE_MOVE,
PGPL_WINDOW_EVENT_CLOSE,
PGPL_WINDOW_EVENT_ERROR
} PGPL_WindowEventType;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,104 @@
#ifndef PGPL_WINDOW_THREAD_H
#define PGPL_WINDOW_THREAD_H
#include <pgpl/window/predef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* This creates a new thread loop, in which a window is also created. The first
* five parameters are shared with the non threaded counterpart. The event_loop
* function is called whenever there is a window event. The user_data parameter
* can be any custom pointer to anything that might be needed inside of the
* event_loop. If the user_data is not needed it can also be NULL.
*
* Returning false from the event_loop will close the window.
*/
PGPL_WindowThread *pgpl_window_thread_create(
const char *title, uint32_t width, uint32_t height, int32_t x, int32_t y,
bool (*event_loop)(PGPL_Window *window, PGPL_WindowEventType event,
PGPL_WindowEventData *event_data, void *user_data),
void *user_data);
/* This exits the thread loop that is running in the background. It also frees
* all resources that were created for this thread, including the Window that
* was created in the thread. */
void pgpl_window_thread_destroy(PGPL_WindowThread *window_thread);
/* Threaded version of pgpl_window_show, see pgpl_window_show for more
* information. */
void pgpl_window_thread_show(PGPL_WindowThread *window_thread);
/* Threaded version of pgpl_window_hide, see pgpl_window_hide for more
* information. */
void pgpl_window_thread_hide(PGPL_WindowThread *window_thread);
/* Threaded version of pgpl_window_set_title, see pgpl_window_set_title for more
* information. */
void pgpl_window_thread_set_title(PGPL_WindowThread *window_thread,
const char *title);
/* Threaded version of pgpl_window_get_title, see pgpl_window_get_title for more
* information. */
const char *pgpl_window_thread_get_title(PGPL_WindowThread *window_thread);
/* Threaded version of pgpl_window_get_size, see pgpl_window_get_size for more
* information. */
void pgpl_window_thread_get_size(PGPL_WindowThread *window_thread,
uint32_t *width, uint32_t *height);
/* Threaded version of pgpl_window_set_size, see pgpl_window_set_size for more
* information. */
void pgpl_window_thread_set_size(PGPL_WindowThread *window_thread,
uint32_t width, uint32_t height);
/* Threaded version of pgpl_window_get_position, see pgpl_window_get_position
* for more information. */
void pgpl_window_thread_get_position(PGPL_WindowThread *window_thread,
int32_t *x, int32_t *y);
/* Threaded version of pgpl_window_set_position, see pgpl_window_set_position
* for more information. */
void pgpl_window_thread_set_position(PGPL_WindowThread *window_thread,
int32_t x, int32_t y);
/* Threaded version of pgpl_window_get_scale, see pgpl_window_get_scale for more
* information. */
double pgpl_window_thread_get_scale(PGPL_WindowThread *window_thread);
/* Threaded version of pgpl_window_set_scale, see pgpl_window_set_scale for more
* information. */
void pgpl_window_thread_set_scale(PGPL_WindowThread *window_thread,
double scale);
/* Threaded version of pgpl_window_create_event, see pgpl_window_create_event
* for more information. */
void pgpl_window_thread_create_event(PGPL_WindowThread *window_thread,
PGPL_WindowEventType event_type,
PGPL_WindowEventData *event_data);
/* Threaded version of pgpl_window_set_transient, see pgpl_window_set_transient
* for more information. */
void pgpl_window_thread_set_transient(PGPL_WindowThread *window_thread,
void *parent);
/* Threaded version of pgpl_window_reparent_to, see pgpl_window_reparent_to for
* more information. */
void pgpl_window_thread_reparent_to(PGPL_WindowThread *window_thread,
void *parent);
/* Threaded version of pgpl_window_get_raw_window, see
* pgpl_window_get_raw_window for more information. */
void *pgpl_window_thread_get_raw_window(PGPL_WindowThread *window_thread);
/* This function halts until the window_thread is destroyed. This function only
* works once per window_thread. */
void pgpl_window_thread_await_destruction(PGPL_WindowThread *window_thread);
#ifdef __cplusplus
}
#endif
#endif

7988
include/stb/stb_image.h Normal file

File diff suppressed because it is too large Load diff

5079
include/stb/stb_truetype.h Normal file

File diff suppressed because it is too large Load diff