DEADSOFTWARE

portability: avoid errors on some compilers
[flatwaifu.git] / src / menu.c
index ddbf0b4deb8a35a4e8735d9fec8d060bcdb457cd..037782a7f7d5e1125a7b81c7709d3e72eaca7c01 100644 (file)
@@ -1,24 +1,17 @@
-/*
-   Copyright (C) Prikol Software 1996-1997
-   Copyright (C) Aleksey Volynskov 1996-1997
-   Copyright (C) <ARembo@gmail.com> 2011
-
-   This file is part of the Doom2D:Rembo project.
-
-   Doom2D:Rembo is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
-
-   Doom2D:Rembo is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, see <http://www.gnu.org/licenses/> or
-   write to the Free Software Foundation, Inc.,
-   51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
-*/
+/* Copyright (C) 2020 SovietPony
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License ONLY.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #include "glob.h"
 #include "files.h"
@@ -164,7 +157,7 @@ static int start_game (int twoplayers, int dm, int level) {
 
 static int new_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
   static int cur;
-  enum { ONEPLAYER, TWOPLAYERS, DEATHMATCH, __NUM__ };
+  enum { ONEPLAYER, TWOPLAYERS, DEATHMATCH, NG__NUM__ };
   static const simple_menu_t sm = {
     GM_BIG, "New Game", "_NEWGAME",
     {
@@ -181,7 +174,7 @@ static int new_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
       // GM_say("_COOP");
     }
   }
-  return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
+  return simple_menu_handler(msg, i, NG__NUM__, &sm, &cur);
 }
 
 static int load_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
@@ -226,16 +219,83 @@ static int save_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
   return basic_menu_handler(msg, GM_BIG, "Save game", "_SAVGAME", max_slots, &cur);
 }
 
+typedef struct controls_menu_t {
+  menu_t base;
+  int *pl_keys;
+} controls_menu_t;
+
+static int controls_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
+  static int cur = 0;
+  static int state = 0;
+  const int max_controls = 9;
+  const char *str = NULL;
+  const controls_menu_t *mm = (controls_menu_t*)m;
+  const char *captions[] = {
+    "Up: ", "Down: ", "Left: ", "Right: ", "Fire: ", "Jump: ", "Prev: ", "Next: ", "Press: "
+  };
+  assert(i >= 0 && i < max_controls);
+  switch (msg->type) {
+    case GM_ENTER:
+      state = 0;
+      break; /* default behavior */
+    case GM_LEAVE:
+      if (state == 0) {
+        break; /* default behavior */
+      } else {
+        state = 0;
+        return 1;
+      }
+    case GM_UP:
+    case GM_DOWN:
+      if (state == 0) {
+        break; /* default behavior */
+      } else {
+        return 1; /* ignore */
+      }
+    case GM_KEY:
+      if (state != 0 && msg->integer.i != KEY_UNKNOWN) {
+        mm->pl_keys[cur] = msg->integer.i;
+        state = 0;
+      }
+      return 1;
+    case GM_GETENTRY:
+      return GM_init_int0(msg, GM_SMALL_BUTTON, 0, 0, 0);
+    case GM_GETCAPTION:
+      return GM_init_str(msg, (char*)captions[i], strlen(captions[i]));
+    case GM_GETSTR:
+      if (state == 0 || i != cur) {
+        str = I_key_to_string(mm->pl_keys[i]);
+      } else {
+        str = "...";
+      }
+      return GM_init_str(msg, (char*)str, strlen(str));
+    case GM_SELECT:
+      state = state == 0 ? 1 : 0;
+      return 1;
+  }
+  return basic_menu_handler(msg, GM_BIG, "Player 1 controls", NULL, max_controls, &cur);
+}
+
 static int options_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
   static int cur;
   const menu_t *mm;
-  enum { VIDEO, SOUND, MUSIC, __NUM__ };
+  enum { VIDEO, SOUND, MUSIC, CONTROLS_1, CONTROLS_2, OPT__NUM__ };
+  static const controls_menu_t c1 = {
+    { controls_menu_handler },
+    &pl1.ku
+  };
+  static const controls_menu_t c2 = {
+    { controls_menu_handler },
+    &pl2.ku
+  };
   static const simple_menu_t sm = {
     GM_BIG, "Options", NULL,
     {
       { "Video", NULL },
       { "Sound", NULL },
       { "Music", NULL },
+      { "Controls 1", &c1.base },
+      { "Controls 2", &c2.base },
     }
   };
   if (msg->type == GM_SELECT) {
@@ -249,12 +309,12 @@ static int options_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
       return GM_push(mm);
     }
   }
-  return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
+  return simple_menu_handler(msg, i, OPT__NUM__, &sm, &cur);
 }
 
 static int exit_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
   static int cur;
-  enum { YES, NO, __NUM__ };
+  enum { YES, NO, EXIT__NUM__ };
   static const simple_menu_t sm = {
     GM_SMALL, "You are sure?", NULL,
     {
@@ -277,14 +337,13 @@ static int exit_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
         return GM_pop();
     }
   }
-  return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
+  return simple_menu_handler(msg, i, EXIT__NUM__, &sm, &cur);
 }
 
 static int main_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
-  enum { NEWGAME, OLDGAME, SAVEGAME, OPTIONS, EXIT, __NUM__ };
-  assert(i >= 0 && i < __NUM__);
+  enum { NEWGAME, OLDGAME, SAVEGAME, OPTIONS, EXIT, MAIN__NUM__ };
   static int cur;
-  static const menu_t hm[__NUM__] = {
+  static const menu_t hm[MAIN__NUM__] = {
     { new_game_menu_handler },
     { load_game_menu_handler },
     { save_game_menu_handler },
@@ -301,16 +360,17 @@ static int main_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
       { "Exit", &hm[EXIT] }
     }
   };
-  return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
+  assert(i >= 0 && i < MAIN__NUM__);
+  return simple_menu_handler(msg, i, MAIN__NUM__, &sm, &cur);
 }
 
 static const menu_t main_menu = { &main_menu_handler };
 
 int GM_push (const menu_t *m) {
+  menu_msg_t msg;
   assert(m != NULL);
   assert(stack_p >= -1);
   assert(stack_p < MAX_STACK - 1);
-  menu_msg_t msg;
   stack_p += 1;
   stack[stack_p].m = m;
   msg.type = GM_ENTER;
@@ -319,8 +379,8 @@ int GM_push (const menu_t *m) {
 }
 
 int GM_pop (void) {
-  assert(stack_p >= 0);
   menu_msg_t msg;
+  assert(stack_p >= 0);
   stack_p -= 1;
   msg.type = GM_LEAVE;
   GM_send_this(stack[stack_p + 1].m, &msg);
@@ -417,7 +477,7 @@ void G_code (void) {
   Z_sound(s,128);
 }
 
-static int strnlen (const char *s, int len) {
+static int x_strnlen (const char *s, int len) {
   int i = 0;
   while (i < len && s[i] != 0) {
     i++;
@@ -439,12 +499,19 @@ int GM_act (void) {
       Z_sound(msnd3, 128);
     }
   } else {
+    /* 1. send key */
+    msg.type = GM_KEY;
+    GM_init_int0(&msg, lastkey, 0, 0, 0);
+    GM_send_this(m, &msg);
+    /* 2. send query */
     msg.type = GM_QUERY;
     if (GM_send_this(m, &msg)) {
+      /* 3. send getentry */
       cur = msg.integer.i;
       n = msg.integer.a;
       msg.type = GM_GETENTRY;
       if (GM_send(m, cur, &msg)) {
+        /* 4. send actions */
         type = msg.integer.i;
         switch (lastkey) {
           case KEY_ESCAPE:
@@ -482,7 +549,7 @@ int GM_act (void) {
             } else if (type == GM_TEXTFIELD) {
               //if (input) {
               //  icur += lastkey == KEY_LEFT ? -1 : +1;
-              //  icur = min(max(icur, 0), strnlen(ibuf, imax));
+              //  icur = min(max(icur, 0), x_strnlen(ibuf, imax));
               //}
             }
             break;
@@ -510,7 +577,7 @@ int GM_act (void) {
                 if (GM_send(m, cur, &msg)) {
                   imax = min(msg.string.maxlen, GM_MAX_INPUT);
                   strncpy(ibuf, msg.string.s, imax);
-                  icur = strnlen(ibuf, imax);
+                  icur = x_strnlen(ibuf, imax);
                 } else {
                   memset(ibuf, 0, GM_MAX_INPUT);
                   imax = GM_MAX_INPUT;
@@ -524,7 +591,6 @@ int GM_act (void) {
               Z_sound(msnd2, 128);
             } else {
               msg.type = GM_SELECT;
-              if (cur < 0) abort();
               if (GM_send(m, cur, &msg)) {
                 Z_sound(msnd2, 128);
               }