menus.h 12.8 KB
Newer Older
1
2
//-------------------------------------------------------------------------
/*
Richard Gobeille's avatar
Richard Gobeille committed
3
Copyright (C) 2016 EDuke32 developers and contributors
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

This file is part of EDuke32.

EDuke32 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.

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, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
21
22
*/
//-------------------------------------------------------------------------

23
24
#ifndef menus_h_
#define menus_h_
25

26
#include "common.h"
27
#include "compat.h"
28
29
#include "pragmas.h"
#include "vfs.h"
30

31
32
33
34
#ifdef __cplusplus
extern "C" {
#endif

35
#if defined EDUKE32_TOUCH_DEVICES
36
# define EDUKE32_RETAIL_MENU
37
# define EDUKE32_ANDROID_MENU
38
39
#endif

40
// #define EDUKE32_SIMPLE_MENU
41

42
enum MenuIndex_t {
43
44
45
    MENU_NULL           = INT32_MIN, // sentinel for "do nothing"
    MENU_CLOSE          = -2, // sentinel for "close the menu"/"no menu"
    MENU_PREVIOUS       = -1, // sentinel for "go to previous menu"
46
47
48
49
    MENU_MAIN           = 0,
    MENU_MAIN_INGAME    = 50,
    MENU_EPISODE        = 100,
    MENU_USERMAP        = 101,
Evan Ramos's avatar
Evan Ramos committed
50
51
    MENU_NEWGAMECUSTOM  = 102,
    MENU_NEWGAMECUSTOMSUB = 103,
52
    MENU_SKILL          = 110,
53
    MENU_GAMESETUP      = 200,
54
55
56
    MENU_OPTIONS        = 202,
    MENU_VIDEOSETUP     = 203,
    MENU_KEYBOARDSETUP  = 204,
57
58
59
60
    MENU_MOUSESETUP     = 205,
    MENU_JOYSTICKSETUP  = 206,
    MENU_JOYSTICKBTNS   = 207,
    MENU_JOYSTICKAXES   = 208,
61
62
    MENU_KEYBOARDKEYS   = 209,
    MENU_MOUSEBTNS      = 210,
63
    MENU_JOYSTICKADV    = 212,
64
    MENU_JOYSTICKAXIS   = 213,
65
    MENU_TOUCHSETUP     = 214,
Richard Gobeille's avatar
Richard Gobeille committed
66
67
    MENU_TOUCHSENS      = 215,
    MENU_TOUCHBUTTONS   = 216,
68
    MENU_CONTROLS       = 220,
69
    MENU_POLYMOST       = 230,
70
71
    MENU_COLCORR        = 231,
    MENU_COLCORR_INGAME = 232,
72
73
    MENU_SCREENSETUP    = 233,
    MENU_DISPLAYSETUP   = 234,
74
    MENU_POLYMER        = 240,
75
    MENU_LOAD           = 300,
76
    MENU_SAVE           = 350,
77
78
79
80
    MENU_STORY          = 400,
    MENU_F1HELP         = 401,
    MENU_QUIT           = 500,
    MENU_QUITTOTITLE    = 501,
81
    MENU_QUIT_INGAME    = 502,
82
83
84
    MENU_NETSETUP       = 600,
    MENU_NETWAITMASTER  = 601,
    MENU_NETWAITVOTES   = 603,
85
86
    MENU_SOUND          = 700,
    MENU_SOUND_INGAME   = 701,
87
88
    MENU_SOUND_DEVSETUP = 702,
    MENU_SOUND_SF2      = 703,
89
    MENU_SAVESETUP      = 750,
90
    MENU_SAVECLEANVERIFY = 751,
91
    MENU_RESETSTATSVERIFY = 752,
92
93
94
95
    MENU_CHEATS         = 800,
    MENU_CHEATENTRY     = 801,
    MENU_CHEAT_WARP     = 802,
    MENU_CHEAT_SKILL    = 803,
96
97
98
99
100
    MENU_CREDITS        = 990,
    MENU_CREDITS2       = 991,
    MENU_CREDITS3       = 992,
    MENU_CREDITS4       = 993,
    MENU_CREDITS5       = 994,
101
    MENU_LOADVERIFY     = 1000,
102
    MENU_LOADDELVERIFY  = 1100,
103
104
    MENU_NEWVERIFY      = 1500,
    MENU_SAVEVERIFY     = 2000,
105
    MENU_SAVEDELVERIFY  = 2100,
106
107
108
    MENU_COLCORRRESETVERIFY = 2200,
    MENU_KEYSRESETVERIFY = 2201,
    MENU_KEYSCLASSICVERIFY = 2202,
109
    MENU_JOYDEFAULTVERIFY = 2203,
110
    MENU_ADULTPASSWORD  = 10001,
111
    MENU_RESETPLAYER    = 15000,
112
    MENU_BUYDUKE        = 20000,
113
114
115
116
117
    MENU_NETWORK        = 20001,
    MENU_PLAYER         = 20002,
    MENU_MACROS         = 20004,
    MENU_NETHOST        = 20010,
    MENU_NETOPTIONS     = 20011,
118
    MENU_NETUSERMAP     = 20012,
119
    MENU_NETJOIN        = 20020,
120
};
121
122
123
124
125
126



typedef int32_t MenuID_t;


127
128
129
130
131
132
133
typedef enum MenuAnimationType_t
{ // Note: This enum is for logical categories, not visual types.
    MA_None,
    MA_Return,
    MA_Advance,
} MenuAnimationType_t;

134
// a subset of screentext parameters, restricted because menus require accessibility
135
typedef struct MenuFont_t
136
{
137
//    int32_t xspace, yline;
Evan Ramos's avatar
Evan Ramos committed
138
    vec2_t emptychar, between;
139
    int32_t ypadding;
Evan Ramos's avatar
Evan Ramos committed
140
    int32_t zoom;
141
    int32_t cursorLeftPosition, cursorCenterPosition, cursorScale;
142
    int32_t textflags;
Evan Ramos's avatar
Evan Ramos committed
143
    int16_t tilenum;
144
145
146
147
148
    // selected shade glows, deselected shade is used by Blood, disabled shade is used by SW
    int8_t shade_deselected, shade_disabled;
    uint8_t pal;
    uint8_t pal_selected, pal_deselected, pal_disabled;
    uint8_t pal_selected_right, pal_deselected_right, pal_disabled_right;
Evan Ramos's avatar
Evan Ramos committed
149

150
151
    int32_t get_yline() const { return mulscale16(emptychar.y + ypadding, zoom); }
    int32_t get_yoffset() const { return mulscale16(ypadding, zoom); }
152
} MenuFont_t;
153
154
155
156
157
158
159
160
161
162
163



typedef enum MenuEntryType_t
{
    Dummy,
    Link,
    Option,
    Custom2Col,
    RangeInt32,
    RangeFloat,
164
#ifdef MENU_ENABLE_RANGEDOUBLE
165
    RangeDouble,
166
#endif
167
    String,
168
    Spacer,
169
170
} MenuEntryType_t;

171
172
173
174
175
176
typedef struct MenuEntryFormat_t
{
    int32_t marginBottom;
    int32_t indent;
    int32_t width; // 0: center, >0: width of the label column (left-aligned options), <0: -width of everything (right-aligned)
} MenuEntryFormat_t;
177
178


179
typedef struct MenuMenuFormat_t
180
181
{
    vec2_t pos;
182
    int32_t bottomcutoff; // >0: the bottom edge of the menu before automatic scrolling kicks in, <0: -total height for vertical justification
183
} MenuMenuFormat_t;
184
185
186
187
188

typedef struct MenuLink_t
{
    // traits
    MenuID_t linkID;
189
    MenuAnimationType_t animation;
190
191
192
193
} MenuLink_t;
typedef struct MenuOptionSet_t
{
    // traits
194
    char const **optionNames;
195
    int32_t *optionValues; // If NULL, the identity of currentOption is assumed.
196
197
198
199
200
201
202

    // pop-up list appearance
    MenuMenuFormat_t *menuFormat;
    MenuEntryFormat_t *entryFormat;
    MenuFont_t *font;

    // traits
203
204
    int32_t numOptions;

205
    // pop-up list state
206
207
    int32_t currentEntry;
    int32_t scrollPos;
208
209
210

    // appearance
    uint8_t features; // bit 1 = disable left/right arrows, bit 2 = disable list
211

212
213
    int32_t getMarginBottom() const { return mulscale16(entryFormat->marginBottom, font->zoom); }
    int32_t getIndent() const { return mulscale16(entryFormat->indent, font->zoom); }
214
215
216
217
} MenuOptionSet_t;
typedef struct MenuOption_t
{
    // appearance
218
    MenuFont_t *font;
219
220
221
222
223
224
225
226
227
228
229
230

    // traits
    MenuOptionSet_t *options; // so that common sets such as Yes/No, On/Off can be reused

    // effect
    int32_t *data;

    // state
    int32_t currentOption;
} MenuOption_t;
typedef struct MenuCustom2Col_t
{
231
232
    // effect
    uint8_t *column[2];
233
    char const **key;
234

235
    // appearance
236
    MenuFont_t *font;
237

238
    // effect
239
240
    size_t numvalid;

241
242
    // appearance
    int32_t columnWidth;
243
244
245
246

    // state
    int8_t screenOpen;
} MenuCustom2Col_t;
247
248
249
250
251
252
253
254
255
256

enum MenuRangeFlags_t
{
    DisplayTypeInteger = 1,
    DisplayTypePercent = 2,
    DisplayTypeNormalizedDecimal = 3,
    DisplayTypeMask = (1<<0)|(1<<1),

    EnforceIntervals = 1<<7,
};
257
258
typedef struct MenuRangeInt32_t
{
259
260
261
    // effect
    int32_t *variable;

262
    // appearance
263
    MenuFont_t *font;
264
265
266
267
268

    // traits
    int32_t min;
    int32_t max;
    int32_t onehundredpercent; // 0 implies max
269
    int32_t steps;
270

271
    uint8_t flags;
272
273
274
} MenuRangeInt32_t;
typedef struct MenuRangeFloat_t
{
275
276
277
    // effect
    float *variable;

278
    // appearance
279
    MenuFont_t *font;
280
281
282
283
284

    // traits
    float min;
    float max;
    float onehundredpercent; // 0 implies 1.0
285
    int32_t steps;
286

287
    uint8_t flags;
288
} MenuRangeFloat_t;
289
#ifdef MENU_ENABLE_RANGEDOUBLE
290
291
typedef struct MenuRangeDouble_t
{
292
293
294
    // effect
    double *variable;

295
    // appearance
296
    MenuFont_t *font;
297
298
299
300
301

    // traits
    double min;
    double max;
    double onehundredpercent; // 0 implies 1.0
302
    int32_t steps;
303

304
    uint8_t flags;
305
} MenuRangeDouble_t;
306
#endif
307
308
typedef struct MenuString_t
{
309
310
    // state
    char* editfield;
311
312
313
314

    // effect
    char* variable;

315
316
    // appearance
    MenuFont_t *font;
317

318
    // effect
319
    int32_t bufsize;
320
    int32_t flags;
321
} MenuString_t;
322
323
324
325
typedef struct MenuSpacer_t
{
    int32_t height;
} MenuSpacer_t;
326

327
328
329
// For internal use only.
enum MenuEntryFlags_t
{
Evan Ramos's avatar
Evan Ramos committed
330
    MEF_Disabled = 1<<0,
331
    MEF_LookDisabled = 1<<1,
332
    MEF_Hidden = 1<<2,
333
};
334
335
336
337
338
339

typedef struct MenuEntry_t
{
    // traits
    const char *name;

340
341
342
343
    // appearance
    MenuFont_t *font;
    MenuEntryFormat_t *format;

344
    void *entry;
345
    MenuEntryType_t type;
346
347

    // state
348
    int32_t flags;
349
    int32_t ytop, ybottom;
350

351
352
    int32_t getMarginBottom() const { return mulscale16(format->marginBottom, font->zoom); }
    int32_t getIndent() const { return mulscale16(format->indent, font->zoom); }
Evan Ramos's avatar
Evan Ramos committed
353
    int32_t getHeight() const
Evan Ramos's avatar
Evan Ramos committed
354
    {
355
        return type == Spacer ? mulscale16(((MenuSpacer_t *)entry)->height, font->zoom) : font->get_yline();
Evan Ramos's avatar
Evan Ramos committed
356
    }
357
358
359
360
361
362
363
364
365
} MenuEntry_t;


typedef enum MenuType_t
{
    Menu,
    Panel,
    Verify,
    Message,
366
    TextForm,
367
368
369
370
371
372
373
    FileSelect,
} MenuType_t;

typedef struct MenuMenu_t
{
    const char *title;

374
375
376
377
378
    MenuMenuFormat_t *format;

    MenuEntry_t **entrylist;
    int32_t numEntries;

379
    // state
380
    int32_t currentEntry, currentColumn;
381
    int32_t scrollPos;
382
383
384
385
386
387
} MenuMenu_t;
typedef struct MenuPanel_t
{
    const char *title;

    MenuID_t previousID;
388
    MenuAnimationType_t previousAnimation;
389
    MenuID_t nextID;
390
    MenuAnimationType_t nextAnimation;
391
392
393
394
395
396
} MenuPanel_t;
typedef struct MenuVerify_t
{
    vec2_t cursorpos;

    MenuID_t linkID;
397
    MenuAnimationType_t animation;
398
399
400
401
402
403
} MenuVerify_t;
typedef struct MenuMessage_t
{
    vec2_t cursorpos;

    MenuID_t linkID;
404
    MenuAnimationType_t animation;
405
} MenuMessage_t;
406
407
408
409
410
enum MenuTextFormFlags_t
{
    MTF_Password = 1<<0,
};
typedef struct MenuTextForm_t
411
412
413
{
    // state
    char *input;
414
415

    // traits
416
    const char *instructions;
417
    int32_t bufsize;
418
419
    uint8_t flags;
} MenuTextForm_t;
420
421
422
423
424
typedef struct MenuFileSelect_t
{
    const char *title;

    // appearance
425
    MenuMenuFormat_t *format[2];
426
    MenuFont_t *font[2];
427
428

    // traits
429
    const char * startdir;
430
431
432
433
    const char *pattern;
    char *destination;

    // state
434
    BUILDVFS_FIND_REC *findhigh[2];
435
    int32_t scrollPos[2];
436
437
438
439
440

    // appearance
    int32_t marginBottom[2];

    // state
441
442
    fnlist_t fnlist;
    int32_t currentList;
443

444
    int32_t getMarginBottom(size_t index) const { return mulscale16(marginBottom[index], font[index]->zoom); }
445
446
447
448
} MenuFileSelect_t;

typedef struct Menu_t
{
449
    void *object;
450
451
    MenuID_t menuID;
    MenuID_t parentID;
452
    MenuAnimationType_t parentAnimation;
453
454
455
    MenuType_t type;
} Menu_t;

456
457
458
459
460
461
462
463
typedef struct MenuAnimation_t
{
    int32_t(*out)(struct MenuAnimation_t *);
    int32_t(*in)(struct MenuAnimation_t *);

    Menu_t *previous;
    Menu_t *current;

464
    uint32_t start;
465
466
467
468
    int32_t length;
} MenuAnimation_t;

extern MenuAnimation_t m_animation;
469

470
471
472
extern MenuID_t g_currentMenu;
extern Menu_t *m_currentMenu;

473
474
extern int32_t g_quitDeadline;
extern int32_t voting;
475
int Menu_Change(MenuID_t cm);
476
477
void Menu_AnimateChange(int32_t cm, MenuAnimationType_t animtype);
int32_t Menu_IsTextInput(Menu_t *cm);
478
int G_CheckPlayerColor(int color);
479
void Menu_Init(void);
480
481
void Menu_Open(uint8_t playerID);
void Menu_Close(uint8_t playerID);
482
void M_DisplayMenus(void);
483

484
extern MenuFont_t MF_Redfont, MF_Bluefont, MF_Minifont;
485

486
#define M_MOUSETIMEOUT 210
487
488
489
extern int32_t m_mouselastactivity;

#if defined EDUKE32_TOUCH_DEVICES
490
# define MOUSEALPHA 0
491
# define CURSORALPHA (255/3)
492
# define MOUSEACTIVECONDITIONAL(condition) (condition)
493
# define MOUSEWATCHPOINTCONDITIONAL(condition) (condition)
494
#else
495
extern int32_t m_mousewake_watchpoint, m_menuchange_watchpoint;
496
// alpha increments of 3 --> 255 / 3 = 85 --> round up to power of 2 --> 128 --> divide by 2 --> 64 alphatabs required
497
// use 16 anyway :P
498
# define MOUSEUSEALPHA (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15)
499
500
# define MOUSEALPHA (MOUSEUSEALPHA ? clamp(((int32_t) totalclock - m_mouselastactivity - 90)*3, 0, 255) : 0)
# define CURSORALPHA (MOUSEUSEALPHA ? clamp(((int32_t) totalclock - m_mouselastactivity - 90)*2 + (255/3), (255/3), 255) : 255/3)
501
502
# define MOUSEACTIVECONDITION (totalclock - m_mouselastactivity < M_MOUSETIMEOUT)
# define MOUSEACTIVECONDITIONAL(condition) (MOUSEACTIVECONDITION && (condition))
503
# define MOUSEINACTIVECONDITIONAL(condition) ((!(g_player[myconnectindex].ps->gm & MODE_MENU) || !MOUSEACTIVECONDITION) && (condition))
504
# define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || m_mousewake_watchpoint || m_menuchange_watchpoint == 3)
505
506
#endif

Evan Ramos's avatar
Evan Ramos committed
507
508
509
510
511
512
#define MAXMENUGAMEPLAYENTRIES 7

enum MenuGameplayEntryFlags
{
    MGE_Locked = 1u<<0u,
    MGE_Hidden = 1u<<1u,
Evan Ramos's avatar
Evan Ramos committed
513
    MGE_UserContent = 1u<<2u,
Evan Ramos's avatar
Evan Ramos committed
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
};

typedef struct MenuGameplayEntry
{
    char name[64];
    uint8_t flags;

    bool isValid() const { return name[0] != '\0'; }
} MenuGameplayEntry;

typedef struct MenuGameplayStemEntry
{
    MenuGameplayEntry entry;
    MenuGameplayEntry subentries[MAXMENUGAMEPLAYENTRIES];
} MenuGameplayStemEntry;

extern MenuGameplayStemEntry g_MenuGameplayEntries[MAXMENUGAMEPLAYENTRIES];

extern MenuEntry_t ME_NEWGAMECUSTOMENTRIES[MAXMENUGAMEPLAYENTRIES];
extern MenuEntry_t ME_NEWGAMECUSTOMSUBENTRIES[MAXMENUGAMEPLAYENTRIES][MAXMENUGAMEPLAYENTRIES];

535
536
537
538
#ifdef __cplusplus
}
#endif

539
#endif