201 lines
4.1 KiB
C
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;
|
|
} |