1 //------------------------------------------------------------------------- 2 /* 3 Copyright (C) 2010-2019 EDuke32 developers and contributors 4 Copyright (C) 2019 Nuke.YKT 5 6 This file is part of NBlood. 7 8 NBlood is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License version 2 10 as published by the Free Software Foundation. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 16 See the GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 */ 22 //------------------------------------------------------------------------- 23 #pragma once 24 25 #include "compat.h" 26 #include "common_game.h" 27 #include "blood.h" 28 #include "inifile.h" 29 #include "resource.h" 30 #include "qav.h" 31 32 #define M_MOUSETIMEOUT 210 33 34 #define kMaxGameMenuItems 128 35 #define kMaxGameCycleItems 128 36 #define kMaxPicCycleItems 128 37 #define kMaxTitleLength 32 38 39 // alpha increments of 3 --> 255 / 3 = 85 --> round up to power of 2 --> 128 --> divide by 2 --> 64 alphatabs required 40 // use 16 anyway :P 41 #define MOUSEUSEALPHA (videoGetRenderMode() != REND_CLASSIC || numalphatabs >= 15) 42 #define MOUSEALPHA (MOUSEUSEALPHA ? clamp(((int)totalclock - gGameMenuMgr.m_mouselastactivity - 90)*3, 0, 255) : 0) 43 #define CURSORALPHA (MOUSEUSEALPHA ? clamp(((int)totalclock - gGameMenuMgr.m_mouselastactivity - 90)*2 + (255/3), (255/3), 255) : 255/3) 44 #define MOUSEACTIVECONDITION ((int)totalclock - gGameMenuMgr.m_mouselastactivity < M_MOUSETIMEOUT) 45 #define MOUSEACTIVECONDITIONAL(condition) (MOUSEACTIVECONDITION && (condition)) 46 #define MOUSEINACTIVECONDITIONAL(condition) (!MOUSEACTIVECONDITION && (condition)) 47 #define MOUSEWATCHPOINTCONDITIONAL(condition) ((condition) || gGameMenuMgr.m_mousewake_watchpoint || gGameMenuMgr.m_menuchange_watchpoint == 3) 48 49 enum { 50 kMenuEventNone = 0, 51 kMenuEventKey = 1, 52 kMenuEventUp = 2, 53 kMenuEventDown = 3, 54 kMenuEventLeft = 4, 55 kMenuEventRight = 5, 56 kMenuEventEnter = 6, 57 kMenuEventEscape = 7, 58 kMenuEventSpace = 8, 59 kMenuEventBackSpace = 9, 60 kMenuEventDelete = 10, 61 kMenuEventScrollUp = 11, 62 kMenuEventScrollDown = 12, 63 64 65 kMenuEventInit = 0x8000, 66 kMenuEventDeInit = 0x8001 67 }; 68 69 enum { 70 kMenuSliderNone = 0, 71 kMenuSliderValue, 72 kMenuSliderPercent, 73 kMenuSliderQ16 74 }; 75 76 struct CGameMenuEvent { 77 unsigned short at0; 78 char at2; 79 }; 80 81 // NUKE-TODO: 82 #ifdef DrawText 83 #undef DrawText 84 #endif 85 86 class CMenuTextMgr 87 { 88 public: 89 int at0; 90 CMenuTextMgr(); 91 void DrawText(const char *pString, int nFont, int x, int y, int nShade, int nPalette, bool shadow ); 92 void GetFontInfo(int nFont, const char *pString, int *pXSize, int *pYSize); 93 }; 94 95 class CGameMenu; 96 97 class CGameMenuItem { 98 public: 99 CGameMenu *pMenu; 100 const char* m_pzText; 101 int m_nFont; 102 int m_nX; 103 int m_nY; 104 int m_nWidth; 105 void (*pPreDrawCallback)(CGameMenuItem *pItem); 106 //int nFlags; 107 unsigned int bCanSelect : 1; 108 unsigned int bEnable : 1; 109 unsigned int bNoDraw : 1; 110 CGameMenuItem(); 111 virtual ~CGameMenuItem(); 112 virtual void Draw(void) = 0; 113 virtual bool Event(CGameMenuEvent &); 114 virtual bool MouseEvent(CGameMenuEvent &); 115 }; 116 117 class CGameMenuItemText : public CGameMenuItem 118 { 119 public: 120 int at20; 121 CGameMenuItemText(); 122 CGameMenuItemText(const char *, int, int, int, int); 123 virtual void Draw(void); 124 //virtual bool Event(CGameMenuEvent &); 125 }; 126 127 class CGameMenuItemTitle : public CGameMenuItem 128 { 129 public: 130 int at20; 131 CGameMenuItemTitle(); 132 CGameMenuItemTitle(const char *, int, int, int, int); 133 virtual void Draw(void); 134 //virtual bool Event(CGameMenuEvent &); 135 }; 136 137 class CGameMenuItemZBool : public CGameMenuItem 138 { 139 public: 140 bool at20; 141 const char *at21; 142 const char *at25; 143 void (*at29)(CGameMenuItemZBool *); 144 CGameMenuItemZBool(); 145 CGameMenuItemZBool(const char *,int,int,int,int,bool,void (*)(CGameMenuItemZBool *),const char *,const char *); 146 virtual void Draw(void); 147 virtual bool Event(CGameMenuEvent &); 148 }; 149 150 class CGameMenuItemChain : public CGameMenuItem 151 { 152 public: 153 int at20; 154 CGameMenu *at24; 155 int at28; 156 void(*at2c)(CGameMenuItemChain *); 157 int at30; 158 CGameMenuItemChain(); 159 CGameMenuItemChain(const char *, int, int, int, int, int, CGameMenu *, int, void(*)(CGameMenuItemChain *), int); 160 virtual void Draw(void); 161 virtual bool Event(CGameMenuEvent &); 162 }; 163 164 class CGameMenuItem7EA1C : public CGameMenuItem 165 { 166 public: 167 int at20; // text align 168 CGameMenu *at24; 169 int at28; 170 void(*at2c)(CGameMenuItem7EA1C *); 171 int at30; 172 IniFile *at34; 173 char at38[16]; 174 char at48[16]; 175 CGameMenuItem7EA1C(); 176 CGameMenuItem7EA1C(const char *a1, int a2, int a3, int a4, int a5, const char *a6, const char *a7, int a8, int a9, void(*a10)(CGameMenuItem7EA1C *), int a11); 177 void Setup(void); 178 virtual void Draw(void); 179 virtual bool Event(CGameMenuEvent &); 180 }; 181 182 class CGameMenuItem7EE34 : public CGameMenuItem 183 { 184 public: 185 int at20; 186 int at24; 187 CGameMenu *at28; 188 CGameMenu *at2c; 189 CGameMenuItem7EE34(); 190 CGameMenuItem7EE34(const char *a1, int a2, int a3, int a4, int a5, int a6); 191 void Setup(void); 192 virtual void Draw(void); 193 virtual bool Event(CGameMenuEvent &); 194 }; 195 196 class CGameMenuItemChain7F2F0 : public CGameMenuItemChain 197 { 198 public: 199 int at34; 200 CGameMenuItemChain7F2F0(); 201 CGameMenuItemChain7F2F0(char *a1, int a2, int a3, int a4, int a5, int a6, CGameMenu *a7, int a8, void(*a9)(CGameMenuItemChain *), int a10); 202 //virtual void Draw(void); 203 virtual bool Event(CGameMenuEvent &); 204 }; 205 206 class CGameMenuItemBitmap : public CGameMenuItem 207 { 208 public: 209 int at20; 210 CGameMenuItemBitmap(); 211 CGameMenuItemBitmap(const char *, int, int, int, int); 212 virtual void Draw(void); 213 virtual bool Event(CGameMenuEvent &); 214 }; 215 216 class CGameMenuItemBitmapLS : public CGameMenuItemBitmap 217 { 218 public: 219 int at24; 220 int at28; 221 CGameMenuItemBitmapLS(); 222 CGameMenuItemBitmapLS(const char *, int, int, int, int); 223 virtual void Draw(void); 224 virtual bool Event(CGameMenuEvent &); 225 }; 226 227 class CGameMenuItemKeyList : public CGameMenuItem 228 { 229 public: 230 void(*pCallback)(CGameMenuItemKeyList *); 231 int at24; 232 int nRows; 233 int nTopDelta; 234 int nFocus; 235 int nGameFuncs; 236 bool bScan; 237 CGameMenuItemKeyList(); 238 CGameMenuItemKeyList(const char * a1, int a2, int a3, int a4, int a5, int a6, int a7, void(*a8)(CGameMenuItemKeyList *)); 239 void Scan(void); 240 virtual void Draw(void); 241 virtual bool Event(CGameMenuEvent &); 242 virtual bool MouseEvent(CGameMenuEvent &); 243 }; 244 245 class CGameMenuItemSlider : public CGameMenuItem 246 { 247 public: 248 int *pValue; 249 int nValue; 250 int nRangeLow; 251 int nRangeHigh; 252 int nStep; 253 void(*pCallback)(CGameMenuItemSlider *); 254 int nSliderTile; 255 int nCursorTile; 256 int nShowValue; 257 CGameMenuItemSlider(); 258 CGameMenuItemSlider(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, int _nValue, int _nRangeLow, int _nRangeHigh, int _nStep, void(*_pCallback)(CGameMenuItemSlider *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); 259 CGameMenuItemSlider(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, int *pnValue, int _nRangeLow, int _nRangeHigh, int _nStep, void(*_pCallback)(CGameMenuItemSlider *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); 260 virtual void Draw(void); 261 virtual bool Event(CGameMenuEvent &); 262 virtual bool MouseEvent(CGameMenuEvent &); 263 }; 264 265 class CGameMenuItemSliderFloat : public CGameMenuItem 266 { 267 public: 268 float *pValue; 269 float fValue; 270 float fRangeLow; 271 float fRangeHigh; 272 float fStep; 273 void(*pCallback)(CGameMenuItemSliderFloat *); 274 int nSliderTile; 275 int nCursorTile; 276 int nShowValue; 277 CGameMenuItemSliderFloat(); 278 CGameMenuItemSliderFloat(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, float _fValue, float _fRangeLow, float _fRangeHigh, float _fStep, void(*_pCallback)(CGameMenuItemSliderFloat *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); 279 CGameMenuItemSliderFloat(const char *_pzText, int _nFont, int _nX, int _nY, int _nWidth, float *pnValue, float _fRangeLow, float _fRangeHigh, float _fStep, void(*_pCallback)(CGameMenuItemSliderFloat *), int _nSliderTile, int _nCursorTile, int _nShowValue = kMenuSliderNone); 280 virtual void Draw(void); 281 virtual bool Event(CGameMenuEvent &); 282 }; 283 284 class CGameMenuItemZEdit : public CGameMenuItem 285 { 286 public: 287 char *at20; 288 int at24; 289 int at28; 290 void(*at2c)(CGameMenuItemZEdit *, CGameMenuEvent *); 291 char at30; 292 char at31; 293 char at32; 294 CGameMenuItemZEdit(); 295 CGameMenuItemZEdit(const char *, int, int, int, int, char *, int, char, void(*)(CGameMenuItemZEdit *, CGameMenuEvent *), int); 296 void AddChar(char); 297 void BackChar(void); 298 virtual void Draw(void); 299 virtual bool Event(CGameMenuEvent &); 300 }; 301 302 class CGameMenuItemZEditBitmap : public CGameMenuItem 303 { 304 public: 305 char *at20; 306 int at24; 307 int at28; // save game slot 308 CGameMenuItemBitmapLS *at2c; 309 void(*at30)(CGameMenuItemZEditBitmap *, CGameMenuEvent *); 310 char bScan; 311 char at35; 312 char at36; 313 char at37; 314 CGameMenuItemZEditBitmap(); 315 CGameMenuItemZEditBitmap(char *, int, int, int, int, char *, int, char, void(*)(CGameMenuItemZEditBitmap *, CGameMenuEvent *), int); 316 void AddChar(char); 317 void BackChar(void); 318 virtual void Draw(void); 319 virtual bool Event(CGameMenuEvent &); 320 }; 321 322 class CGameMenuItemQAV : public CGameMenuItem 323 { 324 public: 325 const char *at20; 326 DICTNODE *at24; 327 QAV *at28; 328 int at2c; 329 int at30; 330 bool bWideScreen; 331 bool bClearBackground; 332 CGameMenuItemQAV(); 333 CGameMenuItemQAV(const char *, int, int, int, const char *, bool widescreen = false, bool clearbackground = false); 334 virtual void Draw(void); 335 virtual bool Event(CGameMenuEvent &); 336 void Reset(void); 337 }; 338 339 class CGameMenuItemZCycleSelect : public CGameMenuItem 340 { 341 public: 342 void(*m_pCallback)(CGameMenuItemZCycleSelect *); 343 int m_nRows; 344 int m_nTopDelta; 345 int m_nFocus; 346 int m_nItems; 347 int *m_pReturn; 348 const char **m_pzStrings; 349 CGameMenuItemZCycleSelect(); 350 CGameMenuItemZCycleSelect(const char *pzText, int nFont, int nX, int nY, int nWidth, int nRows, int nItems, const char **pzStrings, int *pReturn, void(*pCallback)(CGameMenuItemZCycleSelect *)); 351 virtual void Draw(void); 352 virtual bool Event(CGameMenuEvent &); 353 virtual bool MouseEvent(CGameMenuEvent &); 354 }; 355 356 357 class CGameMenuItemZCycle : public CGameMenuItem 358 { 359 public: 360 int m_nItems; 361 int m_nFocus; 362 int m_nAlign; 363 const char *m_pzStrings[kMaxGameCycleItems]; 364 char m_zTitle[kMaxTitleLength]; 365 void(*m_pCallback)(CGameMenuItemZCycle *); 366 void(*m_pCallbackSelect)(CGameMenuItemZCycleSelect *); 367 bool m_bMenu; 368 int m_nMenuSelectReturn; 369 CGameMenu *m_pMenuSelect; 370 CGameMenuItemTitle *m_pItemSelectTitle; 371 CGameMenuItemZCycleSelect *m_pItemSelect; 372 CGameMenuItemZCycle(); 373 CGameMenuItemZCycle(const char *, int, int, int, int, int, void(*)(CGameMenuItemZCycle *), const char **, int, int, bool = false, void(*)(CGameMenuItemZCycleSelect*) = NULL); 374 ~CGameMenuItemZCycle(); 375 virtual void Draw(void); 376 virtual bool Event(CGameMenuEvent &); 377 void Add(const char *, bool); 378 void Next(void); 379 void Prev(void); 380 void Clear(void); 381 void SetTextArray(const char **, int, int); 382 void SetTextIndex(int); 383 }; 384 385 class CGameMenuItemYesNoQuit : public CGameMenuItem 386 { 387 public: 388 int at20; 389 int m_nRestart; 390 CGameMenuItemYesNoQuit(); 391 CGameMenuItemYesNoQuit(const char *, int, int, int, int, int, int); 392 virtual void Draw(void); 393 virtual bool Event(CGameMenuEvent &); 394 }; 395 396 class CGameMenuItemPicCycle : public CGameMenuItem 397 { 398 public: 399 int m_nItems; 400 int at24; 401 int at28; 402 int at2c; 403 int at30[kMaxPicCycleItems]; 404 void(*atb0)(CGameMenuItemPicCycle *); 405 int atb4; 406 CGameMenuItemPicCycle(); 407 CGameMenuItemPicCycle(int, int, void(*)(CGameMenuItemPicCycle *), int *, int, int); 408 virtual void Draw(void); 409 virtual bool Event(CGameMenuEvent &); 410 void Add(int, bool); 411 void Next(void); 412 void Prev(void); 413 void Clear(void); 414 void SetPicArray(int *, int, int); 415 void SetPicIndex(int); 416 }; 417 418 class CGameMenuItemPassword : public CGameMenuItem 419 { 420 public: 421 char at20[9]; 422 char at29[9]; 423 int at32; 424 char at36; 425 int at37; 426 char at3b[32]; 427 int at5b; 428 CGameMenuItemZBool *at5f; 429 CGameMenuItemPassword(); 430 CGameMenuItemPassword(const char *, int, int, int); 431 virtual void Draw(void); 432 virtual bool Event(CGameMenuEvent &); 433 }; 434 435 class CGameMenuFileSelect : public CGameMenuItem 436 { 437 private: 438 const char *startdir; 439 const char *pattern; 440 char *destination; 441 void (*onFileSelectedEventHandler)(); 442 char doPop; 443 BUILDVFS_FIND_REC *findhigh[2]; 444 int32_t nTopDelta[2]; 445 fnlist_t fnlist; 446 int32_t currentList; 447 bool Select(void); 448 void FileSelectInit(void); 449 void MovementVerify(void); 450 void RemoveFilenameFromDestination(void); 451 void SetDestinationToParentDir(void); 452 public: 453 CGameMenuFileSelect(const char *_pzText, int _nFont, int _x, int _y, int _nWidth, const char *_startdir, const char *_pattern, char *_destination, void(*)() = nullptr, const char doPop = 1); 454 virtual void Draw(void); 455 virtual bool Event(CGameMenuEvent&); 456 virtual bool MouseEvent(CGameMenuEvent &); 457 }; 458 459 460 class CGameMenu 461 { 462 public: 463 int m_nItems; 464 int m_nFocus; 465 int at8; 466 char atc; 467 CGameMenuItem *pItemList[kMaxGameMenuItems]; // atd 468 CGameMenu(); 469 CGameMenu(int); 470 ~CGameMenu(); 471 void InitializeItems(CGameMenuEvent &event); 472 void Draw(void); 473 bool Event(CGameMenuEvent &event); 474 void Add(CGameMenuItem *pItem, bool active); 475 void SetFocusItem(int nItem); 476 void SetFocusItem(CGameMenuItem *Item); 477 bool CanSelectItem(int nItem); 478 void FocusPrevItem(void); 479 void FocusNextItem(void); 480 bool IsFocusItem(CGameMenuItem *pItem); 481 bool MouseEvent(CGameMenuEvent &event); 482 }; 483 484 class CGameMenuMgr 485 { 486 public: 487 static bool m_bInitialized; 488 static bool m_bActive; 489 static bool m_bScanning; 490 CGameMenu *pTempMenu; 491 CGameMenu *pActiveMenu; 492 CGameMenu *pMenuStack[8]; 493 int nMenuPointer; 494 int32_t m_mouselastactivity; 495 int32_t m_mousewake_watchpoint, m_menuchange_watchpoint; 496 int32_t m_mousecaught; 497 vec2_t m_prevmousepos, m_mousepos, m_mousedownpos; 498 bool m_postPop; 499 CGameMenuMgr(); 500 ~CGameMenuMgr(); 501 void InitializeMenu(void); 502 void DeInitializeMenu(void); 503 bool Push(CGameMenu *pMenu, int data); 504 void Pop(void); 505 void PostPop(void); 506 void Draw(void); 507 void Clear(void); 508 void Process(void); 509 void Deactivate(void); 510 bool MouseOutsideBounds(vec2_t const * const pos, const int32_t x, const int32_t y, const int32_t width, const int32_t height); 511 }; 512 513 extern CMenuTextMgr gMenuTextMgr; 514 extern CGameMenuMgr gGameMenuMgr; 515