Skip to content

Instantly share code, notes, and snippets.

@kpcftsz
Last active May 22, 2023 19:19
Show Gist options
  • Save kpcftsz/ea7b7b9301c3ee4f5800c8be3428908e to your computer and use it in GitHub Desktop.
Save kpcftsz/ea7b7b9301c3ee4f5800c8be3428908e to your computer and use it in GitHub Desktop.
ldb 1.2 - Info and Source

# Ludum Dare Boilerplate

ldb is a very small single-file framework for game jams. It provides the bare necessities and nothing else.
Think QBASIC and BGI.

This is what a simple project looks like:

#define USE_LDB
#include "ldb.h"

static const uint W = 1024, H = 768;
static struct ldb_bitmap *screen;

static void init(void) {
    screen = ldb_bitmap_create(W, H);
    ldb_set_screen(screen);
}

static void update(void) {
    // ...
}

static void render(void) {
    // ...
}

static void destroy(void) {
    ldb_bitmap_delete(screen);
}

int main(void) {
    return ldb_exec(&(struct ldb_game){init, update, render, destroy}, W, H, FALSE);
}

"Oh, but it isn't versatile!"
You're not versatile, just draw pixels dude

License

        DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 
                    Version 2, December 2004 

 Copyright (C) 2019 KP Games

 Everyone is permitted to copy and distribute verbatim or modified 
 copies of this license document, and changing it is allowed as long 
 as the name is changed. 

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 

  0. You just DO WHAT THE FUCK YOU WANT TO.
(Most of "ldb.h" is kinda self-documenting so I'm only gonna use this to further clarify stuff)
BUILDING:
- Requires SDL2 and stb_image
- Use C99
- GCC preferred, not sure about MSVC
AVAILABLE TYPES:
- int8, uint8
- int16, uint16
- int32, uint32
- int64, uint64
- uchar (uint8)
- ushort (uint16)
- uint (uint32)
- ulong (uint64)
- byte (uint8)
- boolean (uses TRUE/FALSE macros)
GRAPHICS FUNCTIONS:
- ldb_draw() - draws a bitmap to another surface bitmap at a certain location
(dest: destination/surface bitmap,
src: source bitmap,
x, y: location to draw to)
- ldb_draw_s() - draws a *stretched* bitmap to another surface bitmap at a certain location
(dest: destination/surface bitmap,
src: source bitmap,
x, y: location to draw to,
width, height: size to stretch the image to)
- ldb_draw_crop() - similar to the first function, but only uses a specific part of an image
(dest: destination/surface bitmap,
src: source bitmap,
crop_x, crop_y: left/top part of the image,
crop_width, crop_height: right/bottom part of the time,
x, y: location to draw to)
- ldb_draw_crop_s() - similar to the second function, but only uses a specific part of an image
(dest: destination/surface bitmap,
src: source bitmap,
crop_x, crop_y: left/top part of the image,
crop_width, crop_height: right/bottom part of the time,
x, y: location to draw to,
width, height: size to stretch the image to)
Yeah you could argue crop_[x/y/width/height] could be named differently but I can't be fucked to change it
- ldb_draw_line() - draws a line y'know
(dest: destination/surface bitmap,
x_start, y_start: point to start the line,
x_end, y_end: point to end the line,
color: what color the line will be)
- ldb_clear() - clears the screen
(dest: destination/surface bitmap,
color: color to clear it)
NOTE: Colors in ldb are represented in unsigned integers, with each byte representing an ARGB component.
INPUT FUNCTIONS:
- ldb_[key/button]_reset() - basically "turns off" a key, good for preventing repeats in menus
(key/button: the key/button to reset)
- ldb_key_grouped() - test for a certain amount of keys being held out of a group of keys, useful for
key combinations and other things.
(min_keys: minimum amount of keys that have to be held to return TRUE,
num_keys: total number of keys to be tested)
- ldb_cursor_pos() - returns mouse cursor stored in a 2D vector
SETUP:
- Use ldb_game struct, it contains pointers to 4 functions:
init(), update(), render(), destroy()
You should get the idea
SETUP FUNCTIONS:
- ldb_exec() - start up the game loop
(game: read above,
window_width: horizontal length of the window,
window_height: vertical length of the window,
fullscreen: y'know)
MISC NOTES:
- ldb_key/ldb_button were ripped from SDL2 with the useless stuff taken out,
- I don't recommend using the VEC() macro but if you can't be assed to manually pass in the x/y
components of a vector to a function that doesn't take in a vector, I guess it does the trick
- The screen doesn't clear by default, make sure to do that in your render()
/* LDB: Ludum Dare Boilerplate */
/* Written by KPCFTSZ for LD48 */
#ifndef _ldb_h_
#define _ldb_h_
#ifdef __cplusplus
extern "C"
{
#endif
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned short uint16;
typedef signed short int16;
typedef unsigned int uint32;
typedef signed int int32;
typedef unsigned long long uint64;
typedef signed long long int64;
typedef uint8 uchar;
typedef uint16 ushort;
typedef uint32 uint;
typedef uint64 ulong;
typedef uint8 byte;
#undef TRUE
#undef FALSE
typedef enum { FALSE, TRUE } boolean;
/* - GRAPHICS - */
struct ldb_bitmap
{
uint width;
uint height;
uint data[];
};
extern struct ldb_bitmap *ldb_bitmap_create(uint width, uint height);
extern struct ldb_bitmap *ldb_bitmap_load(const char *path);
extern void ldb_bitmap_delete(struct ldb_bitmap *bitmap);
//
extern void ldb_draw(struct ldb_bitmap *dest, const struct ldb_bitmap *src, float x, float y);
extern void ldb_draw_s(struct ldb_bitmap *dest, const struct ldb_bitmap *src, float x, float y, float width, float height);
extern void ldb_draw_crop(struct ldb_bitmap *dest, const struct ldb_bitmap *src, uint crop_x, uint crop_y, uint crop_width, uint crop_height, float x, float y);
extern void ldb_draw_crop_s(struct ldb_bitmap *dest, const struct ldb_bitmap *src, uint crop_x, uint crop_y, uint crop_width, uint crop_height, float x, float y, float width, float height);
extern void ldb_draw_line(struct ldb_bitmap *dest, float x_start, float y_start, float x_end, float y_end, uint color);
extern void ldb_clear(struct ldb_bitmap *dest, uint color);
/* - MATH - */
#define LDB_PI 3.141593f
#define LDB_E 2.718281f
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
extern float ldb_to_radians(float degrees);
extern float ldb_to_degrees(float radians);
extern float ldb_fast_sqrt(float value);
extern uint ldb_random(void);
extern void ldb_seed(uint seed);
extern uint ldb_blend(uint color, uint other);
//
struct ldb_vec2
{
float x, y;
};
extern float ldb_vec2_length(const struct ldb_vec2 *vec2);
extern float ldb_vec2_dot(const struct ldb_vec2 *vec2, const struct ldb_vec2 *other);
extern float ldb_vec2_cross(const struct ldb_vec2 *vec2, const struct ldb_vec2 *other);
extern boolean ldb_vec2_equals(const struct ldb_vec2 *vec2, const struct ldb_vec2 *other);
extern struct ldb_vec2 ldb_vec2_rotate(const struct ldb_vec2 *vec2, float degrees);
#define VEC(v) (v.x), (v.y)
/* - INPUT - */
enum ldb_key
{
LDB_KEY_UNKNOWN = 0,
/* Alphabet/Numbers */
LDB_KEY_A = 4, LDB_KEY_B = 5, LDB_KEY_C = 6, LDB_KEY_D = 7, LDB_KEY_E = 8, LDB_KEY_F = 9,
LDB_KEY_G = 10, LDB_KEY_H = 11, LDB_KEY_I = 12, LDB_KEY_J = 13, LDB_KEY_K = 14, LDB_KEY_L = 15,
LDB_KEY_M = 16, LDB_KEY_N = 17, LDB_KEY_O = 18, LDB_KEY_P = 19, LDB_KEY_Q = 20, LDB_KEY_R = 21,
LDB_KEY_S = 22, LDB_KEY_T = 23, LDB_KEY_U = 24, LDB_KEY_V = 25, LDB_KEY_W = 26, LDB_KEY_X = 27,
LDB_KEY_Y = 28, LDB_KEY_Z = 29, LDB_KEY_1 = 30, LDB_KEY_2 = 31, LDB_KEY_3 = 32, LDB_KEY_4 = 33,
LDB_KEY_5 = 34, LDB_KEY_6 = 35, LDB_KEY_7 = 36, LDB_KEY_8 = 37, LDB_KEY_9 = 38, LDB_KEY_0 = 39,
/* Formatting */
LDB_KEY_RETURN = 40, LDB_KEY_ESCAPE = 41, LDB_KEY_BACKSPACE = 42, LDB_KEY_TAB = 43, LDB_KEY_SPACE = 44, LDB_KEY_MINUS = 45,
LDB_KEY_EQUALS = 46, LDB_KEY_LEFTBRACKET = 47, LDB_KEY_RIGHTBRACKET = 48, LDB_KEY_BACKSLASH = 49, LDB_KEY_NONUSHASH = 50, LDB_KEY_SEMICOLON = 51,
LDB_KEY_APOSTROPHE = 52, LDB_KEY_GRAVE = 53, LDB_KEY_COMMA = 54, LDB_KEY_PERIOD = 55, LDB_KEY_SLASH = 56, LDB_KEY_CAPSLOCK = 57,
/* Function */
LDB_KEY_F1 = 58, LDB_KEY_F2 = 59, LDB_KEY_F3 = 60, LDB_KEY_F4 = 61, LDB_KEY_F5 = 62, LDB_KEY_F6 = 63,
LDB_KEY_F7 = 64, LDB_KEY_F8 = 65, LDB_KEY_F9 = 66, LDB_KEY_F10 = 67, LDB_KEY_F11 = 68, LDB_KEY_F12 = 69,
/* Arrow block */
LDB_KEY_INSERT = 73, DB_KEY_HOME = 74, LDB_KEY_PAGEUP = 75, LDB_KEY_DELETE = 76, LDB_KEY_END = 77, LDB_KEY_PAGEDOWN = 78,
LDB_KEY_RIGHT = 79, LDB_KEY_LEFT = 80, LDB_KEY_DOWN = 81, LDB_KEY_UP = 82,
/* Tenkey */
LDB_KEY_KP_DIVIDE = 84, LDB_KEY_KP_MULTIPLY = 85, LDB_KEY_KP_MINUS = 86, LDB_KEY_KP_PLUS = 87, LDB_KEY_KP_ENTER = 88, LDB_KEY_KP_1 = 89,
LDB_KEY_KP_2 = 90, LDB_KEY_KP_3 = 91, LDB_KEY_KP_4 = 92, LDB_KEY_KP_5 = 93, LDB_KEY_KP_6 = 94, LDB_KEY_KP_7 = 95,
LDB_KEY_KP_8 = 96, LDB_KEY_KP_9 = 97, LDB_KEY_KP_0 = 98, LDB_KEY_KP_PERIOD = 99, LDB_KEY_KP_EQUALS = 103,
LDB_KEY_KP_COMMA = 133, LDB_KEY_KP_EQUALSAS400 = 134,
/* Modifiers */
LDB_KEY_LCTRL = 224, LDB_KEY_LSHIFT = 225, LDB_KEY_LALT = 226, LDB_KEY_LGUI = 227, LDB_KEY_RCTRL = 228, LDB_KEY_RSHIFT = 229,
LDB_KEY_RALT = 230, LDB_KEY_RGUI = 231,
/* For use in arrays */
LDB_NUM_KEYS = 256
};
enum ldb_button
{
LDB_BUTTON_UNKNOWN = 0,
/* No fancy gamer mice here, God said 3 buttons */
LDB_BUTTON_LEFT = 1,
LDB_BUTTON_MIDDLE = 2,
LDB_BUTTON_RIGHT = 3,
/* For use in arrays */
LDB_NUM_BUTTONS = 8
};
extern boolean ldb_key_down(enum ldb_key key);
extern void ldb_key_reset(enum ldb_key key);
extern boolean ldb_button_down(enum ldb_button button);
extern void ldb_button_reset(enum ldb_button button);
extern boolean ldb_key_grouped(uint min_keys, uint num_keys, ...);
//
extern struct ldb_vec2 ldb_cursor_pos(void);
/* - SETUP - */
struct ldb_game
{
void (*func_init)(void);
void (*func_update)(void);
void (*func_render)(void);
void (*func_destroy)(void);
};
extern int ldb_exec(struct ldb_game *game, uint window_width, uint window_height, boolean fullscreen);
extern void ldb_set_screen(struct ldb_bitmap *screen);
extern void ldb_quit(void);
#ifdef __cplusplus
}
#endif
#endif /* _ldb_h_ */
/* - IMPLEMENTATION - */
#ifdef USE_LDB
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <math.h>
#include <stdarg.h>
#ifndef STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#endif
#include <stb_image.h>
#include <SDL2/SDL.h>
#ifdef __CYGWIN__
#undef main
#endif
/********************************/
static SDL_Window *ldb__sdl_window;
static SDL_Renderer *ldb__sdl_renderer;
static SDL_Texture *ldb__sdl_framebuffer;
static boolean ldb__key_state[LDB_NUM_KEYS];
static boolean ldb__button_state[LDB_NUM_BUTTONS];
static struct ldb_game *ldb__user_game;
static struct ldb_bitmap *ldb__user_screen;
static int ldb__cursor_x;
static int ldb__cursor_y;
static uint ldb__seed;
static boolean ldb__running = FALSE;
/********************************/
struct ldb_bitmap *ldb_bitmap_create(uint width, uint height)
{
struct ldb_bitmap *bitmap = malloc(sizeof *bitmap + sizeof(uint) * width * height);
bitmap->width = width;
bitmap->height = height;
return bitmap;
}
struct ldb_bitmap *ldb_bitmap_load(const char *path)
{
int width = 0, height = 0;
byte *data = stbi_load(path, &width, &height, NULL, 4);
struct ldb_bitmap *bitmap = ldb_bitmap_create((uint) width, (uint) height);
for (size_t i = 0; i < bitmap->width * bitmap->height; i++)
{
byte c[4];
for (size_t j = 0; j < 4; j++)
c[j] = data[i * 4 + j];
bitmap->data[i] = c[3] << 24 | c[0] << 16 | c[1] << 8 | c[2];
}
stbi_image_free(data);
return bitmap;
}
void ldb_bitmap_delete(struct ldb_bitmap *bitmap)
{
free(bitmap);
bitmap = NULL;
}
/********************************/
void ldb_draw(struct ldb_bitmap *dest, const struct ldb_bitmap *src, float x, float y)
{
for (size_t i = 0; i < src->width; i++)
{
int xp = i + x;
if (xp < 0 || xp >= dest->width) continue;
for (size_t j = 0; j < src->height; j++)
{
int yp = j + y;
if (yp < 0 || yp >= dest->height) continue;
uint *dest_data = &dest->data[xp + yp * dest->width];
*dest_data = ldb_blend(*dest_data, src->data[i + j * src->width]);
}
}
}
void ldb_draw_s(struct ldb_bitmap *dest, const struct ldb_bitmap *src, float x, float y, float width, float height)
{
for (size_t i = 0; i < width; i++)
{
int xp = i + x;
if (xp < 0 || xp >= dest->width) continue;
int xf = i / (width / src->width);
for (size_t j = 0; j < height; j++)
{
int yp = j + y;
if (yp < 0 || yp >= dest->height) continue;
int yf = j / (height / src->height);
uint *dest_data = &dest->data[xp + yp * dest->width];
*dest_data = ldb_blend(*dest_data, src->data[xf + yf * src->width]);
}
}
}
void ldb_draw_crop(struct ldb_bitmap *dest, const struct ldb_bitmap *src, uint crop_x, uint crop_y, uint crop_width, uint crop_height, float x, float y)
{
for (size_t i = 0; i < crop_width; i++)
{
int xp = i + x;
if (xp < 0 || xp >= dest->width) continue;
for (size_t j = 0; j < crop_height; j++)
{
int yp = j + y;
if (yp < 0 || yp >= dest->height) continue;
uint *dest_data = &dest->data[xp + yp * dest->width];
*dest_data = ldb_blend(*dest_data, src->data[i + crop_x + (j + crop_y) * src->width]);
}
}
}
void ldb_draw_crop_s(struct ldb_bitmap *dest, const struct ldb_bitmap *src, uint crop_x, uint crop_y, uint crop_width, uint crop_height, float x, float y, float width, float height)
{
for (size_t i = 0; i < width; i++)
{
int xp = i + x;
if (xp < 0 || xp >= dest->width) continue;
int xf = i / (width / crop_width);
for (size_t j = 0; j < height; j++)
{
int yp = j + y;
if (yp < 0 || yp >= dest->height) continue;
int yf = j / (height / crop_height);
uint *dest_data = &dest->data[xp + yp * dest->width];
*dest_data = ldb_blend(*dest_data, src->data[xf + crop_x + (yf + crop_y) * src->width]);
}
}
}
void ldb_draw_line(struct ldb_bitmap *dest, float x_start, float y_start, float x_end, float y_end, uint color)
{
int x_start_i = (int) x_start, x_end_i = (int) x_end;
int y_start_i = (int) y_start, y_end_i = (int) y_end;
int x_dist = abs(x_end_i - x_start_i), x_dir = x_start_i < x_end_i ? 1 : -1;
int y_dist = abs(y_end_i - y_start_i), y_dir = y_start_i < y_end_i ? 1 : -1;
int err = (x_dist > y_dist ? x_dist : -y_dist) / 2, e = 0;
for (;;)
{
uint *dest_data = &dest->data[x_start_i + y_start_i * dest->width];
if (x_start_i >= 0 && x_start_i < dest->width && y_start_i >= 0 && y_start_i < dest->height)
*dest_data = ldb_blend(*dest_data, color);
if (x_start_i == x_end_i && y_start_i == y_end_i)
break;
e = err;
if (e > -x_dist) err -= y_dist, x_start_i += x_dir;
if (e < y_dist) err += x_dist, y_start_i += y_dir;
}
}
void ldb_clear(struct ldb_bitmap *dest, uint color)
{
for (int i = 0; i < dest->width * dest->height; i++)
dest->data[i] = color;
}
/********************************/
float ldb_vec2_length(const struct ldb_vec2 *vec2)
{
return sqrtf(vec2->x * vec2->x + vec2->y * vec2->y);
}
float ldb_vec2_dot(const struct ldb_vec2 *vec2, const struct ldb_vec2 *other)
{
return vec2->x * other->x + vec2->y * other->y;
}
float ldb_vec2_cross(const struct ldb_vec2 *vec2, const struct ldb_vec2 *other)
{
return vec2->x * other->y - vec2->y * other->x;
}
boolean ldb_vec2_equals(const struct ldb_vec2 *vec2, const struct ldb_vec2 *other)
{
return vec2->x == other->x && vec2->y == other->y;
}
struct ldb_vec2 ldb_vec2_rotate(const struct ldb_vec2 *vec2, float degrees)
{
float in_radians = ldb_to_radians(degrees);
float cosine = cosf(in_radians);
float sine = sinf(in_radians);
struct ldb_vec2 rotated =
{
vec2->x * cosine - vec2->y * sine,
vec2->x * sine + vec2->y * cosine
};
return rotated;
}
/********************************/
float ldb_to_radians(float degrees)
{
return degrees * LDB_PI / 180.0f;
}
float ldb_to_degrees(float radians)
{
return radians * 180.0f / LDB_PI;
}
float ldb_fast_sqrt(float value)
{
uint i = *(uint*) &value;
i += 127 << 23;
i >>= 1;
return *(float*) &i;
}
uint ldb_random(void)
{
ldb__seed = 0x015A4E35 * ldb__seed + 1;
return (ldb__seed >> 16) & 0x7FFF;
}
void ldb_seed(uint seed)
{
ldb__seed = seed;
}
uint ldb_blend(uint color, uint other)
{
uint masks[4] =
{
0xFF000000,
0x00FF00FF,
0xFF00FF00,
0x0000FF00
};
uint a = (other & masks[0]) >> 24;
uint na = 0xFF - a;
uint rb = ((na * (color & masks[1])) + (a * (other & masks[1]))) >> 8;
uint ag = (na * (color & masks[2]) >> 8) + (a * (1 << 24 | ((other & masks[3]) >> 8)));
return (rb & masks[1]) | (ag & masks[2]);
}
/********************************/
boolean ldb_key_down(enum ldb_key key)
{
return ldb__key_state[key];
}
void ldb_key_reset(enum ldb_key key)
{
ldb__key_state[key] = FALSE;
}
boolean ldb_button_down(enum ldb_button button)
{
return ldb__button_state[button];
}
void ldb_button_reset(enum ldb_button button)
{
ldb__button_state[button] = FALSE;
}
boolean ldb_key_grouped(uint min_keys, uint num_keys, ...)
{
va_list args;
uint grouped = 0;
va_start(args, num_keys);
for (size_t i = 0; i < num_keys; i++)
if (ldb_key_down(va_arg(args, enum ldb_key)))
grouped++;
va_end(args);
return grouped >= min_keys;
}
struct ldb_vec2 ldb_cursor_pos(void)
{
struct ldb_vec2 cursor =
{
(float) ldb__cursor_x,
(float) ldb__cursor_y
};
if (ldb__user_screen)
{
int width = 0, height = 0;
SDL_GetWindowSize(ldb__sdl_window, &width, &height);
cursor.x /= width / (float) ldb__user_screen->width;
cursor.y /= height / (float) ldb__user_screen->height;
}
return cursor;
}
/********************************/
int ldb_exec(struct ldb_game *game, uint window_width, uint window_height, boolean fullscreen)
{
ldb__running = TRUE;
if (SDL_Init(SDL_INIT_EVERYTHING))
{
fprintf(stderr, "SDL initialization failed: %s\n", SDL_GetError());
return 1;
}
ldb__sdl_window = SDL_CreateWindow(
"Game",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
window_width,
window_height,
fullscreen
);
if (!ldb__sdl_window)
{
fprintf(stderr, "SDL window creation failed: %s\n", SDL_GetError());
ldb_quit();
return 1;
}
ldb__sdl_renderer = SDL_CreateRenderer(ldb__sdl_window, -1, SDL_RENDERER_ACCELERATED);
if (!ldb__sdl_renderer)
{
fprintf(stderr, "SDL renderer creation failed: %s\n", SDL_GetError());
ldb_quit();
return 1;
}
ldb__user_game = game;
ldb__user_game->func_init();
ldb__sdl_framebuffer = SDL_CreateTexture(
ldb__sdl_renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
ldb__user_screen ? ldb__user_screen->width : window_width,
ldb__user_screen ? ldb__user_screen->height : window_height
);
if (!ldb__sdl_framebuffer)
{
fprintf(stderr, "SDL framebuffer creation failed: %s\n", SDL_GetError());
ldb_quit();
return 1;
}
double time_delta = 1.0 / 60.0;
double time_accumulator = 0.0;
while (ldb__running)
{
double time_iteration = 0.0;
double time_present = SDL_GetTicks() / 1000.0;
SDL_Event e;
while (SDL_PollEvent(&e))
{
switch (e.type)
{
case SDL_QUIT:
ldb__running = FALSE;
break;
case SDL_MOUSEBUTTONDOWN:
ldb__button_state[e.button.button] = TRUE;
break;
case SDL_MOUSEBUTTONUP:
ldb__button_state[e.button.button] = FALSE;
break;
case SDL_KEYDOWN:
if (e.key.repeat == 0)
ldb__key_state[e.key.keysym.scancode] = TRUE;
break;
case SDL_KEYUP:
ldb__key_state[e.key.keysym.scancode] = FALSE;
break;
}
}
SDL_GetMouseState(&ldb__cursor_x, &ldb__cursor_y);
while (time_accumulator >= time_delta)
{
game->func_update();
time_accumulator -= time_delta;
time_iteration += time_delta;
}
game->func_render();
if (ldb__user_screen)
SDL_UpdateTexture(ldb__sdl_framebuffer, NULL, &ldb__user_screen->data[0], ldb__user_screen->width * 4);
SDL_RenderCopy(ldb__sdl_renderer, ldb__sdl_framebuffer, NULL, NULL);
SDL_RenderPresent(ldb__sdl_renderer);
time_accumulator += SDL_GetTicks() / 1000.0 - time_present;
}
ldb__running = FALSE;
ldb_quit();
return 0;
}
void ldb_set_screen(struct ldb_bitmap *screen)
{
ldb__user_screen = screen;
}
void ldb_quit(void)
{
if (ldb__running)
{
ldb__running = FALSE;
}
else
{
if (ldb__user_game)
ldb__user_game->func_destroy();
if (ldb__sdl_framebuffer)
SDL_DestroyTexture(ldb__sdl_framebuffer);
if (ldb__sdl_renderer)
SDL_DestroyRenderer(ldb__sdl_renderer);
if (ldb__sdl_window)
SDL_DestroyWindow(ldb__sdl_window);
SDL_Quit();
}
}
#endif /* USE_LDB */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment