diff --git a/src/menu.c b/src/menu.c
index 4205285ea1f5436574805f05ad61325c19694784..688fc25bf255bc87a7a1749d9e882329cce36926 100644 (file)
--- a/src/menu.c
+++ b/src/menu.c
-/*
- 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"
return GM_popall();
}
-static int new_game_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
+static int new_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
static int cur;
enum { ONEPLAYER, TWOPLAYERS, DEATHMATCH, __NUM__ };
static const simple_menu_t sm = {
@@ -184,11 +177,7 @@ static int new_game_menu_handler (menu_msg_t *msg, const menu_t *m, void *data,
return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
}
-static const menu_t new_game_menu = {
- NULL, &new_game_menu_handler
-};
-
-static int load_game_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
+static int load_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
static int cur;
const int max_slots = 7;
assert(i >= 0 && i < max_slots);
@@ -206,11 +195,7 @@ static int load_game_menu_handler (menu_msg_t *msg, const menu_t *m, void *data,
return basic_menu_handler(msg, GM_BIG, "Load game", "_OLDGAME", max_slots, &cur);
}
-static const menu_t load_game_menu = {
- NULL, &load_game_menu_handler
-};
-
-static int save_game_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
+static int save_game_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
static int cur;
const int max_slots = 7;
assert(i >= 0 && i < max_slots);
@@ -234,92 +219,96 @@ static int save_game_menu_handler (menu_msg_t *msg, const menu_t *m, void *data,
return basic_menu_handler(msg, GM_BIG, "Save game", "_SAVGAME", max_slots, &cur);
}
-static const menu_t save_game_menu = {
- NULL, &save_game_menu_handler
-};
-
-static int sound_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
- static int cur;
- enum { VOLUME, __NUM__ };
- static const simple_menu_t sm = {
- GM_BIG, "Sound", NULL,
- {
- { "Volume", NULL },
- }
- };
- if (i == VOLUME) {
- switch (msg->type) {
- case GM_GETENTRY: return GM_init_int0(msg, GM_SCROLLER, 0, 0, 0);
- case GM_GETINT: return GM_init_int(msg, snd_vol, 0, 128, 8);
- case GM_SETINT: S_volume(msg->integer.i); return 1;
- }
- }
- return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
-}
-
-static const menu_t sound_menu = {
- NULL, &sound_menu_handler
-};
-
-static int music_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
- static int cur;
- enum { VOLUME, MUSIC, __NUM__ };
- static const simple_menu_t sm = {
- GM_BIG, "Music", NULL,
- {
- { "Volume", NULL },
- { "Music: ", NULL },
- }
+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: "
};
- if (i == VOLUME) {
- switch (msg->type) {
- case GM_GETENTRY: return GM_init_int0(msg, GM_SCROLLER, 0, 0, 0);
- case GM_GETINT: return GM_init_int(msg, mus_vol, 0, 128, 8);
- case GM_SETINT: S_volumemusic(msg->integer.i); return 1;
- }
- } else if (i == MUSIC) {
- switch (msg->type) {
- case GM_GETSTR: return GM_init_str(msg, g_music, strlen(g_music));
- case GM_SELECT:
- F_freemus();
- F_nextmus(g_music);
- F_loadmus(g_music);
- S_startmusic(music_time * 2); // ???
+ 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:
+ str = state == 0 || i != cur ? I_key_to_string(mm->pl_keys[i]) : "...";
+ return GM_init_str(msg, (char*)str, strlen(str));
+ case GM_SELECT:
+ state = state == 0 ? 1 : 0;
+ return 1;
}
- return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
+ return basic_menu_handler(msg, GM_BIG, "Player 1 controls", NULL, max_controls, &cur);
}
-static const menu_t music_menu = {
- NULL, &music_menu_handler
-};
-
-static int options_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
+static int options_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
static int cur;
- enum { VIDEO, SOUND, MUSIC, __NUM__ };
+ const menu_t *mm;
+ enum { VIDEO, SOUND, MUSIC, CONTROLS_1, CONTROLS_2, __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", &sound_menu },
- { "Music", &music_menu },
+ { "Sound", NULL },
+ { "Music", NULL },
+ { "Controls 1", &c1.base },
+ { "Controls 2", &c2.base },
}
};
if (msg->type == GM_SELECT) {
- if (i == VIDEO) {
- const menu_t *mm = R_menu();
- return mm ? GM_push(mm) : 1;
+ switch (i) {
+ case VIDEO: mm = R_menu(); break;
+ case SOUND: mm = S_menu(); break;
+ case MUSIC: mm = MUS_menu(); break;
+ default: mm = NULL;
+ }
+ if (mm != NULL) {
+ return GM_push(mm);
}
}
return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
}
-static const menu_t options_menu = {
- NULL, &options_menu_handler
-};
-
-static int exit_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
+static int exit_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
static int cur;
enum { YES, NO, __NUM__ };
static const simple_menu_t sm = {
} else if (msg->type == GM_SELECT) {
switch (i) {
case YES:
- F_freemus();
+ MUS_free();
GM_stop();
Z_sound(S_get(qsnd[myrand(QSND_NUM)]), 255);
S_wait();
@@ -347,29 +336,31 @@ static int exit_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int
return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
}
-static const menu_t exit_menu = {
- NULL, &exit_menu_handler
-};
-
-static int main_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
- static int 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__);
+ static int cur;
+ static const menu_t hm[__NUM__] = {
+ { new_game_menu_handler },
+ { load_game_menu_handler },
+ { save_game_menu_handler },
+ { options_menu_handler},
+ { exit_menu_handler }
+ };
static const simple_menu_t sm = {
GM_BIG, "Menu", NULL,
{
- { "New Game", &new_game_menu },
- { "Load Game", &load_game_menu },
- { "Save Game", &save_game_menu },
- { "Options", &options_menu },
- { "Exit", &exit_menu },
+ { "New Game", &hm[NEWGAME] },
+ { "Load Game", &hm[OLDGAME] },
+ { "Save Game", &hm[SAVEGAME] },
+ { "Options", &hm[OPTIONS] },
+ { "Exit", &hm[EXIT] }
}
};
return simple_menu_handler(msg, i, __NUM__, &sm, &cur);
}
-static const menu_t main_menu = {
- NULL, &main_menu_handler
-};
+static const menu_t main_menu = { &main_menu_handler };
int GM_push (const menu_t *m) {
assert(m != NULL);
assert(msg != NULL);
if (m->handler != NULL) {
GM_normalize_message(msg);
- return m->handler(msg, m, m->data, 0);
+ return m->handler(msg, m, 0);
}
return 0;
}
assert(msg != NULL);
if (m->handler != NULL) {
GM_normalize_message(msg);
- return m->handler(msg, m, m->data, i);
+ return m->handler(msg, m, i);
}
return 0;
}
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++;
int GM_act (void) {
menu_msg_t msg;
int n, cur, type;
- const menu_t *m = GM_get ();
+ const menu_t *m = GM_get();
if (m == NULL) {
if (lastkey == KEY_ESCAPE || (state_for_anykey(g_st) && lastkey != KEY_UNKNOWN)) {
GM_push(&main_menu);
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;
- assert(GM_send_this(m, &msg));
- cur = msg.integer.i;
- n = msg.integer.a;
- msg.type = GM_GETENTRY;
- assert(GM_send(m, cur, &msg));
- type = msg.integer.i;
- switch (lastkey) {
- case KEY_ESCAPE:
- if (type == GM_TEXTFIELD && input) {
- input = 0;
- Y_disable_text_input();
- msg.type = GM_CANCEL;
- GM_send(m, cur, &msg);
- } else {
- GM_pop();
- Z_sound(msnd4, 128);
- }
- break;
- case KEY_UP:
- case KEY_DOWN:
- msg.type = lastkey == KEY_UP ? GM_UP : GM_DOWN;
- if (GM_send(m, cur, &msg)) {
- Z_sound(msnd1, 128);
- }
- break;
- case KEY_LEFT:
- case KEY_RIGHT:
- if (type == GM_SCROLLER) {
- msg.integer.type = GM_GETINT;
- if (GM_send(m, cur, &msg)) {
- msg.integer.type = GM_SETINT;
- msg.integer.i += lastkey == KEY_LEFT ? -msg.integer.s : msg.integer.s;
- msg.integer.i = min(max(msg.integer.i, msg.integer.a), msg.integer.b);
- if (GM_send(m, cur, &msg)) {
- Z_sound(lastkey == KEY_LEFT ? msnd5 : msnd6, 255);
+ 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:
+ if (type == GM_TEXTFIELD && input) {
+ input = 0;
+ Y_disable_text_input();
+ msg.type = GM_CANCEL;
+ GM_send(m, cur, &msg);
+ } else {
+ GM_pop();
+ Z_sound(msnd4, 128);
}
- }
- } else if (type == GM_TEXTFIELD) {
- //if (input) {
- // icur += lastkey == KEY_LEFT ? -1 : +1;
- // icur = min(max(icur, 0), strnlen(ibuf, imax));
- //}
- }
- break;
- case KEY_BACKSPACE:
- if (type == GM_TEXTFIELD) {
- if (input && icur > 0) {
- // FIXIT buffers in strncpy must not overlap
- strncpy(&ibuf[icur - 1], &ibuf[icur], imax - icur);
- ibuf[imax - 1] = 0;
- icur -= 1;
- }
- }
- break;
- case KEY_RETURN:
- if (type == GM_TEXTFIELD) {
- if (input) {
- input = 0;
- Y_disable_text_input();
- msg.type = GM_END;
- msg.string.s = ibuf;
- msg.string.maxlen = imax;
- GM_send(m, cur, &msg);
- } else {
- msg.type = GM_GETSTR;
- if (GM_send(m, cur, &msg)) {
- imax = min(msg.string.maxlen, GM_MAX_INPUT);
- strncpy(ibuf, msg.string.s, imax);
- icur = strnlen(ibuf, imax);
+ break;
+ case KEY_UP:
+ case KEY_DOWN:
+ if (input == 0) {
+ msg.type = lastkey == KEY_UP ? GM_UP : GM_DOWN;
+ if (GM_send(m, cur, &msg)) {
+ Z_sound(msnd1, 128);
+ }
+ }
+ break;
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (type == GM_SCROLLER) {
+ msg.integer.type = GM_GETINT;
+ if (GM_send(m, cur, &msg)) {
+ msg.integer.type = GM_SETINT;
+ msg.integer.i += lastkey == KEY_LEFT ? -msg.integer.s : msg.integer.s;
+ msg.integer.i = min(max(msg.integer.i, msg.integer.a), msg.integer.b);
+ if (GM_send(m, cur, &msg)) {
+ Z_sound(lastkey == KEY_LEFT ? msnd5 : msnd6, 255);
+ }
+ }
+ } else if (type == GM_TEXTFIELD) {
+ //if (input) {
+ // icur += lastkey == KEY_LEFT ? -1 : +1;
+ // icur = min(max(icur, 0), x_strnlen(ibuf, imax));
+ //}
+ }
+ break;
+ case KEY_BACKSPACE:
+ if (type == GM_TEXTFIELD) {
+ if (input && icur > 0) {
+ // FIXIT buffers in strncpy must not overlap
+ strncpy(&ibuf[icur - 1], &ibuf[icur], imax - icur);
+ ibuf[imax - 1] = 0;
+ icur -= 1;
+ }
+ }
+ break;
+ case KEY_RETURN:
+ if (type == GM_TEXTFIELD) {
+ if (input) {
+ input = 0;
+ Y_disable_text_input();
+ msg.type = GM_END;
+ msg.string.s = ibuf;
+ msg.string.maxlen = imax;
+ GM_send(m, cur, &msg);
+ } else {
+ msg.type = GM_GETSTR;
+ if (GM_send(m, cur, &msg)) {
+ imax = min(msg.string.maxlen, GM_MAX_INPUT);
+ strncpy(ibuf, msg.string.s, imax);
+ icur = x_strnlen(ibuf, imax);
+ } else {
+ memset(ibuf, 0, GM_MAX_INPUT);
+ imax = GM_MAX_INPUT;
+ icur = 0;
+ }
+ input = 1;
+ Y_enable_text_input();
+ msg.type = GM_BEGIN;
+ GM_send(m, cur, &msg);
+ }
+ Z_sound(msnd2, 128);
} else {
- memset(ibuf, 0, GM_MAX_INPUT);
- imax = GM_MAX_INPUT;
- icur = 0;
+ msg.type = GM_SELECT;
+ if (GM_send(m, cur, &msg)) {
+ Z_sound(msnd2, 128);
+ }
}
- input = 1;
- Y_enable_text_input();
- msg.type = GM_BEGIN;
- GM_send(m, cur, &msg);
- }
- Z_sound(msnd2, 128);
- } else {
- msg.type = GM_SELECT;
- if (GM_send(m, cur, &msg)) {
- Z_sound(msnd2, 128);
- }
+ break;
}
- break;
+ }
}
}
lastkey = KEY_UNKNOWN;
msnd4 = Z_getsnd("SWTCHX");
msnd5 = Z_getsnd("SUDI");
msnd6 = Z_getsnd("TUDI");
- F_loadmus("MENU");
- S_startmusic(0);
+ MUS_load("MENU");
+ MUS_start(0);
}