aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-07-07 02:13:14 +0200
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2022-07-07 02:45:23 +0200
commit08951d4af59a8e8c6f760453bc84f59ee8fc157c (patch)
tree4bd9c51d867647a98f4201f11aaa01b15ea21a9c
parentc9dee333fe4883f73d73f04db73227c8d23aafb8 (diff)
Implement join/host and game cfg menus
-rw-r--r--src/menu/CMakeLists.txt5
-rw-r--r--src/menu/privinc/menu_private.h32
-rw-r--r--src/menu/src/gamecfg_menu.c88
-rw-r--r--src/menu/src/hostjoin_menu.c85
-rw-r--r--src/menu/src/main_menu.c87
-rw-r--r--src/menu/src/menu.c116
6 files changed, 341 insertions, 72 deletions
diff --git a/src/menu/CMakeLists.txt b/src/menu/CMakeLists.txt
index c4adb09..50246c4 100644
--- a/src/menu/CMakeLists.txt
+++ b/src/menu/CMakeLists.txt
@@ -1,5 +1,8 @@
add_library(menu
+ "src/gamecfg_menu.c"
+ "src/hostjoin_menu.c"
"src/menu.c"
+ "src/main_menu.c"
)
-target_include_directories(menu PUBLIC "inc")
+target_include_directories(menu PUBLIC "inc" PRIVATE "privinc")
target_link_libraries(menu PRIVATE camera game gfx gui system)
diff --git a/src/menu/privinc/menu_private.h b/src/menu/privinc/menu_private.h
new file mode 100644
index 0000000..1ab267b
--- /dev/null
+++ b/src/menu/privinc/menu_private.h
@@ -0,0 +1,32 @@
+#ifndef MENU_PRIVATE_H
+#define MENU_PRIVATE_H
+
+#include <camera.h>
+#include <peripheral.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+struct menu_common
+{
+ struct camera cam;
+ union peripheral p;
+};
+
+int menu_update(struct menu_common *c,
+ int (*update)(struct menu_common *, void *),
+ int (*render)(const struct menu_common *, void *),
+ void *arg);
+int menu_main(struct menu_common *c);
+int menu_hostjoin(struct menu_common *c, bool *back);
+int menu_gamecfg(struct menu_common *c);
+void menu_on_pressed(void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MENU_PRIVATE_H */
diff --git a/src/menu/src/gamecfg_menu.c b/src/menu/src/gamecfg_menu.c
new file mode 100644
index 0000000..31d105e
--- /dev/null
+++ b/src/menu/src/gamecfg_menu.c
@@ -0,0 +1,88 @@
+#include <menu.h>
+#include <menu_private.h>
+#include <game.h>
+#include <gui.h>
+#include <gui/button.h>
+#include <gui/container.h>
+#include <gui/rounded_rect.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+struct gamecfg_menu
+{
+ struct gui_container cnt, bcnt;
+ struct gui_rounded_rect r;
+ struct gui_button start, back;
+};
+
+static int update(struct menu_common *const c, void *const arg)
+{
+ struct gamecfg_menu *const m = arg;
+
+ m->bcnt.common.y = screen_h - 40;
+
+ if (gui_update(&m->bcnt.common, &c->p, &c->cam))
+ return -1;
+
+ return 0;
+}
+
+static int render(const struct menu_common *const c, void *const arg)
+{
+ const struct gamecfg_menu *const m = arg;
+
+ if (gui_render(&m->cnt.common)
+ || gui_render(&m->bcnt.common))
+ return -1;
+
+ return 0;
+}
+
+int menu_gamecfg(struct menu_common *const c)
+{
+ struct gamecfg_menu m;
+ bool start = false, back = false;
+
+ gui_container_init(&m.cnt);
+ m.cnt.common.hcentered = true;
+ m.cnt.common.vcentered = true;
+
+ gui_rounded_rect_init(&m.r);
+ m.r.w = screen_w / 2;
+ m.r.h = screen_h / 2;
+ gui_add_child(&m.cnt.common, &m.r.common);
+
+ gui_container_init(&m.bcnt);
+ m.bcnt.common.hcentered = true;
+ m.bcnt.mode = GUI_CONTAINER_MODE_H;
+ m.bcnt.spacing = 8;
+
+ gui_button_init(&m.start, GUI_BUTTON_TYPE_1);
+ m.start.u.type1.label.text = "Start";
+ m.start.u.type1.w = 100;
+ m.start.common.vcentered = true;
+ m.start.on_pressed = menu_on_pressed;
+ m.start.arg = &start;
+ m.back.common.vcentered = true;
+ gui_add_child(&m.bcnt.common, &m.start.common);
+
+ gui_button_init(&m.back, GUI_BUTTON_TYPE_1);
+ m.back.u.type1.label.text = "Back";
+ m.back.u.type1.w = 100;
+ m.back.common.vcentered = true;
+ m.back.on_pressed = menu_on_pressed;
+ m.back.arg = &back;
+ m.back.common.vcentered = true;
+ gui_add_child(&m.bcnt.common, &m.back.common);
+
+ while (!back && !c->p.common.exit && !start)
+ {
+ if (menu_update(c, update, render, &m))
+ return -1;
+ }
+
+ if (start)
+ return game(NULL);
+
+ return 0;
+}
diff --git a/src/menu/src/hostjoin_menu.c b/src/menu/src/hostjoin_menu.c
new file mode 100644
index 0000000..33ad3c8
--- /dev/null
+++ b/src/menu/src/hostjoin_menu.c
@@ -0,0 +1,85 @@
+#include <menu.h>
+#include <menu_private.h>
+#include <game.h>
+#include <gui.h>
+#include <gui/button.h>
+#include <gui/container.h>
+#include <stdbool.h>
+
+struct menu_hostjoin
+{
+ struct gui_container cnt;
+ struct gui_button host, join, back;
+};
+
+static int update(struct menu_common *const c, void *const arg)
+{
+ struct menu_hostjoin *const m = arg;
+
+ if (gui_update(&m->cnt.common, &c->p, &c->cam))
+ return -1;
+
+ return 0;
+}
+
+static int render(const struct menu_common *const c, void *const arg)
+{
+ const struct menu_hostjoin *const m = arg;
+
+ if (gui_render(&m->cnt.common))
+ return -1;
+
+ return 0;
+}
+
+int menu_hostjoin(struct menu_common *const c, bool *const back)
+{
+ do
+ {
+ struct menu_hostjoin m;
+ bool host = false, join = false;
+
+ gui_container_init(&m.cnt);
+ m.cnt.common.hcentered = true;
+ m.cnt.common.vcentered = true;
+ m.cnt.spacing = 4;
+ m.cnt.mode = GUI_CONTAINER_MODE_V;
+
+ gui_button_init(&m.host, GUI_BUTTON_TYPE_1);
+ m.host.u.type1.label.text = "Host game";
+ m.host.common.hcentered = true;
+ m.host.u.type1.w = 140;
+ m.host.arg = &host;
+ m.host.on_pressed = menu_on_pressed;
+ gui_add_child(&m.cnt.common, &m.host.common);
+
+ gui_button_init(&m.join, GUI_BUTTON_TYPE_1);
+ m.join.u.type1.label.text = "Join game";
+ m.join.common.hcentered = true;
+ m.join.u.type1.w = 140;
+ m.join.arg = &join;
+ m.join.on_pressed = menu_on_pressed;
+ gui_add_child(&m.cnt.common, &m.join.common);
+
+ gui_button_init(&m.back, GUI_BUTTON_TYPE_1);
+ m.back.u.type1.label.text = "Back";
+ m.back.common.hcentered = true;
+ m.back.u.type1.w = 140;
+ m.back.arg = back;
+ m.back.on_pressed = menu_on_pressed;
+ gui_add_child(&m.cnt.common, &m.back.common);
+
+ while (!*back && !c->p.common.exit && !host && !join)
+ {
+ if (menu_update(c, update, render, &m))
+ return -1;
+ }
+
+ if (host || join)
+ if (menu_gamecfg(c))
+ return -1;
+
+ } while (!*back && !c->p.common.exit);
+
+ return 0;
+}
diff --git a/src/menu/src/main_menu.c b/src/menu/src/main_menu.c
new file mode 100644
index 0000000..9a99e7c
--- /dev/null
+++ b/src/menu/src/main_menu.c
@@ -0,0 +1,87 @@
+#include <menu.h>
+#include <menu_private.h>
+#include <gui.h>
+#include <gui/button.h>
+#include <gui/container.h>
+#include <gui/rounded_rect.h>
+#include <system.h>
+#include <stdbool.h>
+
+struct main_menu
+{
+ bool start, exit;
+ struct gui_button play, exit_btn;
+ struct gui_container cnt;
+};
+
+static int update(struct menu_common *const c, void *const arg)
+{
+ struct main_menu *const m = arg;
+
+ if (gui_update(&m->play.common, &c->p, &c->cam))
+ return -1;
+
+ return 0;
+}
+
+static int render(const struct menu_common *const c, void *const arg)
+{
+ const struct main_menu *const m = arg;
+
+ if (gui_render(&m->cnt.common))
+ return -1;
+
+ return 0;
+}
+
+int menu_main(struct menu_common *const c)
+{
+ bool back;
+
+ do
+ {
+ struct main_menu m = {0};
+
+ back = false;
+
+ gui_container_init(&m.cnt);
+ m.cnt.mode = GUI_CONTAINER_MODE_V;
+ m.cnt.common.hcentered = true;
+ m.cnt.common.vcentered = true;
+ m.cnt.spacing = 4;
+
+ gui_button_init(&m.play, GUI_BUTTON_TYPE_1);
+ m.play.on_pressed = menu_on_pressed;
+ m.play.arg = &m.start;
+ m.play.u.type1.w = 140;
+ m.play.common.hcentered = true;
+ m.play.u.type1.label.text = "Play";
+ gui_add_child(&m.cnt.common, &m.play.common);
+
+ if (system_can_exit())
+ {
+ gui_button_init(&m.exit_btn, GUI_BUTTON_TYPE_1);
+ m.exit_btn.arg = &m.exit;
+ m.exit_btn.u.type1.w = 140;
+ m.exit_btn.common.hcentered = true;
+ m.exit_btn.u.type1.label.text = "Exit";
+ m.exit_btn.on_pressed = menu_on_pressed;
+ gui_add_child(&m.cnt.common, &m.exit_btn.common);
+ }
+
+ while (!m.start)
+ {
+ if (menu_update(c, update, render, &m))
+ return -1;
+
+ if (m.exit)
+ return 0;
+ }
+
+ if (menu_hostjoin(c, &back))
+ return -1;
+
+ } while (back && !c->p.common.exit);
+
+ return 0;
+}
diff --git a/src/menu/src/menu.c b/src/menu/src/menu.c
index c2f1e96..a8df6e9 100644
--- a/src/menu/src/menu.c
+++ b/src/menu/src/menu.c
@@ -1,101 +1,75 @@
#include <menu.h>
+#include <menu_private.h>
#include <camera.h>
#include <game.h>
#include <gfx.h>
-#include <gui.h>
-#include <gui/button.h>
-#include <gui/container.h>
+#include <peripheral.h>
#include <system.h>
#include <stdbool.h>
-static void on_pressed(void *const arg)
+void menu_on_pressed(void *const arg)
{
*(bool *)arg = true;
}
-int menu(void)
+int menu_update(struct menu_common *const c,
+ int (*update)(struct menu_common *, void *),
+ int (*render)(const struct menu_common *, void *),
+ void *const arg)
{
- struct camera cam = {0};
- struct gui_button play, exit_btn;
- struct gui_container cnt;
- union peripheral p;
- bool start = false, exit = false;
+ system_loop();
+ peripheral_update(&c->p);
+ camera_update(&c->cam, &c->p);
- if (game_resinit())
+ if (update && update(c, arg))
return -1;
- cursor_init(&cam.cursor);
- gui_container_init(&cnt);
- cnt.mode = GUI_CONTAINER_MODE_V;
- cnt.common.hcentered = true;
- cnt.common.vcentered = true;
- cnt.spacing = 4;
- gui_button_init(&play, GUI_BUTTON_TYPE_1);
- gui_button_init(&exit_btn, GUI_BUTTON_TYPE_1);
- play.on_pressed = on_pressed;
- play.arg = &start;
- play.u.type1.w = 140;
- play.common.hcentered = true;
- play.u.type1.label.text = "Play";
-
- exit_btn.arg = &exit;
- exit_btn.u.type1.w = 140;
- exit_btn.common.hcentered = true;
- exit_btn.u.type1.label.text = "Exit";
- exit_btn.on_pressed = on_pressed;
- gui_add_child(&cnt.common, &play.common);
- gui_add_child(&cnt.common, &exit_btn.common);
+ rect_get_or_ret(r, -1);
+ rect_init(r);
+ r->w = screen_w;
+ r->h = screen_h;
+ rect_sort(r);
- {
- const struct peripheral_cfg cfg =
- {
- .type = PERIPHERAL_TYPE_KEYBOARD_MOUSE
- };
-
- peripheral_init(&cfg, &p);
- }
+ if (render && render(c, arg))
+ return -1;
- while (!start)
+ switch (c->p.common.type)
{
- system_loop();
- peripheral_update(&p);
- camera_update(&cam, &p);
-
- if (gui_update(&play.common, &p, &cam))
- return -1;
+ case PERIPHERAL_TYPE_PAD:
+ /* Fall through. */
+ case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
+ if (cursor_render(&c->cam.cursor))
+ return -1;
- rect_get_or_ret(r, -1);
- rect_init(r);
- r->w = screen_w;
- r->h = screen_h;
- rect_sort(r);
+ break;
- if (p.common.exit || exit)
- return 0;
+ case PERIPHERAL_TYPE_TOUCH:
+ break;
- if (gui_render(&cnt.common))
+ default:
return -1;
+ }
- switch (p.common.type)
- {
- case PERIPHERAL_TYPE_PAD:
- /* Fall through. */
- case PERIPHERAL_TYPE_KEYBOARD_MOUSE:
- if (cursor_render(&cam.cursor))
- return -1;
+ if (gfx_draw())
+ return -1;
- break;
+ return 0;
+}
- case PERIPHERAL_TYPE_TOUCH:
- break;
+int menu(void)
+{
+ const struct peripheral_cfg cfg =
+ {
+ .type = PERIPHERAL_TYPE_KEYBOARD_MOUSE
+ };
- default:
- return -1;
- }
+ struct menu_common c = {0};
- if (gfx_draw())
+ if (game_resinit())
return -1;
- }
- return game(NULL);
+ cursor_init(&c.cam.cursor);
+ peripheral_init(&cfg, &c.p);
+
+ return menu_main(&c);
}