1 #ifndef __M_MENU_MENU_H__
2 #define __M_MENU_MENU_H__
3 
4 
5 
6 
7 #include "dobject.h"
8 #include "d_player.h"
9 #include "r_data/r_translate.h"
10 #include "c_cvars.h"
11 #include "v_font.h"
12 #include "version.h"
13 #include "textures/textures.h"
14 
15 EXTERN_CVAR(Float, snd_menuvolume)
16 EXTERN_CVAR(Int, m_use_mouse);
17 
18 
19 struct event_t;
20 class FTexture;
21 class FFont;
22 enum EColorRange;
23 class FPlayerClass;
24 class FKeyBindings;
25 
26 enum EMenuKey
27 {
28 	MKEY_Up,
29 	MKEY_Down,
30 	MKEY_Left,
31 	MKEY_Right,
32 	MKEY_PageUp,
33 	MKEY_PageDown,
34 	//----------------- Keys past here do not repeat.
35 	MKEY_Enter,
36 	MKEY_Back,		// Back to previous menu
37 	MKEY_Clear,		// Clear keybinding/flip player sprite preview
38 	NUM_MKEYS,
39 
40 	// These are not buttons but events sent from other menus
41 
42 	MKEY_Input,		// Sent when input is confirmed
43 	MKEY_Abort,		// Input aborted
44 	MKEY_MBYes,
45 	MKEY_MBNo,
46 };
47 
48 
49 struct FGameStartup
50 {
51 	const char *PlayerClass;
52 	int Episode;
53 	int Skill;
54 };
55 
56 extern FGameStartup GameStartupInfo;
57 
58 struct FSaveGameNode
59 {
60 	char Title[SAVESTRINGSIZE];
61 	FString Filename;
62 	bool bOldVersion;
63 	bool bMissingWads;
64 	bool bNoDelete;
65 
FSaveGameNodeFSaveGameNode66 	FSaveGameNode() { bNoDelete = false; }
67 };
68 
69 
70 
71 //=============================================================================
72 //
73 // menu descriptor. This is created from the menu definition lump
74 // Items must be inserted in the order they are cycled through with the cursor
75 //
76 //=============================================================================
77 
78 enum EMenuDescriptorType
79 {
80 	MDESC_ListMenu,
81 	MDESC_OptionsMenu,
82 };
83 
84 struct FMenuDescriptor
85 {
86 	FName mMenuName;
87 	FString mNetgameMessage;
88 	int mType;
89 	const PClass *mClass;
90 
~FMenuDescriptorFMenuDescriptor91 	virtual ~FMenuDescriptor() {}
92 };
93 
94 class FListMenuItem;
95 class FOptionMenuItem;
96 
97 struct FListMenuDescriptor : public FMenuDescriptor
98 {
99 	TDeletingArray<FListMenuItem *> mItems;
100 	int mSelectedItem;
101 	int mSelectOfsX;
102 	int mSelectOfsY;
103 	FTextureID mSelector;
104 	int mDisplayTop;
105 	int mXpos, mYpos;
106 	int mWLeft, mWRight;
107 	int mLinespacing;	// needs to be stored for dynamically created menus
108 	int mAutoselect;	// this can only be set by internal menu creation functions
109 	FFont *mFont;
110 	EColorRange mFontColor;
111 	EColorRange mFontColor2;
112 	FMenuDescriptor *mRedirect;	// used to redirect overlong skill and episode menus to option menu based alternatives
113 	bool mCenter;
114 
ResetFListMenuDescriptor115 	void Reset()
116 	{
117 		// Reset the default settings (ignore all other values in the struct)
118 		mSelectOfsX = 0;
119 		mSelectOfsY = 0;
120 		mSelector.SetInvalid();
121 		mDisplayTop = 0;
122 		mXpos = 0;
123 		mYpos = 0;
124 		mLinespacing = 0;
125 		mNetgameMessage = "";
126 		mFont = NULL;
127 		mFontColor = CR_UNTRANSLATED;
128 		mFontColor2 = CR_UNTRANSLATED;
129 	}
130 };
131 
132 struct FOptionMenuSettings
133 {
134 	EColorRange mTitleColor;
135 	EColorRange mFontColor;
136 	EColorRange mFontColorValue;
137 	EColorRange mFontColorMore;
138 	EColorRange mFontColorHeader;
139 	EColorRange mFontColorHighlight;
140 	EColorRange mFontColorSelection;
141 	int mLinespacing;
142 };
143 
144 struct FOptionMenuDescriptor : public FMenuDescriptor
145 {
146 	TDeletingArray<FOptionMenuItem *> mItems;
147 	FString mTitle;
148 	int mSelectedItem;
149 	int mDrawTop;
150 	int mScrollTop;
151 	int mScrollPos;
152 	int mIndent;
153 	int mPosition;
154 	bool mDontDim;
155 
156 	void CalcIndent();
157 	FOptionMenuItem *GetItem(FName name);
ResetFOptionMenuDescriptor158 	void Reset()
159 	{
160 		// Reset the default settings (ignore all other values in the struct)
161 		mPosition = 0;
162 		mScrollTop = 0;
163 		mIndent = 0;
164 		mDontDim = 0;
165 	}
166 
167 };
168 
169 
170 typedef TMap<FName, FMenuDescriptor *> MenuDescriptorList;
171 
172 extern FOptionMenuSettings OptionSettings;
173 extern MenuDescriptorList MenuDescriptors;
174 
175 #define CURSORSPACE (14 * CleanXfac_1)
176 
177 //=============================================================================
178 //
179 //
180 //
181 //=============================================================================
182 
183 struct FMenuRect
184 {
185 	int x, y;
186 	int width, height;
187 
setFMenuRect188 	void set(int _x, int _y, int _w, int _h)
189 	{
190 		x = _x;
191 		y = _y;
192 		width = _w;
193 		height = _h;
194 	}
195 
insideFMenuRect196 	bool inside(int _x, int _y)
197 	{
198 		return _x >= x && _x < x+width && _y >= y && _y < y+height;
199 	}
200 
201 };
202 
203 
204 class DMenu : public DObject
205 {
DECLARE_CLASS(DMenu,DObject)206 	DECLARE_CLASS (DMenu, DObject)
207 	HAS_OBJECT_POINTERS
208 
209 protected:
210 	bool mMouseCapture;
211 	bool mBackbuttonSelected;
212 
213 public:
214 	enum
215 	{
216 		MOUSE_Click,
217 		MOUSE_Move,
218 		MOUSE_Release
219 	};
220 
221 	enum
222 	{
223 		BACKBUTTON_TIME = 4*TICRATE
224 	};
225 
226 	static DMenu *CurrentMenu;
227 	static int MenuTime;
228 
229 	TObjPtr<DMenu> mParentMenu;
230 
231 	DMenu(DMenu *parent = NULL);
232 	virtual bool Responder (event_t *ev);
233 	virtual bool MenuEvent (int mkey, bool fromcontroller);
234 	virtual void Ticker ();
235 	virtual void Drawer ();
236 	virtual bool DimAllowed ();
237 	virtual bool TranslateKeyboardEvents();
238 	virtual void Close();
239 	virtual bool MouseEvent(int type, int x, int y);
240 	bool MouseEventBack(int type, int x, int y);
241 	void SetCapture();
242 	void ReleaseCapture();
HasCapture()243 	bool HasCapture()
244 	{
245 		return mMouseCapture;
246 	}
247 };
248 
249 //=============================================================================
250 //
251 // base class for menu items
252 //
253 //=============================================================================
254 
255 class FListMenuItem
256 {
257 protected:
258 	int mXpos, mYpos;
259 	FName mAction;
260 
261 public:
262 	bool mEnabled;
263 
264 	FListMenuItem(int xpos = 0, int ypos = 0, FName action = NAME_None)
265 	{
266 		mXpos = xpos;
267 		mYpos = ypos;
268 		mAction = action;
269 		mEnabled = true;
270 	}
271 
272 	virtual ~FListMenuItem();
273 
274 	virtual bool CheckCoordinate(int x, int y);
275 	virtual void Ticker();
276 	virtual void Drawer(bool selected);
277 	virtual bool Selectable();
278 	virtual bool Activate();
279 	virtual FName GetAction(int *pparam);
280 	virtual bool SetString(int i, const char *s);
281 	virtual bool GetString(int i, char *s, int len);
282 	virtual bool SetValue(int i, int value);
283 	virtual bool GetValue(int i, int *pvalue);
284 	virtual void Enable(bool on);
285 	virtual bool MenuEvent (int mkey, bool fromcontroller);
286 	virtual bool MouseEvent(int type, int x, int y);
287 	virtual bool CheckHotkey(int c);
288 	virtual int GetWidth();
289 	void DrawSelector(int xofs, int yofs, FTextureID tex);
OffsetPositionY(int ydelta)290 	void OffsetPositionY(int ydelta) { mYpos += ydelta; }
GetY()291 	int GetY() { return mYpos; }
GetX()292 	int GetX() { return mXpos; }
SetX(int x)293 	void SetX(int x) { mXpos = x; }
294 };
295 
296 class FListMenuItemStaticPatch : public FListMenuItem
297 {
298 protected:
299 	FTextureID mTexture;
300 	bool mCentered;
301 
302 public:
303 	FListMenuItemStaticPatch(int x, int y, FTextureID patch, bool centered);
304 	void Drawer(bool selected);
305 };
306 
307 class FListMenuItemStaticText : public FListMenuItem
308 {
309 protected:
310 	const char *mText;
311 	FFont *mFont;
312 	EColorRange mColor;
313 	bool mCentered;
314 
315 public:
316 	FListMenuItemStaticText(int x, int y, const char *text, FFont *font, EColorRange color, bool centered);
317 	~FListMenuItemStaticText();
318 	void Drawer(bool selected);
319 };
320 
321 //=============================================================================
322 //
323 // the player sprite window
324 //
325 //=============================================================================
326 
327 class FListMenuItemPlayerDisplay : public FListMenuItem
328 {
329 	FListMenuDescriptor *mOwner;
330 	FTexture *mBackdrop;
331 	FRemapTable mRemap;
332 	FPlayerClass *mPlayerClass;
333 	FState *mPlayerState;
334 	int mPlayerTics;
335 	bool mNoportrait;
336 	BYTE mRotation;
337 	BYTE mMode;	// 0: automatic (used by class selection), 1: manual (used by player setup)
338 	BYTE mTranslate;
339 	int mSkin;
340 	int mRandomClass;
341 	int mRandomTimer;
342 	int mClassNum;
343 
344 	void SetPlayerClass(int classnum, bool force = false);
345 	bool UpdatePlayerClass();
346 	void UpdateRandomClass();
347 	void UpdateTranslation();
348 
349 public:
350 
351 	enum
352 	{
353 		PDF_ROTATION = 0x10001,
354 		PDF_SKIN = 0x10002,
355 		PDF_CLASS = 0x10003,
356 		PDF_MODE = 0x10004,
357 		PDF_TRANSLATE = 0x10005,
358 	};
359 
360 	FListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action);
361 	~FListMenuItemPlayerDisplay();
362 	virtual void Ticker();
363 	virtual void Drawer(bool selected);
364 	bool SetValue(int i, int value);
365 };
366 
367 
368 //=============================================================================
369 //
370 // selectable items
371 //
372 //=============================================================================
373 
374 class FListMenuItemSelectable : public FListMenuItem
375 {
376 protected:
377 	int mHotkey;
378 	int mHeight;
379 	int mParam;
380 
381 public:
382 	FListMenuItemSelectable(int x, int y, int height, FName childmenu, int mParam = -1);
383 	bool CheckCoordinate(int x, int y);
384 	bool Selectable();
385 	bool CheckHotkey(int c);
386 	bool Activate();
387 	bool MouseEvent(int type, int x, int y);
388 	FName GetAction(int *pparam);
389 };
390 
391 class FListMenuItemText : public FListMenuItemSelectable
392 {
393 	const char *mText;
394 	FFont *mFont;
395 	EColorRange mColor;
396 	EColorRange mColorSelected;
397 public:
398 	FListMenuItemText(int x, int y, int height, int hotkey, const char *text, FFont *font, EColorRange color, EColorRange color2, FName child, int param = 0);
399 	~FListMenuItemText();
400 	void Drawer(bool selected);
401 	int GetWidth();
402 };
403 
404 class FListMenuItemPatch : public FListMenuItemSelectable
405 {
406 	FTextureID mTexture;
407 public:
408 	FListMenuItemPatch(int x, int y, int height, int hotkey, FTextureID patch, FName child, int param = 0);
409 	void Drawer(bool selected);
410 	int GetWidth();
411 };
412 
413 //=============================================================================
414 //
415 // items for the player menu
416 //
417 //=============================================================================
418 
419 class FPlayerNameBox : public FListMenuItemSelectable
420 {
421 	const char *mText;
422 	FFont *mFont;
423 	EColorRange mFontColor;
424 	int mFrameSize;
425 	char mPlayerName[MAXPLAYERNAME+1];
426 	char mEditName[MAXPLAYERNAME+2];
427 	bool mEntering;
428 
429 	void DrawBorder (int x, int y, int len);
430 
431 public:
432 
433 	FPlayerNameBox(int x, int y, int height, int frameofs, const char *text, FFont *font, EColorRange color, FName action);
434 	~FPlayerNameBox();
435 	bool SetString(int i, const char *s);
436 	bool GetString(int i, char *s, int len);
437 	void Drawer(bool selected);
438 	bool MenuEvent (int mkey, bool fromcontroller);
439 };
440 
441 //=============================================================================
442 //
443 // items for the player menu
444 //
445 //=============================================================================
446 
447 class FValueTextItem : public FListMenuItemSelectable
448 {
449 	TArray<FString> mSelections;
450 	const char *mText;
451 	int mSelection;
452 	FFont *mFont;
453 	EColorRange mFontColor;
454 	EColorRange mFontColor2;
455 
456 public:
457 
458 	FValueTextItem(int x, int y, int height, const char *text, FFont *font, EColorRange color, EColorRange valuecolor, FName action, FName values);
459 	~FValueTextItem();
460 	bool SetString(int i, const char *s);
461 	bool SetValue(int i, int value);
462 	bool GetValue(int i, int *pvalue);
463 	bool MenuEvent (int mkey, bool fromcontroller);
464 	void Drawer(bool selected);
465 };
466 
467 //=============================================================================
468 //
469 // items for the player menu
470 //
471 //=============================================================================
472 
473 class FSliderItem : public FListMenuItemSelectable
474 {
475 	const char *mText;
476 	FFont *mFont;
477 	EColorRange mFontColor;
478 	int mMinrange, mMaxrange;
479 	int mStep;
480 	int mSelection;
481 
482 	void DrawSlider (int x, int y);
483 
484 public:
485 
486 	FSliderItem(int x, int y, int height, const char *text, FFont *font, EColorRange color, FName action, int min, int max, int step);
487 	~FSliderItem();
488 	bool SetValue(int i, int value);
489 	bool GetValue(int i, int *pvalue);
490 	bool MenuEvent (int mkey, bool fromcontroller);
491 	void Drawer(bool selected);
492 	bool MouseEvent(int type, int x, int y);
493 };
494 
495 //=============================================================================
496 //
497 // list menu class runs a menu described by a FListMenuDescriptor
498 //
499 //=============================================================================
500 
501 class DListMenu : public DMenu
502 {
503 	DECLARE_CLASS(DListMenu, DMenu)
504 
505 protected:
506 	FListMenuDescriptor *mDesc;
507 	FListMenuItem *mFocusControl;
508 
509 public:
510 	DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
511 	virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL);
512 	FListMenuItem *GetItem(FName name);
513 	bool Responder (event_t *ev);
514 	bool MenuEvent (int mkey, bool fromcontroller);
515 	bool MouseEvent(int type, int x, int y);
516 	void Ticker ();
517 	void Drawer ();
SetFocus(FListMenuItem * fc)518 	void SetFocus(FListMenuItem *fc)
519 	{
520 		mFocusControl = fc;
521 	}
CheckFocus(FListMenuItem * fc)522 	bool CheckFocus(FListMenuItem *fc)
523 	{
524 		return mFocusControl == fc;
525 	}
ReleaseFocus()526 	void ReleaseFocus()
527 	{
528 		mFocusControl = NULL;
529 	}
530 };
531 
532 
533 //=============================================================================
534 //
535 // base class for menu items
536 //
537 //=============================================================================
538 
539 class FOptionMenuItem : public FListMenuItem
540 {
541 protected:
542 	char *mLabel;
543 	bool mCentered;
544 
545 	void drawLabel(int indent, int y, EColorRange color, bool grayed = false);
546 public:
547 
548 	FOptionMenuItem(const char *text, FName action = NAME_None, bool center = false)
549 		: FListMenuItem(0, 0, action)
550 	{
551 		mLabel = copystring(text);
552 		mCentered = center;
553 	}
554 
555 	~FOptionMenuItem();
556 	virtual int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected);
557 	virtual bool Selectable();
558 	virtual int GetIndent();
559 	virtual bool MouseEvent(int type, int x, int y);
560 };
561 
562 //=============================================================================
563 //
564 //
565 //
566 //=============================================================================
567 struct FOptionValues
568 {
569 	struct Pair
570 	{
571 		double Value;
572 		FString TextValue;
573 		FString Text;
574 	};
575 
576 	TArray<Pair> mValues;
577 };
578 
579 typedef TMap< FName, FOptionValues* > FOptionMap;
580 
581 extern FOptionMap OptionValues;
582 
583 
584 //=============================================================================
585 //
586 // Option menu class runs a menu described by a FOptionMenuDescriptor
587 //
588 //=============================================================================
589 
590 class DOptionMenu : public DMenu
591 {
592 	DECLARE_CLASS(DOptionMenu, DMenu)
593 
594 	bool CanScrollUp;
595 	bool CanScrollDown;
596 	int VisBottom;
597 	FOptionMenuItem *mFocusControl;
598 
599 protected:
600 	FOptionMenuDescriptor *mDesc;
601 
602 public:
603 	FOptionMenuItem *GetItem(FName name);
604 	DOptionMenu(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL);
605 	virtual void Init(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL);
606 	int FirstSelectable();
607 	bool Responder (event_t *ev);
608 	bool MenuEvent (int mkey, bool fromcontroller);
609 	bool MouseEvent(int type, int x, int y);
610 	void Ticker ();
611 	void Drawer ();
GetDescriptor()612 	const FOptionMenuDescriptor *GetDescriptor() const { return mDesc; }
SetFocus(FOptionMenuItem * fc)613 	void SetFocus(FOptionMenuItem *fc)
614 	{
615 		mFocusControl = fc;
616 	}
CheckFocus(FOptionMenuItem * fc)617 	bool CheckFocus(FOptionMenuItem *fc)
618 	{
619 		return mFocusControl == fc;
620 	}
ReleaseFocus()621 	void ReleaseFocus()
622 	{
623 		mFocusControl = NULL;
624 	}
625 };
626 
627 
628 //=============================================================================
629 //
630 // Input some text
631 //
632 //=============================================================================
633 
634 class DTextEnterMenu : public DMenu
635 {
636 	DECLARE_ABSTRACT_CLASS(DTextEnterMenu, DMenu)
637 
638 	char *mEnterString;
639 	unsigned int mEnterSize;
640 	unsigned int mEnterPos;
641 	int mSizeMode; // 1: size is length in chars. 2: also check string width
642 	bool mInputGridOkay;
643 
644 	int InputGridX;
645 	int InputGridY;
646 
647 	// [TP]
648 	bool AllowColors;
649 
650 public:
651 
652 	// [TP] Added allowcolors
653 	DTextEnterMenu(DMenu *parent, char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false);
654 
655 	void Drawer ();
656 	bool MenuEvent (int mkey, bool fromcontroller);
657 	bool Responder(event_t *ev);
658 	bool TranslateKeyboardEvents();
659 	bool MouseEvent(int type, int x, int y);
660 
661 };
662 
663 
664 
665 
666 struct event_t;
667 void M_EnableMenu (bool on) ;
668 bool M_Responder (event_t *ev);
669 void M_Ticker (void);
670 void M_Drawer (void);
671 void M_Init (void);
672 void M_CreateMenus();
673 void M_ActivateMenu(DMenu *menu);
674 void M_ClearMenus ();
675 void M_ParseMenuDefs();
676 void M_StartupSkillMenu(FGameStartup *gs);
677 int M_GetDefaultSkill();
678 void M_StartControlPanel (bool makeSound);
679 void M_SetMenu(FName menu, int param = -1);
680 void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave);
681 void M_StartMessage(const char *message, int messagemode, FName action = NAME_None);
682 DMenu *StartPickerMenu(DMenu *parent, const char *name, FColorCVar *cvar);
683 void M_RefreshModesList ();
684 void M_InitVideoModesMenu ();
685 
686 
687 #endif