#include #include #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 create 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) { printf("could not create renderer! sdl error: %s\n", SDL_GetError()); 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: ; }