Mercurial > molko
comparison src/libmlk-adventure/adventure/state/mainmenu.c @ 320:8f9937403749
misc: improve loading of data
author | David Demelier <markand@malikania.fr> |
---|---|
date | Fri, 01 Oct 2021 20:30:00 +0200 |
parents | libmlk-adventure/adventure/state/mainmenu.c@d01e83210ca2 |
children |
comparison
equal
deleted
inserted
replaced
319:b843eef4cc35 | 320:8f9937403749 |
---|---|
1 /* | |
2 * mainmenu.c -- game main menu | |
3 * | |
4 * Copyright (c) 2020-2021 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 <rpg/character.h> | |
40 | |
41 #include <adventure/assets.h> | |
42 #include <adventure/molko.h> | |
43 #include <adventure/adventure_p.h> | |
44 | |
45 #include <adventure/item/potion.h> | |
46 #include <adventure/character/neth.h> | |
47 | |
48 #include "mainmenu.h" | |
49 #include "continue.h" | |
50 | |
51 struct self { | |
52 struct state state; | |
53 | |
54 struct { | |
55 struct texture tex; | |
56 int x; | |
57 int y; | |
58 } texts[4]; | |
59 | |
60 unsigned int itemsel; /* Selected item. */ | |
61 }; | |
62 | |
63 static void | |
64 new(void) | |
65 { | |
66 /* TODO: temporary. */ | |
67 molko.team.members[0] = &character_neth; | |
68 character_reset(molko.team.members[0]); | |
69 molko.team.members[0]->hp = molko.team.members[0]->hpmax; | |
70 molko.team.members[0]->mp = molko.team.members[0]->mpmax; | |
71 inventory_add(&molko.inventory, &item_potion, 10); | |
72 | |
73 molko_teleport("maps/map-world.map", -1, -1); | |
74 } | |
75 | |
76 static void | |
77 resume(void) | |
78 { | |
79 game_push(state_continue_new()); | |
80 } | |
81 | |
82 static void | |
83 quit(void) | |
84 { | |
85 game_quit(); | |
86 } | |
87 | |
88 static void | |
89 perform(struct self *self) | |
90 { | |
91 assert(self->itemsel < 3); | |
92 | |
93 static void (*handlers[])(void) = { | |
94 [0] = new, | |
95 [1] = resume, | |
96 [2] = quit | |
97 }; | |
98 | |
99 handlers[self->itemsel](); | |
100 } | |
101 | |
102 static void | |
103 init_title(struct self *self, struct font *font) | |
104 { | |
105 if (font_render(font, &self->texts[3].tex, "Molko's Adventure", 0x000000ff) < 0) | |
106 panic(); | |
107 | |
108 /* Align header. */ | |
109 align(ALIGN_CENTER, &self->texts[3].x, NULL, self->texts[3].tex.w, self->texts[3].tex.h, | |
110 0, 0, window.w, window.h); | |
111 | |
112 self->texts[3].y = self->texts[3].x; | |
113 } | |
114 | |
115 static void | |
116 init_items(struct self *self, struct font *font) | |
117 { | |
118 if (font_render(font, &self->texts[0].tex, _("New"), 0x000000ff) < 0 || | |
119 font_render(font, &self->texts[1].tex, _("Continue"), 0x000000ff) < 0 || | |
120 font_render(font, &self->texts[2].tex, _("Quit"), 0x000000ff) < 0) | |
121 panic(); | |
122 | |
123 self->texts[0].x = (window.w / 2) - (self->texts[0].tex.w / 2); | |
124 self->texts[0].y = window.h * 0.75; | |
125 | |
126 self->texts[1].x = self->texts[0].x; | |
127 self->texts[1].y = self->texts[0].y + self->texts[0].tex.h; | |
128 | |
129 self->texts[2].x = self->texts[0].x; | |
130 self->texts[2].y = self->texts[1].y + self->texts[1].tex.h; | |
131 } | |
132 | |
133 static void | |
134 start(struct state *state) | |
135 { | |
136 struct self *self = state->data; | |
137 struct font fonts[2]; | |
138 | |
139 if (font_open(&fonts[0], molko_path("fonts/teutonic.ttf"), 130) < 0|| | |
140 font_open(&fonts[1], molko_path("fonts/pirata-one.ttf"), 30) < 0) | |
141 panic(); | |
142 | |
143 fonts[0].style = fonts[1].style = FONT_STYLE_ANTIALIASED; | |
144 | |
145 init_title(self, &fonts[0]); | |
146 init_items(self, &fonts[1]); | |
147 | |
148 font_finish(&fonts[0]); | |
149 font_finish(&fonts[1]); | |
150 } | |
151 | |
152 static void | |
153 handle(struct state *state, const union event *event) | |
154 { | |
155 struct self *self = state->data; | |
156 | |
157 switch (event->type) { | |
158 case EVENT_QUIT: | |
159 game_quit(); | |
160 break; | |
161 case EVENT_KEYDOWN: | |
162 switch (event->key.key) { | |
163 case KEY_UP: | |
164 self->itemsel = self->itemsel == 0 ? 2 : self->itemsel - 1; | |
165 break; | |
166 case KEY_DOWN: | |
167 self->itemsel = (self->itemsel + 1) % 3; | |
168 break; | |
169 case KEY_ENTER: | |
170 perform(self); | |
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 self *self = state->data; | |
185 struct sprite *cursor = &assets_sprites[ASSETS_SPRITE_UI_CURSOR]; | |
186 int x, y; | |
187 | |
188 painter_set_color(0xffffffff); | |
189 painter_clear(); | |
190 | |
191 for (size_t i = 0; i < UTIL_SIZE(self->texts); ++i) | |
192 texture_draw(&self->texts[i].tex, self->texts[i].x, self->texts[i].y); | |
193 | |
194 x = self->texts[self->itemsel].x; | |
195 x -= cursor->cellw * 2; | |
196 y = self->texts[self->itemsel].y; | |
197 y += self->texts[self->itemsel].tex.h / 2; | |
198 y -= cursor->cellh / 2; | |
199 | |
200 sprite_draw(cursor, 1, 2, x, y); | |
201 painter_present(); | |
202 } | |
203 | |
204 static void | |
205 finish(struct state *state) | |
206 { | |
207 struct self *self = state->data; | |
208 | |
209 for (size_t i = 0; i < UTIL_SIZE(self->texts); ++i) | |
210 texture_finish(&self->texts[i].tex); | |
211 | |
212 free(self); | |
213 } | |
214 | |
215 struct state * | |
216 state_mainmenu_new(void) | |
217 { | |
218 struct self *self; | |
219 | |
220 self = alloc_new0(sizeof (*self)); | |
221 self->state.data = self; | |
222 self->state.start = start; | |
223 self->state.handle = handle; | |
224 self->state.draw = draw; | |
225 self->state.finish = finish; | |
226 | |
227 return &self->state; | |
228 } |