Mercurial > molko
diff libmlk-adventure/adventure/state/mainmenu.c @ 243:71b3b7036de7
misc: lot of cleanups,
- prefix libraries with libmlk,
- move assets from source directories closes #2520,
- prefix header guards closes #2519
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 28 Nov 2020 22:37:30 +0100 |
parents | libadventure/adventure/state/mainmenu.c@befa2e855d3b |
children | 16be1ad3ddba |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmlk-adventure/adventure/state/mainmenu.c Sat Nov 28 22:37:30 2020 +0100 @@ -0,0 +1,225 @@ +/* + * mainmenu.c -- game main menu + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include <core/alloc.h> +#include <core/event.h> +#include <core/font.h> +#include <core/game.h> +#include <core/image.h> +#include <core/painter.h> +#include <core/panic.h> +#include <core/state.h> +#include <core/texture.h> +#include <core/util.h> +#include <core/window.h> + +#include <ui/align.h> +#include <ui/label.h> +#include <ui/theme.h> + +#include <assets/fonts/teutonic.h> +#include <assets/fonts/pirata-one.h> + +#include "adventure_p.h" +#include "mainmenu.h" +#include "molko.h" + +struct mainmenu { + struct { + struct texture tex; + int x; + int y; + } texts[4]; + + unsigned int itemsel; /* Selected item. */ +}; + +static void +new(void) +{ + /* TODO: implement here. */ + if (!map_file_open(&molko.map_file, &molko.map, DIRECTORY "/maps/overworld.map")) + panic(); + + /* Put a sprite. */ + if (!image_open(&molko.map_player_texture, DIRECTORY "/sprites/john.png")) + panic(); + + sprite_init(&molko.map_player_sprite, &molko.map_player_texture, 48, 48); + molko.map.player_sprite = &molko.map_player_sprite; + + if (!map_init(&molko.map)) + panic(); + + game_switch(&molko.states[MOLKO_STATE_MAP], false); +} + +static void +resume(void) +{ + /* TODO: implement here. */ +} + +static void +quit(void) +{ + game_quit(); +} + +static void +perform(struct mainmenu *main) +{ + assert(main->itemsel < 3); + + static void (*handlers[])(void) = { + [0] = new, + [1] = resume, + [2] = quit + }; + + handlers[main->itemsel](); +} + +static void +init_title(struct mainmenu *main, struct font *font) +{ + if (!font_render(font, &main->texts[3].tex, "Molko's Adventure", 0x000000ff)) + panic(); + + /* Align header. */ + align(ALIGN_CENTER, &main->texts[3].x, NULL, main->texts[3].tex.w, main->texts[3].tex.h, + 0, 0, window.w, window.h); + + main->texts[3].y = main->texts[3].x; +} + +static void +init_items(struct mainmenu *main, struct font *font) +{ + if (!font_render(font, &main->texts[0].tex, _("New"), 0x000000ff) || + !font_render(font, &main->texts[1].tex, _("Continue"), 0x000000ff) || + !font_render(font, &main->texts[2].tex, _("Quit"), 0x000000ff)) + panic(); + + main->texts[0].x = (window.w / 2) - (main->texts[0].tex.w / 2); + main->texts[0].y = window.h * 0.75; + + main->texts[1].x = main->texts[0].x; + main->texts[1].y = main->texts[0].y + main->texts[0].tex.h; + + main->texts[2].x = main->texts[0].x; + main->texts[2].y = main->texts[1].y + main->texts[1].tex.h; +} + +static void +start(struct state *state) +{ + struct mainmenu *main; + struct font fonts[2]; + + /* Allocate the main menu data. */ + main = (state->data = alloc_new0(sizeof (*main))); + + if (!font_openmem(&fonts[0], fonts_teutonic, sizeof (fonts_teutonic), 130) || + !font_openmem(&fonts[1], fonts_pirata_one, sizeof (fonts_pirata_one), 30)) + panic(); + + fonts[0].style = fonts[1].style = FONT_STYLE_ANTIALIASED; + + init_title(main, &fonts[0]); + init_items(main, &fonts[1]); + + font_finish(&fonts[0]); + font_finish(&fonts[1]); +} + +static void +handle(struct state *state, const union event *event) +{ + struct mainmenu *main = state->data; + + switch (event->type) { + case EVENT_KEYDOWN: + switch (event->key.key) { + case KEY_UP: + main->itemsel = main->itemsel == 0 ? 2 : main->itemsel - 1; + break; + case KEY_DOWN: + main->itemsel = (main->itemsel + 1) % 3; + break; + case KEY_ENTER: + perform(main); + break; + default: + break; + } + break; + default: + break; + } +} + +static void +draw(struct state *state) +{ + struct mainmenu *main = state->data; + + painter_set_color(0xffffffff); + painter_clear(); + + for (size_t i = 0; i < NELEM(main->texts); ++i) + texture_draw(&main->texts[i].tex, main->texts[i].x, main->texts[i].y); + + /* TODO: a sword here. */ + painter_set_color(0x000000ff); + painter_draw_rectangle( + main->texts[main->itemsel].x - 30, + main->texts[main->itemsel].y + 11, 15, 15); + painter_present(); +} + +static void +finish(struct state *state) +{ + struct mainmenu *main = state->data; + + if (!main) + return; + + for (size_t i = 0; i < NELEM(main->texts); ++i) + texture_finish(&main->texts[i].tex); + + free(main); + memset(state, 0, sizeof (*state)); +} + +void +mainmenu_state(struct state *state) +{ + assert(state); + + memset(state, 0, sizeof (*state)); + state->start = start; + state->handle = handle; + state->draw = draw; + state->finish = finish; +}