Files
dangerzone/src/engine/engine_init.c
T
2026-10-06 12:07:12 +02:00

201 lines
4.1 KiB
C

#include <dangerzone/engine.h>
#include "internal/engine_internal.h"
#include "internal/util/error.h"
bool
engine_sdl_init_state(
engine_sdl_state_t **state,
uint32_t window_width,
uint32_t window_height,
const char window_name[]
) {
*state = (engine_sdl_state_t *)
malloc(sizeof(engine_sdl_state_t));
if (*state == NULL) {
eprintf("failed to initialize engine_sdl_state");
return RCODE_FAILURE;
}
(*state)->width = window_width;
(*state)->height = window_height;
strncpy(
(*state)->window_name, window_name,
WINDOW_NAME_MAX_LENGTH - 1
);
(*state)->window_name[WINDOW_NAME_MAX_LENGTH - 1] = '\0';
return RCODE_SUCCESS;
}
bool
engine_sdl_init_root()
{
if (!SDL_Init(SDL_INIT_VIDEO)) {
eprintf("SDL_Init failed! %s\n", SDL_GetError());
return RCODE_FAILURE;
} else {
return RCODE_SUCCESS;
}
}
bool
engine_sdl_init_window(
engine_sdl_state_t* state
) {
state->window = SDL_CreateWindow(
state->window_name,
state->width, state->height, 0
);
if (state->window == NULL) {
eprintf("SDL_CreateWindow failed! %s\n", SDL_GetError());
SDL_Quit();
return RCODE_FAILURE;
}
return RCODE_SUCCESS;
}
bool
engine_sdl_init_renderer(
engine_sdl_state_t *state
) {
state->renderer = SDL_CreateRenderer(state->window, NULL);
if (state->renderer == NULL) {
eprintf("SDL_CreateRenderer failed! %s\n", SDL_GetError());
SDL_DestroyWindow(state->window);
SDL_Quit();
return RCODE_FAILURE;
}
// enable VSync
if (!SDL_SetRenderVSync(state->renderer, 1)) {
eprintf("SDL_SetRenderVSync failed: %s\n", SDL_GetError());
}
return RCODE_SUCCESS;
}
bool
engine_sdl_init_texture(
engine_sdl_state_t *state
) {
state->texture = SDL_CreateTexture(
state->renderer, SDL_PIXELFORMAT_XRGB8888,
SDL_TEXTUREACCESS_STREAMING,
state->width, state->height
);
if (state->texture == NULL) {
eprintf("SDL_CreateTexture failed! %s\n", SDL_GetError());
SDL_DestroyWindow(state->window);
SDL_DestroyRenderer(state->renderer);
SDL_Quit();
return RCODE_FAILURE;
}
return RCODE_SUCCESS;
}
engine_sdl_state_t*
engine_sdl_init(
uint32_t window_width,
uint32_t window_height,
const char window_name[]
) {
engine_sdl_state_t *state;
if (!engine_sdl_init_state(
&state,
window_width,
window_height,
window_name
) ||
!engine_sdl_init_root() ||
!engine_sdl_init_window(state) ||
!engine_sdl_init_renderer(state) ||
!engine_sdl_init_texture(state)
) {
return NULL;
}
return state;
}
/**
* only call intentinally, not when engine_sdl_init fails
* -> it cleans up after itself already
*/
void
engine_sdl_destroy(
engine_sdl_state_t *state
) {
SDL_DestroyTexture(state->texture);
SDL_DestroyRenderer(state->renderer);
SDL_DestroyWindow(state->window);
SDL_Quit();
free(state);
}
bool
engine_init(
uint32_t window_width,
uint32_t window_height,
const char window_name[],
void (*engine_poll_events)(void),
void (*engine_update_framebuffer)(void)
) {
internal_state = (engine_internal_state_t *)
malloc(sizeof(engine_internal_state_t));
if (internal_state == NULL) {
return RCODE_FAILURE;
}
game_state = (game_state_t *)
malloc(sizeof(game_state_t));
if (game_state == NULL) {
free(internal_state);
return RCODE_FAILURE;
}
game_state->framebuffer = (uint32_t *)
malloc(sizeof(uint32_t) * window_width * window_height);
if (game_state->framebuffer == NULL) {
free(internal_state);
free(game_state);
return RCODE_FAILURE;
}
internal_state->engine_poll_events
= engine_poll_events;
internal_state->engine_update_framebuffer
= engine_update_framebuffer;
internal_state->sdl_state = engine_sdl_init(
window_width,
window_height,
window_name
);
if (internal_state->sdl_state == NULL) {
free(internal_state);
free(game_state->framebuffer);
free(game_state);
return RCODE_FAILURE;
}
game_state->is_running = true;
game_state->framebuffer_dirty = true;
game_state->dirty_rect = (SDL_Rect) {
.x = 0,
.y = 0,
.w = game_state->width,
.h = game_state->height
};
game_state->width = internal_state->sdl_state->width;
game_state->height = internal_state->sdl_state->height;
return RCODE_SUCCESS;
}