#include #define SDL_MAIN_USE_CALLBACKS #include #include "game.h" static yeti_t yeti; static u16 backbuffer[YETI_FRAMEBUFFER_WIDTH * YETI_FRAMEBUFFER_HEIGHT]; static SDL_Window *window = NULL; static SDL_Renderer *renderer = NULL; static SDL_Texture *texture = NULL; static SDL_Surface *front = NULL; static SDL_Surface *back = NULL; static void die(const char *fmt, ...) { static char error[1024]; va_list ap; va_start(ap, fmt); SDL_vsnprintf(error, sizeof(error), fmt, ap); va_end(ap); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, error); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", error, NULL); exit(1); } SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { Uint32 format; if (!SDL_Init(SDL_INIT_VIDEO)) die(SDL_GetError()); window = SDL_CreateWindow(YETI_STR_CAPTION, YETI_FRAMEBUFFER_WIDTH, YETI_FRAMEBUFFER_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED); if (!window) die(SDL_GetError()); SDL_SetWindowMinimumSize(window, YETI_FRAMEBUFFER_WIDTH, YETI_FRAMEBUFFER_HEIGHT); renderer = SDL_CreateRenderer(window, NULL); if (!renderer) die(SDL_GetError()); SDL_SetRenderVSync(renderer, 1); SDL_SetRenderLogicalPresentation(renderer, YETI_FRAMEBUFFER_WIDTH, YETI_FRAMEBUFFER_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); back = SDL_CreateSurfaceFrom(YETI_FRAMEBUFFER_WIDTH, YETI_FRAMEBUFFER_HEIGHT, SDL_PIXELFORMAT_XBGR1555, backbuffer, YETI_FRAMEBUFFER_WIDTH * sizeof(u16)); if (!back) die(SDL_GetError()); format = SDL_GetWindowPixelFormat(window); front = SDL_CreateSurface(YETI_FRAMEBUFFER_WIDTH, YETI_FRAMEBUFFER_HEIGHT, format); if (!front) die(SDL_GetError()); texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STREAMING, YETI_FRAMEBUFFER_WIDTH, YETI_FRAMEBUFFER_HEIGHT); if (!texture) die(SDL_GetError()); SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST); yeti_init(&yeti, backbuffer, backbuffer, textures, palette); yeti_init_lua(&yeti, YETI_GAMMA); game_init(&yeti); return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppIterate(void *appstate) { const bool *keys = SDL_GetKeyboardState(NULL); yeti.keyboard.state.up = keys[SDL_SCANCODE_UP]; yeti.keyboard.state.down = keys[SDL_SCANCODE_DOWN]; yeti.keyboard.state.left = keys[SDL_SCANCODE_LEFT]; yeti.keyboard.state.right = keys[SDL_SCANCODE_RIGHT]; yeti.keyboard.state.a = keys[SDL_SCANCODE_RCTRL]; yeti.keyboard.state.b = keys[SDL_SCANCODE_SPACE]; yeti.keyboard.state.l = keys[SDL_SCANCODE_A]; yeti.keyboard.state.r = keys[SDL_SCANCODE_Z]; yeti.keyboard.state.select = keys[SDL_SCANCODE_ESCAPE]; SDL_FillSurfaceRect(back, NULL, 0); SDL_FillSurfaceRect(front, NULL, 0); game_loop(&yeti); SDL_BlitSurface(back, NULL, front, NULL); SDL_UpdateTexture(texture, NULL, front->pixels, front->pitch); SDL_RenderClear(renderer); SDL_RenderTexture(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { switch (event->type) { case SDL_EVENT_QUIT: return SDL_APP_SUCCESS; } return SDL_APP_CONTINUE; } void SDL_AppQuit(void *appstate, SDL_AppResult result) { if (window) SDL_DestroyWindow(window); if (renderer) SDL_DestroyRenderer(renderer); if (back) SDL_DestroySurface(back); if (front) SDL_DestroySurface(front); if (texture) SDL_DestroyTexture(texture); SDL_Quit(); }