3 #include "./level_picker.h"
4 #include "game/level/background.h"
5 #include "game/sprite_font.h"
7 #include "system/nth_alloc.h"
8 #include "system/stacktrace.h"
9 #include "system/str.h"
10 #include "ui/list_selector.h"
11 #include "system/log.h"
12 #include "game/level_folder.h"
13 #include "ui/wiggly_text.h"
15 #define TITLE_MARGIN_TOP 100.0f
16 #define TITLE_MARGIN_BOTTOM 100.0f
21 Background *background;
23 LevelFolder *level_folder;
24 WigglyText wiggly_text;
25 ListSelector *list_selector;
28 LevelPicker *create_level_picker(const Sprite_font *sprite_font, const char *dirpath)
30 trace_assert(dirpath);
34 LevelPicker *level_picker = PUSH_LT(
36 nth_calloc(1, sizeof(LevelPicker)),
38 if (level_picker == NULL) {
41 level_picker->lt = lt;
43 level_picker->background = PUSH_LT(
45 create_background(hexstr("073642")),
47 if (level_picker->background == NULL) {
51 level_picker->camera_position = vec(0.0f, 0.0f);
53 level_picker->level_folder = PUSH_LT(
55 create_level_folder(dirpath),
56 destroy_level_folder);
57 if (level_picker->level_folder == NULL) {
61 level_picker->wiggly_text = (WigglyText) {
62 .text = "Select Level",
63 .scale = {10.0f, 10.0f},
67 level_picker->list_selector = PUSH_LT(
71 level_folder_titles(level_picker->level_folder),
72 level_folder_count(level_picker->level_folder),
75 destroy_list_selector);
76 if (level_picker->list_selector == NULL) {
83 void destroy_level_picker(LevelPicker *level_picker)
85 trace_assert(level_picker);
86 RETURN_LT0(level_picker->lt);
89 int level_picker_render(const LevelPicker *level_picker,
91 SDL_Renderer *renderer)
93 trace_assert(level_picker);
94 trace_assert(renderer);
96 const Rect viewport = camera_view_port_screen(camera);
98 if (background_render(level_picker->background, camera) < 0) {
102 const Vec title_size = wiggly_text_size(&level_picker->wiggly_text, camera);
104 if (wiggly_text_render(
105 &level_picker->wiggly_text,
107 vec(viewport.w * 0.5f - title_size.x * 0.5f, TITLE_MARGIN_TOP)) < 0) {
111 if (list_selector_render(level_picker->list_selector, renderer) < 0) {
117 const float padding = 20.0f;
118 const Point size = vec(3.0f, 3.0f);
119 const Point position = vec(0.0f, viewport.h - size.y * FONT_CHAR_HEIGHT);
122 if (camera_render_text_screen(
124 "Press 'N' to create new level",
127 vec(position.x + padding,
128 position.y - padding)) < 0) {
136 int level_picker_update(LevelPicker *level_picker,
139 trace_assert(level_picker);
141 vec_add(&level_picker->camera_position,
142 vec(50.0f * delta_time, 0.0f));
144 if (wiggly_text_update(&level_picker->wiggly_text, delta_time) < 0) {
151 int level_picker_event(LevelPicker *level_picker,
152 const SDL_Event *event,
153 const Camera *camera)
155 trace_assert(level_picker);
158 switch (event->type) {
159 case SDL_WINDOWEVENT: {
160 switch (event->window.event) {
161 case SDL_WINDOWEVENT_SHOWN:
162 case SDL_WINDOWEVENT_RESIZED: {
163 const Vec font_scale = vec(5.0f, 5.0f);
164 const float padding_bottom = 50.0f;
167 SDL_GetWindowSize(SDL_GetWindowFromID(event->window.windowID), &width, NULL);
169 const Vec title_size = wiggly_text_size(&level_picker->wiggly_text, camera);
171 const Vec selector_size = list_selector_size(
172 level_picker->list_selector,
177 level_picker->list_selector,
178 vec((float)width * 0.5f - selector_size.x * 0.5f,
179 TITLE_MARGIN_TOP + title_size.y + TITLE_MARGIN_BOTTOM));
185 return list_selector_event(level_picker->list_selector, event);
188 int level_picker_input(LevelPicker *level_picker,
189 const Uint8 *const keyboard_state,
190 SDL_Joystick *the_stick_of_joy)
192 trace_assert(level_picker);
193 trace_assert(keyboard_state);
194 (void) the_stick_of_joy;
198 const char *level_picker_selected_level(const LevelPicker *level_picker)
200 trace_assert(level_picker);
202 const int selected_index = list_selector_selected(level_picker->list_selector);
203 if (selected_index < 0) {
207 const char **filenames = level_folder_filenames(level_picker->level_folder);
209 return filenames[selected_index];
212 void level_picker_clean_selection(LevelPicker *level_picker)
214 trace_assert(level_picker);
215 list_selector_clean_selection(level_picker->list_selector);
218 int level_picker_enter_camera_event(LevelPicker *level_picker,
221 camera_center_at(camera, level_picker->camera_position);