/* * Copyright (C) 2018 Vito Caputo - * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include /* exit, atexit */ #include "credits.h" #include "whale.h" #include "game.h" #include "intro.h" #include "macros.h" #include "stage.h" /* whale - Blender 2018 entry */ /* whales / doing astrophysics / crater lake */ #define DEFAULT_WIDTH 800 #define DEFAULT_HEIGHT 450 #define WINDOW_FLAGS (SDL_WINDOW_RESIZABLE) typedef struct whale_t { struct { SDL_Window *window; SDL_Renderer *renderer; Mix_Music *music; Uint32 tick_offsets[2]; } sdl; whale_context_t context; stage_t *stage; } whale_t; stage_t * whale_get_stage(const whale_t *whale) { return whale->stage; } void whale_set_music(whale_t *whale, const char *file, unsigned flags) { int loop = (flags & WHALE_MUSIC_FLAG_LOOP) ? -1 : 0; int fade = (flags & WHALE_MUSIC_FLAG_FADEIN); if (whale->sdl.music) { Mix_HaltMusic(); Mix_FreeMusic(whale->sdl.music); whale->sdl.music = NULL; } whale->sdl.music = Mix_LoadMUS(file); fatal_if(!whale->sdl.music, "Unable to load music \"%s\"", file); Mix_VolumeMusic(32); /* XXX: just hard-coding music volume for now */ if (fade) { fatal_if(Mix_FadeInMusic(whale->sdl.music, loop, 1000), "Unable to play music"); } else { fatal_if(Mix_PlayMusic(whale->sdl.music, loop), "Unable to play music"); } } void whale_set_context(whale_t *whale, whale_context_t context) { whale->context = context; } /* return ticks counter */ unsigned whale_ticks(whale_t *whale, whale_ticks_t type) { return SDL_GetTicks() - whale->sdl.tick_offsets[type]; } /* reset ticks counter to begin counting from now */ void whale_ticks_reset(whale_t *whale, whale_ticks_t type) { whale->sdl.tick_offsets[type] = SDL_GetTicks(); } static void whale_startup(whale_t *whale) { fatal_if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0, "Unable to initialize SDL"); fatal_if(atexit(SDL_Quit), "Unable to set exit handler"); fatal_if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) == -1, "Unable to open audio"); whale->sdl.window = SDL_CreateWindow("whale", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DEFAULT_WIDTH, DEFAULT_HEIGHT, WINDOW_FLAGS); fatal_if(!whale->sdl.window, "Unable to create SDL window"); whale->sdl.renderer = SDL_CreateRenderer(whale->sdl.window, -1, SDL_RENDERER_PRESENTVSYNC); fatal_if(!whale->sdl.renderer, "Unable to create SDL renderer"); whale->stage = stage_new(whale->sdl.renderer, 1.7777f); fatal_if(!whale->stage, "Unable to create new stage"); } static void whale_update(whale_t *whale) { switch (whale->context) { case WHALE_CONTEXT_INTRO: whale_intro_update(whale); break; case WHALE_CONTEXT_GAME: whale_game_update(whale); break; case WHALE_CONTEXT_CREDITS: whale_credits_update(whale); break; default: assert(0); } stage_render(whale->stage); SDL_RenderPresent(whale->sdl.renderer); } static void whale_event(whale_t *whale, SDL_Event *event) { switch (whale->context) { case WHALE_CONTEXT_INTRO: whale_intro_event(whale, event); break; case WHALE_CONTEXT_GAME: whale_game_event(whale, event); break; case WHALE_CONTEXT_CREDITS: whale_credits_event(whale, event); break; default: assert(0); } } static int whale_shutdown(whale_t *whale) { stage_free(whale->stage); SDL_DestroyRenderer(whale->sdl.renderer); SDL_DestroyWindow(whale->sdl.window); Mix_CloseAudio(); return EXIT_SUCCESS; } static void whale_loop(whale_t *whale) { for (;;) { SDL_Event ev; while (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_APP_TERMINATING: case SDL_QUIT: return; case SDL_WINDOWEVENT: break; case SDL_MOUSEMOTION: break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: break; case SDL_MOUSEWHEEL: break; case SDL_FINGERDOWN: case SDL_FINGERUP: case SDL_FINGERMOTION: break; case SDL_KEYDOWN: case SDL_KEYUP: break; default: break; } whale_event(whale, &ev); } whale_update(whale); } } int main(int argc, char *argv[]) { whale_t whale = {}; whale_startup(&whale); whale_loop(&whale); return whale_shutdown(&whale); }