1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 
20 //
21 // gui_local.h
22 //
23 
24 #include "cl_local.h"
25 
26 #define MAX_GUIS			512				// Maximum in-memory GUIs
27 
28 #define MAX_GUI_CHILDREN	32				// Maximum children per child
29 #define MAX_GUI_DEFINES		32				// Maximum definefloat/definevec's
30 #define MAX_GUI_DEPTH		32				// Maximum opened at the same time
31 #define MAX_GUI_HASH		(MAX_GUIS/4)	// Hash optimization
32 #define MAX_GUI_NAMELEN		64				// Maximum window name length
33 
34 #define MAX_GUI_EVENTS		16				// Maximum events per window
35 #define MAX_EVENT_ARGS		1
36 #define MAX_EVENT_ARGLEN	64
37 #define MAX_EVENT_ACTIONS	16				// Maximum actions per event per window
38 
39 //
40 // Script path location
41 // This is so that moddir gui's of the same name
42 // have precedence over basedir ones
43 //
44 typedef enum guiPathType_s {
45 	GUIPT_BASEDIR,
46 	GUIPT_MODDIR,
47 } guiPathType_t;
48 
49 //
50 // Window types
51 //
52 typedef enum guiType_s {
53 	WTP_GUI,
54 	WTP_GENERIC,
55 
56 	WTP_BIND,
57 	WTP_CHECKBOX,
58 	WTP_CHOICE,
59 	WTP_EDIT,
60 	WTP_LIST,
61 	WTP_RENDER,
62 	WTP_SLIDER,
63 	WTP_TEXT,
64 
65 	WTP_MAX
66 } guiType_t;
67 
68 //
69 // Window flags
70 // FIXME: yyuucckk
71 //
72 typedef enum guiFlags_s {
73 	WFL_CURSOR			= 1 << 0,
74 	WFL_FILL_COLOR		= 1 << 1,
75 	WFL_MATERIAL		= 1 << 2,
76 	WFL_ITEM			= 1 << 3,
77 } guiFlags_t;
78 
79 /*
80 =============================================================================
81 
82 	MEMORY MANAGEMENT
83 
84 =============================================================================
85 */
86 
87 enum {
88 	GUITAG_KEEP,			// What's kept in memory at all times
89 	GUITAG_SCRATCH,			// Scratch tag for init. When a GUI is complete it's tag is shifted to GUITAG_KEEP
90 	GUITAG_VARS,			// for GUI vars
91 };
92 
93 #define GUI_AllocTag(size,zeroFill,tagNum)	_Mem_Alloc((size),(zeroFill),cl_guiSysPool,(tagNum),__FILE__,__LINE__)
94 #define GUI_FreeTag(tagNum)					_Mem_FreeTag(cl_guiSysPool,(tagNum),__FILE__,__LINE__)
95 #define GUI_StrDup(in,tagNum)				_Mem_PoolStrDup((in),cl_guiSysPool,(tagNum),__FILE__,__LINE__)
96 #define GUI_MemFree(ptr)					_Mem_Free((ptr),__FILE__,__LINE__)
97 
98 /*
99 =============================================================================
100 
101 	GUI VARIABLES
102 
103 =============================================================================
104 */
105 
106 #define MAX_GUIVARS			1024
107 #define MAX_GV_NAMELEN		64
108 #define MAX_GV_STRLEN		1024	// Maximum GVT_STR length
109 
110 typedef struct guiVar_s {
111 	char				*name;
112 	guiVarType_t		type;
113 
114 	qBool				modified;
115 
116 	char				*strVal;
117 	float				floatVal;
118 	vec4_t				vecVal;
119 } guiVar_t;
120 
121 void		GUIVar_Init (void);
122 void		GUIVar_Shutdown (void);
123 
124 /*
125 =============================================================================
126 
127 	GUI CURSOR
128 
129 	Each GUI can script their cursor setup, and modify (with events)
130 	the properties.
131 =============================================================================
132 */
133 
134 typedef struct guiCursorData_s {
135 	qBool				visible;
136 
137 	char				matName[MAX_QPATH];
138 	struct shader_s		*matPtr;
139 	vec4_t				color;
140 
141 	qBool				locked;
142 	vec2_t				pos;
143 	vec2_t				size;
144 } guiCursorData_t;
145 
146 typedef struct guiCursor_s {
147 	// Static (compiled) information
148 	guiCursorData_t		s;
149 
150 	// Dynamic information
151 	guiCursorData_t		d;
152 
153 	struct gui_s		*curWindow;
154 	qBool				mouseMoved;
155 } guiCursor_t;
156 
157 /*
158 =============================================================================
159 
160 	GUI SHARED DATA
161 
162 	This data only exists once in any given GUI, and is just pointed to by
163 	all of the children. It's used for things that do not need to be in
164 	every single window.
165 =============================================================================
166 */
167 
168 typedef struct guiShared_s {
169 	guiPathType_t		pathType;
170 	guiCursor_t			cursor;
171 
172 	qBool				queueClose;
173 
174 	float				xScale;
175 	float				yScale;
176 } guiShared_t;
177 
178 /*
179 =============================================================================
180 
181 	WINDOW DEFINES
182 
183 	These can be changed at any time in the script using event actions.
184 =============================================================================
185 */
186 
187 typedef struct defineFloat_s {
188 	char				name[MAX_GUI_NAMELEN];
189 	float				value;
190 } defineFloat_t;
191 
192 typedef struct defineVec_s {
193 	char				name[MAX_GUI_NAMELEN];
194 	vec4_t				value;
195 } defineVec_t;
196 
197 /*
198 =============================================================================
199 
200 	EVENT ACTIONS
201 
202 =============================================================================
203 */
204 
205 typedef enum evaType_s {
206 	EVA_NONE,
207 
208 	EVA_CLOSE,
209 	EVA_COMMAND,
210 	EVA_IF,
211 	EVA_LOCAL_SOUND,
212 	EVA_NAMED_EVENT,
213 	EVA_RESET_TIME,
214 	EVA_SET,
215 	EVA_STOP_TRANSITIONS,
216 	EVA_TRANSITION,
217 
218 	EVA_MAX
219 } evaType_t;
220 
221 //
222 // EVA_LOCAL_SOUND
223 //
224 
225 typedef struct eva_localSound_s {
226 	char				name[MAX_QPATH];
227 	struct sfx_s		*sound;
228 	float				volume;
229 } eva_localSound_t;
230 
231 //
232 // EVA_NAMED_EVENT
233 //
234 
235 typedef struct eva_named_s {
236 	char				destWindowName[MAX_GUI_NAMELEN];
237 	struct gui_s		*destWindowPtr;
238 
239 	char				eventName[MAX_GUI_NAMELEN];
240 } eva_named_t;
241 
242 //
243 // EVA_SET
244 //
245 typedef enum set_destType_s {
246 	EVA_SETDEST_FLOAT	= 1 << 0,
247 	EVA_SETDEST_VEC		= 1 << 1,
248 
249 	// Or'd with what's above
250 	EVA_SETDEST_STORAGE	= 1 << 2,
251 	EVA_SETDEST_DEF		= 1 << 3
252 } set_destType_t;
253 
254 typedef enum set_srcType_s {
255 	EVA_SETSRC_STORAGE,
256 	EVA_SETSRC_DEF,
257 	EVA_SETSRC_GUIVAR,
258 } set_srcType_t;
259 
260 typedef struct eva_set_s {
261 	// Destination
262 	char				destWindowName[MAX_GUI_NAMELEN];
263 	struct gui_s		*destWindowPtr;
264 	guiType_t			destWindowType;
265 
266 	char				destVarName[MAX_GUI_NAMELEN];
267 
268 	set_destType_t		destType;
269 
270 	// EVA_SETDEST_DEF
271 	byte				destDefIndex;
272 
273 	// EVA_SETDEST_STORAGE
274 	uint32				destRegister;
275 	byte				destNumVecs;
276 
277 	// Source
278 	set_srcType_t		srcType;
279 
280 	// EVA_SETSRC_STORAGE
281 	vec4_t				srcStorage;
282 
283 	// EVA_SETSRC_DEF
284 	char				srcWindowName[MAX_GUI_NAMELEN];
285 	struct gui_s		*srcWindowPtr;
286 
287 	char				srcName[MAX_GUI_NAMELEN];
288 	defineFloat_t		*srcDefFloat;
289 	defineVec_t			*srcDefVec;
290 
291 	// EVA_SETSRC_GUIVAR
292 	guiVar_t			*srcGUIVar;
293 } eva_set_t;
294 
295 //
296 // Action handling
297 //
298 typedef struct evAction_s {
299 	evaType_t			type;
300 
301 	// EVA_CLOSE
302 	// EVA_COMMAND
303 	char				*command;
304 
305 	// EVA_IF
306 	// EVA_LOCAL_SOUND
307 	eva_localSound_t	*localSound;
308 
309 	// EVA_NAMED_EVENT
310 	eva_named_t			*named;
311 
312 	// EVA_RESET_TIME
313 	int					resetTime;
314 
315 	// EVA_SET
316 	eva_set_t			*set;
317 
318 	// EVA_STOP_TRANSITIONS
319 	// EVA_TRANSITION
320 } evAction_t;
321 
322 /*
323 =============================================================================
324 
325 	WINDOW EVENTS
326 
327 =============================================================================
328 */
329 
330 typedef enum evType_s {
331 	WEV_NONE,
332 
333 	WEV_ACTION,
334 	WEV_ESCAPE,
335 	WEV_FRAME,
336 	WEV_INIT,
337 	WEV_MOUSE_ENTER,
338 	WEV_MOUSE_EXIT,
339 	WEV_NAMED,
340 	WEV_SHUTDOWN,
341 	WEV_TIME,
342 
343 	WEV_MAX
344 } evType_t;
345 
346 typedef struct event_s {
347 	evType_t			type;
348 
349 	byte				numActions;
350 	evAction_t			*actionList;
351 
352 	// WEV_NAMED
353 	char				*named;
354 
355 	// WEV_TIME
356 	uint32				onTime;
357 } event_t;
358 
359 /*
360 =============================================================================
361 
362 	WINDOW REGISTERS
363 
364 	These can be changed at any time in the script using event actions.
365 =============================================================================
366 */
367 
368 typedef enum regSource_s {
369 	REG_SOURCE_SELF,
370 	REG_SOURCE_DEF,
371 	REG_SOURCE_GUIVAR,
372 
373 	REG_SOURCE_MAX
374 } regSource_t;
375 
376 //
377 // Vector registers
378 //
379 #define VRVALUE(gui,reg) ((gui)->d.vecRegisters[(reg)].var)
380 enum {
381 	// textDef windows
382 	VR_TEXT_COLOR,
383 	VR_TEXT_HOVERCOLOR,
384 
385 	// ALL windows
386 	VR_FILL_COLOR,
387 	VR_MAT_COLOR,
388 	VR_RECT,
389 
390 	VR_MAX,
391 };
392 
393 typedef struct vecRegister_s {
394 	regSource_t			sourceType;
395 	float				*var;
396 
397 	// REG_SOURCE_SELF
398 	vec4_t				storage;
399 
400 	// REG_SOURCE_DEF
401 	struct gui_s		*defVecWindow;
402 	int					defVecIndex;
403 
404 	// REG_SOURCE_GUIVAR
405 	struct guiVar_s		*guiVar;
406 } vecRegister_t;
407 
408 //
409 // Float registers
410 //
411 #define FRVALUE(gui,reg) (*((gui)->d.floatRegisters[(reg)].var))
412 
413 enum {
414 	// textDef windows
415 	FR_TEXT_ALIGN,
416 	FR_TEXT_SCALE,
417 	FR_TEXT_SHADOW,
418 
419 	// ALL windows
420 	FR_MAT_SCALE_X,
421 	FR_MAT_SCALE_Y,
422 
423 	FR_MODAL,
424 	FR_NO_EVENTS,
425 	FR_NO_TIME,
426 	FR_ROTATION,		// FIXME: Todo
427 	FR_VISIBLE,
428 	FR_WANT_ENTER,
429 
430 	FR_MAX
431 };
432 
433 typedef struct floatRegister_s {
434 	regSource_t			sourceType;			// storage, defFloat, or guiVar
435 	float				*var;
436 
437 	// REG_SOURCE_SELF
438 	float				storage;
439 
440 	// REG_SOURCE_DEF
441 	struct gui_s		*defFloatWindow;
442 	int					defFloatIndex;
443 
444 	// REG_SOURCE_GUIVAR
445 	struct guiVar_s		*guiVar;
446 } floatRegister_t;
447 
448 /*
449 =============================================================================
450 
451 	WINDOW STRUCTURES
452 
453 =============================================================================
454 */
455 
456 //
457 // bindDef
458 //
459 typedef struct bindDef_s {
460 	keyNum_t			keyNum;
461 } bindDef_t;
462 
463 //
464 // checkDef
465 //
466 typedef struct checkDef_s {
467 	qBool				liveUpdate;
468 
469 	char				offMatName[MAX_QPATH];
470 	struct shader_s		*offMatPtr;
471 
472 	char				onMatName[MAX_QPATH];
473 	struct shader_s		*onMatPtr;
474 
475 	char				*values[2];
476 
477 	cVar_t				*cvar;
478 } checkDef_t;
479 
480 //
481 // choiceDef
482 //
483 typedef struct choiceDef_s {
484 	int					todo;
485 } choiceDef_t;
486 
487 //
488 // editDef
489 //
490 typedef struct editDef_s {
491 	int					todo;
492 } editDef_t;
493 
494 //
495 // listDef
496 //
497 typedef struct listDef_s {
498 	qBool				scrollBar[2];
499 } listDef_t;
500 
501 //
502 // renderDef
503 //
504 typedef struct renderDef_s {
505 	int					todo;
506 } renderDef_t;
507 
508 //
509 // sliderDef
510 //
511 typedef struct sliderDef_s {
512 	int					todo;
513 } sliderDef_t;
514 
515 //
516 // textDef
517 //
518 #define MAX_TEXTDEF_STRLEN		1024
519 
520 typedef struct textDef_s {
521 	char				fontName[MAX_QPATH];
522 	struct font_s		*fontPtr;
523 
524 	char				*textString;
525 	size_t				textStringLen;
526 } textDef_t;
527 
528 //
529 // Generic window data
530 //
531 typedef struct guiData_s {
532 	byte				numDefFloats;
533 	defineFloat_t		*defFloatList;
534 	byte				numDefVecs;
535 	defineVec_t			*defVecList;
536 
537 	floatRegister_t		floatRegisters[FR_MAX];
538 	vecRegister_t		vecRegisters[VR_MAX];
539 
540 	bindDef_t			*bindDef;
541 	checkDef_t			*checkDef;
542 	choiceDef_t			*choiceDef;
543 	editDef_t			*editDef;
544 	listDef_t			*listDef;
545 	renderDef_t			*renderDef;
546 	sliderDef_t			*sliderDef;
547 	textDef_t			*textDef;
548 } guiData_t;
549 
550 typedef struct gui_s {
551 	// Static (compiled) information
552 	char				name[MAX_GUI_NAMELEN];
553 	guiFlags_t			flags;
554 	guiType_t			type;
555 
556 	guiShared_t			*shared;
557 	guiData_t			s;
558 
559 	char				matName[MAX_QPATH];
560 	struct shader_s		*matShader;
561 
562 	// Events
563 	byte				numEvents;
564 	event_t				*eventList;
565 
566 	// Children
567 	struct gui_s		*owner;							// guiDef
568 	struct gui_s		*parent;						// Next window up
569 
570 	byte				numChildren;
571 	struct gui_s		*childList;
572 
573 	// Dynamic information
574 	guiData_t			d;
575 
576 	vec4_t				rect;
577 	vec3_t				mins, maxs;
578 
579 	uint32				lastTime;
580 	uint32				openTime;
581 	uint32				time;
582 
583 	qBool				mouseEntered;
584 	qBool				mouseExited;
585 
586 	qBool				inited;
587 
588 	// Event queue
589 	byte				numQueued;
590 	event_t				*queueList[MAX_GUI_EVENTS];
591 
592 	byte				numDefaultQueued;
593 	evType_t			defaultQueueList[MAX_GUI_EVENTS];
594 } gui_t;
595 
596 /*
597 =============================================================================
598 
599 	LOCAL GUI STATE
600 
601 =============================================================================
602 */
603 
604 typedef struct guiState_s {
605 	uint32				frameCount;
606 
607 	gui_t				*inputWindow;
608 
609 	byte				numLayers;
610 	gui_t				*openLayers[MAX_GUI_DEPTH];
611 } guiState_t;
612 
613 extern guiState_t	cl_guiState;
614 
615 /*
616 =============================================================================
617 
618 	CVARS
619 
620 =============================================================================
621 */
622 
623 extern cVar_t	*gui_developer;
624 extern cVar_t	*gui_debugBounds;
625 extern cVar_t	*gui_debugScale;
626 extern cVar_t	*gui_mouseFilter;
627 extern cVar_t	*gui_mouseSensitivity;
628 
629 /*
630 =============================================================================
631 
632 	FUNCTION PROTOTYPES
633 
634 =============================================================================
635 */
636 
637 //
638 // gui_cursor.c
639 //
640 void		GUI_GenerateBounds (gui_t *gui);
641 void		GUI_CursorUpdate (gui_t *gui);
642 void		GUI_AdjustCursor (keyNum_t keyNum);
643 
644 //
645 // gui_events.c
646 //
647 void		GUI_TriggerEvents (gui_t *gui);
648 void		GUI_QueueTrigger (gui_t *gui, evType_t trigger);
649 
650 //
651 // gui_init.c
652 //
653 
654 void		GUI_Shutdown (void);
655 
656 //
657 // gui_main.c
658 //
659 void		GUI_ResetGUIState (gui_t *gui);
660