Mercurial > molko
comparison src/adventure/mainmenu_state.c @ 80:05ffbcdee585
adventure: create main menu, closes #2482 @4h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 15 Feb 2020 12:38:25 +0100 |
parents | |
children | ed72843a7194 |
comparison
equal
deleted
inserted
replaced
79:8f95462ac5f8 | 80:05ffbcdee585 |
---|---|
1 /* | |
2 * mainmenu_state.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 <error.h> | |
24 #include <event.h> | |
25 #include <font.h> | |
26 #include <game.h> | |
27 #include <image.h> | |
28 #include <map_state.h> | |
29 #include <painter.h> | |
30 #include <state.h> | |
31 #include <sys.h> | |
32 #include <texture.h> | |
33 #include <window.h> | |
34 | |
35 #include "mainmenu_state.h" | |
36 #include "splashscreen_state.h" | |
37 | |
38 #define SPEED 120 | |
39 #define SEC 1000 | |
40 | |
41 enum substate { | |
42 SUBSTATE_MOVING, | |
43 SUBSTATE_WAITING | |
44 }; | |
45 | |
46 static int x; | |
47 static int y; | |
48 static unsigned int selection; | |
49 static int destination; | |
50 static enum substate substate; | |
51 | |
52 /* Menu items. */ | |
53 static struct { | |
54 struct texture *texture; | |
55 int x; | |
56 int y; | |
57 } items[3]; | |
58 | |
59 static void | |
60 enter(void) | |
61 { | |
62 struct font *font = font_openf(sys_datapath("fonts/pirata-one.ttf"), 30); | |
63 | |
64 if (!font) | |
65 error_fatal(); | |
66 | |
67 substate = SUBSTATE_MOVING; | |
68 x = splashscreen_state_data.x; | |
69 y = splashscreen_state_data.y; | |
70 destination = window_height() / 4; | |
71 | |
72 /* TODO: change continue color if no game exists. */ | |
73 items[0].texture = font_render(font, "New game", 0x000000ff); | |
74 items[0].x = (window_width() / 2) - (texture_width(items[0].texture) / 2); | |
75 items[0].y = window_height() * 0.75; | |
76 | |
77 items[1].texture = font_render(font, "Continue", 0x000000ff); | |
78 items[1].x = items[0].x; | |
79 items[1].y = items[0].y + texture_height(items[0].texture); | |
80 | |
81 items[2].texture = font_render(font, "Quit", 0x000000ff); | |
82 items[2].x = items[0].x; | |
83 items[2].y = items[1].y + texture_height(items[1].texture); | |
84 } | |
85 | |
86 static void | |
87 new(void) | |
88 { | |
89 struct map map; | |
90 struct texture *image; | |
91 | |
92 /* Prepare map. */ | |
93 if (!map_open(&map, sys_datapath("maps/test.map"))) | |
94 error_fatal(); | |
95 | |
96 memcpy(&map_state_data.map.map, &map, sizeof (map)); | |
97 | |
98 /* Prepare image and sprite. */ | |
99 if (!(image = image_openf(sys_datapath("sprites/test-walk.png")))) | |
100 error_fatal(); | |
101 | |
102 sprite_init(&map_state_data.player.sprite, image, 48, 48); | |
103 game_switch(&map_state, false); | |
104 } | |
105 | |
106 static void | |
107 resume(void) | |
108 { | |
109 } | |
110 | |
111 static void | |
112 quit(void) | |
113 { | |
114 game_quit(); | |
115 } | |
116 | |
117 static void | |
118 perform(void) | |
119 { | |
120 assert(selection < 3); | |
121 | |
122 static void (*handlers[])(void) = { | |
123 [0] = new, | |
124 [1] = resume, | |
125 [2] = quit | |
126 }; | |
127 | |
128 handlers[selection](); | |
129 } | |
130 | |
131 static void | |
132 handle(const union event *event) | |
133 { | |
134 if (substate != SUBSTATE_WAITING) | |
135 return; | |
136 | |
137 switch (event->type) { | |
138 case EVENT_KEYDOWN: | |
139 switch (event->key.key) { | |
140 case KEY_UP: | |
141 selection = selection == 0 ? 2 : selection - 1; | |
142 break; | |
143 case KEY_DOWN: | |
144 selection = (selection + 1) % 3; | |
145 break; | |
146 case KEY_ENTER: | |
147 perform(); | |
148 default: | |
149 break; | |
150 } | |
151 break; | |
152 default: | |
153 break; | |
154 } | |
155 } | |
156 | |
157 static void | |
158 update(unsigned int ticks) | |
159 { | |
160 switch (substate) { | |
161 case SUBSTATE_MOVING: | |
162 y -= SPEED * ticks / SEC; | |
163 | |
164 if (y <= destination) { | |
165 y = destination; | |
166 substate = SUBSTATE_WAITING; | |
167 } | |
168 | |
169 break; | |
170 default: | |
171 break; | |
172 } | |
173 } | |
174 | |
175 static void | |
176 draw(void) | |
177 { | |
178 painter_set_color(0xffffffff); | |
179 painter_clear(); | |
180 texture_draw(splashscreen_state_data.text, x, y); | |
181 | |
182 if (substate == SUBSTATE_WAITING) { | |
183 texture_draw(items[0].texture, items[0].x, items[0].y); | |
184 texture_draw(items[1].texture, items[1].x, items[1].y); | |
185 texture_draw(items[2].texture, items[2].x, items[2].y); | |
186 | |
187 /* Selection cursor. */ | |
188 | |
189 /* TODO: a sword here. */ | |
190 painter_set_color(0x000000ff); | |
191 painter_draw_rectangle(true, items[selection].x - 30, | |
192 items[selection].y + 11, 15, 15); | |
193 } | |
194 } | |
195 | |
196 static void | |
197 leave(void) | |
198 { | |
199 texture_close(items[0].texture); | |
200 texture_close(items[1].texture); | |
201 memset(items, 0, sizeof (items)); | |
202 } | |
203 | |
204 struct state mainmenu_state = { | |
205 .enter = enter, | |
206 .handle = handle, | |
207 .update = update, | |
208 .draw = draw, | |
209 .leave = leave | |
210 }; |