123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- #include "button.h"
- #include "strings.h"
- #include "textbox.h"
- #include "window.h"
- #include <SDL_image.h>
- #include <SDL_mixer.h>
- #include <stdio.h>
- #include <stdlib.h>
- #define ERROR(...) fprintf(stderr, __VA_ARGS__)
- #define MUSIC_VOLUME 48
- /* Resources */
- #define DEFINE_RESOURCE(rec_name) extern const char _binary_##rec_name##_start, _binary_##rec_name##_end
- #define RESOURCE_DATA(rec_name) ((const void *) &_binary_##rec_name##_start)
- #define RESOURCE_SIZE(rec_name) ((size_t) (&_binary_##rec_name##_end - &_binary_##rec_name##_start))
- DEFINE_RESOURCE(font_ttf);
- DEFINE_RESOURCE(background_png);
- DEFINE_RESOURCE(button_png);
- DEFINE_RESOURCE(button_pressed_png);
- DEFINE_RESOURCE(mute_png);
- DEFINE_RESOURCE(volume_png);
- DEFINE_RESOURCE(bgm_wav);
- DEFINE_RESOURCE(click_wav);
- DEFINE_RESOURCE(hover_wav);
- DEFINE_RESOURCE(release_wav);
- /* Constants */
- static const SDL_Color COLOR_BLACK = {0x0, 0x0, 0x0, 0xFF};
- static const SDL_Color COLOR_WHITE = {0xFF, 0xFF, 0xFF, 0xFF};
- static const ButtonSoundSet NO_BUTTON_SOUNDS = {NULL, NULL, NULL};
- /* Assets */
- static TTF_Font *font;
- static SDL_Texture *backgroundTexture;
- static SDL_Texture *buttonTexture;
- static SDL_Texture *buttonPressedTexture;
- static SDL_Texture *muteTexture;
- static SDL_Texture *volumeTexture;
- static Mix_Music *bgm;
- static ButtonSoundSet buttonSounds = {NULL, NULL, NULL};
- /* UI Elements */
- static Button *backButton;
- static Button *muteButton;
- static TextBox *nameBox;
- static Button *blackHoleButton;
- static TextBox *blackHoleInfo;
- static Button *haloButton;
- static TextBox *haloInfo;
- static Button *lightButton;
- static TextBox *lightInfo;
- static Button *planetsAndStarsButton;
- static TextBox *planetsAndStarsInfo;
- static Button *deathButton;
- static TextBox *deathInfo;
- /* Variables */
- static Window *window;
- static size_t locationCount;
- static Button **locations;
- static TextBox *currentBox = NULL;
- static int quit = 0;
- static int mute = 0;
- /* Functions */
- static void init(void);
- static void loadAssets(void);
- static void createUI(void);
- static void drawLoop(void);
- static void cleanupAssets(void);
- static void cleanupObjects(void);
- static void addLocation(Button *button);
- static SDL_Texture *loadTexture(const char *data, size_t size);
- static Mix_Music *loadMusic(const char *data, size_t size);
- static Mix_Chunk *loadSound(const char *data, size_t size);
- static void backButtonAction(Button *button, Window *window, float x, float y);
- static void muteButtonAction(Button *button, Window *window, float x, float y);
- static void blackHoleZoomAction(Button *button, Window *window, float x,
- float y);
- static void haloZoomAction(Button *button, Window *window, float x, float y);
- static void lightZoomAction(Button *button, Window *window, float x, float y);
- static void planetsAndStarsZoomAction(Button *button, Window *window, float x,
- float y);
- static void deathZoomAction(Button *button, Window *window, float x, float y);
- int main() {
- init();
- window = windowNew("IC Explorer", 500, 500);
- loadAssets();
- createUI();
- drawLoop();
- cleanupObjects();
- cleanupAssets();
- SDL_Quit();
- return 0;
- }
- void init() {
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO)) {
- ERROR("error: sdl2: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- if (!IMG_Init(IMG_INIT_PNG)) {
- ERROR("error: sdl2: image: %s\n", IMG_GetError());
- SDL_Quit();
- exit(EXIT_FAILURE);
- }
- if (TTF_Init() != 0) {
- ERROR("error: sdl2: ttf: %s\n", TTF_GetError());
- SDL_Quit();
- exit(EXIT_FAILURE);
- }
- if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) != 0) {
- ERROR("error: sdl2: mixer: %s\n", Mix_GetError());
- SDL_Quit();
- exit(EXIT_FAILURE);
- }
- Mix_VolumeMusic(MUSIC_VOLUME);
- locationCount = 0;
- locations = malloc(1);
- if (!locations) {
- ERROR("error: out of memory\n");
- SDL_Quit();
- exit(EXIT_FAILURE);
- }
- }
- void loadAssets() {
- font = TTF_OpenFontRW(SDL_RWFromConstMem(RESOURCE_DATA(font_ttf), RESOURCE_SIZE(font_ttf)), SDL_TRUE, 512);
- backgroundTexture = loadTexture(RESOURCE_DATA(background_png), RESOURCE_SIZE(background_png));
- buttonTexture = loadTexture(RESOURCE_DATA(button_png), RESOURCE_SIZE(button_png));
- buttonPressedTexture = loadTexture(RESOURCE_DATA(button_pressed_png), RESOURCE_SIZE(button_pressed_png));
- muteTexture = loadTexture(RESOURCE_DATA(mute_png), RESOURCE_SIZE(mute_png));
- volumeTexture = loadTexture(RESOURCE_DATA(volume_png), RESOURCE_SIZE(volume_png));
- bgm = loadMusic(RESOURCE_DATA(bgm_wav), RESOURCE_SIZE(bgm_wav));
- buttonSounds.hover = loadSound(RESOURCE_DATA(hover_wav), RESOURCE_SIZE(hover_wav));
- buttonSounds.down = loadSound(RESOURCE_DATA(click_wav), RESOURCE_SIZE(click_wav));
- buttonSounds.up = loadSound(RESOURCE_DATA(release_wav), RESOURCE_SIZE(release_wav));
- }
- void createUI() {
- SDL_SetWindowMinimumSize(window->obj, 500, 500);
- window->background = backgroundTexture;
- backButton = buttonNew("Back", 0.05f, 0.05f, 0.15f, AUTOMATIC_SCALE,
- buttonTexture, buttonPressedTexture, COLOR_BLACK,
- font, buttonSounds, window);
- backButton->action = &backButtonAction;
- muteButton = buttonNew(NULL, 0.9f, 0.9f, 0.075f, 0.075f, volumeTexture,
- NULL, COLOR_BLACK, font, NO_BUTTON_SOUNDS, window);
- muteButton->action = &muteButtonAction;
- nameBox = textBoxNew("IC 1101", 0.02, 0.02, 0.07f, COLOR_WHITE, NULL, font,
- window);
- /* Black Hole */
- blackHoleButton =
- buttonNew(BLACK_HOLE_BUTTON_TEXT, 0.55f, 0.55f, 0.15f, AUTOMATIC_SCALE,
- buttonTexture, buttonPressedTexture, COLOR_BLACK, font,
- buttonSounds, window);
- blackHoleButton->action = &blackHoleZoomAction;
- addLocation(blackHoleButton);
- blackHoleInfo = textBoxNew(BLACK_HOLE_INFO_TEXT, 0.6f, 0.3f, 0.04,
- COLOR_BLACK, buttonTexture, font, window);
- /* Halo */
- haloButton = buttonNew(HALO_BUTTON_TEXT, 0.2f, 0.25f, 0.1f, AUTOMATIC_SCALE,
- buttonTexture, buttonPressedTexture, COLOR_BLACK,
- font, buttonSounds, window);
- haloButton->action = &haloZoomAction;
- addLocation(haloButton);
- haloInfo = textBoxNew(HALO_INFO_TEXT, 0.5f, 0.3f, 0.04, COLOR_BLACK,
- buttonTexture, font, window);
- /* Light */
- lightButton = buttonNew(
- LIGHT_BUTTON_TEXT, 0.55f, 0.4f, 0.12f, AUTOMATIC_SCALE, buttonTexture,
- buttonPressedTexture, COLOR_BLACK, font, buttonSounds, window);
- lightButton->action = &lightZoomAction;
- addLocation(lightButton);
- lightInfo = textBoxNew(LIGHT_INFO_TEXT, 0.45f, 0.15f, 0.04, COLOR_BLACK,
- buttonTexture, font, window);
- /* Planets & Stars */
- planetsAndStarsButton =
- buttonNew(PLANETS_AND_STARS_BUTTON_TEXT, 0.6f, 0.08f, 0.34f,
- AUTOMATIC_SCALE, buttonTexture, buttonPressedTexture,
- COLOR_BLACK, font, buttonSounds, window);
- planetsAndStarsButton->action = &planetsAndStarsZoomAction;
- addLocation(planetsAndStarsButton);
- planetsAndStarsInfo =
- textBoxNew(PLANETS_AND_STARS_INFO_TEXT, 0.05f, 0.3f, 0.04, COLOR_BLACK,
- buttonTexture, font, window);
- /* Death */
- deathButton = buttonNew(
- DEATH_BUTTON_TEXT, 0.1f, 0.85f, 0.12f, AUTOMATIC_SCALE, buttonTexture,
- buttonPressedTexture, COLOR_BLACK, font, buttonSounds, window);
- deathButton->action = &deathZoomAction;
- addLocation(deathButton);
- deathInfo = textBoxNew(DEATH_INFO_TEXT, 0.5f, 0.15f, 0.04, COLOR_BLACK,
- buttonTexture, font, window);
- }
- void drawLoop() {
- while (!quit) {
- if (!Mix_PlayingMusic()) {
- Mix_FadeInMusic(bgm, 0, 1000);
- }
- windowDraw(window);
- buttonDraw(muteButton, window);
- if (window->state == WINDOW_STATE_NORMAL) {
- textBoxDraw(nameBox, window);
- size_t i;
- for (i = 0; i < locationCount; ++i) {
- buttonDraw(locations[i], window);
- }
- } else if (window->state == WINDOW_STATE_ZOOMED) {
- buttonDraw(backButton, window);
- if (currentBox) {
- textBoxDraw(currentBox, window);
- }
- }
- windowUpdate(window);
- SDL_Event e;
- while (SDL_PollEvent(&e)) {
- if (e.type == SDL_QUIT) {
- quit = 1;
- } else {
- buttonProcessInput(muteButton, window, &e);
- if (window->state == WINDOW_STATE_NORMAL) {
- size_t i;
- for (i = 0; i < locationCount; ++i) {
- buttonProcessInput(locations[i], window, &e);
- }
- } else if (window->state == WINDOW_STATE_ZOOMED) {
- if (e.type == SDL_KEYDOWN &&
- e.key.keysym.sym == SDLK_ESCAPE) {
- windowZoomOut(window);
- } else {
- buttonProcessInput(backButton, window, &e);
- }
- }
- }
- }
- }
- }
- void cleanupAssets() {
- TTF_CloseFont(font);
- SDL_DestroyTexture(backgroundTexture);
- SDL_DestroyTexture(buttonTexture);
- SDL_DestroyTexture(buttonPressedTexture);
- SDL_DestroyTexture(muteTexture);
- SDL_DestroyTexture(volumeTexture);
- Mix_CloseAudio();
- Mix_FreeMusic(bgm);
- Mix_FreeChunk(buttonSounds.hover);
- Mix_FreeChunk(buttonSounds.down);
- Mix_FreeChunk(buttonSounds.up);
- }
- void cleanupObjects() {
- size_t i;
- for (i = 0; i < locationCount; ++i) { buttonDelete(locations[i]); }
- free(locations);
- buttonDelete(backButton);
- buttonDelete(muteButton);
- textBoxDelete(nameBox);
- textBoxDelete(blackHoleInfo);
- textBoxDelete(haloInfo);
- textBoxDelete(lightInfo);
- textBoxDelete(planetsAndStarsInfo);
- textBoxDelete(deathInfo);
- windowDelete(window);
- }
- void addLocation(Button *button) {
- locations = realloc(locations, sizeof(Button *) * (++locationCount));
- if (!locations) {
- ERROR("error: out of memory\n");
- exit(EXIT_FAILURE);
- }
- locations[locationCount - 1] = button;
- }
- SDL_Texture *loadTexture(const char *data, size_t size) {
- SDL_Surface *surface = IMG_Load_RW(SDL_RWFromConstMem(data, size), SDL_TRUE);
- if (!surface) {
- ERROR("error: sdl2: image: %s\n", IMG_GetError());
- exit(EXIT_FAILURE);
- }
- SDL_Texture *texture =
- SDL_CreateTextureFromSurface(window->render, surface);
- SDL_FreeSurface(surface);
- if (!texture) {
- ERROR("error: sdl2: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- return texture;
- }
- Mix_Music *loadMusic(const char *data, size_t size) {
- Mix_Music *m = Mix_LoadMUS_RW(SDL_RWFromConstMem(data, size), SDL_TRUE);
- if (!m) {
- ERROR("error: sdl2: mixer: %s\n", Mix_GetError());
- exit(EXIT_FAILURE);
- }
- return m;
- }
- Mix_Chunk *loadSound(const char *data, size_t size) {
- Mix_Chunk *c = Mix_LoadWAV_RW(SDL_RWFromConstMem(data, size), SDL_TRUE);
- if (!c) {
- ERROR("error: sdl2: mixer: %s\n", Mix_GetError());
- exit(EXIT_FAILURE);
- }
- return c;
- }
- void backButtonAction(Button *button, Window *window, float x, float y) {
- windowZoomOut(window);
- }
- void muteButtonAction(Button *button, Window *window, float x, float y) {
- if (mute) {
- Mix_Volume(-1, 128);
- Mix_VolumeMusic(MUSIC_VOLUME);
- mute = 0;
- button->inactive = volumeTexture;
- button->current = volumeTexture;
- } else {
- Mix_Volume(-1, 0);
- Mix_VolumeMusic(0);
- mute = 1;
- button->inactive = muteTexture;
- button->current = muteTexture;
- }
- }
- void blackHoleZoomAction(Button *button, Window *window, float x, float y) {
- windowZoomTo(window, 0.6f, 0.5f);
- currentBox = blackHoleInfo;
- }
- void haloZoomAction(Button *button, Window *window, float x, float y) {
- windowZoomTo(window, 0.25f, 0.3f);
- currentBox = haloInfo;
- }
- void lightZoomAction(Button *button, Window *window, float x, float y) {
- windowZoomTo(window, 0.5f, 0.35f);
- currentBox = lightInfo;
- }
- void planetsAndStarsZoomAction(Button *button, Window *window, float x,
- float y) {
- windowZoomTo(window, 0.55f, 0.03f);
- currentBox = planetsAndStarsInfo;
- }
- void deathZoomAction(Button *button, Window *window, float x, float y) {
- windowZoomTo(window, 0.05f, 0.8f);
- currentBox = deathInfo;
- }
|