From 39494fb2eb80b3589b03c63d8d8c5c4f51a59676 Mon Sep 17 00:00:00 2001 From: Andrei Drexler Date: Wed, 7 Sep 2005 20:24:33 +0000 Subject: [PATCH] Vector support for most item types --- reaction/ta_ui/menudef.h | 6 + reaction/ta_ui/ta_ui.plg | 30 +- reaction/ta_ui/ui.ncb | Bin 330703 -> 25 bytes reaction/ta_ui/ui.opt | Bin 55808 -> 6 bytes reaction/ta_ui/ui_atoms.c | 36 +- reaction/ta_ui/ui_local.h | 24 +- reaction/ta_ui/ui_main.c | 630 ++++++++++++---- reaction/ta_ui/ui_shared.c | 1390 ++++++++++++++++++++++++++++-------- reaction/ta_ui/ui_shared.h | 130 +++- 9 files changed, 1747 insertions(+), 499 deletions(-) diff --git a/reaction/ta_ui/menudef.h b/reaction/ta_ui/menudef.h index 747e2ce0..e6aece34 100644 --- a/reaction/ta_ui/menudef.h +++ b/reaction/ta_ui/menudef.h @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.13 2005/09/07 20:24:33 makro +// Vector support for most item types +// // Revision 1.12 2005/02/15 16:33:39 makro // Tons of updates (entity tree attachment system, UI vectors) // @@ -280,6 +283,9 @@ #define UI_RQ3_REPLACEMENTTYPE 166 #define UI_RQ3_REPLACEMENTSUBTYPE 167 +//Makro - startup menu text +#define UI_RQ3_STARTUP 168 + #define UI_OWNERDRAW_BASE 200 #define UI_HANDICAP 200 #define UI_EFFECTS 201 diff --git a/reaction/ta_ui/ta_ui.plg b/reaction/ta_ui/ta_ui.plg index caa390c6..0c5bf65e 100644 --- a/reaction/ta_ui/ta_ui.plg +++ b/reaction/ta_ui/ta_ui.plg @@ -6,22 +6,13 @@ --------------------Configuration: ui - Win32 Debug TA--------------------

Command Lines

-Creating temporary file "C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP17B.tmp" with contents +Creating temporary file "C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP51.tmp" with contents [ /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "UI_EXPORTS" /Fp"D:\Work\rq3source\reaction\Release/ta_ui.pch" /YX /Fo"D:\Work\rq3source\reaction\Release/" /Fd"D:\Work\rq3source\reaction\Release/" /FD /GZ /c -"D:\Work\rq3source\reaction\game\bg_misc.c" -"D:\Work\rq3source\reaction\game\q_math.c" -"D:\Work\rq3source\reaction\game\q_shared.c" -"D:\Work\rq3source\reaction\ta_ui\ui_atoms.c" -"D:\Work\rq3source\reaction\ta_ui\ui_gameinfo.c" "D:\Work\rq3source\reaction\ta_ui\ui_main.c" -"D:\Work\rq3source\reaction\ta_ui\ui_players.c" -"D:\Work\rq3source\reaction\ta_ui\ui_shared.c" -"D:\Work\rq3source\reaction\ta_ui\ui_syscalls.c" -"D:\Work\rq3source\reaction\ta_ui\ui_util.c" ] -Creating command line "cl.exe @C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP17B.tmp" -Creating temporary file "C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP17C.tmp" with contents +Creating command line "cl.exe @C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP51.tmp" +Creating temporary file "C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP52.tmp" with contents [ /nologo /base:"0x40000000" /dll /incremental:yes /pdb:"../Debug/ui.pdb" /map:"D:\Work\rq3source\reaction\Release/uix86.map" /debug /machine:I386 /def:".\ui.def" /out:"D:\Work\rq3source\reaction\Release\uix86.dll" /implib:"D:\Work\rq3source\reaction\Release/uix86.lib" /pdbtype:sept \Work\rq3source\reaction\Release\bg_misc.obj @@ -35,27 +26,16 @@ Creating temporary file "C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP17C.tmp" with conte \Work\rq3source\reaction\Release\ui_syscalls.obj \Work\rq3source\reaction\Release\ui_util.obj ] -Creating command line "link.exe @C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP17C.tmp" +Creating command line "link.exe @C:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP52.tmp"

Output Window

Compiling... -bg_misc.c -q_math.c -d:\work\rq3source\reaction\game\q_math.c(1885) : warning C4101: 'result' : unreferenced local variable -q_shared.c -ui_atoms.c -ui_gameinfo.c ui_main.c -ui_players.c -ui_shared.c -ui_syscalls.c -ui_util.c Linking... - Creating library D:\Work\rq3source\reaction\Release/uix86.lib and object D:\Work\rq3source\reaction\Release/uix86.exp

Results

-uix86.dll - 0 error(s), 1 warning(s) +uix86.dll - 0 error(s), 0 warning(s) diff --git a/reaction/ta_ui/ui.ncb b/reaction/ta_ui/ui.ncb index cf3588dfe0f6560ba0f514236dcc3587f679db1a..9057ebacbf8c1f0a042244621ebfb90f57445ff0 100644 GIT binary patch delta 6 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

+Uvc9?s_>uvMH9deQ*> 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 G@c#j*`C>Kz diff --git a/reaction/ta_ui/ui.opt b/reaction/ta_ui/ui.opt index ba374802e555906698d0d66e93d7ac899b8944e2..3599f1b0124b12a8187d85386a3d647e4bace67f 100644 GIT binary patch literal 6 Ncmca`Uhu)fjQ|bE1LFVy literal 55808 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 KT{n>~KmS`m!3p;O diff --git a/reaction/ta_ui/ui_atoms.c b/reaction/ta_ui/ui_atoms.c index 2a048c3e..06222f3e 100644 --- a/reaction/ta_ui/ui_atoms.c +++ b/reaction/ta_ui/ui_atoms.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.22 2005/09/07 20:24:33 makro +// Vector support for most item types +// // Revision 1.21 2005/02/15 16:33:39 makro // Tons of updates (entity tree attachment system, UI vectors) // @@ -593,9 +596,11 @@ void UI_Shutdown(void) UI_AdjustFrom640 Adjusted for resolution and screen aspect ratio + +Makro - converted to macro, see ui_local.h ================ */ -void UI_AdjustFrom640(float *x, float *y, float *w, float *h) +void _UI_AdjustFrom640(float *x, float *y, float *w, float *h) { // expect valid pointers #if 0 @@ -619,7 +624,7 @@ void UI_DrawNamedPic(float x, float y, float width, float height, const char *pi hShader = trap_R_RegisterShaderNoMip(picname); UI_AdjustFrom640(&x, &y, &width, &height); //trap_R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, hShader); - uiInfo.uiDC.drawStretchPic(x, y, width, height, 0, 0, 1, 1, hShader); + uiInfo.uiDC.drawStretchPic(x, y, width, height, 0, 0, 1, 1, hShader, qfalse); } void UI_DrawHandlePic(float x, float y, float w, float h, qhandle_t hShader) @@ -649,7 +654,7 @@ void UI_DrawHandlePic(float x, float y, float w, float h, qhandle_t hShader) UI_AdjustFrom640(&x, &y, &w, &h); //trap_R_DrawStretchPic(x, y, w, h, s0, t0, s1, t1, hShader); - uiInfo.uiDC.drawStretchPic(x, y, w, h, s0, t0, s1, t1, hShader); + uiInfo.uiDC.drawStretchPic(x, y, w, h, s0, t0, s1, t1, hShader, qfalse); } /* @@ -665,27 +670,29 @@ void UI_FillRect(float x, float y, float width, float height, const float *color UI_AdjustFrom640(&x, &y, &width, &height); //trap_R_DrawStretchPic(x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader, qfalse); trap_R_SetColor(NULL); } -void UI_DrawSides(float x, float y, float w, float h) +//Makro - added shader parm +void UI_DrawSides(float x, float y, float w, float h, qhandle_t shader) { UI_AdjustFrom640(&x, &y, &w, &h); //trap_R_DrawStretchPic(x, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); //trap_R_DrawStretchPic(x + w - 1, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x + w - 1, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(x, y, 1, h, 0, 0, 0, 0, shader, qfalse); + uiInfo.uiDC.drawStretchPic(x + w - 1, y, 1, h, 0, 0, 0, 0, shader, qfalse); } -void UI_DrawTopBottom(float x, float y, float w, float h) +//Makro - added shader parm +void UI_DrawTopBottom(float x, float y, float w, float h, qhandle_t shader) { UI_AdjustFrom640(&x, &y, &w, &h); //trap_R_DrawStretchPic(x, y, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); //trap_R_DrawStretchPic(x, y + h - 1, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y + h - 1, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(x, y, w, 1, 0, 0, 0, 0, shader, qfalse); + uiInfo.uiDC.drawStretchPic(x, y + h - 1, w, 1, 0, 0, 0, 0, shader, qfalse); } /* @@ -695,12 +702,13 @@ UI_DrawRect Coordinates are 640*480 virtual values ================= */ -void UI_DrawRect(float x, float y, float width, float height, const float *color) +//Makro - added shader +void UI_DrawRect(float x, float y, float width, float height, const float *color, qhandle_t shader) { trap_R_SetColor(color); - UI_DrawTopBottom(x, y, width, height); - UI_DrawSides(x, y, width, height); + UI_DrawTopBottom(x, y, width, height, shader); + UI_DrawSides(x, y, width, height, shader); trap_R_SetColor(NULL); } @@ -720,7 +728,7 @@ void UI_DrawTextBox(int x, int y, int width, int lines) UI_FillRect(x + BIGCHAR_WIDTH / 2, y + BIGCHAR_HEIGHT / 2, (width + 1) * BIGCHAR_WIDTH, (lines + 1) * BIGCHAR_HEIGHT, colorBlack); UI_DrawRect(x + BIGCHAR_WIDTH / 2, y + BIGCHAR_HEIGHT / 2, (width + 1) * BIGCHAR_WIDTH, - (lines + 1) * BIGCHAR_HEIGHT, colorWhite); + (lines + 1) * BIGCHAR_HEIGHT, colorWhite, uiInfo.uiDC.whiteShader); } qboolean UI_CursorInRect(int x, int y, int width, int height) diff --git a/reaction/ta_ui/ui_local.h b/reaction/ta_ui/ui_local.h index 8dc98f68..f82e9f64 100644 --- a/reaction/ta_ui/ui_local.h +++ b/reaction/ta_ui/ui_local.h @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.27 2005/09/07 20:24:33 makro +// Vector support for most item types +// // Revision 1.26 2005/02/15 16:33:39 makro // Tons of updates (entity tree attachment system, UI vectors) // @@ -199,6 +202,9 @@ extern vmCvar_t ui_RQ3_modelCommand; //Makro - model cvar extern vmCvar_t ui_RQ3_model; +//Makro - tablet support in the UI +extern vmCvar_t ui_RQ3_tabletMode; + //Makro - team counts for the join menu //Handled in cgame now //extern vmCvar_t ui_RQ3_teamCount1; @@ -1011,6 +1017,12 @@ typedef struct { //Makro - weapon/item bans int weapBan, itemBan; + + //Makro - custom key bind status + const char *keyBindStatus1, *keyBindStatus2; + + //Makro - startup menu text + char startupText[512]; } uiInfo_t; extern uiInfo_t uiInfo; @@ -1025,9 +1037,9 @@ extern float UI_ClampCvar(float min, float max, float value); extern void UI_DrawNamedPic(float x, float y, float width, float height, const char *picname); extern void UI_DrawHandlePic(float x, float y, float w, float h, qhandle_t hShader); extern void UI_FillRect(float x, float y, float width, float height, const float *color); -extern void UI_DrawRect(float x, float y, float width, float height, const float *color); -extern void UI_DrawTopBottom(float x, float y, float w, float h); -extern void UI_DrawSides(float x, float y, float w, float h); +extern void UI_DrawRect(float x, float y, float width, float height, const float *color, qhandle_t shader); +extern void UI_DrawTopBottom(float x, float y, float w, float h, qhandle_t shader); +extern void UI_DrawSides(float x, float y, float w, float h, qhandle_t shader); extern void UI_UpdateScreen(void); extern void UI_SetColor(const float *rgba); extern void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t); @@ -1038,7 +1050,11 @@ extern int UI_ProportionalStringWidth(const char *str); extern void UI_DrawString(int x, int y, const char *str, int style, vec4_t color); extern void UI_DrawChar(int x, int y, int ch, int style, vec4_t color); extern qboolean UI_CursorInRect(int x, int y, int width, int height); -extern void UI_AdjustFrom640(float *x, float *y, float *w, float *h); + +//Makro - converted to macro +extern void _UI_AdjustFrom640(float *x, float *y, float *w, float *h); +#define UI_AdjustFrom640(px, py, pw, ph) (*(px) *= uiInfo.uiDC.xscale, *(py) *= uiInfo.uiDC.yscale, *(pw) *= uiInfo.uiDC.xscale, *(ph) *= uiInfo.uiDC.yscale) + extern void UI_DrawTextBox(int x, int y, int width, int lines); extern qboolean UI_IsFullscreen(void); extern void UI_SetActiveMenu(uiMenuCommand_t menu); diff --git a/reaction/ta_ui/ui_main.c b/reaction/ta_ui/ui_main.c index 092cfffc..5c65599c 100644 --- a/reaction/ta_ui/ui_main.c +++ b/reaction/ta_ui/ui_main.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.82 2005/09/07 20:24:33 makro +// Vector support for most item types +// // Revision 1.81 2005/02/15 16:33:39 makro // Tons of updates (entity tree attachment system, UI vectors) // @@ -283,9 +286,9 @@ static const char *skillLevels[] = { "Nightmare" }; -//Makro - constants are better -const char *KEYBIND_STATUS1 = "Waiting for new key... Press ESCAPE to cancel"; -const char *KEYBIND_STATUS2 = "Press ENTER or CLICK to change, Press BACKSPACE to clear"; +//Makro - changed from macros to constants +const char *KEYBIND_STATUS1 = "ENTER or CLICK to change, BACKSPACE to clear"; +const char *KEYBIND_STATUS2 = "Waiting for new key... Press ESCAPE to cancel"; static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char *); @@ -565,12 +568,18 @@ void AssetCache() uiInfo.uiDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip(ART_FX_BLUE); uiInfo.uiDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip(ART_FX_CYAN); uiInfo.uiDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip(ART_FX_WHITE); - uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR); + uiInfo.uiDC.Assets.scrollBarH = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_H); + uiInfo.uiDC.Assets.scrollBarV = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_V); uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWDOWN); uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWUP); uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWLEFT); uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWRIGHT); uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip(ASSET_SCROLL_THUMB); + //Makro - shown when clicked + uiInfo.uiDC.Assets.scrollBarArrowDown2 = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWDOWN2); + uiInfo.uiDC.Assets.scrollBarArrowUp2 = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWUP2); + uiInfo.uiDC.Assets.scrollBarArrowLeft2 = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWLEFT2); + uiInfo.uiDC.Assets.scrollBarArrowRight2 = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWRIGHT2); uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip(ASSET_SLIDER_BAR); uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip(ASSET_SLIDER_THUMB); @@ -589,12 +598,12 @@ void AssetCache() } uiInfo.uiDC.Assets.dropShadowRight = trap_R_RegisterShaderNoMip("ui/assets/rq3-ingame-shadow-right"); uiInfo.uiDC.Assets.dropShadowBottom = trap_R_RegisterShaderNoMip("ui/assets/rq3-ingame-shadow-bottom"); - + uiInfo.newHighScoreSound = trap_S_RegisterSound("sound/feedback/voc_newhighscore.wav", qfalse); } //Makro - angled rectangles -void _UI_DrawAngledRect(float x, float y, float w, float h, const float *u, const float *v, float size, const float *color, unsigned char type) +void _UI_DrawAngledRect(float x, float y, float w, float h, const float *u, const float *v, float size, const float *color, unsigned char type, qhandle_t shader) { float p[2], p2[2]; @@ -604,33 +613,35 @@ void _UI_DrawAngledRect(float x, float y, float w, float h, const float *u, cons Vector2MA(p2, h, v, p2); if (type & RECT_TOPBOTTOM) { - uiInfo.uiDC.drawAngledPic(p[0], p[1], w, size, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawAngledPic(p2[0], p2[1], -w, -size, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawAngledPic(p[0], p[1], w, size, u, v, color, 0, 0, 1, 1, shader); + uiInfo.uiDC.drawAngledPic(p2[0], p2[1], -w, -size, u, v, color, 0, 0, 1, 1, shader); } if (type & RECT_SIDES) { - uiInfo.uiDC.drawAngledPic(p[0], p[1], size, h, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawAngledPic(p2[0], p2[1], -size, -h, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawAngledPic(p[0], p[1], size, h, u, v, color, 0, 0, 1, 1, shader); + uiInfo.uiDC.drawAngledPic(p2[0], p2[1], -size, -h, u, v, color, 0, 0, 1, 1, shader); } } -void _UI_DrawSides(float x, float y, float w, float h, float size) +//Makro - added shader +void _UI_DrawSides(float x, float y, float w, float h, float size, qhandle_t shader) { UI_AdjustFrom640(&x, &y, &w, &h); size *= uiInfo.uiDC.xscale; //trap_R_DrawStretchPic(x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); //trap_R_DrawStretchPic(x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(x, y, size, h, 0, 0, 0, 0, shader, qfalse); + uiInfo.uiDC.drawStretchPic(x + w - size, y, size, h, 0, 0, 0, 0, shader, qfalse); } -void _UI_DrawTopBottom(float x, float y, float w, float h, float size) +//Makro - added shader +void _UI_DrawTopBottom(float x, float y, float w, float h, float size, qhandle_t shader) { UI_AdjustFrom640(&x, &y, &w, &h); size *= uiInfo.uiDC.yscale; //trap_R_DrawStretchPic(x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); //trap_R_DrawStretchPic(x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); - uiInfo.uiDC.drawStretchPic(x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(x, y, w, size, 0, 0, 0, 0, shader, qfalse); + uiInfo.uiDC.drawStretchPic(x, y + h - size, w, size, 0, 0, 0, 0, shader, qfalse); } /* @@ -640,12 +651,13 @@ UI_DrawRect Coordinates are 640*480 virtual values ================= */ -void _UI_DrawRect(float x, float y, float width, float height, float size, const float *color) +//Makro - added shader +void _UI_DrawRect(float x, float y, float width, float height, float size, const float *color, qhandle_t shader) { trap_R_SetColor(color); - _UI_DrawTopBottom(x, y, width, height, size); - _UI_DrawSides(x, y, width, height, size); + _UI_DrawTopBottom(x, y, width, height, size, shader); + _UI_DrawSides(x, y, width, height, size, shader); trap_R_SetColor(NULL); } @@ -693,7 +705,7 @@ int Text_Width(const char *text, float scale, int limit) } } } - return out * useScale; + return (int) (out * useScale); } int Text_Height(const char *text, float scale, int limit) @@ -763,15 +775,17 @@ void Text_PaintChar(float x, float y, float width, float height, float scale, fl h = height * scale; UI_AdjustFrom640(&x, &y, &w, &h); //trap_R_DrawStretchPic(x, y, w, h, s, t, s2, t2, hShader); - uiInfo.uiDC.drawStretchPic(x, y, w, h, s, t, s2, t2, hShader); + uiInfo.uiDC.drawStretchPic(x, y, w, h, s, t, s2, t2, hShader, qfalse); } -void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style) +void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, float maxwidth, int style, qboolean forceColor) { int len, count; qboolean underlined = qfalse; + //Makro - added width + float width; vec4_t newColor; float useScale; fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; @@ -790,11 +804,14 @@ void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, f trap_R_SetColor(color); memcpy(&newColor[0], &color[0], sizeof(vec4_t)); - len = strlen(text); + //Makro - changed + //len = strlen(text); + len = Q_PrintStrlen(text); if (limit > 0 && len > limit) { len = limit; } count = 0; + width = 0; while (s && *s && count < len) { glyph = &font->glyphs[(int) *s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top; @@ -808,7 +825,7 @@ void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, f } else if (*(s+1)== '_') { underlined ^= qtrue; - } else { + } else if (!forceColor) { memcpy(newColor, g_color_table[ColorIndex(*(s + 1))], sizeof(newColor)); newColor[3] = color[3]; trap_R_SetColor(newColor); @@ -841,6 +858,11 @@ void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, f useScale, uglyph->s, uglyph->t, uglyph->s2, uglyph->t2, uglyph->glyph); } + //Makro - added width + width += (glyph->xSkip * useScale) + adjust; + if (maxwidth > 0 && width > maxwidth) + break; + x += (glyph->xSkip * useScale) + adjust; s++; count++; @@ -855,33 +877,82 @@ void UI_AddQuadToScene(qhandle_t hShader, const polyVert_t *verts) polyVert_t mverts[4]; memcpy(mverts, verts, sizeof(mverts)); - mverts[0].xyz[0] += uiInfo.uiDC.polyZ; - mverts[1].xyz[0] += uiInfo.uiDC.polyZ; - mverts[2].xyz[0] += uiInfo.uiDC.polyZ; - mverts[3].xyz[0] += uiInfo.uiDC.polyZ; - /* - verts[0].xyz[0] += uiInfo.uiDC.polyZ; - verts[1].xyz[0] += uiInfo.uiDC.polyZ; - verts[2].xyz[0] += uiInfo.uiDC.polyZ; - verts[3].xyz[0] += uiInfo.uiDC.polyZ; - */ + mverts[0].xyz[0] -= uiInfo.uiDC.polyZ; + mverts[1].xyz[0] -= uiInfo.uiDC.polyZ; + mverts[2].xyz[0] -= uiInfo.uiDC.polyZ; + mverts[3].xyz[0] -= uiInfo.uiDC.polyZ; trap_R_AddPolyToScene(hShader, 4, mverts); - /* - verts[0].xyz[0] -= uiInfo.uiDC.polyZ; - verts[1].xyz[0] -= uiInfo.uiDC.polyZ; - verts[2].xyz[0] -= uiInfo.uiDC.polyZ; - verts[3].xyz[0] -= uiInfo.uiDC.polyZ; - */ uiInfo.uiDC.polyZ += UI_POLY_Z_OFFSET; uiInfo.uiDC.pendingPolys++; } +/* +void _UI_DrawAngledRect(float x, float y, float w, float h, const float *u, const float *v, float size, const float *color, unsigned char type) +{ + float p[2], p2[2]; + + p[0] = x; + p[1] = y; + Vector2MA(p, w, u, p2); + Vector2MA(p2, h, v, p2); + + if (type & RECT_TOPBOTTOM) { + uiInfo.uiDC.drawAngledPic(p[0], p[1], w, size, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawAngledPic(p2[0], p2[1], -w, -size, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + } + if (type & RECT_SIDES) { + uiInfo.uiDC.drawAngledPic(p[0], p[1], size, h, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawAngledPic(p2[0], p2[1], -size, -h, u, v, color, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + } +} +*/ + +//TODO +void UI_AddFrameToScene(float x, float y, float w, float h, const float *u, const float *v, float size, const float *color, unsigned char type) +{ + polyVert_t verts[4]; + + verts[0].modulate[0]=verts[1].modulate[0]=verts[2].modulate[0]=verts[3].modulate[0]=((int)(color[0]*255))&255; + verts[0].modulate[1]=verts[1].modulate[1]=verts[2].modulate[1]=verts[3].modulate[1]=((int)(color[1]*255))&255; + verts[0].modulate[2]=verts[1].modulate[2]=verts[2].modulate[2]=verts[3].modulate[2]=((int)(color[2]*255))&255; + verts[0].modulate[3]=verts[1].modulate[3]=verts[2].modulate[3]=verts[3].modulate[3]=((int)(color[3]*255))&255; + //0 + verts[0].st[0]=0; + verts[0].st[1]=0; + //1 + verts[1].st[0]=1; + verts[1].st[1]=0; + //2 + verts[2].st[0]=1; + verts[2].st[1]=1; + //3 + verts[3].st[0]=0; + verts[3].st[1]=1; + VectorSet(verts[0].xyz, 320, 320-x, 240-y); + VectorSet(verts[1].xyz, 320, verts[0].xyz[1]-u[0]*w, verts[0].xyz[2]-u[1]*w); + VectorSet(verts[2].xyz, 320, verts[1].xyz[1]-v[0]*h, verts[1].xyz[2]-v[1]*h); + VectorSet(verts[3].xyz, 320, verts[0].xyz[1]-v[0]*h, verts[0].xyz[2]-v[1]*h); + verts[0].xyz[0] -= uiInfo.uiDC.polyZ; + verts[1].xyz[0] -= uiInfo.uiDC.polyZ; + verts[2].xyz[0] -= uiInfo.uiDC.polyZ; + verts[3].xyz[0] -= uiInfo.uiDC.polyZ; + + trap_R_AddPolyToScene(uiInfo.uiDC.whiteShader, 4, verts); + uiInfo.uiDC.polyZ += UI_POLY_Z_OFFSET; + uiInfo.uiDC.pendingPolys++; +} + +//Makro - draws a skewed textured rectangle void UI_DrawAngledPic(float x, float y, float w, float h, const float *u, const float *v, const float *color, float s, float t, float s2, float t2, qhandle_t hShader) { polyVert_t verts[4]; //memset(verts, 0, sizeof(verts)); + //avoid "null poly shader" warnings + if (!hShader) + return; + verts[0].modulate[0]=verts[1].modulate[0]=verts[2].modulate[0]=verts[3].modulate[0]=((int)(color[0]*255))&255; verts[0].modulate[1]=verts[1].modulate[1]=verts[2].modulate[1]=verts[3].modulate[1]=((int)(color[1]*255))&255; verts[0].modulate[2]=verts[1].modulate[2]=verts[2].modulate[2]=verts[3].modulate[2]=((int)(color[2]*255))&255; @@ -914,10 +985,13 @@ void UI_DrawAngledPic(float x, float y, float w, float h, const float *u, const //trap_R_RenderScene(&uiInfo.uiDC.scene2D); } -//Makro - angled text -void Text_PaintAngled(float x, float y, const float *u, const float *v, float scale, vec4_t color, const char *text, float adjust, int limit, int style) +//Makro - same as the old Text_Paint, this time using vectors +void Text_PaintAngled(float x, float y, const float *u, const float *v, float scale, vec4_t color, const char *text, + float adjust, int limit, float maxwidth, int style, qboolean forceColor) { int len, count; + //Makro - added + float width; qboolean underlined = qfalse; vec4_t newColor; float useScale; @@ -944,6 +1018,7 @@ void Text_PaintAngled(float x, float y, const float *u, const float *v, float sc if (limit > 0 && len > limit) { len = limit; } + width = 0; count = 0; while (s && *s && count < len) { glyph = &font->glyphs[(int) *s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build @@ -957,7 +1032,7 @@ void Text_PaintAngled(float x, float y, const float *u, const float *v, float sc } else if (*(s+1)== '_') { underlined ^= qtrue; - } else { + } else if (!forceColor) { memcpy(newColor, g_color_table[ColorIndex(*(s + 1))], sizeof(newColor)); newColor[3] = color[3]; //trap_R_SetColor(newColor); @@ -996,6 +1071,10 @@ void Text_PaintAngled(float x, float y, const float *u, const float *v, float sc UI_DrawAngledPic(x, y, glyph->imageWidth * useScale, uglyph->imageHeight * useScale, u, v, colorPtr, uglyph->s, uglyph->t, uglyph->s2, uglyph->t2, uglyph->glyph); } + //Makro - added width + width += (glyph->xSkip * useScale) + adjust; + if (maxwidth > 0 && width > maxwidth) + break; x += ((glyph->xSkip * useScale) + adjust) * u[0]; y += ((glyph->xSkip * useScale) + adjust) * u[1]; s++; @@ -1093,6 +1172,130 @@ void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const cha } } +//Makro - modified version of Text_PaintAngled +void Text_PaintWithCursorAngled(float x, float y, const float *u, const float *v, float scale, vec4_t color, const char *text, + int cursorPos, char cursor, int limit, int style) +{ + int len, count; + //Makro - added + float width; + qboolean underlined = qfalse; + vec4_t newColor; + float useScale; + float p[2], *colorPtr; + fontInfo_t *font = &uiInfo.uiDC.Assets.textFont; + glyphInfo_t *glyph, *glyph2, *uglyph = &font->glyphs[(int)'_']; //Makro - added for underlined chars; + + if (scale <= ui_smallFont.value) { + font = &uiInfo.uiDC.Assets.smallFont; + } else if (scale >= ui_bigFont.value) { + font = &uiInfo.uiDC.Assets.bigFont; + } + useScale = scale * font->glyphScale; + + if (text) { + // TTimo: FIXME + // const unsigned char *s = text; // bk001206 - unsigned + const char *s = text; // bk001206 - unsigned + + //trap_R_SetColor(color); + colorPtr = color; + memcpy(&newColor[0], &color[0], sizeof(vec4_t)); + len = strlen(text); + if (limit > 0 && len > limit) { + len = limit; + } + width = 0; + count = 0; + glyph2 = &font->glyphs[(int) cursor]; // bk001206 - possible signed char + while (s && *s && count < len) + { + glyph = &font->glyphs[(int) *s]; // TTimo: FIXME: getting nasty warnings without the cast, hopefully this doesn't break the VM build + if (Q_IsColorString(s)) { + //Makro - new tricks + if (*(s+1) == '*') + { + memcpy(newColor, color, sizeof(newColor)); + //trap_R_SetColor(newColor); + colorPtr = color; + } else if (*(s+1)== '_') + { + underlined ^= qtrue; + } else /* if (!forceColor) */ { + memcpy(newColor, g_color_table[ColorIndex(*(s + 1))], sizeof(newColor)); + newColor[3] = color[3]; + //trap_R_SetColor(newColor); + colorPtr = newColor; + } + s += 2; + continue; + } else { + float yadj = useScale * glyph->top; + if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) + { + int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2; + colorBlack[3] = newColor[3]; + + Vector2Set(p, x, y); + Vector2MA(p, ofs, u, p); + Vector2MA(p, ofs-yadj, v, p); + + UI_DrawAngledPic(p[0], p[1], + glyph->imageWidth * useScale, + glyph->imageHeight * useScale, + u,v, colorBlack, + glyph->s, glyph->t, glyph->s2, glyph->t2, glyph->glyph); + colorBlack[3] = 1.0; + } + Vector2Set(p, x, y); + Vector2MA(p, -yadj, v, p); + UI_DrawAngledPic(p[0], p[1], + glyph->imageWidth * useScale, + glyph->imageHeight * useScale, + u,v,colorPtr, + glyph->s, glyph->t, glyph->s2, glyph->t2, glyph->glyph); + //Makro - added + if (underlined) + { + UI_DrawAngledPic(x, y, glyph->imageWidth * useScale, uglyph->imageHeight * useScale, + u, v, colorPtr, uglyph->s, uglyph->t, uglyph->s2, uglyph->t2, uglyph->glyph); + } + //Makro - added width + //width += (glyph->xSkip * useScale) + adjust; + width += (glyph->xSkip * useScale); + /* + if (maxwidth > 0 && width > maxwidth) + break; + */ + //x += ((glyph->xSkip * useScale) + adjust) * u[0]; + //y += ((glyph->xSkip * useScale) + adjust) * u[1]; + if (count == cursorPos && !((uiInfo.uiDC.realTime / BLINK_DIVISOR) & 1)) { + float adj2 = useScale * (glyph2->top - glyph->top); + UI_DrawAngledPic(p[0] - adj2 * v[0], p[1] - adj2 * v[1], + glyph2->imageWidth * useScale, + glyph2->imageHeight * useScale, + u, v, colorPtr, + glyph2->s, glyph2->t, glyph2->s2, glyph2->t2, glyph2->glyph); + } + x += (glyph->xSkip * useScale) * u[0]; + y += (glyph->xSkip * useScale) * u[1]; + s++; + count++; + } + } + // need to paint cursor at end of text + if (cursorPos == len && !((uiInfo.uiDC.realTime / BLINK_DIVISOR) & 1)) { + float yadj = useScale * glyph2->top; + UI_DrawAngledPic(x - yadj * v[0], y - yadj * v[1], + glyph2->imageWidth * useScale, + glyph2->imageHeight * useScale, + u, v, colorPtr, + glyph2->s, glyph2->t, glyph2->s2, glyph2->t2, glyph2->glyph); + + } + } +} + static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit) { @@ -1188,6 +1391,10 @@ void UI_DrawCenteredPic(qhandle_t image, int w, int h) //int startTime; #define UI_FPS_FRAMES 4 +//Makro - mouse fading constants +#define UI_MOUSE_HIDE_TIME 3500 +#define UI_MOUSE_FADE_START 3000 + void _UI_Refresh(int realtime) { static int index; @@ -1197,6 +1404,7 @@ void _UI_Refresh(int realtime) int modelModCount; //Makro - added uiClientState_t cstate; + int lifeTime; //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) { // return; @@ -1272,7 +1480,7 @@ void _UI_Refresh(int realtime) angle = -RAD2DEG(atan2(dif[1], dif[0])); Text_Paint(20, 20, 0.225f, colorCyan, va("(%i, %i) - (%i,%i) = (%i, %i) = %.2f = %.3f deg", uiInfo.uiDC.mouseDownPos[0], uiInfo.uiDC.mouseDownPos[1], uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory, - dif[0], dif[1], norm, angle), 0, 0, ITEM_TEXTSTYLE_SHADOWED); + dif[0], dif[1], norm, angle), 0, 0, 0, ITEM_TEXTSTYLE_SHADOWED, qfalse); if (norm) { Vector2Scale(dif, 1.0f/norm, u); @@ -1280,7 +1488,7 @@ void _UI_Refresh(int realtime) Vector2Set(v, -u[1], u[0]); UI_DrawAngledPic(uiInfo.uiDC.mouseDownPos[0], uiInfo.uiDC.mouseDownPos[1], norm, 2, u, v, linecolor, 0, 0, norm/16, 1, uiInfo.uiDC.selectShader); } - Text_Paint(uiInfo.uiDC.mouseDownPos[0]-4, uiInfo.uiDC.mouseDownPos[1]+6, 0.4f, colorYellow, "x", 0, 0, ITEM_TEXTSTYLE_SHADOWED); + Text_Paint(uiInfo.uiDC.mouseDownPos[0]-4, uiInfo.uiDC.mouseDownPos[1]+6, 0.4f, colorYellow, "x", 0, 0, 0, ITEM_TEXTSTYLE_SHADOWED, qfalse); } else { char *s; menuDef_t *menu = Menu_GetFocused(); @@ -1291,9 +1499,10 @@ void _UI_Refresh(int realtime) } else { s = va("(%i, %i)", uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); } - Text_Paint(20, 20, 0.225f, colorCyan, s, 0, 0, ITEM_TEXTSTYLE_SHADOWED); + Text_Paint(20, 20, 0.225f, colorCyan, s, 0, 0, 0, ITEM_TEXTSTYLE_SHADOWED, qfalse); } - Text_Paint(20, 40, 0.225f, colorCyan, va("%i fps", uiInfo.uiDC.smoothFPS), 0, 0, ITEM_TEXTSTYLE_SHADOWED); + Text_Paint(20, 40, 0.225f, colorCyan, va("%i fps", uiInfo.uiDC.smoothFPS), 0, 0, 0, + ITEM_TEXTSTYLE_SHADOWED, qfalse); } //any left-overs? if (uiInfo.uiDC.pendingPolys) @@ -1304,7 +1513,11 @@ void _UI_Refresh(int realtime) // draw cursor UI_SetColor(NULL); trap_GetClientState(&cstate); - if (Menu_Count() > 0 && (cstate.connState != CA_LOADING)) { + //Makro - not if it hasn't moved for a while + lifeTime = uiInfo.uiDC.realTime - uiInfo.uiDC.mouseMoveTime; + + if (Menu_Count() > 0 && (cstate.connState != CA_LOADING) && (lifeTime < UI_MOUSE_HIDE_TIME)) + { float ccolor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; int size = uiInfo.uiDC.cursorSize; if (!size) @@ -1315,26 +1528,30 @@ void _UI_Refresh(int realtime) ccolor[1] = 0.50f; ccolor[2] = 0.25f; } + if (lifeTime > UI_MOUSE_FADE_START) + { + ccolor[3] = 1.0f - (lifeTime - UI_MOUSE_FADE_START) / (float) (UI_MOUSE_HIDE_TIME - UI_MOUSE_FADE_START); + } UI_SetColor(ccolor); UI_DrawHandlePic(uiInfo.uiDC.cursorx - (size>>1), uiInfo.uiDC.cursory - (size>>1), size, size, uiInfo.uiDC.Assets.cursor); UI_SetColor(NULL); } //Makro - draw overlay - //is fading ? + //is it fading ? if (IsBetween(realtime, uiInfo.uiDC.overlayFadeStart, uiInfo.uiDC.overlayFadeEnd)) { float oColor[4]; float amt = (float) (realtime - uiInfo.uiDC.overlayFadeStart) / (uiInfo.uiDC.overlayFadeEnd - uiInfo.uiDC.overlayFadeStart); LerpColor(uiInfo.uiDC.overlayColor, uiInfo.uiDC.overlayColor2, oColor, amt); if (oColor[3] != 0.0f) { UI_SetColor(oColor); - uiInfo.uiDC.drawStretchPic(0, 0, uiInfo.uiDC.glconfig.vidWidth, uiInfo.uiDC.glconfig.vidHeight, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(0, 0, uiInfo.uiDC.glconfig.vidWidth, uiInfo.uiDC.glconfig.vidHeight, 0, 0, 1, 1, uiInfo.uiDC.whiteShader, qfalse); UI_SetColor(NULL); } } else { if (uiInfo.uiDC.overlayColor2[3] != 0.0f) { UI_SetColor(uiInfo.uiDC.overlayColor2); - uiInfo.uiDC.drawStretchPic(0, 0, uiInfo.uiDC.glconfig.vidWidth, uiInfo.uiDC.glconfig.vidHeight, 0, 0, 1, 1, uiInfo.uiDC.whiteShader); + uiInfo.uiDC.drawStretchPic(0, 0, uiInfo.uiDC.glconfig.vidWidth, uiInfo.uiDC.glconfig.vidHeight, 0, 0, 1, 1, uiInfo.uiDC.whiteShader, qfalse); UI_SetColor(NULL); } } @@ -1490,6 +1707,23 @@ qboolean Asset_Parse(int handle) continue; } + //Makro - key bind status 1 + if (Q_stricmp(token.string, "keyBindStatus1") == 0) { + if (!PC_String_Parse(handle, &uiInfo.keyBindStatus1)) { + return qfalse; + } + continue; + } + + //Makro - key bind status 2 + if (Q_stricmp(token.string, "keyBindStatus2") == 0) { + if (!PC_String_Parse(handle, &uiInfo.keyBindStatus2)) { + return qfalse; + } + continue; + } + + //Makro - added cursor size if (Q_stricmp(token.string, "cursorSize") == 0) { if (!PC_Int_Parse(handle, &uiInfo.uiDC.cursorSize)) { @@ -1541,6 +1775,23 @@ qboolean Asset_Parse(int handle) continue; } + //Makro - for grouped checkboxes + if (Q_stricmp(token.string, "checkBox0") == 0) { + if (!PC_String_Parse(handle, &tempStr)) { + return qfalse; + } + uiInfo.uiDC.Assets.checkBox0 = trap_R_RegisterShaderNoMip(tempStr); + continue; + } + if (Q_stricmp(token.string, "checkBox1") == 0) { + if (!PC_String_Parse(handle, &tempStr)) { + return qfalse; + } + uiInfo.uiDC.Assets.checkBox1 = trap_R_RegisterShaderNoMip(tempStr); + continue; + } + + } return qfalse; } @@ -1712,7 +1963,7 @@ void UI_Load() UI_LoadMenus(menuSet, qtrue); Menus_CloseAll(); - Menus_ActivateByName(lastName); + Menus_ActivateByName(lastName, qfalse); } @@ -1731,12 +1982,12 @@ static void UI_DrawHandicap(rectDef_t * rect, float scale, vec4_t color, int tex h = Com_Clamp(5, 100, trap_Cvar_VariableValue("handicap")); i = 20 - h / 5; - Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, 0, textStyle, qfalse); } static void UI_DrawClanName(rectDef_t * rect, float scale, vec4_t color, int textStyle) { - Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, 0, textStyle, qfalse); } static void UI_SetCapFragLimits(qboolean uiVars) @@ -1761,7 +2012,7 @@ static void UI_SetCapFragLimits(qboolean uiVars) // ui_gameType assumes gametype 0 is -1 ALL and will not show static void UI_DrawGameType(rectDef_t * rect, float scale, vec4_t color, int textStyle) { - Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_gameType.integer].gameType, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_gameType.integer].gameType, 0, 0, 0, textStyle, qfalse); } static void UI_DrawNetGameType(rectDef_t * rect, float scale, vec4_t color, int textStyle) @@ -1770,7 +2021,7 @@ static void UI_DrawNetGameType(rectDef_t * rect, float scale, vec4_t color, int trap_Cvar_Set("ui_netGameType", "0"); trap_Cvar_Set("ui_actualNetGameType", "0"); } - Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_netGameType.integer].gameType, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_netGameType.integer].gameType, 0, 0, 0, textStyle, qfalse); } static void UI_DrawJoinGameType(rectDef_t * rect, float scale, vec4_t color, int textStyle) @@ -1778,8 +2029,8 @@ static void UI_DrawJoinGameType(rectDef_t * rect, float scale, vec4_t color, int if (ui_joinGameType.integer < 0 || ui_joinGameType.integer > uiInfo.numJoinGameTypes) { trap_Cvar_Set("ui_joinGameType", "0"); } - Text_Paint(rect->x, rect->y, scale, color, uiInfo.joinGameTypes[ui_joinGameType.integer].gameType, 0, 0, - textStyle); + Text_Paint(rect->x, rect->y, scale, color, uiInfo.joinGameTypes[ui_joinGameType.integer].gameType, 0, 0, 0, + textStyle, qfalse); } static int UI_TeamIndexFromName(const char *name) @@ -1876,7 +2127,7 @@ static void UI_DrawSkill(rectDef_t * rect, float scale, vec4_t color, int textSt if (i < 1 || i > numSkillLevels) { i = 1; } - Text_Paint(rect->x, rect->y, scale, color, skillLevels[i - 1], 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, skillLevels[i - 1], 0, 0, 0, textStyle, qfalse); } static void UI_DrawTeamName(rectDef_t * rect, float scale, vec4_t color, qboolean blue, int textStyle) @@ -1886,7 +2137,7 @@ static void UI_DrawTeamName(rectDef_t * rect, float scale, vec4_t color, qboolea i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam")); if (i >= 0 && i < uiInfo.teamCount) { Text_Paint(rect->x, rect->y, scale, color, - va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName), 0, 0, textStyle); + va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName), 0, 0, 0, textStyle, qfalse); } } @@ -1898,7 +2149,7 @@ static void UI_RQ3_DrawPreset(rectDef_t * rect, float scale, vec4_t color, int n if (radioPresets[num-1].Text->string[0]) { text = radioPresets[num-1].Text->string; } - Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, 0, textStyle, qfalse); } static char team1Name[128], team2Name[128]; @@ -1906,7 +2157,7 @@ static char team1Name[128], team2Name[128]; static void UI_RQ3_DrawJoinTeam(rectDef_t * rect, float scale, vec4_t color, int num, int textStyle) { //char *text = va("Team %i", num); - Text_Paint(rect->x, rect->y, scale, color, (num == 1) ? team1Name : team2Name, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, (num == 1) ? team1Name : team2Name, 0, 0, 0, textStyle, qfalse); } static void UI_DrawTeamMember(rectDef_t * rect, float scale, vec4_t color, qboolean blue, int num, int textStyle) @@ -1946,9 +2197,10 @@ static void UI_DrawTeamMember(rectDef_t * rect, float scale, vec4_t color, qbool //Makro - changed //Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); if (ui_actualNetGameType.integer >= GT_TEAM) { - Text_Paint(rect->x, rect->y, scale, color, va("%i. %s", num, text), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, va("%i. %s", num, text), 0, 0, 0, textStyle, qfalse); } else { - Text_Paint(rect->x, rect->y, scale, color, va("%i. %s", blue ? (num + 5) : num, text), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, va("%i. %s", blue ? (num + 5) : num, text), 0, 0, 0, + textStyle, qfalse); } } @@ -2000,7 +2252,7 @@ static void UI_DrawMapTimeToBeat(rectDef_t * rect, float scale, vec4_t color, in minutes = time / 60; seconds = time % 60; - Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, 0, textStyle, qfalse); } static void UI_DrawMapCinematic(rectDef_t * rect, float scale, vec4_t color, qboolean net) @@ -2195,7 +2447,8 @@ static void UI_DrawNetSource(rectDef_t * rect, float scale, vec4_t color, int te if (ui_netSource.integer < 0 || ui_netSource.integer > numNetSources) { ui_netSource.integer = 0; } - Text_Paint(rect->x, rect->y, scale, color, va("Source: %s", netSources[ui_netSource.integer]), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, va("Source: %s", netSources[ui_netSource.integer]), 0, 0, 0, + textStyle, qfalse); } static void UI_DrawNetMapPreview(rectDef_t * rect, float scale, vec4_t color) @@ -2230,7 +2483,8 @@ static void UI_DrawNetFilter(rectDef_t * rect, float scale, vec4_t color, int te ui_serverFilterType.integer = 0; } Text_Paint(rect->x, rect->y, scale, color, - va("Filter: %s", serverFilters[ui_serverFilterType.integer].description), 0, 0, textStyle); + va("Filter: %s", serverFilters[ui_serverFilterType.integer].description), 0, 0, 0, + textStyle, qfalse); } static void UI_DrawTier(rectDef_t * rect, float scale, vec4_t color, int textStyle) @@ -2241,7 +2495,8 @@ static void UI_DrawTier(rectDef_t * rect, float scale, vec4_t color, int textSty if (i < 0 || i >= uiInfo.tierCount) { i = 0; } - Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName), 0, 0, 0, + textStyle, qfalse); } static void UI_DrawTierMap(rectDef_t * rect, int index) @@ -2286,7 +2541,8 @@ static void UI_DrawTierMapName(rectDef_t * rect, float scale, vec4_t color, int j = 0; } - Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), + 0, 0, 0, textStyle, qfalse); } static void UI_DrawTierGameType(rectDef_t * rect, float scale, vec4_t color, int textStyle) @@ -2302,8 +2558,8 @@ static void UI_DrawTierGameType(rectDef_t * rect, float scale, vec4_t color, int j = 0; } - Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType, 0, 0, - textStyle); + Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType, + 0, 0, 0, textStyle, qfalse); } //Makro - not used anywhere @@ -2554,13 +2810,14 @@ static void UI_DrawAllMapsSelection(rectDef_t * rect, float scale, vec4_t color, int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer; if (map >= 0 && map < uiInfo.mapCount) { - Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, 0, textStyle, qfalse); } } static void UI_DrawOpponentName(rectDef_t * rect, float scale, vec4_t color, int textStyle) { - Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, 0, + textStyle, qfalse); } static int UI_OwnerDrawWidth(int ownerDraw, float scale) @@ -2669,9 +2926,9 @@ static int UI_OwnerDrawWidth(int ownerDraw, float scale) break; case UI_KEYBINDSTATUS: if (Display_KeyBindPending()) { - s = KEYBIND_STATUS1; + s = uiInfo.keyBindStatus2; } else { - s = KEYBIND_STATUS2; + s = uiInfo.keyBindStatus1; } break; case UI_SERVERREFRESHDATE: @@ -2716,20 +2973,20 @@ static void UI_DrawBotName(rectDef_t * rect, float scale, vec4_t color, int text } text = UI_GetBotNameByNumber(value); // } - Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, 0, textStyle, qfalse); } static void UI_DrawBotSkill(rectDef_t * rect, float scale, vec4_t color, int textStyle) { if (uiInfo.skillIndex >= 0 && uiInfo.skillIndex < numSkillLevels) { - Text_Paint(rect->x, rect->y, scale, color, skillLevels[uiInfo.skillIndex], 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, skillLevels[uiInfo.skillIndex], 0, 0, 0, textStyle, qfalse); } } static void UI_DrawRedBlue(rectDef_t * rect, float scale, vec4_t color, int textStyle) { //Makro - added Team 1/2 - Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? "1 (Red)" : "2 (Blue)", 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? "1 (Red)" : "2 (Blue)", 0, 0, 0, textStyle, qfalse); } static void UI_DrawCrosshair(rectDef_t * rect, float scale, vec4_t color) @@ -2759,10 +3016,10 @@ static void UI_DrawClock(itemDef_t *item, rectDef_t * rect, float scale, vec4_t text = va("%02i:%02i", qt.tm_hour, qt.tm_min); if (!item->window.rectClient.hasVectors) { - Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, 0, textStyle, qfalse); } else { Text_PaintAngled(rect->x, rect->y, - item->window.rectClient.u, item->window.rectClient.v, scale, color, text, 0, 0, textStyle); + item->window.rectClient.u, item->window.rectClient.v, scale, color, text, 0, 0, 0, textStyle, qfalse); } } @@ -3207,7 +3464,7 @@ static void UI_DrawSelectedPlayer(rectDef_t * rect, float scale, vec4_t color, i Text_Paint(rect->x, rect->y, scale, color, (uiInfo. teamLeader) ? UI_Cvar_VariableString("cg_selectedPlayerName") : UI_Cvar_VariableString("name"), 0, - 0, textStyle); + 0, 0, textStyle, qfalse); } static void UI_DrawServerRefreshDate(rectDef_t * rect, float scale, vec4_t color, int textStyle) @@ -3225,12 +3482,12 @@ static void UI_DrawServerRefreshDate(rectDef_t * rect, float scale, vec4_t color } LerpColor(color, lowLight, newColor, 0.5 + 0.5 * sin(uiInfo.uiDC.realTime / PULSE_DIVISOR)); Text_Paint(rect->x, rect->y, scale, newColor, - va("Getting info for %d servers (ESC to cancel)", count), 0, 0, textStyle); + va("Getting info for %d servers (ESC to cancel)", count), 0, 0, 0, textStyle, qfalse); } else { char buff[64]; Q_strncpyz(buff, UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)), 64); - Text_Paint(rect->x, rect->y, scale, color, va("Refresh Time: %s", buff), 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, va("Refresh Time: %s", buff), 0, 0, 0, textStyle, qfalse); } } @@ -3299,13 +3556,25 @@ static void UI_DrawServerMOTD(rectDef_t * rect, float scale, vec4_t color) } } -static void UI_DrawKeyBindStatus(rectDef_t * rect, float scale, vec4_t color, int textStyle) +static void UI_DrawKeyBindStatus(itemDef_t *item, rectDef_t * rect, float scale, vec4_t color, int textStyle) { // int ofs = 0; TTimo: unused if (Display_KeyBindPending()) { - Text_Paint(rect->x, rect->y, scale, color, KEYBIND_STATUS1, 0, 0, textStyle); + if (item->window.rect.hasVectors) + { + Text_PaintAngled(rect->x, rect->y, item->window.rect.u, item->window.rect.v, + scale, color, uiInfo.keyBindStatus2, 0, 0, 0, textStyle, qfalse); + } else { + Text_Paint(rect->x, rect->y, scale, color, uiInfo.keyBindStatus2, 0, 0, 0, textStyle, qfalse); + } } else { - Text_Paint(rect->x, rect->y, scale, color, KEYBIND_STATUS2, 0, 0, textStyle); + if (item->window.rect.hasVectors) + { + Text_PaintAngled(rect->x, rect->y, item->window.rect.u, item->window.rect.v, + scale, color, uiInfo.keyBindStatus1, 0, 0, 0, textStyle, qfalse); + } else { + Text_Paint(rect->x, rect->y, scale, color, uiInfo.keyBindStatus1, 0, 0, 0, textStyle, qfalse); + } } } @@ -3317,14 +3586,14 @@ static void UI_DrawGLInfo(rectDef_t * rect, float scale, vec4_t color, int textS int y, numLines, i; //Makro - changed from 30 to 48; changed pixelformat display from (x-bits) to (x) - Text_Paint(rect->x + 2, rect->y, scale, color, va("VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, 48, - textStyle); + Text_Paint(rect->x + 2, rect->y, scale, color, va("VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, 48, 0, + textStyle, qfalse); Text_Paint(rect->x + 2, rect->y + 15, scale, color, va("VERSION: %s: %s", uiInfo.uiDC.glconfig.version_string, uiInfo.uiDC.glconfig.renderer_string), 0, - 48, textStyle); + 48, 0, textStyle, qfalse); Text_Paint(rect->x + 2, rect->y + 30, scale, color, va("PIXELFORMAT: color(%d) Z(%d) stencil(%d)", uiInfo.uiDC.glconfig.colorBits, - uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), 0, 48, textStyle); + uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), 0, 48, 0, textStyle, qfalse); // build null terminated extension strings Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, 1024); @@ -3346,9 +3615,9 @@ static void UI_DrawGLInfo(rectDef_t * rect, float scale, vec4_t color, int textS i = 0; while (i < numLines) { - Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, 20, textStyle); + Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, 20, 0, textStyle, qfalse); if (i < numLines) { - Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, 20, textStyle); + Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, 20, 0, textStyle, qfalse); } y += 10; if (y > rect->y + rect->h - 11) { @@ -3358,6 +3627,17 @@ static void UI_DrawGLInfo(rectDef_t * rect, float scale, vec4_t color, int textS } +//Makro - startup menu text +static void UI_DrawStartupText(itemDef_t *item, rectDef_t *rect, float scale, vec4_t color, int textStyle) +{ + if (!item->window.rectClient.hasVectors) { + Text_Paint(rect->x, rect->y, scale, color, uiInfo.startupText, 0, 0, 0, textStyle, qfalse); + } else { + Text_PaintAngled(rect->x, rect->y, + item->window.rectClient.u, item->window.rectClient.v, scale, color, uiInfo.startupText, 0, 0, 0, textStyle, qfalse); + } +} + //Makro - replacement model info static void UI_DrawReplacementInfo(rectDef_t * rect, float scale, vec4_t color, int textStyle) { @@ -3371,7 +3651,7 @@ static void UI_DrawReplacementInfo(rectDef_t * rect, float scale, vec4_t color, l = strlen(p); while ( l>0 && Text_Width(p, scale, 0) > rect->w ) p[l--]=0; - Text_Paint(rect->x, y, scale, color, p, 0, 0, textStyle); + Text_Paint(rect->x, y, scale, color, p, 0, 0, 0, textStyle, qfalse); y += Text_Height(p, scale, 0) + 4; } while (strlen(text)>0 /*&& yh*/); } @@ -3396,14 +3676,14 @@ static void UI_DrawReplacementName(rectDef_t * rect, float scale, vec4_t color, while (l>0 && Text_Width(name, scale, 0)>rect->w) name[l--]=0; - Text_Paint(rect->x, rect->y, scale, color, name, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, name, 0, 0, 0, textStyle, qfalse); } static void UI_DrawReplacementType(rectDef_t * rect, float scale, vec4_t color, int textStyle) { const char *p = replacementTypes[uiInfo.replacements.TypeIndex % replacementTypeCount].displayName; - Text_Paint(rect->x, rect->y, scale, color, p, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, p, 0, 0, 0, textStyle, qfalse); } static void UI_DrawReplacementSubtype(rectDef_t * rect, float scale, vec4_t color, int textStyle) @@ -3424,7 +3704,7 @@ static void UI_DrawReplacementSubtype(rectDef_t * rect, float scale, vec4_t colo default: return; } - Text_Paint(rect->x, rect->y, scale, color, p, 0, 0, textStyle); + Text_Paint(rect->x, rect->y, scale, color, p, 0, 0, 0, textStyle, qfalse); } static void UI_DrawReplacementModel(rectDef_t *rect) @@ -3722,6 +4002,10 @@ static void UI_OwnerDraw(itemDef_t *item, float x, float y, float w, float h, fl case UI_RQ3_REPLACEMENTSUBTYPE: UI_DrawReplacementSubtype(&rect, scale, color, textStyle); break; + //Makro - startup menu text + case UI_RQ3_STARTUP: + UI_DrawStartupText(item, &rect, scale, color, textStyle); + break; case UI_SELECTEDPLAYER: UI_DrawSelectedPlayer(&rect, scale, color, textStyle); break; @@ -3735,7 +4019,7 @@ static void UI_OwnerDraw(itemDef_t *item, float x, float y, float w, float h, fl UI_DrawGLInfo(&rect, scale, color, textStyle); break; case UI_KEYBINDSTATUS: - UI_DrawKeyBindStatus(&rect, scale, color, textStyle); + UI_DrawKeyBindStatus(item, &rect, scale, color, textStyle); break; default: break; @@ -4794,11 +5078,11 @@ static void UI_LoadMovies() UI_LoadDemos =============== */ -static int q3Protocols[] = {66, 67, 68}; -static char *q3Versions[] = {"1.30", "1.31", "1.32"}; +static const int q3Protocols[] = {66, 67, 68}; +static const char *q3Versions[] = {"1.30", "1.31", "1.32"}; static const int q3VersionCount = sizeof(q3Protocols)/sizeof(q3Protocols[0]); -char *q3VersionFromProtocol(int protocol) +const char *q3VersionFromProtocol(int protocol) { int i; @@ -4810,7 +5094,7 @@ char *q3VersionFromProtocol(int protocol) return q3Versions[q3VersionCount-1]; } -int q3ProtocolFromVersion(char *version) +int q3ProtocolFromVersion(const char *version) { int i; @@ -4822,13 +5106,22 @@ int q3ProtocolFromVersion(char *version) return q3Protocols[q3VersionCount-1]; } -void UI_SortDemoList(int start, int end) +void UI_SortDemoList(int start, int end, int column) { int i, j; - //sort list alphabetically for (i=start; i0) + { + qboolean swap; + //sort list alphabetically + if (column == 0) + swap = (Q_stricmp(uiInfo.demoList[i], uiInfo.demoList[j]) > 0); + //sort by q3 version + else + swap = (uiInfo.demoType[i] - uiInfo.demoType[j] > 0); + + if (swap) { int tmp; const char *tmpstr; @@ -4840,6 +5133,8 @@ void UI_SortDemoList(int start, int end) uiInfo.demoList[j] = tmpstr; uiInfo.demoType[j] = tmp; } + } + } } static void UI_LoadDemos() @@ -4876,12 +5171,13 @@ static void UI_LoadDemos() //Makro - bad for linux users //Q_strupr(demoname); uiInfo.demoType[uiInfo.demoCount] = j; - uiInfo.demoList[uiInfo.demoCount++] = String_Alloc(va("%s (%s)", demoname, q3VersionFromProtocol(j))); + //uiInfo.demoList[uiInfo.demoCount++] = String_Alloc(va("%s (%s)", demoname, q3VersionFromProtocol(j))); + uiInfo.demoList[uiInfo.demoCount++] = String_Alloc(demoname); demoname += len + 1; } } } - UI_SortDemoList(0, uiInfo.demoCount); + UI_SortDemoList(0, uiInfo.demoCount, 0); } static qboolean UI_SetNextMap(int actual, int index) @@ -5459,13 +5755,15 @@ static void UI_RunMenuScript(char **args) //Makro - missing check if (uiInfo.demoIndex >= 0 && uiInfo.demoIndex < uiInfo.demoCount) { + //Makro - no longer needed //Makro - remove version info - char demoname[128], *p; - Q_strncpyz(demoname, uiInfo.demoList[uiInfo.demoIndex], sizeof(demoname)); - p = Q_strrchr(demoname, '('); - if (p) - *(p-1)=0; - trap_Cmd_ExecuteText(EXEC_APPEND, va("demo %s.dm_%d\n", demoname, uiInfo.demoType[uiInfo.demoIndex])); + //char demoname[128], *p; + //Q_strncpyz(demoname, uiInfo.demoList[uiInfo.demoIndex], sizeof(demoname)); + //p = Q_strrchr(demoname, '('); + //if (p) + // *(p-1)=0; + //trap_Cmd_ExecuteText(EXEC_APPEND, va("demo %s.dm_%d\n", demoname, uiInfo.demoType[uiInfo.demoIndex])); + trap_Cmd_ExecuteText(EXEC_APPEND, va("demo %s.dm_%d\n", uiInfo.demoList[uiInfo.demoIndex], uiInfo.demoType[uiInfo.demoIndex])); } } else if (Q_stricmp(name, "Quake3") == 0) { trap_Cvar_Set("fs_game", ""); @@ -5479,7 +5777,7 @@ static void UI_RunMenuScript(char **args) UI_BuildServerDisplayList(qtrue); } else { Menus_CloseByName("joinserver"); - Menus_OpenByName("main"); + Menus_OpenByName("main", qfalse); } } else if (Q_stricmp(name, "StopRefresh") == 0) { UI_StopServerRefresh(); @@ -5566,12 +5864,12 @@ static void UI_RunMenuScript(char **args) trap_Cvar_Set("cl_paused", "1"); trap_Key_SetCatcher(KEYCATCH_UI); Menus_CloseAll(); - Menus_ActivateByName("setup_menu2"); + Menus_ActivateByName("setup_menu2", qfalse); } else if (Q_stricmp(name, "Leave") == 0) { trap_Cmd_ExecuteText(EXEC_APPEND, "disconnect\n"); trap_Key_SetCatcher(KEYCATCH_UI); Menus_CloseAll(); - Menus_ActivateByName("main"); + Menus_ActivateByName("main", qfalse); } else if (Q_stricmp(name, "ServerSort") == 0) { int sortColumn; @@ -6771,7 +7069,7 @@ static const char *UI_FeederItemText(float feederID, int index, int column, qhan } } else if (feederID == FEEDER_MODS) { if (index >= 0 && index < uiInfo.modCount) { - if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) { + if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr && column == 0) { return uiInfo.modList[index].modDescr; } else { return uiInfo.modList[index].modName; @@ -6783,7 +7081,11 @@ static const char *UI_FeederItemText(float feederID, int index, int column, qhan } } else if (feederID == FEEDER_DEMOS) { if (index >= 0 && index < uiInfo.demoCount) { - return uiInfo.demoList[index]; + if (column == 0) { + return uiInfo.demoList[index]; + } else if (column == 1) { + return q3VersionFromProtocol(uiInfo.demoType[index]); + } } //Makro - improved in-game server info list } else if (feederID == FEEDER_INGAME_SERVERINFO) { @@ -7524,8 +7826,11 @@ static void UI_BuildQ3Model_List(void) void UI_RQ3_StopBackgroundTrack(void) { trap_S_StopBackgroundTrack(); - uiInfo.playingIntro = ""; - uiInfo.playingLoop = ""; + uiInfo.playingIntro = NULL; + uiInfo.playingLoop = NULL; +#ifdef DEBUG + Com_Printf("Stopped music\n"); +#endif } void UI_RQ3_StartBackgroundTrack(const char *intro, const char *loop) @@ -7534,6 +7839,9 @@ void UI_RQ3_StartBackgroundTrack(const char *intro, const char *loop) uiInfo.playingIntro = intro; uiInfo.playingLoop = loop; trap_S_StartBackgroundTrack(intro, loop); +#ifdef DEBUG + Com_Printf("Started music: %s %s\n", intro, loop); +#endif } } @@ -7558,12 +7866,16 @@ void UI_RenderScene(const refdef_t *ref) trap_R_ClearScene(); } -void UI_DrawPolyStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader) +void UI_DrawPolyStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader, qboolean adjust) { if (uiInfo.uiDC.pendingPolys) { UI_Render2DScene(); } + if (adjust) + { + UI_AdjustFrom640(&x, &y, &w, &h); + } trap_R_DrawStretchPic(x, y, w, h, s1, t1, s2, t2, hShader); } @@ -7590,9 +7902,10 @@ void _UI_Init(qboolean inGameLoad) // cache redundant calulations trap_GetGlconfig(&uiInfo.uiDC.glconfig); - if (ui_maxpolys.integer < 4096) + //Makro - 8192 polys should be enough for the new UI... + if (ui_maxpolys.integer < 8192) { - trap_Cvar_SetValue("r_maxpolys", 4096); + trap_Cvar_SetValue("r_maxpolys", 8192); trap_Cmd_ExecuteText(EXEC_INSERT, "vid_restart"); } @@ -7608,6 +7921,7 @@ void _UI_Init(qboolean inGameLoad) uiInfo.uiDC.bias = 0; } + //Makro - set up 2D scene memset(&uiInfo.uiDC.scene2D, 0, sizeof(&uiInfo.uiDC.scene2D)); uiInfo.uiDC.scene2D.x = 0; uiInfo.uiDC.scene2D.y = 0; @@ -7619,6 +7933,13 @@ void _UI_Init(qboolean inGameLoad) AxisClear(uiInfo.uiDC.scene2D.viewaxis); + //Makro - default values for the key bind strings + uiInfo.keyBindStatus1 = KEYBIND_STATUS1; + uiInfo.keyBindStatus2 = KEYBIND_STATUS2; + + //Makro - empty startup menu text + *uiInfo.startupText = 0; + //UI_Load(); uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip; uiInfo.uiDC.setColor = &UI_SetColor; @@ -7656,6 +7977,8 @@ void _UI_Init(qboolean inGameLoad) uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer; uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue; uiInfo.uiDC.drawTextWithCursor = &Text_PaintWithCursor; + //Makro - items using vectors + uiInfo.uiDC.drawAngledTextWithCursor = &Text_PaintWithCursorAngled; uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode; uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode; uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound; @@ -7743,8 +8066,8 @@ void _UI_Init(qboolean inGameLoad) uiInfo.savedMusicVol = qfalse; //Makro - music files being played - uiInfo.playingIntro = ""; - uiInfo.playingLoop = ""; + uiInfo.playingIntro = NULL; + uiInfo.playingLoop = NULL; //Makro - set default bot skill to medium uiInfo.skillIndex = 2; @@ -7755,7 +8078,7 @@ void _UI_Init(qboolean inGameLoad) trap_GetConfigString(CS_SERVERINFO, info, sizeof(info)); uiInfo.weapBan = atoi(Info_ValueForKey(info, "g_RQ3_weaponBan")); uiInfo.itemBan = atoi(Info_ValueForKey(info, "g_RQ3_itemBan")); - + uiInfo.serverStatus.currentServerCinematic = -1; uiInfo.previewMovie = -1; @@ -7771,6 +8094,9 @@ void _UI_Init(qboolean inGameLoad) uiInfo.uiDC.cursorx = 320; uiInfo.uiDC.cursory = 240; + + //Makro - keep the cursor visible for 5 seconds + uiInfo.uiDC.mouseMoveTime = trap_Milliseconds() + 5000; } /* @@ -7784,12 +8110,15 @@ void _UI_KeyEvent(int key, qboolean down) if (key == K_MOUSE1) { uiInfo.uiDC.mouseDown[0] = down; + uiInfo.uiDC.mouseMoveTime = uiInfo.uiDC.realTime; Vector2Set(uiInfo.uiDC.mouseDownPos, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); } else if (key == K_MOUSE2) { uiInfo.uiDC.mouseDown[1] = down; + uiInfo.uiDC.mouseMoveTime = uiInfo.uiDC.realTime; Vector2Set(uiInfo.uiDC.mouseDownPos, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); } else if (key == K_MOUSE3) { uiInfo.uiDC.mouseDown[2] = down; + uiInfo.uiDC.mouseMoveTime = uiInfo.uiDC.realTime; Vector2Set(uiInfo.uiDC.mouseDownPos, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); } @@ -7820,14 +8149,24 @@ UI_MouseEvent */ void _UI_MouseEvent(int dx, int dy) { - // update mouse screen position - uiInfo.uiDC.cursorx += dx; + //Makro - added tablet code + if (ui_RQ3_tabletMode.integer) + { + uiInfo.uiDC.cursorx = (int) (SCREEN_WIDTH / 2.0f + + (float) dx * SCREEN_WIDTH / uiInfo.uiDC.glconfig.vidWidth); + uiInfo.uiDC.cursory = (int) (SCREEN_HEIGHT / 2.0f + + (float) dy * SCREEN_HEIGHT / uiInfo.uiDC.glconfig.vidHeight); + } else { + // update mouse screen position + uiInfo.uiDC.cursorx += dx; + uiInfo.uiDC.cursory += dy; + } + if (uiInfo.uiDC.cursorx < 0) uiInfo.uiDC.cursorx = 0; else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH) uiInfo.uiDC.cursorx = SCREEN_WIDTH; - uiInfo.uiDC.cursory += dy; if (uiInfo.uiDC.cursory < 0) uiInfo.uiDC.cursory = 0; else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT) @@ -7838,6 +8177,9 @@ void _UI_MouseEvent(int dx, int dy) //Menu_HandleMouseMove(menu, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory); } + + //Makro - update the time + uiInfo.uiDC.mouseMoveTime = uiInfo.uiDC.realTime; } void UI_LoadNonIngame() @@ -7878,11 +8220,11 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) UI_LoadNonIngame(); } Menus_CloseAll(); - Menus_ActivateByName("main"); + Menus_ActivateByName("main", qfalse); trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf)); if (strlen(buf)) { if (!ui_singlePlayerActive.integer) { - Menus_ActivateByName("error_popmenu"); + Menus_ActivateByName("error_popmenu", qfalse); } else { trap_Cvar_Set("com_errorMessage", ""); } @@ -7891,13 +8233,13 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) if ((int)trap_Cvar_VariableValue("com_hunkMegs") < 96) { trap_Cvar_SetValue("com_hunkMegs", 96); - Menus_ActivateByName("memory_popmenu"); + Menus_ActivateByName("memory_popmenu", qfalse); }; } return; case UIMENU_TEAM: trap_Key_SetCatcher(KEYCATCH_UI); - Menus_ActivateByName("team"); + Menus_ActivateByName("team", qfalse); return; case UIMENU_NEED_CD: // no cd check in TA @@ -7918,7 +8260,7 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) UI_LoadNonIngame(); } Menus_CloseAll(); - Menus_ActivateByName("endofgame"); + Menus_ActivateByName("endofgame", qfalse); //UI_ConfirmMenu( "Bad CD Key", NULL, NeedCDKeyAction ); return; case UIMENU_INGAME: @@ -7926,7 +8268,7 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) trap_Key_SetCatcher(KEYCATCH_UI); UI_BuildPlayerList(); Menus_CloseAll(); - Menus_ActivateByName("ingame"); + Menus_ActivateByName("ingame", qfalse); return; //Makro - RQ3 menus case UIMENU_RQ3_WEAPON: @@ -7934,7 +8276,7 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) trap_Key_SetCatcher(KEYCATCH_UI); UI_BuildPlayerList(); Menus_CloseAll(); - Menus_ActivateByName("ingame_weapon"); + Menus_ActivateByName("ingame_weapon", qfalse); return; case UIMENU_RQ3_JOIN: trap_Cvar_Set("cl_paused", "1"); @@ -7942,9 +8284,9 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) UI_BuildPlayerList(); Menus_CloseAll(); if (trap_Cvar_VariableValue("g_gametype") >= GT_TEAM) { - Menus_ActivateByName("ingame_join"); + Menus_ActivateByName("ingame_join", qfalse); } else { - Menus_ActivateByName("ingame_join_dm"); + Menus_ActivateByName("ingame_join_dm", qfalse); } return; case UIMENU_RQ3_TKOK: @@ -7952,14 +8294,14 @@ void _UI_SetActiveMenu(uiMenuCommand_t menu) trap_Key_SetCatcher(KEYCATCH_UI); UI_BuildPlayerList(); Menus_CloseAll(); - Menus_ActivateByName("ingame_tkok"); + Menus_ActivateByName("ingame_tkok", qfalse); return; case UIMENU_RQ3_PRESETS: trap_Cvar_Set("cl_paused", "1"); trap_Key_SetCatcher(KEYCATCH_UI); UI_BuildPlayerList(); Menus_CloseAll(); - Menus_ActivateByName("ingame_presets"); + Menus_ActivateByName("ingame_presets", qfalse); return; } } @@ -8008,7 +8350,7 @@ void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *t { int len = Text_Width(text, scale, 0); - Text_Paint(x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE); + Text_Paint(x - len / 2, y, scale, color, text, 0, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE, qfalse); } void Text_PaintCenter_AutoWrapped(float x, float y, float xmax, float ystep, float scale, vec4_t color, const char *str, float adjust) @@ -8183,9 +8525,11 @@ void UI_DrawConnectScreen(qboolean overlay) if (!Q_stricmp(cstate.servername, "localhost")) { Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, va("Starting up..."), ITEM_TEXTSTYLE_SHADOWEDMORE); + //Q_strncpyz(uiInfo.startupText, "Starting up...", sizeof(uiInfo.startupText)); } else { strcpy(text, va("Connecting to %s", cstate.servername)); Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, text, ITEM_TEXTSTYLE_SHADOWEDMORE); + //Q_strncpyz(uiInfo.startupText, va("Connecting to %s", cstate.servername), sizeof(uiInfo.startupText)); } // display global MOTD at bottom @@ -8231,6 +8575,7 @@ void UI_DrawConnectScreen(qboolean overlay) if (Q_stricmp(cstate.servername, "localhost")) { Text_PaintCenter(centerPoint, yStart + 80, scale, colorWhite, s, 0); } + // password required / connection rejected information goes here } @@ -8368,6 +8713,9 @@ vmCvar_t ui_serverStatusTimeOut; //Makro - cvar for player model display vmCvar_t ui_RQ3_modelCommand; +//Makro - tablet support in the UI +vmCvar_t ui_RQ3_tabletMode; + //Makro - model cvar vmCvar_t ui_RQ3_model; @@ -8563,6 +8911,8 @@ static cvarTable_t cvarTable[] = { {&ui_realWarmUp, "g_warmup", "20", CVAR_ARCHIVE}, {&ui_realCaptureLimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART}, {&ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE}, + //Makro - tablet support in the UI + {&ui_RQ3_tabletMode, "ui_RQ3_tabletMode", "0", CVAR_ARCHIVE}, //Makro - cvar for player model display {&ui_RQ3_modelCommand, "ui_RQ3_modelCommand", "0", 0}, {&ui_RQ3_ssgCrosshair, "ui_RQ3_ssgCrosshair", "0", 0}, diff --git a/reaction/ta_ui/ui_shared.c b/reaction/ta_ui/ui_shared.c index 5998f15c..690fa056 100644 --- a/reaction/ta_ui/ui_shared.c +++ b/reaction/ta_ui/ui_shared.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.32 2005/09/07 20:24:33 makro +// Vector support for most item types +// // Revision 1.31 2005/02/15 16:33:39 makro // Tons of updates (entity tree attachment system, UI vectors) // @@ -151,6 +154,7 @@ int GMemory() menuDef_t *menuStack[MAX_OPEN_MENUS]; int openMenuCount = 0; + //Makro - previous menu static menuDef_t *prevMenu = NULL; @@ -766,13 +770,14 @@ void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboo } //Makro - new fading method +//TODO: support for border and overlay colors void UI_RQ3_HandleFading(Window * w) { if (w) { if ((w->timeFade.active)) { if (DC->realTime > w->timeFade.endTime) { w->timeFade.active = qfalse; - if ((w->timeFade.forecolor)) { + if ((w->timeFade.colorType = FORECOLOR)) { memcpy(w->foreColor, w->timeFade.color2, sizeof(vec4_t)); //autohide if (w->foreColor[3] == 0) @@ -788,7 +793,7 @@ void UI_RQ3_HandleFading(Window * w) float frac = ((float) (DC->realTime - w->timeFade.startTime)) / ((float) (w->timeFade.endTime - w->timeFade.startTime)); - qboolean forecolor = w->timeFade.forecolor; + qboolean forecolor = (w->timeFade.colorType == FORECOLOR); if (forecolor) { LerpColor(w->timeFade.color1, w->timeFade.color2, w->foreColor, frac); } else { @@ -808,7 +813,8 @@ void Window_Paint(Window * w, float fadeAmount, float fadeClamp, float fadeCycle if (debugMode) { //color[0] = color[1] = color[2] = color[3] = 1; - DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color); + //Makro - added shader parm + DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color, DC->whiteShader); } if (w == NULL) { @@ -926,29 +932,35 @@ void Window_Paint(Window * w, float fadeAmount, float fadeClamp, float fadeCycle color[3] = 1; if (w->rectClient.hasVectors) { + //Makro - added shader parm DC->drawAngledRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->rect.u, w->rect.v, - w->borderSize, color, RECT_FULL); + w->borderSize, color, RECT_FULL, DC->whiteShader); } else { - DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, color); + //Makro - added shader parm + DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, color, DC->whiteShader); } } else { if (w->rectClient.hasVectors) { + //Makro - added shader parm DC->drawAngledRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->rect.u, w->rect.v, - w->borderSize, w->borderColor, RECT_FULL); + w->borderSize, w->borderColor, RECT_FULL, DC->whiteShader); } else { - DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, w->borderColor); + //Makro - added shader parm + DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, w->borderColor, DC->whiteShader); } } } else if (w->border == WINDOW_BORDER_HORZ) { // top/bottom DC->setColor(w->borderColor); - DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize); + //Makro - added shader parm + DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, DC->whiteShader); DC->setColor(NULL); } else if (w->border == WINDOW_BORDER_VERT) { // left right DC->setColor(w->borderColor); - DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize); + //Makro - added shader parm + DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, DC->whiteShader); DC->setColor(NULL); } else if (w->border == WINDOW_BORDER_KCGRADIENT) { // this is just two gradient bars along each horz edge @@ -1091,22 +1103,11 @@ qboolean IsVisible(int flags) qboolean Rect_ContainsPoint(rectDef_t * rect, float x, float y) { if (rect) { - //Makro - twisted rectangle? - if (rect->hasVectors) + float px, py; + Rect_ToInnerCoords(rect, x, y, &px, &py); + if (px > 0 && px < rect->w && py > 0 && py < rect->h) { - float dx = x - rect->x; - float dy = y - rect->y; - float px = dx * rect->u[0] + dy * rect->u[1]; - float py = dx * rect->v[0] + dy * rect->v[1]; - if (px > 0 && px < rect->w && py > 0 && py < rect->h) - { - return qtrue; - } - } else { - if (x > rect->x && x < rect->x + rect->w && y > rect->y && y < rect->y + rect->h) - { - return qtrue; - } + return qtrue; } } return qfalse; @@ -1495,9 +1496,10 @@ void Menus_ShowByName(const char *p) } } -void Menus_OpenByName(const char *p) +//Makro - added second parameter +void Menus_OpenByName(const char *p, qboolean special) { - Menus_ActivateByName(p); + Menus_ActivateByName(p, special); } static void Menu_RunCloseScript(menuDef_t * menu) @@ -1510,13 +1512,37 @@ static void Menu_RunCloseScript(menuDef_t * menu) } } +//Makro - closes a menu +void Menus_Close(menuDef_t *menu) +{ + int i; + + if (!menu) + return; + + for (i=0; iwindow.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); +} + void Menus_CloseByName(const char *p) { menuDef_t *menu = Menus_FindByName(p); if (menu != NULL) { - Menu_RunCloseScript(menu); - menu->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS); + Menus_Close(menu); } } @@ -1525,8 +1551,7 @@ void Menus_CloseAll() int i; for (i = 0; i < menuCount; i++) { - Menu_RunCloseScript(&Menus[i]); - Menus[i].window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); + Menus_Close(&Menus[i]); } } @@ -1559,7 +1584,7 @@ void Script_Hide(itemDef_t * item, char **args) } //Makro - for the new fading method -void UI_RQ3_TimeFadeItem(itemDef_t * item, vec4_t endColor, int offset, int duration, qboolean forecolor) +void UI_RQ3_TimeFadeItem(itemDef_t * item, vec4_t endColor, int offset, int duration, colorType_t colorType) { int i; @@ -1567,7 +1592,7 @@ void UI_RQ3_TimeFadeItem(itemDef_t * item, vec4_t endColor, int offset, int dura duration = 1; } - if (forecolor) { + if (colorType == FORECOLOR) { memcpy(item->window.timeFade.color1, item->window.foreColor, sizeof(vec4_t)); item->window.flags |= WINDOW_FORECOLORSET; } else { @@ -1585,7 +1610,7 @@ void UI_RQ3_TimeFadeItem(itemDef_t * item, vec4_t endColor, int offset, int dura } item->window.timeFade.active = qtrue; - item->window.timeFade.forecolor = forecolor; + item->window.timeFade.colorType = colorType; item->window.timeFade.startTime = DC->realTime + offset; item->window.timeFade.endTime = item->window.timeFade.startTime + duration; /* @@ -1597,7 +1622,7 @@ void UI_RQ3_TimeFadeItem(itemDef_t * item, vec4_t endColor, int offset, int dura */ } void Menu_TimeFadeItemByName(menuDef_t * menu, const char *name, vec4_t endColor, int offset, int duration, - qboolean forecolor) + colorType_t colorType) { if (menu) { int i; @@ -1607,7 +1632,7 @@ void Menu_TimeFadeItemByName(menuDef_t * menu, const char *name, vec4_t endColor if (!Q_stricmp(menu->items[i]->window.name, name) || !Q_stricmp(menu->items[i]->window.group, name) || !Q_stricmp(menu->items[i]->window.subgroup, name)) { - UI_RQ3_TimeFadeItem(menu->items[i], endColor, offset, duration, forecolor); + UI_RQ3_TimeFadeItem(menu->items[i], endColor, offset, duration, colorType); } } //} @@ -1628,10 +1653,10 @@ void Script_TimeFade(itemDef_t * item, char **args) if (Int_Parse(args, &duration)) { if (!Q_stricmp(isForeColor, "forecolor")) { Menu_TimeFadeItemByName(item->parent, name, endColor, offset, - duration, qtrue); + duration, FORECOLOR); } else { Menu_TimeFadeItemByName(item->parent, name, endColor, offset, - duration, qfalse); + duration, BACKCOLOR); } } } @@ -1650,9 +1675,9 @@ void Script_TimeFadeSelf(itemDef_t * item, char **args) if (Int_Parse(args, &offset)) { if (Int_Parse(args, &duration)) { if (!Q_stricmp(isForeColor, "forecolor")) { - UI_RQ3_TimeFadeItem(item, endColor, offset, duration, qtrue); + UI_RQ3_TimeFadeItem(item, endColor, offset, duration, FORECOLOR); } else { - UI_RQ3_TimeFadeItem(item, endColor, offset, duration, qfalse); + UI_RQ3_TimeFadeItem(item, endColor, offset, duration, BACKCOLOR); } } } @@ -1685,9 +1710,9 @@ void Script_Open(itemDef_t * item, char **args) if (String_Parse(args, &name)) { //Makro - previous menu if ( (!Q_stricmp(name, "_previous") || !Q_stricmp(name, "_prev")) && prevMenu) { - Menus_OpenByName(prevMenu->window.name); + Menus_OpenByName(prevMenu->window.name, qfalse); } else { - Menus_OpenByName(name); + Menus_OpenByName(name, qfalse); } prevMenu = (menuDef_t*)item->parent; } @@ -1703,9 +1728,9 @@ void Script_ConditionalOpen(itemDef_t * item, char **args) if (String_Parse(args, &cvar) && String_Parse(args, &name1) && String_Parse(args, &name2)) { val = DC->getCVarValue(cvar); if (val == 0.f) { - Menus_OpenByName(name2); + Menus_OpenByName(name2, qfalse); } else { - Menus_OpenByName(name1); + Menus_OpenByName(name1, qfalse); } } } @@ -1726,6 +1751,22 @@ void Script_Close(itemDef_t * item, char **args) } } +//Makro - opens a menu and runs its "special" script +void Script_OpenSpecial(itemDef_t * item, char **args) +{ + const char *name; + + if (String_Parse(args, &name)) { + //Makro - previous menu + if ( (!Q_stricmp(name, "_previous") || !Q_stricmp(name, "_prev")) && prevMenu) { + Menus_OpenByName(prevMenu->window.name, qtrue); + } else { + Menus_OpenByName(name, qtrue); + } + prevMenu = (menuDef_t*)item->parent; + } +} + void Menu_TransitionItemByName(menuDef_t * menu, const char *p, rectDef_t rectFrom, rectDef_t rectTo, int time, float amt) { @@ -1738,13 +1779,22 @@ void Menu_TransitionItemByName(menuDef_t * menu, const char *p, rectDef_t rectFr if (item != NULL) { item->window.flags |= (WINDOW_INTRANSITION | WINDOW_VISIBLE); item->window.offsetTime = time; - //FIXME: this is probably breaking vectors + //Makro - copy vector info + rectFrom.hasVectors = item->window.rect.hasVectors; + Vector2Copy(item->window.rect.u, rectFrom.u); + Vector2Copy(item->window.rect.v, rectFrom.v); + // + rectTo.hasVectors = rectFrom.hasVectors; + Vector2Copy(rectFrom.u, rectTo.u); + Vector2Copy(rectFrom.v, rectTo.v); + // memcpy(&item->window.rectClient, &rectFrom, sizeof(rectDef_t)); memcpy(&item->window.rectEffects, &rectTo, sizeof(rectDef_t)); item->window.rectEffects2.x = abs(rectTo.x - rectFrom.x) / amt; item->window.rectEffects2.y = abs(rectTo.y - rectFrom.y) / amt; item->window.rectEffects2.w = abs(rectTo.w - rectFrom.w) / amt; item->window.rectEffects2.h = abs(rectTo.h - rectFrom.h) / amt; + Item_UpdatePosition(item); } } @@ -1976,9 +2026,11 @@ commandDef_t commandList[] = { {"setoverlaycolor", &Script_SetOverlayColor}, //Makro - sets random color {"setrandomcolor", &Script_SetRandomColor}, - {"open", &Script_Open}, // nenu + {"open", &Script_Open}, // menu {"conditionalopen", &Script_ConditionalOpen}, // menu {"close", &Script_Close}, // menu + //Makro - opens a menu and runs its "special" script + {"openspecial", &Script_OpenSpecial}, {"setasset", &Script_SetAsset}, // works on this {"setbackground", &Script_SetBackground}, // works on this {"setitemcolor", &Script_SetItemColor}, // group/name @@ -2170,12 +2222,14 @@ int Item_ListBox_MaxScroll(itemDef_t * item) return max; } +//returns absolute position int Item_ListBox_ThumbPosition(itemDef_t * item) { float max, pos, size; listBoxDef_t *listPtr = (listBoxDef_t *) item->typeData; max = Item_ListBox_MaxScroll(item); + //horizontal if (item->window.flags & WINDOW_HORIZONTAL) { size = item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2; if (max > 0) { @@ -2185,6 +2239,7 @@ int Item_ListBox_ThumbPosition(itemDef_t * item) } pos *= listPtr->startPos; return item->window.rect.x + 1 + SCROLLBAR_SIZE + pos; + //vertical } else { size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2; if (max > 0) { @@ -2197,31 +2252,73 @@ int Item_ListBox_ThumbPosition(itemDef_t * item) } } +//returns absolute position +//TODO: return relative position, convert value in drawing function int Item_ListBox_ThumbDrawPosition(itemDef_t * item) { int min, max; - if (itemCapture == item) { + //Makro - added thumb condition + if (itemCapture == item && item->window.flags & WINDOW_LB_THUMB) { + //horizontal if (item->window.flags & WINDOW_HORIZONTAL) { - min = item->window.rect.x + SCROLLBAR_SIZE + 1; - max = item->window.rect.x + item->window.rect.w - 2 * SCROLLBAR_SIZE - 1; - if (DC->cursorx >= min + SCROLLBAR_SIZE / 2 && DC->cursorx <= max + SCROLLBAR_SIZE / 2) { - return DC->cursorx - SCROLLBAR_SIZE / 2; - } else { - return Item_ListBox_ThumbPosition(item); + //Makro - vectors? + float px; + + min = SCROLLBAR_SIZE + 1; + max = item->window.rect.w - 2 * SCROLLBAR_SIZE - 1; + if (item->window.rect.hasVectors) + { + Rect_ToInnerCoords(&item->window.rect, DC->cursorx, DC->cursory, &px, NULL); + /* + if (px >= min + SCROLLBAR_SIZE / 2 && px <= max + SCROLLBAR_SIZE / 2) { + return item->window.rect.x + px - SCROLLBAR_SIZE / 2; + } + */ + } else { //no vectors + px = DC->cursorx - item->window.rect.x; + /* + if (DC->cursorx >= min + SCROLLBAR_SIZE / 2 && DC->cursorx <= max + SCROLLBAR_SIZE / 2) { + return DC->cursorx - SCROLLBAR_SIZE / 2; + } + */ } + if (px <= min + SCROLLBAR_SIZE / 2) + return item->window.rect.x + min; + else if (px >= max + SCROLLBAR_SIZE / 2) + return item->window.rect.x + max; + else + return item->window.rect.x + px - SCROLLBAR_SIZE / 2; + //vertical } else { - min = item->window.rect.y + SCROLLBAR_SIZE + 1; - max = item->window.rect.y + item->window.rect.h - 2 * SCROLLBAR_SIZE - 1; - if (DC->cursory >= min + SCROLLBAR_SIZE / 2 && DC->cursory <= max + SCROLLBAR_SIZE / 2) { - return DC->cursory - SCROLLBAR_SIZE / 2; + float py; + //Makro - vectors? + if (item->window.rect.hasVectors) { + + min = SCROLLBAR_SIZE + 1; + max = item->window.rect.h - 2 * SCROLLBAR_SIZE - 1; + /* + py = (DC->cursorx - item->window.rect.x) * item->window.rect.v[0] + + (DC->cursory - item->window.rect.y) * item->window.rect.v[1]; + */ + Rect_ToInnerCoords(&item->window.rect, DC->cursorx, DC->cursory, NULL, &py); } else { - return Item_ListBox_ThumbPosition(item); + min = SCROLLBAR_SIZE + 1; + max = item->window.rect.h - 2 * SCROLLBAR_SIZE - 1; + py = DC->cursory - item->window.rect.y; + //if (DC->cursory >= min + SCROLLBAR_SIZE / 2 && DC->cursory <= max + SCROLLBAR_SIZE / 2) + // return DC->cursory - SCROLLBAR_SIZE / 2; + //if (DC->cursory <= min + SCROLLBAR_SIZE / 2) } + if (py <= min + SCROLLBAR_SIZE / 2) + return item->window.rect.y + min; + else if (py >= max + SCROLLBAR_SIZE / 2) + return item->window.rect.y + max; + else + return item->window.rect.y + py - SCROLLBAR_SIZE / 2; } - } else { - return Item_ListBox_ThumbPosition(item); } + return Item_ListBox_ThumbPosition(item); } Point Item_Slider_ThumbPosition(itemDef_t * item) @@ -2307,71 +2404,175 @@ int Item_Slider_OverSlider(itemDef_t * item, float x, float y) return 0; } +//Makro - vector support int Item_ListBox_OverLB(itemDef_t * item, float x, float y) { rectDef_t r; listBoxDef_t *listPtr; int thumbstart; int count; + float p[2]; - r.hasVectors = qfalse; + r.hasVectors = item->window.rect.hasVectors; + Vector2Copy(item->window.rect.u, r.u); + Vector2Copy(item->window.rect.v, r.v); count = DC->feederCount(item->special); listPtr = (listBoxDef_t *) item->typeData; + //horizontal if (item->window.flags & WINDOW_HORIZONTAL) { - // check if on left arrow - r.x = item->window.rect.x; - r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; - r.h = r.w = SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_LEFTARROW; - } - // check if on right arrow - r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_RIGHTARROW; - } - // check if on thumb - thumbstart = Item_ListBox_ThumbPosition(item); - r.x = thumbstart; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_THUMB; - } - r.x = item->window.rect.x + SCROLLBAR_SIZE; - r.w = thumbstart - r.x; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_PGUP; - } - r.x = thumbstart + SCROLLBAR_SIZE; - r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_PGDN; + //vectors? + if (r.hasVectors) { + // check if on left arrow + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.h - SCROLLBAR_SIZE, r.v, p); + r.x = p[0]; + r.y = p[1]; + r.h = r.w = SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_LEFTARROW; + } + // check if on right arrow + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE, r.u, p); + r.x = p[0]; + r.y = p[1]; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_RIGHTARROW; + } + // check if on thumb + thumbstart = Item_ListBox_ThumbPosition(item); + Vector2MA(p, (thumbstart - item->window.rect.x) - (item->window.rect.w - SCROLLBAR_SIZE), r.u, p); + r.x = p[0]; + r.y = p[1]; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_THUMB; + } + // check if on page down + Vector2MA(p, SCROLLBAR_SIZE, r.u, p); + r.x = p[0]; + r.y = p[1]; + r.w = item->window.rect.w - (thumbstart - item->window.rect.x) - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGDN; + } + // check if on page up + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.h - SCROLLBAR_SIZE, r.v, p); + Vector2MA(p, SCROLLBAR_SIZE, r.u, p); + r.x = p[0]; + r.y = p[1]; + r.w = thumbstart - item->window.rect.x - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGUP; + } + //no vectors + } else { + // check if on left arrow + r.x = item->window.rect.x; + r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; + r.h = r.w = SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_LEFTARROW; + } + // check if on right arrow + r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_RIGHTARROW; + } + // check if on thumb + thumbstart = Item_ListBox_ThumbPosition(item); + r.x = thumbstart; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_THUMB; + } + r.x = item->window.rect.x + SCROLLBAR_SIZE; + r.w = thumbstart - r.x; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGUP; + } + r.x = thumbstart + SCROLLBAR_SIZE; + r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGDN; + } } + //vertical } else { - r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; - r.y = item->window.rect.y; - r.h = r.w = SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_LEFTARROW; - } - r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_RIGHTARROW; - } - thumbstart = Item_ListBox_ThumbPosition(item); - r.y = thumbstart; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_THUMB; - } - r.y = item->window.rect.y + SCROLLBAR_SIZE; - r.h = thumbstart - r.y; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_PGUP; - } - r.y = thumbstart + SCROLLBAR_SIZE; - r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; - if (Rect_ContainsPoint(&r, x, y)) { - return WINDOW_LB_PGDN; + //vectors? + if (r.hasVectors) { + //Makro - TODO: optimize this code + // check if on left arrow + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE, r.u, p); + r.h = r.w = SCROLLBAR_SIZE; + r.x = p[0]; + r.y = p[1]; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_LEFTARROW; + } + // check if on right arrow + Vector2MA(p, item->window.rect.h - SCROLLBAR_SIZE, r.v, p); + r.x = p[0]; + r.y = p[1]; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_RIGHTARROW; + } + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE, r.u, p); + thumbstart = Item_ListBox_ThumbPosition(item); + Vector2MA(p, thumbstart - item->window.rect.y, r.v, p); + r.x = p[0]; + r.y = p[1]; + //Com_Printf("Rect: %.1f %.1f %.1f %.1f Point: %.1f %.1f\n", PRINT_RECT(r), x, y); + //Com_Printf("%.3f %.3f\n", r.w, r.h); + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_THUMB; + } + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE, r.u, p); + Vector2MA(p, SCROLLBAR_SIZE, r.v, p); + r.x = p[0]; + r.y = p[1]; + r.h = thumbstart - item->window.rect.y - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGUP; + } + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE, r.u, p); + Vector2MA(p, thumbstart - item->window.rect.y + SCROLLBAR_SIZE, r.v, p); + r.x = p[0]; + r.y = p[1]; + r.h = item->window.rect.h - (thumbstart - item->window.rect.y) - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGDN; + } + //no vectors + } else { + r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE; + r.y = item->window.rect.y; + r.h = r.w = SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_LEFTARROW; + } + r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_RIGHTARROW; + } + thumbstart = Item_ListBox_ThumbPosition(item); + r.y = thumbstart; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_THUMB; + } + r.y = item->window.rect.y + SCROLLBAR_SIZE; + r.h = thumbstart - r.y; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGUP; + } + r.y = thumbstart + SCROLLBAR_SIZE; + r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE; + if (Rect_ContainsPoint(&r, x, y)) { + return WINDOW_LB_PGDN; + } } } return 0; @@ -2382,7 +2583,9 @@ void Item_ListBox_MouseEnter(itemDef_t * item, float x, float y) rectDef_t r; listBoxDef_t *listPtr = (listBoxDef_t *) item->typeData; - r.hasVectors = qfalse; + r.hasVectors = item->window.rect.hasVectors; + Vector2Copy(item->window.rect.u, r.u); + Vector2Copy(item->window.rect.v, r.v); item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN); @@ -2398,27 +2601,43 @@ void Item_ListBox_MouseEnter(itemDef_t * item, float x, float y) r.h = item->window.rect.h - SCROLLBAR_SIZE; r.w = item->window.rect.w - listPtr->drawPadding; if (Rect_ContainsPoint(&r, x, y)) { - listPtr->cursorPos = - (int) ((x - r.x) / listPtr->elementWidth) + listPtr->startPos; + //vectors? + if (r.hasVectors) { + float px; + Rect_ToInnerCoords(&item->window.rect, x, y, &px, NULL); + listPtr->cursorPos = (int) (px / listPtr->elementWidth) + listPtr->startPos; + } else { + listPtr->cursorPos = (int) ((x - r.x) / listPtr->elementWidth) + listPtr->startPos; + } if (listPtr->cursorPos >= listPtr->endPos) { listPtr->cursorPos = listPtr->endPos; } + //item->cursorPos = listPtr->cursorPos; + //DC->feederSelection(item->special, item->cursorPos); } } else { // text hit.. } } - } else - if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | - WINDOW_LB_PGDN))) { - r.x = item->window.rect.x; - r.y = item->window.rect.y; - r.w = item->window.rect.w - SCROLLBAR_SIZE; - r.h = item->window.rect.h - listPtr->drawPadding; - if (Rect_ContainsPoint(&r, x, y)) { - listPtr->cursorPos = (int) ((y - 2 - r.y) / listPtr->elementHeight) + listPtr->startPos; - if (listPtr->cursorPos > listPtr->endPos) { - listPtr->cursorPos = listPtr->endPos; + } else { + if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | + WINDOW_LB_PGDN))) { + r.x = item->window.rect.x; + r.y = item->window.rect.y; + r.w = item->window.rect.w - SCROLLBAR_SIZE; + r.h = item->window.rect.h - listPtr->drawPadding; + if (Rect_ContainsPoint(&r, x, y)) { + //vectors? + if (r.hasVectors) { + float py; + Rect_ToInnerCoords(&item->window.rect, x, y, NULL, &py); + listPtr->cursorPos = (int) ((py - 2) / listPtr->elementHeight) + listPtr->startPos; + } else { + listPtr->cursorPos = (int) ((y - 2 - r.y) / listPtr->elementHeight) + listPtr->startPos; + } + if (listPtr->cursorPos > listPtr->endPos) { + listPtr->cursorPos = listPtr->endPos; + } } } } @@ -2524,6 +2743,7 @@ qboolean Item_ListBox_HandleKey(itemDef_t * item, int key, qboolean down, qboole || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS)) { max = Item_ListBox_MaxScroll(item); + //horizontal if (item->window.flags & WINDOW_HORIZONTAL) { viewmax = (item->window.rect.w / listPtr->elementWidth); if (key == K_LEFTARROW || key == K_KP_LEFTARROW) { @@ -2533,15 +2753,15 @@ qboolean Item_ListBox_HandleKey(itemDef_t * item, int key, qboolean down, qboole listPtr->cursorPos = 0; } if (listPtr->cursorPos < listPtr->startPos) { - listPtr->startPos = listPtr->cursorPos; + //listPtr->startPos = listPtr->cursorPos; } if (listPtr->cursorPos >= listPtr->startPos + viewmax) { - listPtr->startPos = listPtr->cursorPos - viewmax + 1; + //listPtr->startPos = listPtr->cursorPos - viewmax + 1; } item->cursorPos = listPtr->cursorPos; DC->feederSelection(item->special, item->cursorPos); } else { - listPtr->startPos--; + //listPtr->startPos--; if (listPtr->startPos < 0) listPtr->startPos = 0; } @@ -2551,13 +2771,13 @@ qboolean Item_ListBox_HandleKey(itemDef_t * item, int key, qboolean down, qboole if (!listPtr->notselectable) { listPtr->cursorPos++; if (listPtr->cursorPos < listPtr->startPos) { - listPtr->startPos = listPtr->cursorPos; + //listPtr->startPos = listPtr->cursorPos; } if (listPtr->cursorPos >= count) { listPtr->cursorPos = count - 1; } if (listPtr->cursorPos >= listPtr->startPos + viewmax) { - listPtr->startPos = listPtr->cursorPos - viewmax + 1; + //listPtr->startPos = listPtr->cursorPos - viewmax + 1; } item->cursorPos = listPtr->cursorPos; DC->feederSelection(item->special, item->cursorPos); @@ -2568,6 +2788,7 @@ qboolean Item_ListBox_HandleKey(itemDef_t * item, int key, qboolean down, qboole } return qtrue; } + //vertical } else { viewmax = (item->window.rect.h / listPtr->elementHeight); if (key == K_UPARROW || key == K_KP_UPARROW) { @@ -2641,15 +2862,20 @@ qboolean Item_ListBox_HandleKey(itemDef_t * item, int key, qboolean down, qboole } else if (item->window.flags & WINDOW_LB_THUMB) { // Display_SetCaptureItem(item); } else { - // select an item - if (DC->realTime < lastListBoxClickTime && listPtr->doubleClick) { - Item_RunScript(item, listPtr->doubleClick); - } - lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY; - if (item->cursorPos != listPtr->cursorPos) { + //Makro - double click only if we didn't select another item + //Com_Printf("POZ: %d %d / START: %d / END: %d\n", listPtr->cursorPos, item->cursorPos, + // listPtr->startPos, listPtr->endPos); + if (item->cursorPos != listPtr->cursorPos) + { item->cursorPos = listPtr->cursorPos; DC->feederSelection(item->special, item->cursorPos); + } else { + if (DC->realTime < lastListBoxClickTime && listPtr->doubleClick) + { + Item_RunScript(item, listPtr->doubleClick); + } } + lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY; } return qtrue; } @@ -2717,10 +2943,10 @@ qboolean Item_ListBox_HandleKey(itemDef_t * item, int key, qboolean down, qboole qboolean Item_YesNo_HandleKey(itemDef_t * item, int key) { - + yesnoDef_t *data = (yesnoDef_t*)item->typeData; qboolean ok = qfalse; - //Makro - an item should react on key presses even if the mouse isn't over it + //Makro - an item should react to key presses even if the mouse isn't over it if (item->window.flags & WINDOW_HASFOCUS && item->cvar) { if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) { if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) { @@ -2734,7 +2960,13 @@ qboolean Item_YesNo_HandleKey(itemDef_t * item, int key) } if (ok) { - DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar))); + //Makro - grouped checkboxes? + if (data->groupIndex) + { + DC->setCVar(item->cvar, va("%f", data->activeCvarVal)); + } else { + DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar))); + } return qtrue; } @@ -2804,7 +3036,8 @@ const char *Item_Multi_Setting(itemDef_t * item) } } } - return ""; + //Makro - changed from "" to NULL + return NULL; } qboolean Item_Multi_HandleKey(itemDef_t * item, int key) @@ -3066,6 +3299,7 @@ static void Scroll_ListBox_AutoFunc(void *p) } } +//Makro - vector support static void Scroll_ListBox_ThumbFunc(void *p) { scrollInfo_t *si = (scrollInfo_t *) p; @@ -3074,19 +3308,32 @@ static void Scroll_ListBox_ThumbFunc(void *p) listBoxDef_t *listPtr = (listBoxDef_t *) si->item->typeData; - r.hasVectors = qfalse; + r.hasVectors = si->item->window.rect.hasVectors; + Vector2Copy(si->item->window.rect.u, r.u); + Vector2Copy(si->item->window.rect.v, r.v); + //horizontal if (si->item->window.flags & WINDOW_HORIZONTAL) { - if (DC->cursorx == si->xStart) { + if (DC->cursorx == si->xStart && DC->cursory == si->yStart) { return; } - r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1; - r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_SIZE - 1; - r.h = SCROLLBAR_SIZE; - r.w = si->item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2; - max = Item_ListBox_MaxScroll(si->item); - // - pos = (DC->cursorx - r.x - SCROLLBAR_SIZE / 2) * max / (r.w - SCROLLBAR_SIZE); + max = Item_ListBox_MaxScroll(si->item); + //vectors? + if (r.hasVectors) { + float p[2]; + //Makro - FIXME!!! + Rect_ToInnerCoords(&si->item->window.rect, DC->cursorx, DC->cursory, &p[0], NULL); + p[1] = (p[0] - SCROLLBAR_SIZE / 2 - SCROLLBAR_SIZE - 1) / (si->item->window.rect.w - 3 * SCROLLBAR_SIZE - 2); + pos = (int) (max * p[1]); + //no vectors + } else { + r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1; + r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_SIZE - 1; + r.h = SCROLLBAR_SIZE; + r.w = si->item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2; + // + pos = (DC->cursorx - r.x - SCROLLBAR_SIZE / 2) * max / (r.w - SCROLLBAR_SIZE); + } if (pos < 0) { pos = 0; } else if (pos > max) { @@ -3094,21 +3341,37 @@ static void Scroll_ListBox_ThumbFunc(void *p) } listPtr->startPos = pos; si->xStart = DC->cursorx; - } else if (DC->cursory != si->yStart) { - - r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1; - r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1; - r.h = si->item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2; - r.w = SCROLLBAR_SIZE; + si->yStart = DC->cursory; + //vertical + } else if (DC->cursory != si->yStart || DC->cursorx != si->xStart) { max = Item_ListBox_MaxScroll(si->item); - // - pos = (DC->cursory - r.y - SCROLLBAR_SIZE / 2) * max / (r.h - SCROLLBAR_SIZE); + //vectors? + if (r.hasVectors) { + float p[2]; + Vector2Set(p, DC->cursorx - si->item->window.rect.x, DC->cursory - si->item->window.rect.y); + + //projection + //p[0] = p[0] * si->item->window.rect.v[0] + p[1] * si->item->window.rect.v[1]; + Rect_ToInnerCoords(&si->item->window.rect, DC->cursorx, DC->cursory, NULL, &p[0]); + //0..1 fraction + p[1] = (p[0] - SCROLLBAR_SIZE / 2 - SCROLLBAR_SIZE - 1) / (si->item->window.rect.h - 3 * SCROLLBAR_SIZE - 2); + pos = (int) (max * p[1]); + //no vectors + } else { + r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1; + r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1; + r.h = si->item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2; + r.w = SCROLLBAR_SIZE; + // + pos = (DC->cursory - r.y - SCROLLBAR_SIZE / 2) * max / (r.h - SCROLLBAR_SIZE); + } if (pos < 0) { pos = 0; } else if (pos > max) { pos = max; } listPtr->startPos = pos; + si->xStart = DC->cursorx; si->yStart = DC->cursory; } @@ -3157,6 +3420,7 @@ static void Scroll_Slider_ThumbFunc(void *p) //vectors if (si->item->textRect.hasVectors) { + //Makro - FIXME!!! - use appropriate transformation instead of a simple projection value = (cursorx - x) * si->item->textRect.u[0] + (cursory - y) * si->item->textRect.u[1]; if (value < 0) { value = 0; @@ -3182,8 +3446,11 @@ void Item_StartCapture(itemDef_t * item, int key) int flags; switch (item->type) { + //Makro - not needed, comented out + /* case ITEM_TYPE_EDITFIELD: case ITEM_TYPE_NUMERICFIELD: + */ case ITEM_TYPE_LISTBOX: { @@ -3618,7 +3885,6 @@ void Menus_Activate(menuDef_t * menu) UI_RQ3_SelectPlayerIcon(menu); Display_CloseCinematics(); - } int Display_VisibleMenuCount() @@ -3636,26 +3902,37 @@ int Display_VisibleMenuCount() void Menus_HandleOOBClick(menuDef_t * menu, int key, qboolean down) { - if (menu) { - int i; + //Makro - moved check up here + if (menu && down) { + //int i; // basically the behaviour we are looking for is if there are windows in the stack.. see if // the cursor is within any of them.. if not close them otherwise activate them and pass the // key on.. force a mouse move to activate focus and script stuff - if (down && menu->window.flags & WINDOW_OOB_CLICK) { - Menu_RunCloseScript(menu); - menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); + //Makro - moved check above + if (menu->window.flags & WINDOW_OOB_CLICK) { + if (menu->itemCount > 0) { + Item_RunScript(menu->items[0], menu->onOOBClick); + } + //Makro - if this is a popup window, don't broadcast the event + if (menu->window.flags & WINDOW_POPUP) { + return; + } } + //Makro - disabled for now + /* for (i = 0; i < menuCount; i++) { if (Menu_OverActiveItem(&Menus[i], DC->cursorx, DC->cursory)) { - Menu_RunCloseScript(menu); + //Makro - I really doubt this was supposed to be duplicated here + //Menu_RunCloseScript(menu); menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE); Menus_Activate(&Menus[i]); Menu_HandleMouseMove(&Menus[i], DC->cursorx, DC->cursory); Menu_HandleKey(&Menus[i], key, down); } } + */ if (Display_VisibleMenuCount() == 0) { if (DC->Pause) { @@ -3763,16 +4040,21 @@ void Menu_HandleKey(menuDef_t * menu, int key, qboolean down) inHandler = qfalse; return; } + // see if the mouse is within the window bounds and if so is this a mouse click - if (down && !(menu->window.flags & WINDOW_POPUP) - && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory)) { - static qboolean inHandleKey = qfalse; + //Makro - changed behaviour; popup windows with OOB click set are closed + //without broadcasting the event instead of simply ignoring the OOB + //- removed "!(menu->window.flags & WINDOW_POPUP)" check + if (down && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory)) { + //Makro - commented out + //static qboolean inHandleKey = qfalse; // bk001206 - parentheses - if (!inHandleKey && (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3)) { - inHandleKey = qtrue; + //if (!inHandleKey && (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3)) { + if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3) { + //inHandleKey = qtrue; Menus_HandleOOBClick(menu, key, down); - inHandleKey = qfalse; + //inHandleKey = qfalse; inHandler = qfalse; return; } @@ -3904,6 +4186,33 @@ void Menu_HandleKey(menuDef_t * menu, int key, qboolean down) inHandler = qfalse; } +//Makro - transforms a point to relative co-ordinates +void Rect_ToInnerCoords(rectDef_t *rect, float x, float y, float *resx, float *resy) +{ + if (rect) + { + //Makro - twisted rectangle? + if (rect->hasVectors) + { + float dx = x - rect->x; + float dy = y - rect->y; + float det = rect->u[0] * rect->v[1] - rect->u[1] * rect->v[0]; + if (fabs(det) < 0.001f) { + //degenerate rect + if (resx) *resx = 0; + if (resy) *resy = 0; + return; + } else { + if (resx) *resx = (dx * rect->v[1] - dy * rect->v[0]) / det; + if (resy) *resy = (- dx * rect->u[1] + dy * rect->u[0]) / det; + } + } else { + if (resx) *resx = x - rect->x; + if (resy) *resy = y - rect->y; + } + } +} + void ToWindowCoords(float *x, float *y, windowDef_t * window) { //Makro - vectors @@ -4109,10 +4418,10 @@ void Item_Text_AutoWrapped_Paint(itemDef_t * item) if (item->textRect.hasVectors) { DC->drawAngledText(item->textRect.x, item->textRect.y, item->textRect.u, item->textRect.v, item->textscale, - color, buff, 0, 0, item->textStyle); + color, buff, 0, 0, 0, item->textStyle, qfalse); } else { - DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, - item->textStyle); + DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, 0, + item->textStyle, qfalse); } } if (*p == '\0') { @@ -4171,12 +4480,12 @@ void Item_Text_Wrapped_Paint(itemDef_t * item) while (p && *p) { strncpy(buff, start, p - start + 1); buff[p - start] = '\0'; - DC->drawText(x, y, item->textscale, color, buff, 0, 0, item->textStyle); + DC->drawText(x, y, item->textscale, color, buff, 0, 0, 0, item->textStyle, qfalse); y += height + 5; start += p - start + 1; p = strchr(p + 1, '\r'); } - DC->drawText(x, y, item->textscale, color, start, 0, 0, item->textStyle); + DC->drawText(x, y, item->textscale, color, start, 0, 0, 0, item->textStyle, qfalse); } void Item_Text_Paint(itemDef_t * item) @@ -4246,12 +4555,13 @@ void Item_Text_Paint(itemDef_t * item) if (item->window.rectClient.hasVectors) { DC->drawAngledText(item->textRect.x, item->textRect.y, item->window.rectClient.u, item->window.rectClient.v, - item->textscale, color, textPtr, 0, 0, item->textStyle); + item->textscale, color, textPtr, 0, 0, 0, item->textStyle, (item->window.flags & WINDOW_FORCE_TEXT_COLOR)); //debug //DC->drawAngledRect(item->textRect.x, item->textRect.y, item->textRect.w, item->textRect.h, // item->textRect.u, item->textRect.v, 2, colorYellow, RECT_FULL); } else { - DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, 0, item->textStyle); + DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, 0, 0, item->textStyle, + (item->window.flags & WINDOW_FORCE_TEXT_COLOR)); //debug //DC->drawRect(item->textRect.x, item->textRect.y, item->textRect.w, item->textRect.h, 2, colorYellow); } @@ -4295,17 +4605,28 @@ void Item_TextField_Paint(itemDef_t * item) if (item->window.flags & WINDOW_HASFOCUS && g_editingField) { char cursor = DC->getOverstrikeMode()? '_' : '|'; - DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, - newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset, - cursor, editPtr->maxPaintChars, item->textStyle); + if (item->window.rect.hasVectors) + DC->drawAngledTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, + item->window.rect.u, item->window.rect.v, item->textscale, + newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset, + cursor, editPtr->maxPaintChars, item->textStyle); + else + DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, + newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset, + cursor, editPtr->maxPaintChars, item->textStyle); /* DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset, cursor, maxChars, item->textStyle); */ } else { - DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, - buff + editPtr->paintOffset, 0, editPtr->maxPaintChars, item->textStyle); + if (item->window.rect.hasVectors) + DC->drawAngledText(item->textRect.x + item->textRect.w + offset, item->textRect.y, + item->window.rect.u, item->window.rect.v, item->textscale, newColor, + buff + editPtr->paintOffset, 0, editPtr->maxPaintChars, 0, item->textStyle, qfalse); + else + DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, + buff + editPtr->paintOffset, 0, editPtr->maxPaintChars, 0, item->textStyle, qfalse); /* DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, 0, maxChars, item->textStyle); @@ -4314,13 +4635,24 @@ void Item_TextField_Paint(itemDef_t * item) } + + + +#define YESNO_MARK_FADETIME 150 + +//Makro - heavily modified void Item_YesNo_Paint(itemDef_t * item) { vec4_t newColor, lowLight; float value; menuDef_t *parent = (menuDef_t *) item->parent; + //Makro - added to simplify the rendering + float p[2]; + const char *text; + qboolean on = qfalse; + yesnoDef_t *data = (yesnoDef_t*)item->typeData; - value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0; + //value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0; if (item->window.flags & WINDOW_HASFOCUS) { //Makro - changed to fade from normal text color to focus color @@ -4334,21 +4666,102 @@ void Item_YesNo_Paint(itemDef_t * item) memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); } + value = DC->getCVarValue(item->cvar); + //Makro - grouped checkboxes? + if (data->groupIndex) + { + on = (value == data->activeCvarVal); + } else { + on = (value != 0); + } + text = (on) ? "Yes" : "No"; + if (item->text) { Item_Text_Paint(item); - DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, - (value != 0) ? "Yes" : "No", 0, 0, item->textStyle); + } + + if (data->kind == YESNO_TEXT) + { + Vector2Set(p, item->textRect.x, item->textRect.y); + if (item->window.rect.hasVectors) + { + if (item->text) + Vector2MA(p, item->textRect.w + 8, item->window.rect.u, p); + + DC->drawAngledText(p[0], p[1], item->window.rect.u, item->window.rect.v, + item->textscale, newColor, text, 0, 0, 0, item->textStyle, qfalse); + } else { + if (item->text) + p[0] += item->textRect.w + 8; + DC->drawText(p[0], p[1], item->textscale, newColor, text, + 0, 0, 0, item->textStyle, qfalse); + } } else { - DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "Yes" : "No", - 0, 0, item->textStyle); + qhandle_t front, back; + float imgColor[4] = {1, 1, 1, 1}; + + if (on != data->wasActive) + data->lastChangeTime = DC->realTime; + data->wasActive = on; + + if (on) + { + front = DC->Assets.checkBox1; + back = DC->Assets.checkBox0; + } else { + front = DC->Assets.checkBox0; + back = DC->Assets.checkBox1; + } + + if (DC->realTime - data->lastChangeTime < YESNO_MARK_FADETIME) + { + imgColor[3] = (float) (DC->realTime - data->lastChangeTime) / YESNO_MARK_FADETIME; + } + + //compute drawing position + if (data->kind == YESNO_ICON_LEFT) + { + if (item->window.rect.hasVectors) + { + Vector2Set(p, item->textRect.x, item->textRect.y); + Vector2MA(p, -item->textRect.h + 0.5f * (item->textRect.h - SCROLLBAR_SIZE), item->window.rect.v, p); + Vector2MA(p, - SCROLLBAR_SIZE - 8, item->window.rect.u, p); + } else { + Vector2Set(p, item->textRect.x - (SCROLLBAR_SIZE + 8), + item->textRect.y - item->textRect.h + 0.5f * (item->textRect.h - SCROLLBAR_SIZE)); + } + } else { + if (item->window.rect.hasVectors) + { + Vector2Set(p, item->textRect.x, item->textRect.y); + Vector2MA(p, -item->textRect.h + 0.5f * (item->textRect.h - SCROLLBAR_SIZE), item->window.rect.v, p); + Vector2MA(p, item->textRect.w + 8, item->window.rect.u, p); + } else { + Vector2Set(p, item->textRect.x + item->textRect.w + 8, + item->textRect.y - item->textRect.h + 0.5f * (item->textRect.h - SCROLLBAR_SIZE)); + } + } + + if (item->window.rect.hasVectors) + { + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + imgColor, 0, 0, 1, 1, front); + imgColor[3] = 1.0f - imgColor[3]; + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + imgColor, 0, 0, 1, 1, back); + } else { + DC->drawHandlePic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + (on) ? DC->Assets.checkBox1 : DC->Assets.checkBox0); + } } } void Item_Multi_Paint(itemDef_t * item) { vec4_t newColor, lowLight; - const char *text = ""; + const char *text; menuDef_t *parent = (menuDef_t *) item->parent; + float x; if (item->window.flags & WINDOW_HASFOCUS) { //Makro - changed to fade from normal text color to focus color @@ -4363,14 +4776,25 @@ void Item_Multi_Paint(itemDef_t * item) } text = Item_Multi_Setting(item); - - if (item->text) { + //Makro - added check + if (!text) + text = ""; + + x = item->textRect.x; + if (item->text) + { Item_Text_Paint(item); - DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, text, - 0, 0, item->textStyle); + x += item->textRect.w + 8; + } + //Makro - vectors? + if (item->window.rect.hasVectors) + { + DC->drawAngledText(x, item->textRect.y, + item->window.rect.u, item->window.rect.v, item->textscale, newColor, text, + 0, 0, 0, item->textStyle, qfalse); } else { - DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, text, 0, 0, - item->textStyle); + DC->drawText(x, item->textRect.y, item->textscale, newColor, text, + 0, 0, 0, item->textStyle, qfalse); } } @@ -4628,12 +5052,12 @@ void BindingFromName(const char *cvar) return; } } - strcpy(g_nameBind1, "???"); + strcpy(g_nameBind1, "[ not assigned ]"); } void Item_Slider_Paint(itemDef_t * item) { - vec4_t newColor, lowLight; + vec4_t newColor; float x, y, value; menuDef_t *parent = (menuDef_t *) item->parent; Point pt; @@ -4646,10 +5070,13 @@ void Item_Slider_Paint(itemDef_t * item) //lowLight[1] = 0.8 * parent->focusColor[1]; //lowLight[2] = 0.8 * parent->focusColor[2]; //lowLight[3] = 0.8 * parent->focusColor[3]; - memcpy(lowLight, &item->window.foreColor, sizeof(vec4_t)); - LerpColor(parent->focusColor, lowLight, newColor, 0.5 + 0.5 * sin(DC->realTime / PULSE_DIVISOR)); + //Makro - changed again, this time from focus color to white + LerpColor(colorWhite, parent->focusColor, newColor, 0.5 + 0.5 * sin(DC->realTime / PULSE_DIVISOR)); } else { - memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); + //Makro - slider should be painted in white when not focused + //this is so we can have visibile sliders with black text + //memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t)); + memcpy(newColor, colorWhite, sizeof(vec4_t)); } if (item->text) { @@ -4668,17 +5095,18 @@ void Item_Slider_Paint(itemDef_t * item) x = item->window.rect.x; y = item->window.rect.y; } - DC->setColor(newColor); + //paint the slider if (item->textRect.hasVectors) { DC->drawAngledPic(x, y, SLIDER_WIDTH, SLIDER_HEIGHT, item->textRect.u, item->textRect.v, - newColor, 0, 0, 1, 1, DC->Assets.sliderBar); + colorWhite, 0, 0, 1, 1, DC->Assets.sliderBar); } else { + DC->setColor(colorWhite); DC->drawHandlePic(x, y, SLIDER_WIDTH, SLIDER_HEIGHT, DC->Assets.sliderBar); } - //paint the slider pt = Item_Slider_ThumbPosition(item); + //paint the thumb if (item->textRect.hasVectors) { float srx = pt.x - (SLIDER_THUMB_WIDTH / 2) * item->textRect.u[0]; @@ -4687,6 +5115,7 @@ void Item_Slider_Paint(itemDef_t * item) newColor, 0, 0, 1, 1, DC->Assets.sliderThumb); } else { pt.x -= (SLIDER_THUMB_WIDTH / 2); + DC->setColor(newColor); DC->drawHandlePic(pt.x, pt.y, SLIDER_THUMB_WIDTH, SLIDER_THUMB_HEIGHT, DC->Assets.sliderThumb); } } @@ -4728,11 +5157,20 @@ void Item_Bind_Paint(itemDef_t * item) if (item->text) { Item_Text_Paint(item); BindingFromName(item->cvar); - DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, - g_nameBind1, 0, maxChars, item->textStyle); + //Makro - vectors + if (item->window.rect.hasVectors) + { + DC->drawAngledText(item->textRect.x + (item->textRect.w + 8) * item->window.rect.u[0], + item->textRect.y + (item->textRect.w + 8) * item->window.rect.u[1], + item->window.rect.u, item->window.rect.v, item->textscale, newColor, + g_nameBind1, 0, maxChars, 0, item->textStyle, qfalse); + } else { + DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, + g_nameBind1, 0, maxChars, 0, item->textStyle, qfalse); + } } else { DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, - (value != 0) ? "FIXME" : "FIXME", 0, maxChars, item->textStyle); + (value != 0) ? "FIXME" : "FIXME", 0, maxChars, 0, item->textStyle, qfalse); } } @@ -4878,10 +5316,12 @@ void Item_Model_Paint(itemDef_t * item) memset(&refdef, 0, sizeof(refdef)); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear(refdef.viewaxis); - x = item->window.rect.x + 1; - y = item->window.rect.y + 1; - w = item->window.rect.w - 2; - h = item->window.rect.h - 2; + //Makro - removed +1 / -2 offsets + //this way, clipping is done exactly at the specifiend co-ordinates + x = item->window.rect.x; //+1 + y = item->window.rect.y; //+1 + w = item->window.rect.w; //-2 + h = item->window.rect.h; //-2 AdjustFrom640(&x, &y, &w, &h); @@ -4966,6 +5406,7 @@ void Item_Image_Paint(itemDef_t * item) item->window.rect.h - 2, item->asset); } +//Makro - added vector support void Item_ListBox_Paint(itemDef_t * item) { float x, y, size, count, i, thumb; @@ -4979,77 +5420,288 @@ void Item_ListBox_Paint(itemDef_t * item) // there is no clipping available so only the last completely visible item is painted count = DC->feederCount(item->special); // default is vertical if horizontal flag is not here + + //Makro - added just in case + DC->setColor(colorWhite); + + + // HORIZONTAL // + if (item->window.flags & WINDOW_HORIZONTAL) { - // draw scrollbar in bottom of the window - // bar - x = item->window.rect.x + 1; - y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE - 1; - DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft); - x += SCROLLBAR_SIZE - 1; - size = item->window.rect.w - (SCROLLBAR_SIZE * 2); - DC->drawHandlePic(x, y, size + 1, SCROLLBAR_SIZE, DC->Assets.scrollBar); - x += size - 1; - DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight); - // thumb - thumb = Item_ListBox_ThumbDrawPosition(item); //Item_ListBox_ThumbPosition(item); - if (thumb > x - SCROLLBAR_SIZE - 1) { - thumb = x - SCROLLBAR_SIZE - 1; + //vectors? + if (item->window.rect.hasVectors) { + float p[2]; + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, 1, item->window.rect.u, p); + Vector2MA(p, item->window.rect.h - SCROLLBAR_SIZE - 1, item->window.rect.v, p); + // draw scrollbar in bottom of the window + // bar + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_LEFTARROW) + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0, 0, 1, 1, + DC->Assets.scrollBarArrowLeft2); + else + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0, 0, 1, 1, + DC->Assets.scrollBarArrowLeft); + Vector2MA(p, SCROLLBAR_SIZE - 1, item->window.rect.u, p); + size = item->window.rect.w - (SCROLLBAR_SIZE * 4); + //start + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0, 0, 0.25f, 1, + DC->Assets.scrollBarH); + Vector2MA(p, SCROLLBAR_SIZE, item->window.rect.u, p); + //middle + DC->drawAngledPic(p[0], p[1], size, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0.25f, 0, 0.75f, 1, + DC->Assets.scrollBarH); + Vector2MA(p, size, item->window.rect.u, p); + //end + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0.75f, 0, 1, 1, + DC->Assets.scrollBarH); + Vector2MA(p, SCROLLBAR_SIZE, item->window.rect.u, p); + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_RIGHTARROW) + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0, 0, 1, 1, + DC->Assets.scrollBarArrowRight2); + else + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, item->window.foreColor, 0, 0, 1, 1, + DC->Assets.scrollBarArrowRight); + // thumb + thumb = Item_ListBox_ThumbDrawPosition(item); //Item_ListBox_ThumbPosition(item); + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.h - SCROLLBAR_SIZE - 1, item->window.rect.v, p); + Vector2MA(p, thumb - item->window.rect.x, item->window.rect.u, p); + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + item->window.foreColor, 0, 0, 1, 1, DC->Assets.scrollBarThumb); + //no vectors? + } else { + // draw scrollbar in bottom of the window + // bar + x = item->window.rect.x + 1; + y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE - 1; + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_LEFTARROW) + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft2); + else + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft); + x += SCROLLBAR_SIZE - 1; + size = item->window.rect.w - (SCROLLBAR_SIZE * 4); + //start + DC->drawStretchPic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, 0, 0, 0.25f, 1, DC->Assets.scrollBarH, qtrue); + x += SCROLLBAR_SIZE; + //middle + DC->drawStretchPic(x, y, size, SCROLLBAR_SIZE, 0.25f, 0, 0.75f, 1, DC->Assets.scrollBarH, qtrue); + x += size; + //start + DC->drawStretchPic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, 0.75f, 0, 1, 1, DC->Assets.scrollBarH, qtrue); + x += SCROLLBAR_SIZE; + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_RIGHTARROW) + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight2); + else + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight); + // thumb + thumb = Item_ListBox_ThumbDrawPosition(item); //Item_ListBox_ThumbPosition(item); + if (thumb > x - SCROLLBAR_SIZE - 1) { + thumb = x - SCROLLBAR_SIZE - 1; + } + DC->drawHandlePic(thumb, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb); } - DC->drawHandlePic(thumb, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb); // listPtr->endPos = listPtr->startPos; size = item->window.rect.w - 2; // items // size contains max available space if (listPtr->elementStyle == LISTBOX_IMAGE) { - // fit = 0; - x = item->window.rect.x + 1; - y = item->window.rect.y + 1; - for (i = listPtr->startPos; i < count; i++) { - // always draw at least one - // which may overdraw the box if it is too small for the element - image = DC->feederItemImage(item->special, i); - if (image) { - DC->drawHandlePic(x + 1, y + 1, listPtr->elementWidth - 2, - listPtr->elementHeight - 2, image); - } + //vectors? + if (item->window.rect.hasVectors) + { + float p[2]; + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, 1, item->window.rect.u, p); + Vector2MA(p, 1, item->window.rect.v, p); + for (i = listPtr->startPos; i < count; i++) { + // always draw at least one + // which may overdraw the box if it is too small for the element + image = DC->feederItemImage(item->special, i); - if (i == item->cursorPos) { - DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, - item->window.borderSize, item->window.borderColor); + //Makro - added background + if (i == item->cursorPos) { + DC->drawAngledPic(p[0], p[1], listPtr->elementWidth - 2, + listPtr->elementHeight - 2, item->window.rect.u, item->window.rect.v, + item->window.outlineColor, 0, 0, 1, 1, DC->whiteShader); + //Makro - add a render point here; hackish, but it gets things done + if (DC->pendingPolys) + { + UI_Render2DScene(); + } + } + + if (image) { + DC->drawAngledPic(p[0], p[1], listPtr->elementWidth - 2, + listPtr->elementHeight - 2, item->window.rect.u, item->window.rect.v, + item->window.foreColor, 0, 0, 1, 1, image); + } + + if (i == item->cursorPos) { + //Makro - add a render point here; hackish, but it gets things done + if (DC->pendingPolys) + { + UI_Render2DScene(); + } + DC->drawAngledRect(p[0], p[1], listPtr->elementWidth - 1, listPtr->elementHeight - 1, + item->window.rect.u, item->window.rect.v, + item->window.borderSize, item->window.borderColor, RECT_FULL, DC->whiteShader); + } + + size -= listPtr->elementWidth; + if (size < listPtr->elementWidth) { + listPtr->drawPadding = size; //listPtr->elementWidth - size; + break; + } + Vector2MA(p, listPtr->elementWidth, item->window.rect.u, p); + listPtr->endPos++; + // fit++; } + //no vectors + } else { + // fit = 0; + x = item->window.rect.x + 1; + y = item->window.rect.y + 1; + for (i = listPtr->startPos; i < count; i++) { + // always draw at least one + // which may overdraw the box if it is too small for the element + //Makro - added background + if (i == item->cursorPos) + { + DC->setColor(item->window.outlineColor); + DC->drawHandlePic(x + 1, y + 1, listPtr->elementWidth - 2, + listPtr->elementHeight - 2, DC->whiteShader); + DC->setColor(item->window.foreColor); + } - size -= listPtr->elementWidth; - if (size < listPtr->elementWidth) { - listPtr->drawPadding = size; //listPtr->elementWidth - size; - break; + image = DC->feederItemImage(item->special, i); + if (image) { + DC->drawHandlePic(x + 1, y + 1, listPtr->elementWidth - 2, + listPtr->elementHeight - 2, image); + } + + if (i == item->cursorPos) { + //Makro - added shader parm + DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, + item->window.borderSize, item->window.borderColor, DC->whiteShader); + } + + size -= listPtr->elementWidth; + if (size < listPtr->elementWidth) { + listPtr->drawPadding = size; //listPtr->elementWidth - size; + break; + } + x += listPtr->elementWidth; + listPtr->endPos++; + // fit++; } - x += listPtr->elementWidth; - listPtr->endPos++; - // fit++; } } else { // } + + + // VERTICAL // + + } else { - // draw scrollbar to right side of the window - x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1; - y = item->window.rect.y + 1; - DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp); - y += SCROLLBAR_SIZE - 1; + //vectors? + if (item->window.rect.hasVectors) { + float p[2]; + // draw scrollbar to right side of the window + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE - 1, item->window.rect.u, p); + Vector2MA(p, 1, item->window.rect.v, p); + + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_LEFTARROW) + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, colorWhite, 0, 0, 1, 1, DC->Assets.scrollBarArrowUp2); + else + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, + item->window.rect.u, item->window.rect.v, colorWhite, 0, 0, 1, 1, DC->Assets.scrollBarArrowUp); + + Vector2MA(p, SCROLLBAR_SIZE - 1, item->window.rect.v, p); + - listPtr->endPos = listPtr->startPos; - size = item->window.rect.h - (SCROLLBAR_SIZE * 2); - DC->drawHandlePic(x, y, SCROLLBAR_SIZE, size + 1, DC->Assets.scrollBar); - y += size - 1; - DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown); - // thumb - thumb = Item_ListBox_ThumbDrawPosition(item); //Item_ListBox_ThumbPosition(item); - if (thumb > y - SCROLLBAR_SIZE - 1) { - thumb = y - SCROLLBAR_SIZE - 1; + listPtr->endPos = listPtr->startPos; + size = item->window.rect.h - (SCROLLBAR_SIZE * 4); + + //start + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + colorWhite, 0, 0, 1, 0.25f, DC->Assets.scrollBarV); + //middle + Vector2MA(p, SCROLLBAR_SIZE, item->window.rect.v, p); + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, size, item->window.rect.u, item->window.rect.v, + colorWhite, 0, 0.25f, 1, 0.75f, DC->Assets.scrollBarV); + //end + Vector2MA(p, size, item->window.rect.v, p); + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + colorWhite, 0, 0.75f, 1, 1, DC->Assets.scrollBarV); + Vector2MA(p, SCROLLBAR_SIZE, item->window.rect.v, p); + + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_RIGHTARROW) + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + colorWhite, 0, 0, 1, 1, DC->Assets.scrollBarArrowDown2); + else + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + colorWhite, 0, 0, 1, 1, DC->Assets.scrollBarArrowDown); + + // thumb + thumb = Item_ListBox_ThumbDrawPosition(item); //Item_ListBox_ThumbPosition(item); + Vector2Set(p, item->window.rect.x, item->window.rect.y); + Vector2MA(p, item->window.rect.w - SCROLLBAR_SIZE - 1, item->window.rect.u, p); + Vector2MA(p, thumb - item->window.rect.y, item->window.rect.v, p); + DC->drawAngledPic(p[0], p[1], SCROLLBAR_SIZE, SCROLLBAR_SIZE, item->window.rect.u, item->window.rect.v, + colorWhite, 0, 0, 1, 1, DC->Assets.scrollBarThumb); + //no vectors? + } else { + // draw scrollbar to right side of the window + x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1; + y = item->window.rect.y + 1; + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_LEFTARROW) + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp2); + else + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp); + y += SCROLLBAR_SIZE - 1; + + listPtr->endPos = listPtr->startPos; + size = item->window.rect.h - (SCROLLBAR_SIZE * 4); + //start + DC->drawStretchPic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, 0, 0, 1, 0.25f, DC->Assets.scrollBarV, qtrue); + y += SCROLLBAR_SIZE; + //middle + DC->drawStretchPic(x, y, SCROLLBAR_SIZE, size, 0, 0.25f, 1, 0.75f, DC->Assets.scrollBarV, qtrue); + y += size; + //end + DC->drawStretchPic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, 0, 0.75f, 1, 1, DC->Assets.scrollBarV, qtrue); + y += SCROLLBAR_SIZE; + + //clicked? + if (itemCapture == item && item->window.flags & WINDOW_LB_RIGHTARROW) + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown2); + else + DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown); + // thumb + thumb = Item_ListBox_ThumbDrawPosition(item); //Item_ListBox_ThumbPosition(item); + if (thumb > y - SCROLLBAR_SIZE - 1) { + thumb = y - SCROLLBAR_SIZE - 1; + } + DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb); } - DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb); - // adjust size for item painting size = item->window.rect.h - 2; if (listPtr->elementStyle == LISTBOX_IMAGE) { @@ -5066,8 +5718,9 @@ void Item_ListBox_Paint(itemDef_t * item) } if (i == item->cursorPos) { + //Makro - added shader parm DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, - item->window.borderSize, item->window.borderColor); + item->window.borderSize, item->window.borderColor, DC->whiteShader); } listPtr->endPos++; @@ -5094,15 +5747,29 @@ void Item_ListBox_Paint(itemDef_t * item) for (j = 0; j < listPtr->numColumns; j++) { text = DC->feederItemText(item->special, i, j, &optionalImage); if (optionalImage >= 0) { + //TODO: vectors DC->drawHandlePic(x + 4 + listPtr->columnInfo[j].pos, y - 1 + listPtr->elementHeight / 2, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage); } else if (text) { - DC->drawText(x + 4 + listPtr->columnInfo[j].pos, - y + listPtr->elementHeight, item->textscale, - item->window.foreColor, text, 0, - listPtr->columnInfo[j].maxChars, item->textStyle); + if (item->window.rect.hasVectors) { + float p[2]; + Vector2Set(p, x, y); + Vector2MA(p, 4 + listPtr->columnInfo[j].pos, item->window.rectClient.u, p); + Vector2MA(p, listPtr->elementHeight, item->window.rectClient.v, p); + DC->drawAngledText(p[0], p[1], + item->window.rectClient.u, item->window.rectClient.v, item->textscale, + item->window.foreColor, text, 0, + listPtr->columnInfo[j].maxChars, listPtr->columnInfo[j].width, + item->textStyle, (item->window.flags & WINDOW_FORCE_TEXT_COLOR)); + } else { + DC->drawText(x + 4 + listPtr->columnInfo[j].pos, + y + listPtr->elementHeight, item->textscale, + item->window.foreColor, text, 0, + listPtr->columnInfo[j].maxChars, listPtr->columnInfo[j].width, + item->textStyle, (item->window.flags & WINDOW_FORCE_TEXT_COLOR)); + } } } } else { @@ -5110,14 +5777,38 @@ void Item_ListBox_Paint(itemDef_t * item) if (optionalImage >= 0) { //DC->drawHandlePic(x + 4 + listPtr->elementHeight, y, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage); } else if (text) { - DC->drawText(x + 4, y + listPtr->elementHeight, item->textscale, - item->window.foreColor, text, 0, 0, item->textStyle); + //vectors? + if (item->window.rect.hasVectors) { + float p[2]; + Vector2Set(p, x, y); + Vector2MA(p, 4, item->window.rectClient.u, p); + Vector2MA(p, listPtr->elementHeight, item->window.rectClient.v, p); + DC->drawAngledText(p[0], p[1], + item->window.rectClient.u, item->window.rectClient.v, item->textscale, + item->window.foreColor, text, 0, 0, 0, item->textStyle, qfalse); + } else { + DC->drawText(x + 4, y + listPtr->elementHeight, item->textscale, + item->window.foreColor, text, 0, 0, 0, item->textStyle, qfalse); + } } } + //selected item? if (i == item->cursorPos) { - DC->fillRect(x + 2, y + 2, item->window.rect.w - SCROLLBAR_SIZE - 4, - listPtr->elementHeight, item->window.outlineColor); + //vectors? + if (item->window.rect.hasVectors) { + float p[2]; + Vector2Set(p, x, y); + Vector2MA(p, 2, item->window.rectClient.u, p); + Vector2MA(p, 2, item->window.rectClient.v, p); + DC->drawAngledPic(p[0], p[1], + item->window.rect.w - SCROLLBAR_SIZE - 4, listPtr->elementHeight, + item->window.rectClient.u, item->window.rectClient.v, + item->window.outlineColor, 0, 0, 1, 1, DC->whiteShader); + } else { + DC->fillRect(x + 2, y + 2, item->window.rect.w - SCROLLBAR_SIZE - 4, + listPtr->elementHeight, item->window.outlineColor); + } } size -= listPtr->elementHeight; @@ -5126,7 +5817,13 @@ void Item_ListBox_Paint(itemDef_t * item) break; } listPtr->endPos++; - y += listPtr->elementHeight; + //vectors? + if (item->window.rect.hasVectors) { + x += listPtr->elementHeight * item->window.rect.v[0]; + y += listPtr->elementHeight * item->window.rect.v[1]; + } else { + y += listPtr->elementHeight; + } // fit++; } } @@ -5390,7 +6087,8 @@ void Item_Paint(itemDef_t * item) color[1] = color[3] = 1; color[0] = color[2] = 0; - DC->drawRect(r->x, r->y, r->w, r->h, 1, color); + //Makro - added shader parm + DC->drawRect(r->x, r->y, r->w, r->h, 1, color, DC->whiteShader); } //DC->drawRect(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, 1, red); @@ -5532,7 +6230,8 @@ qboolean Menus_AnyFullScreenVisible() return qfalse; } -menuDef_t *Menus_ActivateByName(const char *p) +//Makro - added second parameter +menuDef_t *Menus_ActivateByName(const char *p, qboolean special) { int i; menuDef_t *m = NULL; @@ -5540,10 +6239,33 @@ menuDef_t *Menus_ActivateByName(const char *p) for (i = 0; i < menuCount; i++) { if (Q_stricmp(Menus[i].window.name, p) == 0) { + int j; + qboolean alreadyActive = qfalse; + m = &Menus[i]; Menus_Activate(m); - if (openMenuCount < MAX_OPEN_MENUS && focus != NULL) { - menuStack[openMenuCount++] = focus; + + //Makro - if special is true, run onOpenSpecial + if (special && m->onOpenSpecial && m->itemCount > 0) + Item_RunScript(m->items[0], m->onOpenSpecial); + + //Makro - this code didn't do anything useful + //if (openMenuCount < MAX_OPEN_MENUS && focus != NULL) { + // menuStack[openMenuCount++] = focus; + + for (j = 0; j < openMenuCount; j++) { + if (menuStack[j] == m) { + alreadyActive = qtrue; + //move to the top of the stack + if (j != openMenuCount - 1) { + menuStack[j] = menuStack[openMenuCount-1]; + menuStack[openMenuCount-1] = m; + } + break; + } + } + if (!alreadyActive && openMenuCount < MAX_OPEN_MENUS) { + menuStack[openMenuCount++] = m; } } else { Menus[i].window.flags &= ~WINDOW_HASFOCUS; @@ -5604,6 +6326,11 @@ void Menu_HandleMouseMove(menuDef_t * menu, float x, float y) continue; } + if (menu->items[i]->type == ITEM_TYPE_LISTBOX) { + rectDef_t *r = &menu->items[i]->window.rect; + //Com_Printf("Listbox: %d\n", r->hasVectors); + //DC->drawAngledPic(r->x, r->y, r->w, r->h, r->u, r->v, colorYellow, 0, 0, 1, 1, DC->whiteShader); + } if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) { if (pass == 1) { overItem = menu->items[i]; @@ -5623,10 +6350,16 @@ void Menu_HandleMouseMove(menuDef_t * menu, float x, float y) focusSet = Item_SetFocus(overItem, x, y); } } + if (menu->items[i]->type == ITEM_TYPE_LISTBOX) { + //Com_Printf("Listbox: %.1f %.1f %.1f %.1f / %.1f %.1f %.1f %.1f / %d %d %d IN\n", PRINT_RECT(menu->items[i]->window.rect), menu->items[i]->window.rectClient.u[0], menu->items[i]->window.rectClient.u[1], menu->items[i]->window.rectClient.v[0], menu->items[i]->window.rectClient.v[1], menu->items[i]->window.rectClient.hasVectors, DC->cursorx, DC->cursory); + } } } else if (menu->items[i]->window.flags & WINDOW_MOUSEOVER) { Item_MouseLeave(menu->items[i]); Item_SetMouseOver(menu->items[i], qfalse); + if (menu->items[i]->type == ITEM_TYPE_LISTBOX) { + //Com_Printf("Listbox: %.1f %.1f %.1f %.1f / %.1f %.1f %.1f %.1f / %d %d %d OUT\n", PRINT_RECT(menu->items[i]->window.rect), menu->items[i]->window.rectClient.u[0], menu->items[i]->window.rectClient.u[1], menu->items[i]->window.rectClient.v[0], menu->items[i]->window.rectClient.v[1], menu->items[i]->window.rect.hasVectors, DC->cursorx, DC->cursory); + } } } } @@ -5735,8 +6468,8 @@ void Menu_Paint(menuDef_t * menu, qboolean forcePaint) menu->window.flags |= WINDOW_FORCED; } //Makro - kinda hackish; oh well... - if (UI_NeedToUpdateModel()) - UI_RQ3_SelectPlayerIcon(menu); + //if (UI_NeedToUpdateModel()) + //UI_RQ3_SelectPlayerIcon(menu); //Makro - see if we have any onShow script if (!(menu->shown)) { //If it's the first time a menu is shown, look for a onFirstShow script @@ -5783,8 +6516,9 @@ void Menu_Paint(menuDef_t * menu, qboolean forcePaint) color[0] = color[2] = color[3] = 1; color[1] = 0; + //Makro - added shader parm DC->drawRect(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, 1, - color); + color, DC->whiteShader); } } @@ -5802,8 +6536,9 @@ void Item_ValidateTypeData(itemDef_t * item) if (item->type == ITEM_TYPE_LISTBOX) { item->typeData = UI_Alloc(sizeof(listBoxDef_t)); memset(item->typeData, 0, sizeof(listBoxDef_t)); + //Makro - moved YES/NO items out of here } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD - || item->type == ITEM_TYPE_YESNO || item->type == ITEM_TYPE_BIND || item->type == ITEM_TYPE_SLIDER + || item->type == ITEM_TYPE_BIND || item->type == ITEM_TYPE_SLIDER || item->type == ITEM_TYPE_TEXT) { item->typeData = UI_Alloc(sizeof(editFieldDef_t)); memset(item->typeData, 0, sizeof(editFieldDef_t)); @@ -5816,6 +6551,9 @@ void Item_ValidateTypeData(itemDef_t * item) item->typeData = UI_Alloc(sizeof(multiDef_t)); } else if (item->type == ITEM_TYPE_MODEL) { item->typeData = UI_Alloc(sizeof(modelDef_t)); + //Makro - special code for YES/NO items + } else if (item->type == ITEM_TYPE_YESNO) { + item->typeData = UI_Alloc(sizeof(yesnoDef_t)); } } @@ -6269,6 +7007,13 @@ qboolean ItemParse_model_angles(itemDef_t * item, int handle) return qfalse; } +//Makro - forced text color +qboolean ItemParse_forceTextColor(itemDef_t * item, int handle) +{ + item->window.flags |= WINDOW_FORCE_TEXT_COLOR; + return qtrue; +} + qboolean ItemParse_renderpoint(itemDef_t * item, int handle) { item->window.flags |= WINDOW_RENDERPOINT; @@ -6710,7 +7455,8 @@ qboolean ItemParse_cvar(itemDef_t * item, int handle) if (!PC_String_Parse(handle, &item->cvar)) { return qfalse; } - if (item->typeData) { + //Makro - not for yes/no items + if (item->typeData && item->type != ITEM_TYPE_YESNO) { editPtr = (editFieldDef_t *) item->typeData; editPtr->minVal = -1; editPtr->maxVal = -1; @@ -6719,6 +7465,37 @@ qboolean ItemParse_cvar(itemDef_t * item, int handle) return qtrue; } + +//Makro - for grouped checkboxes +qboolean ItemParse_groupIndex(itemDef_t * item, int handle) +{ + yesnoDef_t *data = (yesnoDef_t*)item->typeData; + if (!PC_Int_Parse(handle, &data->groupIndex)) { + return qfalse; + } + return qtrue; +} + +qboolean ItemParse_activeCvarValue(itemDef_t * item, int handle) +{ + yesnoDef_t *data = (yesnoDef_t*)item->typeData; + if (!PC_Float_Parse(handle, &data->activeCvarVal)) { + return qfalse; + } + return qtrue; +} + +qboolean ItemParse_kind(itemDef_t * item, int handle) +{ + yesnoDef_t *data = (yesnoDef_t*)item->typeData; + if (!PC_Int_Parse(handle, &data->kind)) { + return qfalse; + } + return qtrue; +} + +// + qboolean ItemParse_maxChars(itemDef_t * item, int handle) { editFieldDef_t *editPtr; @@ -6949,6 +7726,8 @@ keywordHash_t itemParseKeywords[] = { {"rect", ItemParse_rect, NULL}, //Makro - ugliest hack ever... by far {"renderpoint", ItemParse_renderpoint, NULL}, + //Makro - forced text color + {"forceTextColor", ItemParse_forceTextColor, NULL}, //Makro - angled items {"alignrect", ItemParse_alignrect, NULL}, {"adjustrect", ItemParse_adjustrect, NULL}, @@ -6996,6 +7775,12 @@ keywordHash_t itemParseKeywords[] = { {"action", ItemParse_action, NULL}, {"special", ItemParse_special, NULL}, {"cvar", ItemParse_cvar, NULL}, + + //Makro - for checkboxes + {"groupIndex", ItemParse_groupIndex, NULL}, + {"activeCvarValue", ItemParse_activeCvarValue, NULL}, + {"kind", ItemParse_kind, NULL}, + {"maxChars", ItemParse_maxChars, NULL}, {"maxPaintChars", ItemParse_maxPaintChars, NULL}, {"focusSound", ItemParse_focusSound, NULL}, @@ -7277,6 +8062,29 @@ qboolean MenuParse_onFirstShow(itemDef_t * item, int handle) return qtrue; } +//Makro - executed when the item is shown with openSpecial +qboolean MenuParse_onOpenSpecial(itemDef_t * item, int handle) +{ + menuDef_t *menu = (menuDef_t *) item; + + if (!PC_Script_Parse(handle, &menu->onOpenSpecial)) { + return qfalse; + } + return qtrue; +} + +//Makro - executed when the user clicks outside the active area +qboolean MenuParse_onOOBClick(itemDef_t * item, int handle) +{ + menuDef_t *menu = (menuDef_t *) item; + + if (!PC_Script_Parse(handle, &menu->onOOBClick)) { + return qfalse; + } + menu->window.flags |= WINDOW_OOB_CLICK; + return qtrue; +} + //Makro - executed in addition to the item script qboolean MenuParse_onTimerShow(itemDef_t * item, int handle) { @@ -7533,6 +8341,8 @@ qboolean MenuParse_popup(itemDef_t * item, int handle) return qtrue; } +//Makro - obsolete +/* qboolean MenuParse_outOfBounds(itemDef_t * item, int handle) { menuDef_t *menu = (menuDef_t *) item; @@ -7540,7 +8350,7 @@ qboolean MenuParse_outOfBounds(itemDef_t * item, int handle) menu->window.flags |= WINDOW_OOB_CLICK; return qtrue; } - +*/ qboolean MenuParse_soundLoop(itemDef_t * item, int handle) { menuDef_t *menu = (menuDef_t *) item; @@ -7628,6 +8438,11 @@ keywordHash_t menuParseKeywords[] = { //Makro - executed when the menu is shown {"onShow", MenuParse_onShow, NULL}, {"onFirstShow", MenuParse_onFirstShow, NULL}, + //Makro - executed when the user clicks outside the active area + {"onOOBClick", MenuParse_onOOBClick, NULL}, + //Makro - executed when the menu is shown with showSpecial + {"onOpenSpecial", MenuParse_onOpenSpecial, NULL}, + {"onShowSpecial", MenuParse_onOpenSpecial, NULL}, {"onClose", MenuParse_onClose, NULL}, {"onESC", MenuParse_onESC, NULL}, //Makro - executed when all the items in a timed sequence have been shown @@ -7655,7 +8470,8 @@ keywordHash_t menuParseKeywords[] = { {"background", MenuParse_background, NULL}, {"ownerdraw", MenuParse_ownerdraw, NULL}, {"ownerdrawFlag", MenuParse_ownerdrawFlag, NULL}, - {"outOfBoundsClick", MenuParse_outOfBounds, NULL}, + //Makro - obsolete + //{"outOfBoundsClick", MenuParse_outOfBounds, NULL}, {"soundLoop", MenuParse_soundLoop, NULL}, //Makro - support for music with intro {"soundIntro", MenuParse_soundIntro, NULL}, @@ -7757,14 +8573,18 @@ void Menu_PaintAll() captureFunc(captureData); } - for (i = 0; i < Menu_Count(); i++) { - Menu_Paint(&Menus[i], qfalse); + //Makro - using menu stack now + //for (i = 0; i < Menu_Count(); i++) { + // Menu_Paint(&Menus[i], qfalse); + //} + for (i = 0; i < openMenuCount; i++) { + Menu_Paint(menuStack[i], qfalse); } if (debugMode) { vec4_t v = { 1, 1, 1, 1 }; - DC->drawText(5, 25, .5, v, va("fps: %f", DC->FPS), 0, 0, 0); + DC->drawText(5, 25, .5, v, va("fps: %f", DC->FPS), 0, 0, 0, 0, qfalse); } } diff --git a/reaction/ta_ui/ui_shared.h b/reaction/ta_ui/ui_shared.h index c3f44039..a742c0cf 100644 --- a/reaction/ta_ui/ui_shared.h +++ b/reaction/ta_ui/ui_shared.h @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.21 2005/09/07 20:24:33 makro +// Vector support for most item types +// // Revision 1.20 2005/02/15 16:33:39 makro // Tons of updates (entity tree attachment system, UI vectors) // @@ -88,16 +91,16 @@ #define WINDOW_MOUSEOVER 0x00000001 // mouse is over it, non exclusive #define WINDOW_HASFOCUS 0x00000002 // has cursor focus, exclusive #define WINDOW_VISIBLE 0x00000004 // is visible -#define WINDOW_GREY 0x00000008 // is visible but grey ( non-active ) +#define WINDOW_GREY 0x00000008 // is visible but grey ( non-active ) #define WINDOW_DECORATION 0x00000010 // for decoration only, no mouse, keyboard, etc.. #define WINDOW_FADINGOUT 0x00000020 // fading out, non-active #define WINDOW_FADINGIN 0x00000040 // fading in -#define WINDOW_MOUSEOVERTEXT 0x00000080 // mouse is over it, non exclusive -#define WINDOW_INTRANSITION 0x00000100 // window is in transition -#define WINDOW_FORECOLORSET 0x00000200 // forecolor was explicitly set ( used to color alpha images or not ) +#define WINDOW_MOUSEOVERTEXT 0x00000080 // mouse is over it, non exclusive +#define WINDOW_INTRANSITION 0x00000100 // window is in transition +#define WINDOW_FORECOLORSET 0x00000200 // forecolor was explicitly set ( used to color alpha images or not ) #define WINDOW_HORIZONTAL 0x00000400 // for list boxes and sliders, vertical is default this is set of horizontal -#define WINDOW_LB_LEFTARROW 0x00000800 // mouse is over left/up arrow -#define WINDOW_LB_RIGHTARROW 0x00001000 // mouse is over right/down arrow +#define WINDOW_LB_LEFTARROW 0x00000800 // mouse is over left/up arrow +#define WINDOW_LB_RIGHTARROW 0x00001000 // mouse is over right/down arrow #define WINDOW_LB_THUMB 0x00002000 // mouse is over thumb #define WINDOW_LB_PGUP 0x00004000 // mouse is over page up #define WINDOW_LB_PGDN 0x00008000 // mouse is over page down @@ -105,12 +108,14 @@ #define WINDOW_OOB_CLICK 0x00020000 // close on out of bounds click #define WINDOW_WRAPPED 0x00040000 // manually wrap text #define WINDOW_AUTOWRAPPED 0x00080000 // auto wrap text -#define WINDOW_FORCED 0x00100000 // forced open -#define WINDOW_POPUP 0x00200000 // popup -#define WINDOW_BACKCOLORSET 0x00400000 // backcolor was explicitly set -#define WINDOW_TIMEDVISIBLE 0x00800000 // visibility timing ( NOT implemented ) +#define WINDOW_FORCED 0x00100000 // forced open +#define WINDOW_POPUP 0x00200000 // popup +#define WINDOW_BACKCOLORSET 0x00400000 // backcolor was explicitly set +#define WINDOW_TIMEDVISIBLE 0x00800000 // visibility timing ( NOT implemented ) //Makro - ugliest hack ever... by far -#define WINDOW_RENDERPOINT 0x01000000 +#define WINDOW_RENDERPOINT 0x01000000 +//Makro - forced text color +#define WINDOW_FORCE_TEXT_COLOR 0x02000000 // CGAME cursor type bits @@ -137,15 +142,22 @@ #define ART_FX_WHITE "menu/art/fx_white" #define ART_FX_YELLOW "menu/art/fx_yel" -#define ASSET_GRADIENTBAR "ui/assets/gradientbar2.tga" -#define ASSET_SCROLLBAR "ui/assets/scrollbar.tga" -#define ASSET_SCROLLBAR_ARROWDOWN "ui/assets/scrollbar_arrow_dwn_a.tga" -#define ASSET_SCROLLBAR_ARROWUP "ui/assets/scrollbar_arrow_up_a.tga" -#define ASSET_SCROLLBAR_ARROWLEFT "ui/assets/scrollbar_arrow_left.tga" -#define ASSET_SCROLLBAR_ARROWRIGHT "ui/assets/scrollbar_arrow_right.tga" -#define ASSET_SCROLL_THUMB "ui/assets/scrollbar_thumb.tga" -#define ASSET_SLIDER_BAR "ui/assets/slider2.tga" -#define ASSET_SLIDER_THUMB "ui/assets/sliderbutt_1.tga" +#define ASSET_GRADIENTBAR "ui/assets/gradientbar2.tga" +#define ASSET_SCROLLBAR_V "ui/assets/scrollbar_vert.tga" +//Makro - horizontal scrollbar +#define ASSET_SCROLLBAR_H "ui/assets/scrollbar_horz.tga" +#define ASSET_SCROLLBAR_ARROWDOWN "ui/assets/scrollbar_arrow_dwn_a.tga" +#define ASSET_SCROLLBAR_ARROWUP "ui/assets/scrollbar_arrow_up_a.tga" +#define ASSET_SCROLLBAR_ARROWLEFT "ui/assets/scrollbar_arrow_left_a.tga" +#define ASSET_SCROLLBAR_ARROWRIGHT "ui/assets/scrollbar_arrow_right_a.tga" +//Makro - displayed when clicked +#define ASSET_SCROLLBAR_ARROWDOWN2 "ui/assets/scrollbar_arrow_dwn_b.tga" +#define ASSET_SCROLLBAR_ARROWUP2 "ui/assets/scrollbar_arrow_up_b.tga" +#define ASSET_SCROLLBAR_ARROWLEFT2 "ui/assets/scrollbar_arrow_left_b.tga" +#define ASSET_SCROLLBAR_ARROWRIGHT2 "ui/assets/scrollbar_arrow_right_b.tga" +#define ASSET_SCROLL_THUMB "ui/assets/scrollbar_thumb.tga" +#define ASSET_SLIDER_BAR "ui/assets/slider2.tga" +#define ASSET_SLIDER_THUMB "ui/assets/sliderbutt_1.tga" #define SCROLLBAR_SIZE 16.0 #define SLIDER_WIDTH 96.0 #define SLIDER_HEIGHT 16.0 @@ -180,12 +192,19 @@ typedef struct { } pointDef_t; typedef pointDef_t Point; +typedef enum +{ + BACKCOLOR, + FORECOLOR, + BORDERCOLOR +} colorType_t; + //Makro - for the new fading method typedef struct { vec4_t color1; vec4_t color2; qboolean active; - qboolean forecolor; + colorType_t colorType; int startTime, endTime; } timeFade_t; @@ -303,6 +322,27 @@ typedef struct modelDef_s { #define CVAR_SHOW 0x00000004 #define CVAR_HIDE 0x00000008 + +//Makro - added for YES/NO items + +#define YESNO_TEXT 0 +#define YESNO_ICON_LEFT 1 +#define YESNO_ICON_RIGHT 2 + +typedef struct yesnoDef_s +{ + int groupIndex; + float activeCvarVal; + char activeCvarStr[128]; + int kind; //text / icon_left / icon_right + qboolean strDef; + qboolean wasActive; + int lastChangeTime; +} yesnoDef_t; + +// + + typedef struct itemDef_s { Window window; // common positional, border, style, layout info Rectangle textRect; // rectangle the text ( if any ) consumes @@ -337,6 +377,7 @@ typedef struct itemDef_s { colorRangeDef_t colorRanges[MAX_COLOR_RANGES]; float special; // used for feeder id's etc.. diff per type int cursorPos; // cursor position in characters + void *typeData; // type specific data ptr's //Makro - color to fade when } itemDef_t; @@ -361,6 +402,10 @@ typedef struct { //Makro - executed when the menu is shown const char *onShow; const char *onFirstShow; + //Makro - executed when the user clicks outside the active area + const char *onOOBClick; + //Makro - special script to be executed when the menu is opened with "openspecial" + const char *onOpenSpecial; qboolean shown; int showCount; const char *soundName; // background loop sound for menu @@ -389,7 +434,14 @@ typedef struct { qhandle_t scrollBarArrowDown; qhandle_t scrollBarArrowLeft; qhandle_t scrollBarArrowRight; - qhandle_t scrollBar; + //Makro - shown when clicked + qhandle_t scrollBarArrowUp2; + qhandle_t scrollBarArrowDown2; + qhandle_t scrollBarArrowLeft2; + qhandle_t scrollBarArrowRight2; + //Makro - two separate backgrounds + qhandle_t scrollBarH; + qhandle_t scrollBarV; qhandle_t scrollBarThumb; qhandle_t buttonMiddle; qhandle_t buttonInside; @@ -418,6 +470,8 @@ typedef struct { //Makro - for drop shadow effects qhandle_t dropShadowCorners[4]; qhandle_t dropShadowRight, dropShadowBottom; + //Makro - for grouped checkboxes + qhandle_t checkBox0, checkBox1; } cachedAssets_t; @@ -439,25 +493,28 @@ typedef struct { qhandle_t(*registerShaderNoMip) (const char *p); void (*setColor) (const vec4_t v); void (*drawHandlePic) (float x, float y, float w, float h, qhandle_t asset); + //Makro - added "adjust" void (*drawStretchPic) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, - qhandle_t hShader); + qhandle_t hShader, qboolean adjust); //Makro - angled pictures void (*drawAngledPic) (float x, float y, float w, float h, const float *u, const float *v, const float *color, float s1, float t1, float s2, float t2, qhandle_t hShader); + //Makro - added forceColor and maxwidth void (*drawText) (float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, - int style); + float maxwidth, int style, qboolean forceColor); //Makro - angled text void (*drawAngledText) (float x, float y, const float *u, const float *v, float scale, vec4_t color, const char *text, float adjust, int limit, - int style); + float maxwidth, int style, qboolean forceColor); int (*textWidth) (const char *text, float scale, int limit); int (*textHeight) (const char *text, float scale, int limit); qhandle_t(*registerModel) (const char *p); void (*modelBounds) (qhandle_t model, vec3_t min, vec3_t max); void (*fillRect) (float x, float y, float w, float h, const vec4_t color); - void (*drawRect) (float x, float y, float w, float h, float size, const vec4_t color); - void (*drawSides) (float x, float y, float w, float h, float size); - void (*drawAngledRect) (float x, float y, float w, float h, const float *u, const float *v, float size, const float *color, unsigned char type); - void (*drawTopBottom) (float x, float y, float w, float h, float size); + //Makro - added shader parm + void (*drawRect) (float x, float y, float w, float h, float size, const vec4_t color, qhandle_t shader); + void (*drawSides) (float x, float y, float w, float h, float size, qhandle_t shader); + void (*drawAngledRect) (float x, float y, float w, float h, const float *u, const float *v, float size, const float *color, unsigned char type, qhandle_t shader); + void (*drawTopBottom) (float x, float y, float w, float h, float size, qhandle_t shader); void (*clearScene) (); void (*addRefEntityToScene) (const refEntity_t * re); void (*renderScene) (const refdef_t * fd); @@ -475,6 +532,9 @@ typedef struct { void (*setCVar) (const char *cvar, const char *value); void (*drawTextWithCursor) (float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style); + //Makro - vector items + void (*drawAngledTextWithCursor) (float x, float y, const float *u, const float *v, float scale, vec4_t color, const char *text, int cursorPos, + char cursor, int limit, int style); void (*setOverstrikeMode) (qboolean b); qboolean(*getOverstrikeMode) (); void (*startLocalSound) (sfxHandle_t sfx, int channelNum); @@ -511,6 +571,9 @@ typedef struct { //Makro - mouse down qboolean mouseDown[3]; int mouseDownPos[2]; + //Makro - last time the cursor was moved + int mouseMoveTime; + qboolean debug; cachedAssets_t Assets; @@ -563,7 +626,8 @@ qboolean PC_Script_Parse(int handle, const char **out); int Menu_Count(); void Menu_New(int handle); void Menu_PaintAll(); -menuDef_t *Menus_ActivateByName(const char *p); +//Makro - added second parameter +menuDef_t *Menus_ActivateByName(const char *p, qboolean special); void Menu_Reset(); qboolean Menus_AnyFullScreenVisible(); void Menus_Activate(menuDef_t * menu); @@ -577,7 +641,8 @@ void *Display_CaptureItem(int x, int y); qboolean Display_MouseMove(void *p, int x, int y); int Display_CursorType(int x, int y); qboolean Display_KeyBindPending(); -void Menus_OpenByName(const char *p); +//Makro - added second parameter +void Menus_OpenByName(const char *p, qboolean special); menuDef_t *Menus_FindByName(const char *p); void Menus_ShowByName(const char *p); void Menus_CloseByName(const char *p); @@ -605,9 +670,12 @@ int trap_PC_SourceFileAndLine(int handle, char *filename, int *line); //Makro - new rendering stuff void UI_AddQuadToScene(qhandle_t hShader, const polyVert_t *verts); void UI_Render2DScene(); +void Rect_ToInnerCoords(rectDef_t *rect, float x, float y, float *resx, float *resy); + #define UI_POLY_Z_OFFSET -0.00001f //Makro - for all the lazy people #define IsBetween(a, min, max) ( (a) >= (min) && (a) <= (max) ) +#define PRINT_RECT(r) (r).x, (r).y, (r).w, (r).h #define RECT_SIDES 1 #define RECT_TOPBOTTOM 2