]> git.mcshandy.xyz Git - barrow_crawler/commitdiff
Add proper difficulty options and difficulty select sub menu for new game.
authorRandy McShandy <randy@mcshandy.xyz>
Mon, 11 Aug 2025 01:49:08 +0000 (20:49 -0500)
committerRandy McShandy <randy@mcshandy.xyz>
Mon, 11 Aug 2025 01:49:08 +0000 (20:49 -0500)
bin/posix_BC
src/enums.h
src/menufuncs.c
src/menufuncs.h
src/render_raylib.c
src/structs.c
src/structs.h
src/ui.c
src/ui.h
src/utils.c

index 4c7ab7006b52be8fcd88597f930d06b5f1f3081a..1b7b423e120b4b966c135fde4513107182d5d228 100755 (executable)
Binary files a/bin/posix_BC and b/bin/posix_BC differ
index 503f6bf233b7cceb87e5c8671507a5745ac4333c..1591c77370eb02af71cd4c7520d552ad5257d5de 100644 (file)
@@ -58,12 +58,30 @@ typedef enum
   CONTROL_MODES
 } eControlMode;
 
+typedef enum
+{
+  MAIN_MENU = 0,
+  DIFFICULTY_MENU,
+  MENU_COUNT
+} eMenus;
+
+typedef enum
+{
+  DIFFICULTY_1 = 0,
+  DIFFICULTY_2,
+  DIFFICULTY_3,
+  DIFFICULTY_ITEMS
+} eDifficultyItem;
+
 #define MENU_ITEMS  \
   X(MI_NONE)                     \
   X(MI_NEW_GAME)         \
   X(MI_LOAD_GAME)        \
   X(MI_SAVE_GAME)        \
   X(MI_QUIT)                     \
+  X(MI_DIFFICULTY_1)\
+  X(MI_DIFFICULTY_2)\
+  X(MI_DIFFICULTY_3)\
   X(MI_ITEMS)
 
 #define X(item) item,
index 26273b82d155f8dab6d389fcb146f6ce7fa5462e..45885d95f120d0d4e065f891b22004ee4f86bcc6 100644 (file)
@@ -7,10 +7,7 @@
 #include "structs.h"
 #include "utils.h"
 
-bool menu_action_MI_NONE()
-{ return true; }
-
-bool menu_action_MI_NEW_GAME()
+bool internal_new_game()
 {
   bool response = false;
   resource_state = RENDER_RESOURCE_WAIT;
@@ -18,12 +15,60 @@ bool menu_action_MI_NEW_GAME()
   /* Clean up previous run's files and the old save. */
   cleanup_generated_files();
 
+  const float density = 1.6f;
+  const size_t barrow_size = sizes[generation_info.difficulty];
+
+  initialize_generation_info((IVec2){.x = barrow_size * density, .y = barrow_size * density}, 8);
+
+  playtime.room_count = generation_info.room_count;
+
   pthread_create(&generation_info.generator_thread, NULL, generate_rd, NULL);
   pthread_detach(generation_info.generator_thread);
 
   return response;
 }
 
+bool menu_action_MI_NONE()
+{ return true; }
+
+bool menu_action_MI_NEW_GAME()
+{
+  bool response = false;
+
+  (menu_info.difficulty_select_visible = true);
+
+  return response;
+}
+
+bool menu_action_MI_DIFFICULTY_1()
+{
+  bool response = false;
+
+  generation_info.difficulty = DIFFICULTY_1;
+  response |= internal_new_game();
+  return response;
+}
+
+bool menu_action_MI_DIFFICULTY_2()
+{
+  bool response = false;
+
+  generation_info.difficulty = DIFFICULTY_2;
+  response |= internal_new_game();
+
+  return response;
+}
+
+bool menu_action_MI_DIFFICULTY_3()
+{
+  bool response = false;
+
+  generation_info.difficulty = DIFFICULTY_3;
+  response |= internal_new_game();
+
+  return response;
+}
+
 bool menu_action_MI_LOAD_GAME()
 {
   bool response = false;
index c82e776f3342807134da85b965c2177bc963c077..eb28978b95cf956710e331775b0da3aab9dfefca 100644 (file)
@@ -13,6 +13,11 @@ bool menu_action_MI_SAVE_GAME();
 bool menu_action_MI_QUIT();
 bool menu_action_MI_ITEMS();
 
+#define X(item) \
+  bool menu_action_ ## item ();
+MENU_ITEMS
+#undef X
+
 extern menufunc menufuncs[MI_ITEMS + 1];
 
 #endif /* __MENU_FUNCS__ */
index 3877989088db3909ff78fc949e3cf282709f2a7f..8a2e8425b072b18a479fbd6ad986a346cd164533 100644 (file)
@@ -136,20 +136,11 @@ Color ColorLerp(Color c1, Color c2, float amount)
        return new_color;
 }
 
-void drawing_main_menu_mode()
+void draw_menu(MenuButton* menu_buttons, size_t menu_size)
 {
-  ClearBackground(LIGHTGRAY);
-
-  const size_t title_font_size = 64;
-  const size_t sub_font_size = 48;
-  const char title_text[] = "Randy's Barrow Adventure";
-
-       DrawText(title_text,
-                       (fscreen_dims.x/2.0f) - (MeasureText(title_text, title_font_size)/2.0f), (fscreen_dims.y/4.0f) * 1.0f, title_font_size, BLACK);
-
-  for (size_t n = 0; n < 3; n++)
+  for (size_t n = 0; n < menu_size; n++)
   {
-    const MenuButton button = main_menu_items[n];
+    const MenuButton button = menu_buttons[n];
     const char* text = menu_items[button.item_index].text;
     const Vector2 text_v2 = button.text_v2;
     const Rectangle button_bound = button.button_bound;
@@ -160,7 +151,24 @@ void drawing_main_menu_mode()
 
     DrawRectangle(button_bound.x, button_bound.y, button_bound.width, button_bound.height, bg);
     DrawText(text,
-        text_v2.x, text_v2.y, sub_font_size, fg);
+        text_v2.x, text_v2.y, button.font_size, fg);
+  }
+}
+
+void drawing_main_menu_mode()
+{
+  ClearBackground(LIGHTGRAY);
+
+  const size_t title_font_size = 64;
+  const char title_text[] = "Kurgan of The Worm King";
+
+       DrawText(title_text,
+                       (fscreen_dims.x/2.0f) - (MeasureText(title_text, title_font_size)/2.0f), (fscreen_dims.y/4.0f) * 1.0f, title_font_size, BLACK);
+
+  draw_menu(main_menu_items, sizeof(main_menu_items)/sizeof(main_menu_items[0]));
+  if(menu_info.difficulty_select_visible)
+  {
+    draw_menu(new_game_menu_items, sizeof(new_game_menu_items)/sizeof(new_game_menu_items[0]));
   }
 }
 
@@ -611,13 +619,6 @@ void initialize_prerenderer()
 {
        fscreen_dims = (Vector2){.x=screen_dims.x, .y=screen_dims.y};
 
-  const float density = 1.6f;
-  const size_t barrow_size = sizes[0];
-
-  initialize_generation_info((IVec2){.x = barrow_size * density, .y = barrow_size * density}, 8);
-
-  playtime.room_count = generation_info.room_count;
-
        /* Mode handler setup */
        {
                renderfuncs[RENDER_MAIN_MENU]       = drawing_main_menu_mode;
index 55b71596b584a43cde01d291fa14a402e5ff81de..d99dac630b9cf7ce473b50df15449676d8379d16 100644 (file)
@@ -103,7 +103,7 @@ const int target_fps = 60;
 
 GenerationInfo generation_info;
 
-const size_t sizes[3] = {128, 168, 208};
+const size_t sizes[DIFFICULTY_ITEMS] = {128, 168, 208};
 
 // Move this into menuinfo
 // Actually merge all of them into a display manager
index 4836c8c6d3447c49fb1536d67658dd970d5b732f..b20fc09cc313eb5dcd657d02ea605d0de6d7ebf5 100644 (file)
@@ -110,6 +110,7 @@ typedef struct
   float generation_progress;
   uint32_t worker_count;
   uint32_t room_count;
+  eDifficultyItem difficulty;
 
   RD_Opts rd_opt;
 
@@ -139,7 +140,7 @@ extern const char* screen_title;
 extern const int target_fps;
 
 extern int resource_state;
-extern const size_t sizes[3];
+extern const size_t sizes[DIFFICULTY_ITEMS];
 
 //int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size);
 void* generate_rd(void* args);
index 22e2ff651f13cbdb5473bda12fc8fad49eb5f2e1..c4dceadcb9bf97f189c9218a4488a2af9f0c04d8 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -6,11 +6,14 @@
 
 const MenuItem menu_items[MI_ITEMS] =
 {
-  { MI_NONE,      ""          , false},
-  { MI_NEW_GAME,  "New Game"  , false},
-  { MI_LOAD_GAME, "Load Game" , false},
-  { MI_SAVE_GAME, "Save Game" , false},
-  { MI_QUIT,      "Quit"      , false},
+  { MI_NONE,          ""            , false },
+  { MI_NEW_GAME,      "New Game >"  , false },
+  { MI_LOAD_GAME,     "Load Game"   , false },
+  { MI_SAVE_GAME,     "Save Game"   , false },
+  { MI_QUIT,          "Quit"        , false },
+  { MI_DIFFICULTY_1,  "Normal"      , false },
+  { MI_DIFFICULTY_2,  "Hard"        , false },
+  { MI_DIFFICULTY_3,  "FREAKS"      , false },
 };
 
 MenuButton main_menu_items[3] =
@@ -20,6 +23,13 @@ MenuButton main_menu_items[3] =
   { MI_QUIT     , (Rectangle){}, (Vector2){}, DARKGRAY, LIGHTGRAY, 48 }
 };
 
+MenuButton new_game_menu_items[DIFFICULTY_ITEMS] =
+{
+  { MI_DIFFICULTY_1 , (Rectangle){}, (Vector2){}, DARKGRAY, LIGHTGRAY, 48 },
+  { MI_DIFFICULTY_2 , (Rectangle){}, (Vector2){}, DARKGRAY, LIGHTGRAY, 48 },
+  { MI_DIFFICULTY_3 , (Rectangle){}, (Vector2){}, DARKGRAY, LIGHTGRAY, 48 }
+};
+
 MenuInfo menu_info =
 {
   RENDER_MAIN_MENU,
@@ -31,6 +41,8 @@ menufunc menufuncs[MI_ITEMS+1];
 
 void init_menus(Vector2 screen_dims)
 {
+  menu_info.difficulty_select_visible = false;
+
   for (size_t n = 0; n < sizeof(main_menu_items)/sizeof(main_menu_items[0]); n++)
   {
     MenuButton* button = &main_menu_items[n];
@@ -58,13 +70,40 @@ void init_menus(Vector2 screen_dims)
 
   }
 
+  for (size_t n = 0; n < sizeof(new_game_menu_items)/sizeof(new_game_menu_items[0]); n++)
+  {
+    MenuButton* button = &new_game_menu_items[n];
+    const MenuItem* menu_item = &menu_items[button->item_index];
+    const int text_width = MeasureText(menu_item->text, button->font_size);
+    const Vector2 text_size = {.x = text_width, .y = button->font_size};
+    const uint32_t margin = 8U;
+
+    Vector2 text_v2 =
+    {
+      main_menu_items[0].button_bound.x + main_menu_items[0].button_bound.width + (margin * 4U),
+      (screen_dims.y/13.0f) * (n+5),
+    };
+
+    Rectangle button_bound =
+    (Rectangle){
+      .x       = text_v2.x - margin,
+      .y       = text_v2.y - margin,
+      .width   = text_size.x + margin * 2U,
+      .height  = text_size.y + margin,
+    };
+
+    button->button_bound = button_bound;
+    button->text_v2 = text_v2;
+
+  }
+
 #define X(emenu_item) menufuncs[emenu_item] = menu_action_ ## emenu_item;
   MENU_ITEMS
 #undef X
 
 }
 
-void control_main_menu_mode()
+void control_menu(MenuButton* menu_buttons, size_t menu_size)
 {
   const Vector2 mouse = GetMousePosition();
   const bool left_click = IsMouseButtonReleased(MOUSE_LEFT_BUTTON);
@@ -73,11 +112,9 @@ void control_main_menu_mode()
      Set globals
      Let renderfunc act on it
    */
-
-  menu_info.hover_item = MI_NONE;
-  for (size_t n = 0; n < sizeof(main_menu_items)/sizeof(main_menu_items[0]); n++)
+  for (size_t n = 0; n < menu_size; n++)
   {
-    const MenuButton button = main_menu_items[n];
+    const MenuButton button = menu_buttons[n];
     const Rectangle button_bound = button.button_bound;
     const bool mouse_in_container = CheckCollisionPointRec(mouse, button_bound);
 
@@ -92,6 +129,12 @@ void control_main_menu_mode()
       menufuncs[menu_info.hover_item]();
     }
   }
+}
 
+void control_main_menu_mode()
+{
+  menu_info.hover_item = MI_NONE;
+  control_menu(main_menu_items, sizeof(main_menu_items)/sizeof(main_menu_items[0]));
+  control_menu(new_game_menu_items, sizeof(new_game_menu_items)/sizeof(new_game_menu_items[0]));
 }
 
index 446f8656ba20b1afd515d49a3ebbe1075513417c..4e6aa7f0907f4342992fcaa9ea82dca64a4a508c 100644 (file)
--- a/src/ui.h
+++ b/src/ui.h
@@ -12,6 +12,8 @@ typedef struct
   eControlMode control_mode;
   eMenuItem hover_item;
   bool hover_item_picked;
+
+  bool difficulty_select_visible;
 } MenuInfo;
 
 typedef struct
@@ -34,6 +36,7 @@ typedef struct
 extern MenuInfo menu_info;
 extern const MenuItem menu_items[MI_ITEMS];
 extern MenuButton main_menu_items[3];
+extern MenuButton new_game_menu_items[DIFFICULTY_ITEMS];
 
 void init_menus(Vector2 screen_dims);
 void control_main_menu_mode();
index 9b805fc5f7fcc6d5ed698f12cc7bfdcac41d4536..2694828e8b5d10da1b7b0ed6133b590d581bfa51 100644 (file)
@@ -344,7 +344,7 @@ bool initialize_generation_info(const IVec2 pgrid_size, const int pworker_count)
   generation_info.generation_progress = 0.0f;
   generation_info.worker_count = pworker_count;
   generation_info.rd_opt = barrow;
-  generation_info.room_count = 4;
+  generation_info.room_count = 9;
 
   response |= !(generation_info.grid = (FVec2**)malloc(grid_size.x * sizeof(FVec2*)));
   for (int n = 0; n < grid_size.x; n++)