comparison 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
comparison
equal deleted inserted replaced
242:4c24604efcab 243:71b3b7036de7
1 /*
2 * mainmenu.c -- game main menu
3 *
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include <core/alloc.h>
24 #include <core/event.h>
25 #include <core/font.h>
26 #include <core/game.h>
27 #include <core/image.h>
28 #include <core/painter.h>
29 #include <core/panic.h>
30 #include <core/state.h>
31 #include <core/texture.h>
32 #include <core/util.h>
33 #include <core/window.h>
34
35 #include <ui/align.h>
36 #include <ui/label.h>
37 #include <ui/theme.h>
38
39 #include <assets/fonts/teutonic.h>
40 #include <assets/fonts/pirata-one.h>
41
42 #include "adventure_p.h"
43 #include "mainmenu.h"
44 #include "molko.h"
45
46 struct mainmenu {
47 struct {
48 struct texture tex;
49 int x;
50 int y;
51 } texts[4];
52
53 unsigned int itemsel; /* Selected item. */
54 };
55
56 static void
57 new(void)
58 {
59 /* TODO: implement here. */
60 if (!map_file_open(&molko.map_file, &molko.map, DIRECTORY "/maps/overworld.map"))
61 panic();
62
63 /* Put a sprite. */
64 if (!image_open(&molko.map_player_texture, DIRECTORY "/sprites/john.png"))
65 panic();
66
67 sprite_init(&molko.map_player_sprite, &molko.map_player_texture, 48, 48);
68 molko.map.player_sprite = &molko.map_player_sprite;
69
70 if (!map_init(&molko.map))
71 panic();
72
73 game_switch(&molko.states[MOLKO_STATE_MAP], false);
74 }
75
76 static void
77 resume(void)
78 {
79 /* TODO: implement here. */
80 }
81
82 static void
83 quit(void)
84 {
85 game_quit();
86 }
87
88 static void
89 perform(struct mainmenu *main)
90 {
91 assert(main->itemsel < 3);
92
93 static void (*handlers[])(void) = {
94 [0] = new,
95 [1] = resume,
96 [2] = quit
97 };
98
99 handlers[main->itemsel]();
100 }
101
102 static void
103 init_title(struct mainmenu *main, struct font *font)
104 {
105 if (!font_render(font, &main->texts[3].tex, "Molko's Adventure", 0x000000ff))
106 panic();
107
108 /* Align header. */
109 align(ALIGN_CENTER, &main->texts[3].x, NULL, main->texts[3].tex.w, main->texts[3].tex.h,
110 0, 0, window.w, window.h);
111
112 main->texts[3].y = main->texts[3].x;
113 }
114
115 static void
116 init_items(struct mainmenu *main, struct font *font)
117 {
118 if (!font_render(font, &main->texts[0].tex, _("New"), 0x000000ff) ||
119 !font_render(font, &main->texts[1].tex, _("Continue"), 0x000000ff) ||
120 !font_render(font, &main->texts[2].tex, _("Quit"), 0x000000ff))
121 panic();
122
123 main->texts[0].x = (window.w / 2) - (main->texts[0].tex.w / 2);
124 main->texts[0].y = window.h * 0.75;
125
126 main->texts[1].x = main->texts[0].x;
127 main->texts[1].y = main->texts[0].y + main->texts[0].tex.h;
128
129 main->texts[2].x = main->texts[0].x;
130 main->texts[2].y = main->texts[1].y + main->texts[1].tex.h;
131 }
132
133 static void
134 start(struct state *state)
135 {
136 struct mainmenu *main;
137 struct font fonts[2];
138
139 /* Allocate the main menu data. */
140 main = (state->data = alloc_new0(sizeof (*main)));
141
142 if (!font_openmem(&fonts[0], fonts_teutonic, sizeof (fonts_teutonic), 130) ||
143 !font_openmem(&fonts[1], fonts_pirata_one, sizeof (fonts_pirata_one), 30))
144 panic();
145
146 fonts[0].style = fonts[1].style = FONT_STYLE_ANTIALIASED;
147
148 init_title(main, &fonts[0]);
149 init_items(main, &fonts[1]);
150
151 font_finish(&fonts[0]);
152 font_finish(&fonts[1]);
153 }
154
155 static void
156 handle(struct state *state, const union event *event)
157 {
158 struct mainmenu *main = state->data;
159
160 switch (event->type) {
161 case EVENT_KEYDOWN:
162 switch (event->key.key) {
163 case KEY_UP:
164 main->itemsel = main->itemsel == 0 ? 2 : main->itemsel - 1;
165 break;
166 case KEY_DOWN:
167 main->itemsel = (main->itemsel + 1) % 3;
168 break;
169 case KEY_ENTER:
170 perform(main);
171 break;
172 default:
173 break;
174 }
175 break;
176 default:
177 break;
178 }
179 }
180
181 static void
182 draw(struct state *state)
183 {
184 struct mainmenu *main = state->data;
185
186 painter_set_color(0xffffffff);
187 painter_clear();
188
189 for (size_t i = 0; i < NELEM(main->texts); ++i)
190 texture_draw(&main->texts[i].tex, main->texts[i].x, main->texts[i].y);
191
192 /* TODO: a sword here. */
193 painter_set_color(0x000000ff);
194 painter_draw_rectangle(
195 main->texts[main->itemsel].x - 30,
196 main->texts[main->itemsel].y + 11, 15, 15);
197 painter_present();
198 }
199
200 static void
201 finish(struct state *state)
202 {
203 struct mainmenu *main = state->data;
204
205 if (!main)
206 return;
207
208 for (size_t i = 0; i < NELEM(main->texts); ++i)
209 texture_finish(&main->texts[i].tex);
210
211 free(main);
212 memset(state, 0, sizeof (*state));
213 }
214
215 void
216 mainmenu_state(struct state *state)
217 {
218 assert(state);
219
220 memset(state, 0, sizeof (*state));
221 state->start = start;
222 state->handle = handle;
223 state->draw = draw;
224 state->finish = finish;
225 }