1 // SONIC ROBO BLAST 2 2 //----------------------------------------------------------------------------- 3 // Copyright (C) 1993-1996 by id Software, Inc. 4 // Copyright (C) 1998-2000 by DooM Legacy Team. 5 // Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. 6 // Copyright (C) 1999-2020 by Sonic Team Junior. 7 // 8 // This program is free software distributed under the 9 // terms of the GNU General Public License, version 2. 10 // See the 'LICENSE' file for more details. 11 //----------------------------------------------------------------------------- 12 /// \file m_menu.h 13 /// \brief Menu widget stuff, selection and such 14 15 #ifndef __X_MENU__ 16 #define __X_MENU__ 17 18 #include "doomstat.h" // for NUMGAMETYPES 19 #include "d_event.h" 20 #include "command.h" 21 #include "f_finale.h" // for ttmode_enum 22 #include "i_threads.h" 23 #include "mserv.h" 24 #include "r_things.h" // for SKINNAMESIZE 25 26 // Compatibility with old-style named NiGHTS replay files. 27 #define OLDNREPLAYNAME 28 29 // 30 // MENUS 31 // 32 33 // If menu hierarchies go deeper, change this up to 5. 34 // Zero-based, inclusive. 35 #define NUMMENULEVELS 3 36 #define MENUBITS 6 37 38 // Menu IDs sectioned by numeric places to signify hierarchy 39 /** 40 * IF YOU MODIFY THIS, MODIFY MENUTYPES_LIST[] IN dehacked.c TO MATCH. 41 */ 42 typedef enum 43 { 44 MN_NONE, 45 46 MN_MAIN, 47 48 // Single Player 49 MN_SP_MAIN, 50 51 MN_SP_LOAD, 52 MN_SP_PLAYER, 53 54 MN_SP_LEVELSELECT, 55 MN_SP_LEVELSTATS, 56 57 MN_SP_TIMEATTACK, 58 MN_SP_TIMEATTACK_LEVELSELECT, 59 MN_SP_GUESTREPLAY, 60 MN_SP_REPLAY, 61 MN_SP_GHOST, 62 63 MN_SP_NIGHTSATTACK, 64 MN_SP_NIGHTS_LEVELSELECT, 65 MN_SP_NIGHTS_GUESTREPLAY, 66 MN_SP_NIGHTS_REPLAY, 67 MN_SP_NIGHTS_GHOST, 68 69 MN_SP_MARATHON, 70 71 // Multiplayer 72 MN_MP_MAIN, 73 MN_MP_SPLITSCREEN, // SplitServer 74 MN_MP_SERVER, 75 MN_MP_CONNECT, 76 MN_MP_ROOM, 77 MN_MP_PLAYERSETUP, // MP_PlayerSetupDef shared with SPLITSCREEN if #defined NONET 78 MN_MP_SERVER_OPTIONS, 79 80 // Options 81 MN_OP_MAIN, 82 83 MN_OP_P1CONTROLS, 84 MN_OP_CHANGECONTROLS, // OP_ChangeControlsDef shared with P2 85 MN_OP_P1MOUSE, 86 MN_OP_P1JOYSTICK, 87 MN_OP_JOYSTICKSET, // OP_JoystickSetDef shared with P2 88 MN_OP_P1CAMERA, 89 90 MN_OP_P2CONTROLS, 91 MN_OP_P2MOUSE, 92 MN_OP_P2JOYSTICK, 93 MN_OP_P2CAMERA, 94 95 MN_OP_PLAYSTYLE, 96 97 MN_OP_VIDEO, 98 MN_OP_VIDEOMODE, 99 MN_OP_COLOR, 100 MN_OP_OPENGL, 101 MN_OP_OPENGL_LIGHTING, 102 103 MN_OP_SOUND, 104 105 MN_OP_SERVER, 106 MN_OP_MONITORTOGGLE, 107 108 MN_OP_DATA, 109 MN_OP_ADDONS, 110 MN_OP_SCREENSHOTS, 111 MN_OP_ERASEDATA, 112 113 // Extras 114 MN_SR_MAIN, 115 MN_SR_PANDORA, 116 MN_SR_LEVELSELECT, 117 MN_SR_UNLOCKCHECKLIST, 118 MN_SR_EMBLEMHINT, 119 MN_SR_PLAYER, 120 MN_SR_SOUNDTEST, 121 122 // Addons (Part of MISC, but let's make it our own) 123 MN_AD_MAIN, 124 125 // MISC 126 // MN_MESSAGE, 127 // MN_SPAUSE, 128 129 // MN_MPAUSE, 130 // MN_SCRAMBLETEAM, 131 // MN_CHANGETEAM, 132 // MN_CHANGELEVEL, 133 134 // MN_MAPAUSE, 135 // MN_HELP, 136 137 MN_SPECIAL, 138 NUMMENUTYPES, 139 } menutype_t; // up to 63; MN_SPECIAL = 53 140 #define MTREE2(a,b) (a | (b<<MENUBITS)) 141 #define MTREE3(a,b,c) MTREE2(a, MTREE2(b,c)) 142 #define MTREE4(a,b,c,d) MTREE2(a, MTREE3(b,c,d)) 143 144 typedef struct 145 { 146 char bgname[8]; // name for background gfx lump; lays over titlemap if this is set 147 SINT8 fadestrength; // darken background when displaying this menu, strength 0-31 or -1 for undefined 148 INT32 bgcolor; // fill color, overrides bg name. -1 means follow bg name rules. 149 INT32 titlescrollxspeed; // background gfx scroll per menu; inherits global setting 150 INT32 titlescrollyspeed; // y scroll 151 boolean bghide; // for titlemaps, hide the background. 152 153 SINT8 hidetitlepics; // hide title gfx per menu; -1 means undefined, inherits global setting 154 ttmode_enum ttmode; // title wing animation mode; default TTMODE_OLD 155 UINT8 ttscale; // scale of title wing gfx (FRACUNIT / ttscale); -1 means undefined, inherits global setting 156 char ttname[9]; // lump name of title wing gfx. If name length is <= 6, engine will attempt to load numbered frames (TTNAMExx) 157 INT16 ttx; // X position of title wing 158 INT16 tty; // Y position of title wing 159 INT16 ttloop; // # frame to loop; -1 means dont loop 160 UINT16 tttics; // # of tics per frame 161 162 char musname[7]; ///< Music track to play. "" for no music. 163 UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. 164 boolean muslooping; ///< Loop the music 165 boolean musstop; ///< Don't play any music 166 boolean musignore; ///< Let the current music keep playing 167 168 boolean enterbubble; // run all entrance line execs after common ancestor and up to child. If false, only run the child's exec 169 boolean exitbubble; // run all exit line execs from child and up to before common ancestor. If false, only run the child's exec 170 INT32 entertag; // line exec to run on menu enter, if titlemap 171 INT32 exittag; // line exec to run on menu exit, if titlemap 172 INT16 enterwipe; // wipe type to run on menu enter, -1 means default 173 INT16 exitwipe; // wipe type to run on menu exit, -1 means default 174 } menupres_t; 175 176 extern menupres_t menupres[NUMMENUTYPES]; 177 extern UINT32 prevMenuId; 178 extern UINT32 activeMenuId; 179 180 void M_InitMenuPresTables(void); 181 UINT8 M_GetYoungestChildMenu(void); 182 void M_ChangeMenuMusic(const char *defaultmusname, boolean defaultmuslooping); 183 void M_SetMenuCurBackground(const char *defaultname); 184 void M_SetMenuCurFadeValue(UINT8 defaultvalue); 185 void M_SetMenuCurTitlePics(void); 186 187 // Called by main loop, 188 // saves config file and calls I_Quit when user exits. 189 // Even when the menu is not displayed, 190 // this can resize the view and change game parameters. 191 // Does all the real work of the menu interaction. 192 boolean M_Responder(event_t *ev); 193 194 // Called by main loop, only used for menu (skull cursor) animation. 195 void M_Ticker(void); 196 197 // Called by main loop, draws the menus directly into the screen buffer. 198 void M_Drawer(void); 199 200 // Called by D_SRB2Main, loads the config file. 201 void M_Init(void); 202 203 // Called by D_SRB2Main also, sets up the playermenu and description tables. 204 void M_InitCharacterTables(void); 205 206 // Called by intro code to force menu up upon a keypress, 207 // does nothing if menu is already up. 208 void M_StartControlPanel(void); 209 210 // Called upon end of a mode attack run 211 void M_EndModeAttackRun(void); 212 213 // Called on new server add, or other reasons 214 void M_SortServerList(void); 215 216 // Draws a box with a texture inside as background for messages 217 void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines); 218 219 // the function to show a message box typing with the string inside 220 // string must be static (not in the stack) 221 // routine is a function taking a INT32 in parameter 222 typedef enum 223 { 224 MM_NOTHING = 0, // is just displayed until the user do someting 225 MM_YESNO, // routine is called with only 'y' or 'n' in param 226 MM_EVENTHANDLER // the same of above but without 'y' or 'n' restriction 227 // and routine is void routine(event_t *) (ex: set control) 228 } menumessagetype_t; 229 void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype); 230 231 typedef enum 232 { 233 M_NOT_WAITING, 234 235 M_WAITING_VERSION, 236 M_WAITING_ROOMS, 237 M_WAITING_SERVERS, 238 } 239 M_waiting_mode_t; 240 241 extern M_waiting_mode_t m_waiting_mode; 242 243 // Called by linux_x/i_video_xshm.c 244 void M_QuitResponse(INT32 ch); 245 246 // Determines whether to show a level in the list (platter version does not need to be exposed) 247 boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); 248 249 // flags for items in the menu 250 // menu handle (what we do when key is pressed 251 #define IT_TYPE 15 // (1+2+4+8) 252 #define IT_CALL 0 // call the function 253 #define IT_SPACE 1 // no handling 254 #define IT_ARROWS 2 // call function with 0 for left arrow and 1 for right arrow in param 255 #define IT_KEYHANDLER 4 // call with the key in param 256 #define IT_SUBMENU 6 // go to sub menu 257 #define IT_CVAR 8 // handle as a cvar 258 #define IT_PAIR 11 // no handling, define both sides of text 259 #define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message) 260 261 #define IT_DISPLAY (48+64+128) // 16+32+64+128 262 #define IT_NOTHING 0 // space 263 #define IT_PATCH 16 // a patch or a string with big font 264 #define IT_STRING 32 // little string (spaced with 10) 265 #define IT_WHITESTRING 48 // little string in white 266 #define IT_DYBIGSPACE 64 // same as noting 267 #define IT_DYLITLSPACE (16+64) // little space 268 #define IT_STRING2 (32+64) // a simple string 269 #define IT_GRAYPATCH (16+32+64) // grayed patch or big font string 270 #define IT_BIGSLIDER 128 // volume sound use this 271 #define IT_TRANSTEXT (16+128) // Transparent text 272 #define IT_TRANSTEXT2 (32+128) // used for control names 273 #define IT_HEADERTEXT (48+128) // Non-selectable header option, displays in yellow offset to the left a little 274 #define IT_QUESTIONMARKS (64+128) // Displays as question marks, used for secrets 275 #define IT_CENTER 256 // if IT_PATCH, center it on screen 276 277 //consvar specific 278 #define IT_CVARTYPE (512+1024+2048) 279 #define IT_CV_NORMAL 0 280 #define IT_CV_SLIDER 512 281 #define IT_CV_STRING 1024 282 #define IT_CV_NOPRINT 1536 283 #define IT_CV_NOMOD 2048 284 #define IT_CV_INVISSLIDER 2560 285 #define IT_CV_INTEGERSTEP 4096 // if IT_CV_NORMAL and cvar is CV_FLOAT, modify it by 1 instead of 0.0625 286 #define IT_CV_FLOATSLIDER 4608 // IT_CV_SLIDER, value modified by 0.0625 instead of 1 (for CV_FLOAT cvars) 287 288 //call/submenu specific 289 // There used to be a lot more here but ... 290 // A lot of them became redundant with the advent of the Pause menu, so they were removed 291 #define IT_CALLTYPE (512+1024) 292 #define IT_CALL_NORMAL 0 293 #define IT_CALL_NOTMODIFIED 512 294 295 // in INT16 for some common use 296 #define IT_BIGSPACE (IT_SPACE +IT_DYBIGSPACE) 297 #define IT_LITLSPACE (IT_SPACE +IT_DYLITLSPACE) 298 #define IT_CONTROL (IT_STRING2+IT_CALL) 299 #define IT_CVARMAX (IT_CVAR +IT_CV_NOMOD) 300 #define IT_DISABLED (IT_SPACE +IT_GRAYPATCH) 301 #define IT_GRAYEDOUT (IT_SPACE +IT_TRANSTEXT) 302 #define IT_GRAYEDOUT2 (IT_SPACE +IT_TRANSTEXT2) 303 #define IT_HEADER (IT_SPACE +IT_HEADERTEXT) 304 #define IT_SECRET (IT_SPACE +IT_QUESTIONMARKS) 305 306 #define MAXSTRINGLENGTH 32 307 308 typedef union 309 { 310 struct menu_s *submenu; // IT_SUBMENU 311 consvar_t *cvar; // IT_CVAR 312 void (*routine)(INT32 choice); // IT_CALL, IT_KEYHANDLER, IT_ARROWS 313 } itemaction_t; 314 315 // 316 // MENU TYPEDEFS 317 // 318 typedef struct menuitem_s 319 { 320 // show IT_xxx 321 UINT16 status; 322 323 const char *patch; 324 const char *text; // used when FONTBxx lump is found 325 326 // FIXME: should be itemaction_t 327 void *itemaction; 328 329 // hotkey in menu or y of the item 330 UINT16 alphaKey; 331 } menuitem_t; 332 333 extern menuitem_t MP_RoomMenu[]; 334 extern UINT32 roomIds[NUM_LIST_ROOMS]; 335 336 typedef struct menu_s 337 { 338 UINT32 menuid; // ID to encode menu type and hierarchy 339 const char *menutitlepic; 340 INT16 numitems; // # of menu items 341 struct menu_s *prevMenu; // previous menu 342 menuitem_t *menuitems; // menu items 343 void (*drawroutine)(void); // draw routine 344 INT16 x, y; // x, y of menu 345 INT16 lastOn; // last item user was on in menu 346 boolean (*quitroutine)(void); // called before quit a menu return true if we can 347 } menu_t; 348 349 void M_SetupNextMenu(menu_t *menudef); 350 void M_ClearMenus(boolean callexitmenufunc); 351 352 // Maybe this goes here????? Who knows. 353 boolean M_MouseNeeded(void); 354 355 #ifdef HAVE_THREADS 356 extern I_mutex m_menu_mutex; 357 #endif 358 359 extern menu_t *currentMenu; 360 361 extern menu_t MainDef; 362 extern menu_t SP_LoadDef; 363 364 // Call upon joystick hotplug 365 void M_SetupJoystickMenu(INT32 choice); 366 extern menu_t OP_JoystickSetDef; 367 368 // Stuff for customizing the player select screen 369 typedef struct 370 { 371 boolean used; 372 char notes[441]; 373 char picname[8]; 374 char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 375 patch_t *charpic; 376 UINT8 prev; 377 UINT8 next; 378 379 // new character select 380 char displayname[SKINNAMESIZE+1]; 381 SINT8 skinnum[2]; 382 UINT16 oppositecolor; 383 char nametag[8]; 384 patch_t *namepic; 385 UINT16 tagtextcolor; 386 UINT16 tagoutlinecolor; 387 } description_t; 388 389 // level select platter 390 typedef struct 391 { 392 char header[22+5]; // mapheader_t lvltttl max length + " ZONE" 393 INT32 maplist[3]; 394 char mapnames[3][17+1]; 395 boolean mapavailable[4]; // mapavailable[3] == wide or not 396 } levelselectrow_t; 397 398 typedef struct 399 { 400 UINT8 numrows; 401 levelselectrow_t *rows; 402 } levelselect_t; 403 // experimental level select end 404 405 // descriptions for gametype select screen 406 typedef struct 407 { 408 UINT8 col[2]; 409 char notes[441]; 410 } gtdesc_t; 411 extern gtdesc_t gametypedesc[NUMGAMETYPES]; 412 413 // mode descriptions for video mode menu 414 typedef struct 415 { 416 INT32 modenum; // video mode number in the vidmodes list 417 const char *desc; // XXXxYYY 418 UINT8 goodratio; // aspect correct if 1 419 } modedesc_t; 420 421 // savegame struct for save game menu 422 typedef struct 423 { 424 char levelname[32]; 425 UINT8 skinnum; 426 UINT8 botskin; 427 UINT8 numemeralds; 428 UINT8 numgameovers; 429 INT32 lives; 430 INT32 continuescore; 431 INT32 gamemap; 432 } saveinfo_t; 433 434 extern description_t description[MAXSKINS]; 435 436 extern consvar_t cv_showfocuslost; 437 extern consvar_t cv_newgametype, cv_nextmap, cv_chooseskin, cv_serversort; 438 extern CV_PossibleValue_t gametype_cons_t[]; 439 440 extern INT16 startmap; 441 extern INT32 ultimate_selectable; 442 extern INT16 char_on, startchar; 443 444 #define MAXSAVEGAMES 31 445 #define NOSAVESLOT 0 //slot where Play Without Saving appears 446 #define MARATHONSLOT 420 // just has to be nonzero, but let's use one that'll show up as an obvious error if something goes wrong while not using our existing saves 447 448 #define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he 449 450 void M_TutorialSaveControlResponse(INT32 ch); 451 452 void M_ForceSaveSlotSelected(INT32 sslot); 453 454 void M_CheatActivationResponder(INT32 ch); 455 456 void M_ModeAttackRetry(INT32 choice); 457 458 // Level select updating 459 void Nextmap_OnChange(void); 460 461 // Screenshot menu updating 462 void Moviemode_mode_Onchange(void); 463 void Screenshot_option_Onchange(void); 464 465 // Addons menu updating 466 void Addons_option_Onchange(void); 467 468 // Moviemode menu updating 469 void Moviemode_option_Onchange(void); 470 471 // Player Setup menu colors linked list 472 typedef struct menucolor_s { 473 struct menucolor_s *next; 474 struct menucolor_s *prev; 475 UINT16 color; 476 } menucolor_t; 477 478 extern menucolor_t *menucolorhead, *menucolortail; 479 480 void M_AddMenuColor(UINT16 color); 481 void M_MoveColorBefore(UINT16 color, UINT16 targ); 482 void M_MoveColorAfter(UINT16 color, UINT16 targ); 483 UINT16 M_GetColorBefore(UINT16 color); 484 UINT16 M_GetColorAfter(UINT16 color); 485 void M_InitPlayerSetupColors(void); 486 void M_FreePlayerSetupColors(void); 487 488 // These defines make it a little easier to make menus 489 #define DEFAULTMENUSTYLE(id, header, source, prev, x, y)\ 490 {\ 491 id,\ 492 header,\ 493 sizeof(source)/sizeof(menuitem_t),\ 494 prev,\ 495 source,\ 496 M_DrawGenericMenu,\ 497 x, y,\ 498 0,\ 499 NULL\ 500 } 501 502 #define DEFAULTSCROLLMENUSTYLE(id, header, source, prev, x, y)\ 503 {\ 504 id,\ 505 header,\ 506 sizeof(source)/sizeof(menuitem_t),\ 507 prev,\ 508 source,\ 509 M_DrawGenericScrollMenu,\ 510 x, y,\ 511 0,\ 512 NULL\ 513 } 514 515 #define PAUSEMENUSTYLE(source, x, y)\ 516 {\ 517 MN_SPECIAL,\ 518 NULL,\ 519 sizeof(source)/sizeof(menuitem_t),\ 520 NULL,\ 521 source,\ 522 M_DrawPauseMenu,\ 523 x, y,\ 524 0,\ 525 NULL\ 526 } 527 528 #define CENTERMENUSTYLE(id, header, source, prev, y)\ 529 {\ 530 id,\ 531 header,\ 532 sizeof(source)/sizeof(menuitem_t),\ 533 prev,\ 534 source,\ 535 M_DrawCenteredMenu,\ 536 BASEVIDWIDTH/2, y,\ 537 0,\ 538 NULL\ 539 } 540 541 #define MAPPLATTERMENUSTYLE(id, header, source)\ 542 {\ 543 id,\ 544 header,\ 545 sizeof (source)/sizeof (menuitem_t),\ 546 &MainDef,\ 547 source,\ 548 M_DrawLevelPlatterMenu,\ 549 0,0,\ 550 0,\ 551 NULL\ 552 } 553 554 #define CONTROLMENUSTYLE(id, source, prev)\ 555 {\ 556 id,\ 557 "M_CONTRO",\ 558 sizeof (source)/sizeof (menuitem_t),\ 559 prev,\ 560 source,\ 561 M_DrawControl,\ 562 24, 40,\ 563 0,\ 564 NULL\ 565 } 566 567 #define IMAGEDEF(source)\ 568 {\ 569 MN_SPECIAL,\ 570 NULL,\ 571 sizeof (source)/sizeof (menuitem_t),\ 572 NULL,\ 573 source,\ 574 M_DrawImageDef,\ 575 0, 0,\ 576 0,\ 577 NULL\ 578 } 579 580 #endif //__X_MENU__ 581