crocparty/sdl_host.c
2024-02-24 19:00:23 -08:00

147 lines
3.6 KiB
C

#include <stdio.h>
#include <stdbool.h>
#include "sdl_host.h"
#include "vendored/sdl/include/SDL.h"
#include "game.h"
#include "device.h"
void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h);
void sdl_host_loop();
SDL_Window* sdl_host_window;
SDL_Renderer* sdl_host_renderer;
SDL_Texture* sdl_host_target;
int sdl_host_main(void) {
int result = 0;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) {
printf("could not initialize SDL! sdl error: %s\n", SDL_GetError());
result = 1;
goto sdl_done;
}
uint32_t window_w, window_h;
sdl_host_suggest_dimensions(&window_w, &window_h);
// create window
sdl_host_window = SDL_CreateWindow(
"Croc Party!",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
(int) window_w, (int) window_h,
SDL_WINDOW_SHOWN
);
if (sdl_host_window == NULL) {
printf("could not load window! sdl error: %s\n", SDL_GetError());
result = 1;
goto window_done;
}
// create renderer
sdl_host_renderer = SDL_CreateRenderer(sdl_host_window, -1, 0);
if (sdl_host_renderer == NULL) {
result = 1;
goto renderer_done;
}
// create target
sdl_host_target = SDL_CreateTexture(
sdl_host_renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING,
DEVICE_W, DEVICE_H
);
if (sdl_host_target == NULL) {
printf("could not create target texture! sdl error: %s\n", SDL_GetError());
result = 1;
goto target_done;
}
sdl_host_loop();
// renderer_cleanup:
SDL_DestroyRenderer(sdl_host_renderer);
sdl_host_renderer = NULL;
renderer_done: ;
// target_cleanup:
SDL_DestroyTexture(sdl_host_target);
sdl_host_target = NULL;
target_done: ;
// window_cleanup:
SDL_DestroyWindow(sdl_host_window);
sdl_host_window = NULL;
window_done: ;
// sdl_cleanup:
SDL_Quit();
sdl_done: ;
return result;
}
void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h) {
SDL_DisplayMode dm;
if (SDL_GetCurrentDisplayMode(0, &dm) != 0) {
printf("could not get current display mode: %s\n", SDL_GetError());
dm.w = 0;
dm.h = 0;
}
for (int scalar = 5; scalar >= 1; scalar--) {
uint32_t w = DEVICE_W * scalar;
uint32_t h = DEVICE_H * scalar;
if (w <= dm.w && h <= dm.h) {
*window_w = w;
*window_h = h;
return;
}
}
for (int scalar = 1; scalar <= 5; scalar++) {
uint32_t w = DEVICE_W / scalar;
uint32_t h = DEVICE_H / scalar;
if (w <= dm.w && h <= dm.h) {
*window_w = w;
*window_h = h;
return;
}
}
*window_w = DEVICE_W;
*window_h = DEVICE_H;
}
void sdl_host_loop() {
uint32_t ticks_per_frame = 1000/60;
game_init();
while (true) {
uint32_t frame_start = SDL_GetTicks();
uint32_t next_frame_start = frame_start + ticks_per_frame;
SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT) { goto quit; }
}
// trigger game logic
game_update();
game_draw();
SDL_UpdateTexture(sdl_host_target, NULL, &device_pixels, sizeof(device_pixels[0]));
SDL_RenderClear(sdl_host_renderer);
SDL_RenderCopy(sdl_host_renderer, sdl_host_target, NULL, NULL);
SDL_RenderPresent(sdl_host_renderer);
// hold off until next frame
while (SDL_GetTicks() < next_frame_start) {
SDL_Delay(1);
}
}
quit: ;
}