00001
00002
00003
00004 #ifndef CGAME
00005 #include "ui_local.h"
00006 #endif
00007 #ifdef _XBOX
00008 #include "../client/client.h"
00009 #endif
00010
00011 #include "ui_shared.h"
00012 #include "../game/bg_public.h"
00013 #include "../game/anims.h"
00014 #include "../ghoul2/G2.h"
00015 extern stringID_table_t animTable [MAX_ANIMATIONS+1];
00016 extern void UI_UpdateCharacterSkin( void );
00017
00018
00019 #define SCROLL_TIME_START 500
00020 #define SCROLL_TIME_ADJUST 150
00021 #define SCROLL_TIME_ADJUSTOFFSET 40
00022 #define SCROLL_TIME_FLOOR 20
00023
00024 typedef struct scrollInfo_s {
00025 int nextScrollTime;
00026 int nextAdjustTime;
00027 int adjustValue;
00028 int scrollKey;
00029 float xStart;
00030 float yStart;
00031 itemDef_t *item;
00032 qboolean scrollDir;
00033 } scrollInfo_t;
00034
00035 #ifdef _XBOX
00036
00037
00038 #endif
00039
00040
00041 #ifndef CGAME // Defined in ui_main.c, not in the namespace
00042 extern vmCvar_t ui_char_color_red;
00043 extern vmCvar_t ui_char_color_green;
00044 extern vmCvar_t ui_char_color_blue;
00045 extern vmCvar_t se_language;
00046
00047
00048
00049 extern void UI_SaberDrawBlades( itemDef_t *item, vec3_t origin, vec3_t angles );
00050
00051 extern void UI_SaberLoadParms( void );
00052 extern qboolean ui_saber_parms_parsed;
00053 extern void UI_CacheSaberGlowGraphics( void );
00054
00055 #endif //
00056
00057 #include "../namespace_begin.h"
00058
00059 #ifdef CGAME
00060
00061 extern int trap_Key_GetCatcher( void ) ;
00062 extern void trap_Key_SetCatcher( int catcher );
00063 extern void trap_Cvar_Set( const char *var_name, const char *value );
00064
00065 #endif
00066
00067
00068 #ifdef _XBOX
00069
00070
00071 #define DEMO_TIME_MAX 45000 //g_demoTimeBeforeStart
00072 int g_demoLastKeypress = 0;
00073 bool g_ReturnToSplash = false;
00074 bool g_runningDemo = false;
00075
00076 void G_DemoStart();
00077 void G_DemoEnd();
00078 void G_DemoFrame();
00079 void G_DemoKeypress();
00080
00081 void PlayDemo();
00082
00083 bool TestDemoTimer();
00084
00085
00086
00087 #define TICK_COUNT 20
00088
00089
00090 qboolean Item_HandleSelectionNext(itemDef_t * item);
00091 qboolean Item_HandleSelectionPrev(itemDef_t * item);
00092
00093 #endif // _XBOX
00094
00095 qboolean Item_SetFocus(itemDef_t *item, float x, float y);
00096
00097 static scrollInfo_t scrollInfo;
00098
00099 static void (*captureFunc) (void *p) = 0;
00100 static void *captureData = NULL;
00101 static itemDef_t *itemCapture = NULL;
00102
00103 displayContextDef_t *DC = NULL;
00104
00105 static qboolean g_waitingForKey = qfalse;
00106 static qboolean g_editingField = qfalse;
00107
00108 static itemDef_t *g_bindItem = NULL;
00109 static itemDef_t *g_editItem = NULL;
00110
00111 menuDef_t Menus[MAX_MENUS];
00112 int menuCount = 0;
00113
00114 menuDef_t *menuStack[MAX_OPEN_MENUS];
00115 int openMenuCount = 0;
00116
00117 static qboolean debugMode = qfalse;
00118
00119 #define DOUBLE_CLICK_DELAY 300
00120 static int lastListBoxClickTime = 0;
00121
00122 void Item_RunScript(itemDef_t *item, const char *s);
00123 void Item_SetupKeywordHash(void);
00124 void Menu_SetupKeywordHash(void);
00125 int BindingIDFromName(const char *name);
00126 qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down);
00127 itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu);
00128 itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu);
00129 static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y);
00130 static void Item_TextScroll_BuildLines ( itemDef_t* item );
00131 void Menu_SetItemText(const menuDef_t *menu,const char *itemName, const char *text);
00132 extern qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name,int *runTimeLength );
00133 extern qboolean ItemParse_model_g2anim_go( itemDef_t *item, const char *animName );
00134
00135
00136 #ifdef CGAME
00137 #define MEM_POOL_SIZE 128 * 1024
00138 #define UI_ALLOCATION_TAG TAG_CG_UI_ALLOC
00139 #else
00140
00141 #define MEM_POOL_SIZE 2048 * 1024
00142 #define UI_ALLOCATION_TAG TAG_UI_ALLOC
00143 #endif
00144
00145 #ifndef _XBOX
00146 static char memoryPool[MEM_POOL_SIZE];
00147 #endif // _XBOX
00148
00149 static int allocPoint, outOfMemory;
00150
00151
00152 typedef struct itemFlagsDef_s {
00153 char *string;
00154 int value;
00155 } itemFlagsDef_t;
00156
00157 itemFlagsDef_t itemFlags [] = {
00158 "WINDOW_INACTIVE", WINDOW_INACTIVE,
00159 NULL, (int) NULL
00160 };
00161
00162 char *styles [] = {
00163 "WINDOW_STYLE_EMPTY",
00164 "WINDOW_STYLE_FILLED",
00165 "WINDOW_STYLE_GRADIENT",
00166 "WINDOW_STYLE_SHADER",
00167 "WINDOW_STYLE_TEAMCOLOR",
00168 "WINDOW_STYLE_CINEMATIC",
00169 NULL
00170 };
00171
00172 char *alignment [] = {
00173 "ITEM_ALIGN_LEFT",
00174 "ITEM_ALIGN_CENTER",
00175 "ITEM_ALIGN_RIGHT",
00176 NULL
00177 };
00178
00179 char *types [] = {
00180 "ITEM_TYPE_TEXT",
00181 "ITEM_TYPE_BUTTON",
00182 "ITEM_TYPE_RADIOBUTTON",
00183 "ITEM_TYPE_CHECKBOX",
00184 "ITEM_TYPE_EDITFIELD",
00185 "ITEM_TYPE_COMBO",
00186 "ITEM_TYPE_LISTBOX",
00187 "ITEM_TYPE_MODEL",
00188 "ITEM_TYPE_OWNERDRAW",
00189 "ITEM_TYPE_NUMERICFIELD",
00190 "ITEM_TYPE_SLIDER",
00191 "ITEM_TYPE_YESNO",
00192 "ITEM_TYPE_MULTI",
00193 "ITEM_TYPE_BIND",
00194 "ITEM_TYPE_TEXTSCROLL",
00195 NULL
00196 };
00197
00198
00199 extern int MenuFontToHandle(int iMenuFont);
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 void *UI_Alloc( int size ) {
00210 #ifdef _XBOX
00211
00212 allocPoint += size;
00213 return Z_Malloc(size, UI_ALLOCATION_TAG, qfalse, 4);
00214
00215 #else // _XBOX
00216
00217 char *p;
00218
00219 if ( allocPoint + size > MEM_POOL_SIZE ) {
00220 outOfMemory = qtrue;
00221 if (DC->Print) {
00222 DC->Print("UI_Alloc: Failure. Out of memory!\n");
00223 }
00224
00225 return NULL;
00226 }
00227
00228 p = &memoryPool[allocPoint];
00229
00230 allocPoint += ( size + 15 ) & ~15;
00231
00232 return p;
00233 #endif
00234 }
00235
00236
00237
00238
00239
00240
00241 void UI_InitMemory( void ) {
00242 allocPoint = 0;
00243 outOfMemory = qfalse;
00244 #ifdef _XBOX
00245 Z_TagFree(UI_ALLOCATION_TAG);
00246 #endif
00247 }
00248
00249 qboolean UI_OutOfMemory() {
00250 return outOfMemory;
00251 }
00252
00253
00254
00255
00256
00257 #define HASH_TABLE_SIZE 2048
00258
00259
00260
00261
00262
00263 static long hashForString(const char *str) {
00264 int i;
00265 long hash;
00266 char letter;
00267
00268 hash = 0;
00269 i = 0;
00270 while (str[i] != '\0') {
00271 letter = tolower((unsigned char)str[i]);
00272 hash+=(long)(letter)*(i+119);
00273 i++;
00274 }
00275 hash &= (HASH_TABLE_SIZE-1);
00276 return hash;
00277 }
00278
00279 typedef struct stringDef_s {
00280 struct stringDef_s *next;
00281 const char *str;
00282 } stringDef_t;
00283
00284 static int strPoolIndex = 0;
00285 static char strPool[STRING_POOL_SIZE];
00286
00287 static int strHandleCount = 0;
00288 static stringDef_t *strHandle[HASH_TABLE_SIZE];
00289
00290
00291 const char *String_Alloc(const char *p) {
00292 int len;
00293 long hash;
00294 stringDef_t *str, *last;
00295 static const char *staticNULL = "";
00296
00297 if (p == NULL) {
00298 return NULL;
00299 }
00300
00301 if (*p == 0) {
00302 return staticNULL;
00303 }
00304
00305 hash = hashForString(p);
00306
00307 str = strHandle[hash];
00308 while (str) {
00309 if (strcmp(p, str->str) == 0) {
00310 return str->str;
00311 }
00312 str = str->next;
00313 }
00314
00315 len = strlen(p);
00316 if (len + strPoolIndex + 1 < STRING_POOL_SIZE) {
00317 int ph = strPoolIndex;
00318 strcpy(&strPool[strPoolIndex], p);
00319 strPoolIndex += len + 1;
00320
00321 str = strHandle[hash];
00322 last = str;
00323 while (last && last->next)
00324 {
00325 last = last->next;
00326 }
00327
00328 str = (stringDef_t *) UI_Alloc(sizeof(stringDef_t));
00329 str->next = NULL;
00330 str->str = &strPool[ph];
00331 if (last) {
00332 last->next = str;
00333 } else {
00334 strHandle[hash] = str;
00335 }
00336 return &strPool[ph];
00337 }
00338
00339
00340 assert(0);
00341 return NULL;
00342 }
00343
00344 void String_Report() {
00345 float f;
00346 Com_Printf("Memory/String Pool Info\n");
00347 Com_Printf("----------------\n");
00348 f = strPoolIndex;
00349 f /= STRING_POOL_SIZE;
00350 f *= 100;
00351 Com_Printf("String Pool is %.1f%% full, %i bytes out of %i used.\n", f, strPoolIndex, STRING_POOL_SIZE);
00352 f = allocPoint;
00353 f /= MEM_POOL_SIZE;
00354 f *= 100;
00355 Com_Printf("Memory Pool is %.1f%% full, %i bytes out of %i used.\n", f, allocPoint, MEM_POOL_SIZE);
00356 }
00357
00358
00359
00360
00361
00362
00363 void String_Init() {
00364 int i;
00365 for (i = 0; i < HASH_TABLE_SIZE; i++) {
00366 strHandle[i] = 0;
00367 }
00368 strHandleCount = 0;
00369 strPoolIndex = 0;
00370 menuCount = 0;
00371 openMenuCount = 0;
00372 UI_InitMemory();
00373 Item_SetupKeywordHash();
00374 Menu_SetupKeywordHash();
00375 if (DC && DC->getBindingBuf) {
00376 Controls_GetConfig();
00377 }
00378 }
00379
00380
00381
00382
00383
00384
00385 void PC_SourceWarning(int handle, char *format, ...) {
00386 int line;
00387 char filename[128];
00388 va_list argptr;
00389 static char string[4096];
00390
00391 va_start (argptr, format);
00392 vsprintf (string, format, argptr);
00393 va_end (argptr);
00394
00395 filename[0] = '\0';
00396 line = 0;
00397 trap_PC_SourceFileAndLine(handle, filename, &line);
00398
00399 Com_Printf(S_COLOR_YELLOW "WARNING: %s, line %d: %s\n", filename, line, string);
00400 }
00401
00402
00403
00404
00405
00406
00407 void PC_SourceError(int handle, char *format, ...) {
00408 int line;
00409 char filename[128];
00410 va_list argptr;
00411 static char string[4096];
00412
00413 va_start (argptr, format);
00414 vsprintf (string, format, argptr);
00415 va_end (argptr);
00416
00417 filename[0] = '\0';
00418 line = 0;
00419 trap_PC_SourceFileAndLine(handle, filename, &line);
00420
00421 Com_Printf(S_COLOR_RED "ERROR: %s, line %d: %s\n", filename, line, string);
00422 }
00423
00424
00425
00426
00427
00428
00429 void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t)
00430 {
00431 int i;
00432
00433
00434 for (i=0; i<4; i++)
00435 {
00436 c[i] = a[i] + t*(b[i]-a[i]);
00437 if (c[i] < 0)
00438 c[i] = 0;
00439 else if (c[i] > 1.0)
00440 c[i] = 1.0;
00441 }
00442 }
00443
00444
00445
00446
00447
00448
00449 qboolean Float_Parse(char **p, float *f) {
00450 char *token;
00451 token = COM_ParseExt((const char **)p, qfalse);
00452 if (token && token[0] != 0) {
00453 *f = atof(token);
00454 return qtrue;
00455 } else {
00456 return qfalse;
00457 }
00458 }
00459
00460
00461
00462
00463
00464
00465 qboolean PC_Float_Parse(int handle, float *f) {
00466 pc_token_t token;
00467 int negative = qfalse;
00468
00469 if (!trap_PC_ReadToken(handle, &token))
00470 return qfalse;
00471 if (token.string[0] == '-') {
00472 if (!trap_PC_ReadToken(handle, &token))
00473 return qfalse;
00474 negative = qtrue;
00475 }
00476 if (token.type != TT_NUMBER) {
00477 PC_SourceError(handle, "expected float but found %s\n", token.string);
00478 return qfalse;
00479 }
00480 if (negative)
00481 *f = -token.floatvalue;
00482 else
00483 *f = token.floatvalue;
00484 return qtrue;
00485 }
00486
00487
00488
00489
00490
00491
00492 qboolean Color_Parse(char **p, vec4_t *c) {
00493 int i;
00494 float f;
00495
00496 for (i = 0; i < 4; i++) {
00497 if (!Float_Parse(p, &f)) {
00498 return qfalse;
00499 }
00500 (*c)[i] = f;
00501 }
00502 return qtrue;
00503 }
00504
00505
00506
00507
00508
00509
00510 qboolean PC_Color_Parse(int handle, vec4_t *c) {
00511 int i;
00512 float f;
00513
00514 for (i = 0; i < 4; i++) {
00515 if (!PC_Float_Parse(handle, &f)) {
00516 return qfalse;
00517 }
00518 (*c)[i] = f;
00519 }
00520 return qtrue;
00521 }
00522
00523
00524
00525
00526
00527
00528 qboolean Int_Parse(char **p, int *i) {
00529 char *token;
00530 token = COM_ParseExt((const char **)p, qfalse);
00531
00532 if (token && token[0] != 0) {
00533 *i = atoi(token);
00534 return qtrue;
00535 } else {
00536 return qfalse;
00537 }
00538 }
00539
00540
00541
00542
00543
00544
00545 qboolean PC_Int_Parse(int handle, int *i) {
00546 pc_token_t token;
00547 int negative = qfalse;
00548
00549 if (!trap_PC_ReadToken(handle, &token))
00550 return qfalse;
00551 if (token.string[0] == '-') {
00552 if (!trap_PC_ReadToken(handle, &token))
00553 return qfalse;
00554 negative = qtrue;
00555 }
00556 if (token.type != TT_NUMBER) {
00557 PC_SourceError(handle, "expected integer but found %s\n", token.string);
00558 return qfalse;
00559 }
00560 *i = token.intvalue;
00561 if (negative)
00562 *i = - *i;
00563 return qtrue;
00564 }
00565
00566
00567
00568
00569
00570
00571 qboolean Rect_Parse(char **p, rectDef_t *r) {
00572 if (Float_Parse(p, &r->x)) {
00573 if (Float_Parse(p, &r->y)) {
00574 if (Float_Parse(p, &r->w)) {
00575 if (Float_Parse(p, &r->h)) {
00576 return qtrue;
00577 }
00578 }
00579 }
00580 }
00581 return qfalse;
00582 }
00583
00584
00585
00586
00587
00588
00589 qboolean PC_Rect_Parse(int handle, rectDef_t *r) {
00590 if (PC_Float_Parse(handle, &r->x)) {
00591 if (PC_Float_Parse(handle, &r->y)) {
00592 if (PC_Float_Parse(handle, &r->w)) {
00593 if (PC_Float_Parse(handle, &r->h)) {
00594 return qtrue;
00595 }
00596 }
00597 }
00598 }
00599 return qfalse;
00600 }
00601
00602
00603
00604
00605
00606
00607 qboolean String_Parse(char **p, const char **out) {
00608 char *token;
00609
00610 token = COM_ParseExt((const char **)p, qfalse);
00611 if (token && token[0] != 0) {
00612 *(out) = String_Alloc(token);
00613 return *(out)!=NULL;
00614 }
00615 return qfalse;
00616 }
00617
00618
00619
00620
00621
00622
00623 qboolean PC_String_Parse(int handle, const char **out)
00624 {
00625 static char* squiggy = "}";
00626 pc_token_t token;
00627
00628 if (!trap_PC_ReadToken(handle, &token))
00629 {
00630 return qfalse;
00631 }
00632
00633
00634 if ( !Q_stricmp ( token.string, "}" ) )
00635 {
00636 *(out) = squiggy;
00637 }
00638 else
00639 {
00640 *(out) = String_Alloc(token.string);
00641 }
00642 return qtrue;
00643 }
00644
00645
00646
00647
00648
00649
00650 qboolean PC_Script_Parse(int handle, const char **out) {
00651 char script[2048];
00652 pc_token_t token;
00653
00654 script[0] = 0;
00655
00656
00657
00658 if (!trap_PC_ReadToken(handle, &token))
00659 return qfalse;
00660 if (Q_stricmp(token.string, "{") != 0) {
00661 return qfalse;
00662 }
00663
00664 while ( 1 ) {
00665 if (!trap_PC_ReadToken(handle, &token))
00666 return qfalse;
00667
00668 if (Q_stricmp(token.string, "}") == 0) {
00669 *out = String_Alloc(script);
00670 return qtrue;
00671 }
00672
00673 if (token.string[1] != '\0') {
00674 Q_strcat(script, 2048, va("\"%s\"", token.string));
00675 } else {
00676 Q_strcat(script, 2048, token.string);
00677 }
00678 Q_strcat(script, 2048, " ");
00679 }
00680 return qfalse;
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693 void Init_Display(displayContextDef_t *dc) {
00694 DC = dc;
00695 }
00696
00697
00698
00699
00700
00701 void GradientBar_Paint(rectDef_t *rect, vec4_t color) {
00702
00703 DC->setColor( color );
00704 DC->drawHandlePic(rect->x, rect->y, rect->w, rect->h, DC->Assets.gradientBar);
00705 DC->setColor( NULL );
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 void Window_Init(Window *w) {
00718 memset(w, 0, sizeof(windowDef_t));
00719 w->borderSize = 1;
00720 w->foreColor[0] = w->foreColor[1] = w->foreColor[2] = w->foreColor[3] = 1.0;
00721 w->cinematic = -1;
00722 }
00723
00724 void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboolean bFlags, float fadeAmount) {
00725 if (*flags & (WINDOW_FADINGOUT | WINDOW_FADINGIN)) {
00726 if (DC->realTime > *nextTime) {
00727 *nextTime = DC->realTime + offsetTime;
00728 if (*flags & WINDOW_FADINGOUT) {
00729 *f -= fadeAmount;
00730 if (bFlags && *f <= 0.0) {
00731 *flags &= ~(WINDOW_FADINGOUT | WINDOW_VISIBLE);
00732 }
00733 } else {
00734 *f += fadeAmount;
00735 if (*f >= clamp) {
00736 *f = clamp;
00737 if (bFlags) {
00738 *flags &= ~WINDOW_FADINGIN;
00739 }
00740 }
00741 }
00742 }
00743 }
00744 }
00745
00746
00747
00748 void Window_Paint(Window *w, float fadeAmount, float fadeClamp, float fadeCycle)
00749 {
00750
00751 vec4_t color;
00752 rectDef_t fillRect = w->rect;
00753
00754
00755 if (debugMode)
00756 {
00757 color[0] = color[1] = color[2] = color[3] = 1;
00758 DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color);
00759 }
00760
00761 if (w == NULL || (w->style == 0 && w->border == 0))
00762 {
00763 return;
00764 }
00765
00766 if (w->border != 0)
00767 {
00768 fillRect.x += w->borderSize;
00769 fillRect.y += w->borderSize;
00770 fillRect.w -= w->borderSize + 1;
00771 fillRect.h -= w->borderSize + 1;
00772 }
00773
00774 if (w->style == WINDOW_STYLE_FILLED)
00775 {
00776
00777 if (w->background)
00778 {
00779 Fade(&w->flags, &w->backColor[3], fadeClamp, &w->nextTime, fadeCycle, qtrue, fadeAmount);
00780 DC->setColor(w->backColor);
00781 DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
00782 DC->setColor(NULL);
00783 }
00784 else
00785 {
00786 DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->backColor);
00787 }
00788 }
00789 else if (w->style == WINDOW_STYLE_GRADIENT)
00790 {
00791 GradientBar_Paint(&fillRect, w->backColor);
00792
00793 }
00794 else if (w->style == WINDOW_STYLE_SHADER)
00795 {
00796 #ifndef CGAME
00797 if (w->flags & WINDOW_PLAYERCOLOR)
00798 {
00799 vec4_t color;
00800 color[0] = ui_char_color_red.integer/255.0f;
00801 color[1] = ui_char_color_green.integer/255.0f;
00802 color[2] = ui_char_color_blue.integer/255.0f;
00803 color[3] = 1;
00804 DC->setColor(color);
00805 }
00806 #endif //
00807
00808 if (w->flags & WINDOW_FORECOLORSET)
00809 {
00810 DC->setColor(w->foreColor);
00811 }
00812 DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
00813 DC->setColor(NULL);
00814 }
00815 else if (w->style == WINDOW_STYLE_TEAMCOLOR)
00816 {
00817 if (DC->getTeamColor)
00818 {
00819 DC->getTeamColor(&color);
00820 DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, color);
00821 }
00822 }
00823 else if (w->style == WINDOW_STYLE_CINEMATIC)
00824 {
00825 if (w->cinematic == -1)
00826 {
00827 w->cinematic = DC->playCinematic(w->cinematicName, fillRect.x, fillRect.y, fillRect.w, fillRect.h);
00828 if (w->cinematic == -1)
00829 {
00830 w->cinematic = -2;
00831 }
00832 }
00833 if (w->cinematic >= 0)
00834 {
00835 DC->runCinematicFrame(w->cinematic);
00836 DC->drawCinematic(w->cinematic, fillRect.x, fillRect.y, fillRect.w, fillRect.h);
00837 }
00838 }
00839
00840 if (w->border == WINDOW_BORDER_FULL)
00841 {
00842
00843
00844 if (w->style == WINDOW_STYLE_TEAMCOLOR)
00845 {
00846 if (color[0] > 0)
00847 {
00848
00849 color[0] = 1;
00850 color[1] = color[2] = .5;
00851 }
00852 else
00853 {
00854 color[2] = 1;
00855 color[0] = color[1] = .5;
00856 }
00857 color[3] = 1;
00858 DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, color);
00859 }
00860 else
00861 {
00862 DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, w->borderColor);
00863 }
00864 }
00865 else if (w->border == WINDOW_BORDER_HORZ)
00866 {
00867
00868 DC->setColor(w->borderColor);
00869 DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
00870 DC->setColor( NULL );
00871 }
00872 else if (w->border == WINDOW_BORDER_VERT)
00873 {
00874
00875 DC->setColor(w->borderColor);
00876 DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
00877 DC->setColor( NULL );
00878 }
00879 else if (w->border == WINDOW_BORDER_KCGRADIENT)
00880 {
00881
00882 rectDef_t r = w->rect;
00883 r.h = w->borderSize;
00884 GradientBar_Paint(&r, w->borderColor);
00885 r.y = w->rect.y + w->rect.h - 1;
00886 GradientBar_Paint(&r, w->borderColor);
00887 }
00888 }
00889
00890
00891 void Item_SetScreenCoords(itemDef_t *item, float x, float y)
00892 {
00893
00894 if (item == NULL)
00895 {
00896 return;
00897 }
00898
00899 if (item->window.border != 0)
00900 {
00901 x += item->window.borderSize;
00902 y += item->window.borderSize;
00903 }
00904
00905 item->window.rect.x = x + item->window.rectClient.x;
00906 item->window.rect.y = y + item->window.rectClient.y;
00907 item->window.rect.w = item->window.rectClient.w;
00908 item->window.rect.h = item->window.rectClient.h;
00909
00910
00911 item->textRect.w = 0;
00912 item->textRect.h = 0;
00913
00914 switch ( item->type)
00915 {
00916 case ITEM_TYPE_TEXTSCROLL:
00917 {
00918 textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
00919 if ( scrollPtr )
00920 {
00921 scrollPtr->startPos = 0;
00922 scrollPtr->endPos = 0;
00923 }
00924
00925 Item_TextScroll_BuildLines ( item );
00926
00927 break;
00928 }
00929 }
00930 }
00931
00932
00933 void Item_UpdatePosition(itemDef_t *item)
00934 {
00935 float x, y;
00936 menuDef_t *menu;
00937
00938 if (item == NULL || item->parent == NULL)
00939 {
00940 return;
00941 }
00942
00943 menu = (menuDef_t *) item->parent;
00944
00945 x = menu->window.rect.x;
00946 y = menu->window.rect.y;
00947
00948 if (menu->window.border != 0)
00949 {
00950 x += menu->window.borderSize;
00951 y += menu->window.borderSize;
00952 }
00953
00954 Item_SetScreenCoords(item, x, y);
00955
00956 }
00957
00958
00959 void Menu_UpdatePosition(menuDef_t *menu) {
00960 int i;
00961 float x, y;
00962
00963 if (menu == NULL) {
00964 return;
00965 }
00966
00967 x = menu->window.rect.x;
00968 y = menu->window.rect.y;
00969 if (menu->window.border != 0) {
00970 x += menu->window.borderSize;
00971 y += menu->window.borderSize;
00972 }
00973
00974 for (i = 0; i < menu->itemCount; i++) {
00975 Item_SetScreenCoords(menu->items[i], x, y);
00976 }
00977 }
00978
00979 void Menu_PostParse(menuDef_t *menu) {
00980 if (menu == NULL) {
00981 return;
00982 }
00983 if (menu->fullScreen) {
00984 menu->window.rect.x = 0;
00985 menu->window.rect.y = 0;
00986 menu->window.rect.w = 640;
00987 menu->window.rect.h = 480;
00988 }
00989 Menu_UpdatePosition(menu);
00990 }
00991
00992 itemDef_t *Menu_ClearFocus(menuDef_t *menu) {
00993 int i;
00994 itemDef_t *ret = NULL;
00995
00996 if (menu == NULL) {
00997 return NULL;
00998 }
00999
01000 for (i = 0; i < menu->itemCount; i++) {
01001 if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
01002 ret = menu->items[i];
01003 }
01004 menu->items[i]->window.flags &= ~WINDOW_HASFOCUS;
01005 if (menu->items[i]->leaveFocus) {
01006 Item_RunScript(menu->items[i], menu->items[i]->leaveFocus);
01007 }
01008 }
01009
01010 return ret;
01011 }
01012
01013 qboolean IsVisible(int flags) {
01014 return (flags & WINDOW_VISIBLE && !(flags & WINDOW_FADINGOUT));
01015 }
01016
01017 qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y) {
01018 if (rect) {
01019 if (x > rect->x && x < rect->x + rect->w && y > rect->y && y < rect->y + rect->h) {
01020 return qtrue;
01021 }
01022 }
01023 return qfalse;
01024 }
01025
01026 int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name)
01027 {
01028 int i;
01029 int count = 0;
01030
01031 for (i = 0; i < menu->itemCount; i++)
01032 {
01033 if ((!menu->items[i]->window.name) && (!menu->items[i]->window.group))
01034 {
01035 Com_Printf(S_COLOR_YELLOW"WARNING: item has neither name or group\n");
01036 continue;
01037 }
01038
01039 if (Q_stricmp(menu->items[i]->window.name, name) == 0 ||
01040 (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0))
01041 {
01042 count++;
01043 }
01044 }
01045
01046 return count;
01047 }
01048
01049 itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name) {
01050 int i;
01051 int count = 0;
01052 for (i = 0; i < menu->itemCount; i++) {
01053 if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0)) {
01054 if (count == index) {
01055 return menu->items[i];
01056 }
01057 count++;
01058 }
01059 }
01060 return NULL;
01061 }
01062
01063 qboolean Script_SetColor ( itemDef_t *item, char **args )
01064 {
01065 const char *name;
01066 int i;
01067 float f;
01068 vec4_t *out;
01069
01070
01071 if (String_Parse(args, &name))
01072 {
01073 out = NULL;
01074 if (Q_stricmp(name, "backcolor") == 0)
01075 {
01076 out = &item->window.backColor;
01077 item->window.flags |= WINDOW_BACKCOLORSET;
01078 }
01079 else if (Q_stricmp(name, "forecolor") == 0)
01080 {
01081 out = &item->window.foreColor;
01082 item->window.flags |= WINDOW_FORECOLORSET;
01083 }
01084 else if (Q_stricmp(name, "bordercolor") == 0)
01085 {
01086 out = &item->window.borderColor;
01087 }
01088
01089 if (out)
01090 {
01091 for (i = 0; i < 4; i++)
01092 {
01093 if (!Float_Parse(args, &f))
01094 {
01095 return qtrue;
01096 }
01097 (*out)[i] = f;
01098 }
01099 }
01100 }
01101
01102 return qtrue;
01103 }
01104
01105 qboolean Script_SetAsset(itemDef_t *item, char **args)
01106 {
01107 const char *name;
01108
01109 if (String_Parse(args, &name))
01110 {
01111
01112 if (item->type == ITEM_TYPE_MODEL)
01113 {
01114 }
01115 }
01116 return qtrue;
01117 }
01118
01119 qboolean Script_SetBackground(itemDef_t *item, char **args)
01120 {
01121 const char *name;
01122
01123 if (String_Parse(args, &name))
01124 {
01125 item->window.background = DC->registerShaderNoMip(name);
01126 }
01127 return qtrue;
01128 }
01129
01130 qboolean Script_SetItemRectCvar(itemDef_t *item, char **args)
01131 {
01132 const char *itemName;
01133 const char *cvarName;
01134 char cvarBuf[1024];
01135 const char *holdVal;
01136 char *holdBuf;
01137 itemDef_t *item2=0;
01138 menuDef_t *menu;
01139
01140
01141 if (String_Parse(args, &itemName) && String_Parse(args, &cvarName))
01142 {
01143 item2 = Menu_FindItemByName((menuDef_t *) item->parent, itemName);
01144
01145 if (item2)
01146 {
01147
01148 DC->getCVarString(cvarName, cvarBuf, sizeof(cvarBuf));
01149
01150 holdBuf = cvarBuf;
01151 if (String_Parse(&holdBuf,&holdVal))
01152 {
01153 menu = (menuDef_t *) item->parent;
01154
01155 item2->window.rectClient.x = atof(holdVal) + menu->window.rect.x;
01156 if (String_Parse(&holdBuf,&holdVal))
01157 {
01158 item2->window.rectClient.y = atof(holdVal) + menu->window.rect.y;
01159 if (String_Parse(&holdBuf,&holdVal))
01160 {
01161 item2->window.rectClient.w = atof(holdVal);
01162 if (String_Parse(&holdBuf,&holdVal))
01163 {
01164 item2->window.rectClient.h = atof(holdVal);
01165
01166 item2->window.rect.x = item2->window.rectClient.x;
01167 item2->window.rect.y = item2->window.rectClient.y;
01168 item2->window.rect.w = item2->window.rectClient.w;
01169 item2->window.rect.h = item2->window.rectClient.h;
01170
01171 return qtrue;
01172 }
01173 }
01174 }
01175 }
01176 }
01177 }
01178
01179
01180 if (item2)
01181 {
01182 item2->window.rectClient.x = 0;
01183 item2->window.rectClient.y = 0;
01184 item2->window.rectClient.w = 0;
01185 item2->window.rectClient.h = 0;
01186 }
01187
01188
01189
01190 return qtrue;
01191 }
01192
01193 qboolean Script_SetItemBackground(itemDef_t *item, char **args)
01194 {
01195 const char *itemName;
01196 const char *name;
01197
01198
01199 if (String_Parse(args, &itemName) && String_Parse(args, &name))
01200 {
01201 Menu_SetItemBackground((menuDef_t *) item->parent, itemName, name);
01202 }
01203 return qtrue;
01204 }
01205
01206 qboolean Script_SetItemText(itemDef_t *item, char **args)
01207 {
01208 const char *itemName;
01209 const char *text;
01210
01211
01212 if (String_Parse(args, &itemName) && String_Parse(args, &text))
01213 {
01214 Menu_SetItemText((menuDef_t *) item->parent, itemName, text);
01215 }
01216 return qtrue;
01217 }
01218
01219
01220 itemDef_t *Menu_FindItemByName(menuDef_t *menu, const char *p) {
01221 int i;
01222 if (menu == NULL || p == NULL) {
01223 return NULL;
01224 }
01225
01226 for (i = 0; i < menu->itemCount; i++) {
01227 if (Q_stricmp(p, menu->items[i]->window.name) == 0) {
01228 return menu->items[i];
01229 }
01230 }
01231
01232 return NULL;
01233 }
01234
01235 qboolean Script_SetTeamColor(itemDef_t *item, char **args)
01236 {
01237 if (DC->getTeamColor)
01238 {
01239 int i;
01240 vec4_t color;
01241 DC->getTeamColor(&color);
01242 for (i = 0; i < 4; i++)
01243 {
01244 item->window.backColor[i] = color[i];
01245 }
01246 }
01247 return qtrue;
01248 }
01249
01250 qboolean Script_SetItemColor(itemDef_t *item, char **args)
01251 {
01252 const char *itemname;
01253 const char *name;
01254 vec4_t color;
01255 int i;
01256 vec4_t *out;
01257
01258
01259 if (String_Parse(args, &itemname) && String_Parse(args, &name))
01260 {
01261 itemDef_t *item2;
01262 int j,count;
01263 char buff[1024];
01264
01265
01266 if (itemname[0] == '*')
01267 {
01268 itemname += 1;
01269 DC->getCVarString(itemname, buff, sizeof(buff));
01270 itemname = buff;
01271 }
01272
01273 count = Menu_ItemsMatchingGroup((menuDef_t *) item->parent, itemname);
01274
01275 if (!Color_Parse(args, &color))
01276 {
01277 return qtrue;
01278 }
01279
01280 for (j = 0; j < count; j++)
01281 {
01282 item2 = Menu_GetMatchingItemByNumber((menuDef_t *) item->parent, j, itemname);
01283 if (item2 != NULL)
01284 {
01285 out = NULL;
01286 if (Q_stricmp(name, "backcolor") == 0)
01287 {
01288 out = &item2->window.backColor;
01289 }
01290 else if (Q_stricmp(name, "forecolor") == 0)
01291 {
01292 out = &item2->window.foreColor;
01293 item2->window.flags |= WINDOW_FORECOLORSET;
01294 }
01295 else if (Q_stricmp(name, "bordercolor") == 0)
01296 {
01297 out = &item2->window.borderColor;
01298 }
01299
01300 if (out)
01301 {
01302 for (i = 0; i < 4; i++)
01303 {
01304 (*out)[i] = color[i];
01305 }
01306 }
01307 }
01308 }
01309 }
01310
01311 return qtrue;
01312 }
01313
01314 qboolean Script_SetItemColorCvar(itemDef_t *item, char **args)
01315 {
01316 const char *itemname;
01317 char *colorCvarName,*holdBuf,*holdVal;
01318 char cvarBuf[1024];
01319 const char *name;
01320 vec4_t color;
01321 int i;
01322 vec4_t *out;
01323
01324
01325 if (String_Parse(args, &itemname) && String_Parse(args, &name))
01326 {
01327 itemDef_t *item2;
01328 int j,count;
01329 char buff[1024];
01330
01331
01332 if (itemname[0] == '*')
01333 {
01334 itemname += 1;
01335 DC->getCVarString(itemname, buff, sizeof(buff));
01336 itemname = buff;
01337 }
01338
01339 count = Menu_ItemsMatchingGroup((menuDef_t *) item->parent, itemname);
01340
01341
01342 if (!String_Parse(args,(const char **) &colorCvarName))
01343 {
01344 return qtrue;
01345 }
01346 else
01347 {
01348 DC->getCVarString(colorCvarName, cvarBuf, sizeof(cvarBuf));
01349
01350 holdBuf = cvarBuf;
01351 if (String_Parse(&holdBuf,(const char **) &holdVal))
01352 {
01353 color[0] = atof(holdVal);
01354 if (String_Parse(&holdBuf,(const char **) &holdVal))
01355 {
01356 color[1] = atof(holdVal);
01357 if (String_Parse(&holdBuf,(const char **) &holdVal))
01358 {
01359 color[2] = atof(holdVal);
01360 if (String_Parse(&holdBuf,(const char **) &holdVal))
01361 {
01362 color[3] = atof(holdVal);
01363 }
01364 }
01365 }
01366 }
01367 }
01368
01369 for (j = 0; j < count; j++)
01370 {
01371 item2 = Menu_GetMatchingItemByNumber((menuDef_t *) item->parent, j, itemname);
01372 if (item2 != NULL)
01373 {
01374 out = NULL;
01375 if (Q_stricmp(name, "backcolor") == 0)
01376 {
01377 out = &item2->window.backColor;
01378 }
01379 else if (Q_stricmp(name, "forecolor") == 0)
01380 {
01381 out = &item2->window.foreColor;
01382 item2->window.flags |= WINDOW_FORECOLORSET;
01383 }
01384 else if (Q_stricmp(name, "bordercolor") == 0)
01385 {
01386 out = &item2->window.borderColor;
01387 }
01388
01389 if (out)
01390 {
01391 for (i = 0; i < 4; i++)
01392 {
01393 (*out)[i] = color[i];
01394 }
01395 }
01396 }
01397 }
01398 }
01399
01400 return qtrue;
01401 }
01402
01403 qboolean Script_SetItemRect(itemDef_t *item, char **args)
01404 {
01405 const char *itemname;
01406 rectDef_t *out;
01407 rectDef_t rect;
01408 menuDef_t *menu;
01409
01410
01411 if (String_Parse(args, &itemname))
01412 {
01413 itemDef_t *item2;
01414 int j;
01415 int count = Menu_ItemsMatchingGroup((menuDef_t *) item->parent, itemname);
01416
01417 if (!Rect_Parse(args, &rect))
01418 {
01419 return qtrue;
01420 }
01421
01422 menu = (menuDef_t *) item->parent;
01423
01424 for (j = 0; j < count; j++)
01425 {
01426 item2 = Menu_GetMatchingItemByNumber(menu, j, itemname);
01427 if (item2 != NULL)
01428 {
01429 out = &item2->window.rect;
01430
01431 if (out)
01432 {
01433 item2->window.rect.x = rect.x + menu->window.rect.x;
01434 item2->window.rect.y = rect.y + menu->window.rect.y;
01435 item2->window.rect.w = rect.w;
01436 item2->window.rect.h = rect.h;
01437 }
01438 }
01439 }
01440 }
01441 return qtrue;
01442 }
01443
01444 void Menu_ShowGroup (menuDef_t *menu, char *groupName, qboolean showFlag)
01445 {
01446 itemDef_t *item;
01447 int count,j;
01448
01449 count = Menu_ItemsMatchingGroup( menu, groupName);
01450 for (j = 0; j < count; j++)
01451 {
01452 item = Menu_GetMatchingItemByNumber( menu, j, groupName);
01453 if (item != NULL)
01454 {
01455 if (showFlag)
01456 {
01457 item->window.flags |= WINDOW_VISIBLE;
01458 }
01459 else
01460 {
01461 item->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS);
01462 }
01463 }
01464 }
01465 }
01466
01467 void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow) {
01468 itemDef_t *item;
01469 int i;
01470 int count = Menu_ItemsMatchingGroup(menu, p);
01471 for (i = 0; i < count; i++) {
01472 item = Menu_GetMatchingItemByNumber(menu, i, p);
01473 if (item != NULL) {
01474 if (bShow) {
01475 item->window.flags |= WINDOW_VISIBLE;
01476 } else {
01477 item->window.flags &= ~WINDOW_VISIBLE;
01478
01479 if (item->window.cinematic >= 0) {
01480 DC->stopCinematic(item->window.cinematic);
01481 item->window.cinematic = -1;
01482 }
01483 }
01484 }
01485 }
01486 }
01487
01488 void Menu_FadeItemByName(menuDef_t *menu, const char *p, qboolean fadeOut) {
01489 itemDef_t *item;
01490 int i;
01491 int count = Menu_ItemsMatchingGroup(menu, p);
01492 for (i = 0; i < count; i++) {
01493 item = Menu_GetMatchingItemByNumber(menu, i, p);
01494 if (item != NULL) {
01495 if (fadeOut) {
01496 item->window.flags |= (WINDOW_FADINGOUT | WINDOW_VISIBLE);
01497 item->window.flags &= ~WINDOW_FADINGIN;
01498 } else {
01499 item->window.flags |= (WINDOW_VISIBLE | WINDOW_FADINGIN);
01500 item->window.flags &= ~WINDOW_FADINGOUT;
01501 }
01502 }
01503 }
01504 }
01505
01506 menuDef_t *Menus_FindByName(const char *p) {
01507 int i;
01508 for (i = 0; i < menuCount; i++) {
01509 if (Q_stricmp(Menus[i].window.name, p) == 0) {
01510 return &Menus[i];
01511 }
01512 }
01513 return NULL;
01514 }
01515
01516 void Menus_ShowByName(const char *p) {
01517 menuDef_t *menu = Menus_FindByName(p);
01518 if (menu) {
01519 Menus_Activate(menu);
01520 }
01521 }
01522
01523 void Menus_OpenByName(const char *p) {
01524 Menus_ActivateByName(p);
01525 }
01526
01527 static void Menu_RunCloseScript(menuDef_t *menu) {
01528 if (menu && menu->window.flags & WINDOW_VISIBLE && menu->onClose) {
01529 itemDef_t item;
01530 item.parent = menu;
01531 Item_RunScript(&item, menu->onClose);
01532 }
01533 }
01534
01535 void Menus_CloseByName ( const char *p )
01536 {
01537 menuDef_t *menu = Menus_FindByName(p);
01538
01539
01540 if (menu == NULL)
01541 {
01542 return;
01543 }
01544
01545
01546 Menu_RunCloseScript(menu);
01547
01548
01549 if ( menu->window.flags & WINDOW_HASFOCUS )
01550 {
01551
01552
01553 if ( openMenuCount )
01554 {
01555
01556
01557 openMenuCount -= 1;
01558
01559
01560 menuStack[openMenuCount]->window.flags |= WINDOW_HASFOCUS;
01561
01562
01563 menuStack[openMenuCount] = NULL;
01564 }
01565 }
01566
01567
01568 menu->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS);
01569 }
01570
01571 int FPMessageTime = 0;
01572
01573 void Menus_CloseAll()
01574 {
01575 int i;
01576
01577 g_waitingForKey = qfalse;
01578
01579 for (i = 0; i < menuCount; i++)
01580 {
01581 Menu_RunCloseScript ( &Menus[i] );
01582 Menus[i].window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
01583 }
01584
01585
01586 openMenuCount = 0;
01587
01588 FPMessageTime = 0;
01589 }
01590
01591 qboolean Script_Show(itemDef_t *item, char **args)
01592 {
01593 const char *name;
01594 if (String_Parse(args, &name))
01595 {
01596 Menu_ShowItemByName((menuDef_t *) item->parent, name, qtrue);
01597 }
01598 return qtrue;
01599 }
01600
01601 qboolean Script_Hide(itemDef_t *item, char **args)
01602 {
01603 const char *name;
01604 if (String_Parse(args, &name))
01605 {
01606 Menu_ShowItemByName((menuDef_t *) item->parent, name, qfalse);
01607 }
01608 return qtrue;
01609 }
01610
01611 qboolean Script_FadeIn(itemDef_t *item, char **args)
01612 {
01613 const char *name;
01614 if (String_Parse(args, &name))
01615 {
01616 Menu_FadeItemByName((menuDef_t *) item->parent, name, qfalse);
01617 }
01618
01619 return qtrue;
01620 }
01621
01622 qboolean Script_FadeOut(itemDef_t *item, char **args)
01623 {
01624 const char *name;
01625 if (String_Parse(args, &name))
01626 {
01627 Menu_FadeItemByName((menuDef_t *) item->parent, name, qtrue);
01628 }
01629 return qtrue;
01630 }
01631
01632 qboolean Script_Open(itemDef_t *item, char **args)
01633 {
01634 const char *name;
01635 if (String_Parse(args, &name))
01636 {
01637 Menus_OpenByName(name);
01638 }
01639 return qtrue;
01640 }
01641
01642 qboolean Script_Close(itemDef_t *item, char **args)
01643 {
01644 const char *name;
01645 if (String_Parse(args, &name))
01646 {
01647 if (Q_stricmp(name, "all") == 0)
01648 {
01649 Menus_CloseAll();
01650 }
01651 else
01652 {
01653 Menus_CloseByName(name);
01654 }
01655 }
01656 return qtrue;
01657 }
01658
01659
01660 void Menu_TransitionItemByName(menuDef_t *menu, const char *p, const rectDef_t *rectFrom, const rectDef_t *rectTo, int time, float amt)
01661 {
01662 itemDef_t *item;
01663 int i;
01664 int count = Menu_ItemsMatchingGroup(menu, p);
01665 for (i = 0; i < count; i++)
01666 {
01667 item = Menu_GetMatchingItemByNumber(menu, i, p);
01668 if (item != NULL)
01669 {
01670 if (!rectFrom)
01671 {
01672 rectFrom = &item->window.rect;
01673 }
01674 item->window.flags |= (WINDOW_INTRANSITION | WINDOW_VISIBLE);
01675 item->window.offsetTime = time;
01676 memcpy(&item->window.rectClient, rectFrom, sizeof(rectDef_t));
01677 memcpy(&item->window.rectEffects, rectTo, sizeof(rectDef_t));
01678 item->window.rectEffects2.x = abs(rectTo->x - rectFrom->x) / amt;
01679 item->window.rectEffects2.y = abs(rectTo->y - rectFrom->y) / amt;
01680 item->window.rectEffects2.w = abs(rectTo->w - rectFrom->w) / amt;
01681 item->window.rectEffects2.h = abs(rectTo->h - rectFrom->h) / amt;
01682
01683 Item_UpdatePosition(item);
01684 }
01685 }
01686 }
01687
01688
01689
01690
01691
01692
01693
01694 #define _TRANS3
01695 #ifdef _TRANS3
01696 void Menu_Transition3ItemByName(menuDef_t *menu, const char *p, const float minx, const float miny, const float minz,
01697 const float maxx, const float maxy, const float maxz, const float fovtx, const float fovty,
01698 const int time, const float amt)
01699 {
01700 itemDef_t *item;
01701 int i;
01702 int count = Menu_ItemsMatchingGroup(menu, p);
01703 modelDef_t * modelptr;
01704 for (i = 0; i < count; i++)
01705 {
01706 item = Menu_GetMatchingItemByNumber(menu, i, p);
01707 if (item != NULL)
01708 {
01709 if ( item->type == ITEM_TYPE_MODEL)
01710 {
01711 modelptr = (modelDef_t*)item->typeData;
01712
01713 item->window.flags |= (WINDOW_INTRANSITIONMODEL | WINDOW_VISIBLE);
01714 item->window.offsetTime = time;
01715 modelptr->fov_x2 = fovtx;
01716 modelptr->fov_y2 = fovty;
01717 VectorSet(modelptr->g2maxs2, maxx, maxy, maxz);
01718 VectorSet(modelptr->g2mins2, minx, miny, minz);
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729 modelptr->g2maxsEffect[0] = abs(modelptr->g2maxs2[0] - modelptr->g2maxs[0]) / amt;
01730 modelptr->g2maxsEffect[1] = abs(modelptr->g2maxs2[1] - modelptr->g2maxs[1]) / amt;
01731 modelptr->g2maxsEffect[2] = abs(modelptr->g2maxs2[2] - modelptr->g2maxs[2]) / amt;
01732
01733 modelptr->g2minsEffect[0] = abs(modelptr->g2mins2[0] - modelptr->g2mins[0]) / amt;
01734 modelptr->g2minsEffect[1] = abs(modelptr->g2mins2[1] - modelptr->g2mins[1]) / amt;
01735 modelptr->g2minsEffect[2] = abs(modelptr->g2mins2[2] - modelptr->g2mins[2]) / amt;
01736
01737
01738 modelptr->fov_Effectx = abs(modelptr->fov_x2 - modelptr->fov_x) / amt;
01739 modelptr->fov_Effecty = abs(modelptr->fov_y2 - modelptr->fov_y) / amt;
01740 }
01741
01742 }
01743 }
01744 }
01745
01746 #endif
01747
01748
01749
01750
01751
01752
01753
01754 #define MAX_DEFERRED_SCRIPT 2048
01755
01756 char ui_deferredScript [ MAX_DEFERRED_SCRIPT ];
01757 itemDef_t* ui_deferredScriptItem = NULL;
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767 qboolean Script_Defer ( itemDef_t* item, char **args )
01768 {
01769
01770 if ( DC->deferScript ( (char**)args ) )
01771 {
01772
01773 ui_deferredScriptItem = item;
01774
01775
01776 Q_strncpyz ( ui_deferredScript, *args, MAX_DEFERRED_SCRIPT );
01777
01778
01779 return qfalse;
01780 }
01781
01782
01783 return qtrue;
01784 }
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794 qboolean Script_RunDeferred ( itemDef_t* item, char **args )
01795 {
01796
01797 if ( !ui_deferredScript[0] || !ui_deferredScriptItem )
01798 {
01799 return qtrue;
01800 }
01801
01802
01803 Item_RunScript ( ui_deferredScriptItem, ui_deferredScript );
01804
01805 return qtrue;
01806 }
01807
01808 qboolean Script_Transition(itemDef_t *item, char **args)
01809 {
01810 const char *name;
01811 rectDef_t rectFrom, rectTo;
01812 int time;
01813 float amt;
01814
01815 if (String_Parse(args, &name))
01816 {
01817 if ( Rect_Parse(args, &rectFrom) && Rect_Parse(args, &rectTo) && Int_Parse(args, &time) && Float_Parse(args, &amt))
01818 {
01819 Menu_TransitionItemByName((menuDef_t *) item->parent, name, &rectFrom, &rectTo, time, amt);
01820 }
01821 }
01822
01823 return qtrue;
01824 }
01825
01826 void Menu_OrbitItemByName(menuDef_t *menu, const char *p, float x, float y, float cx, float cy, int time)
01827 {
01828 itemDef_t *item;
01829 int i;
01830 int count = Menu_ItemsMatchingGroup(menu, p);
01831 for (i = 0; i < count; i++) {
01832 item = Menu_GetMatchingItemByNumber(menu, i, p);
01833 if (item != NULL) {
01834 item->window.flags |= (WINDOW_ORBITING | WINDOW_VISIBLE);
01835 item->window.offsetTime = time;
01836 item->window.rectEffects.x = cx;
01837 item->window.rectEffects.y = cy;
01838 item->window.rectClient.x = x;
01839 item->window.rectClient.y = y;
01840 Item_UpdatePosition(item);
01841 }
01842 }
01843 }
01844
01845 void Menu_ItemDisable(menuDef_t *menu, char *name,int disableFlag)
01846 {
01847 int j,count;
01848 itemDef_t *itemFound;
01849
01850 count = Menu_ItemsMatchingGroup(menu, name);
01851
01852 for (j = 0; j < count; j++)
01853 {
01854 itemFound = Menu_GetMatchingItemByNumber( menu, j, name);
01855 if (itemFound != NULL)
01856 {
01857 itemFound->disabled = disableFlag;
01858
01859 itemFound->window.flags &= ~WINDOW_MOUSEOVER;
01860 }
01861 }
01862 }
01863
01864
01865 qboolean Script_Disable(itemDef_t *item, char **args)
01866 {
01867 char *name;
01868 int value;
01869 menuDef_t *menu;
01870
01871 if (String_Parse(args, (const char **)&name))
01872 {
01873 char buff[1024];
01874
01875
01876 if (name[0] == '*')
01877 {
01878 name += 1;
01879 DC->getCVarString(name, buff, sizeof(buff));
01880 name = buff;
01881 }
01882
01883 if ( Int_Parse(args, &value))
01884 {
01885 menu = Menu_GetFocused();
01886 Menu_ItemDisable(menu, name,value);
01887 }
01888 }
01889
01890 return qtrue;
01891 }
01892
01893
01894
01895 qboolean Script_Scale(itemDef_t *item, char **args)
01896 {
01897 const char *name;
01898 float scale;
01899 int j,count;
01900 itemDef_t *itemFound;
01901 rectDef_t rectTo;
01902
01903 if (String_Parse(args, &name))
01904 {
01905 char buff[1024];
01906
01907
01908 if (name[0] == '*')
01909 {
01910 name += 1;
01911 DC->getCVarString(name, buff, sizeof(buff));
01912 name = buff;
01913 }
01914
01915 count = Menu_ItemsMatchingGroup((menuDef_t *) item->parent, name);
01916
01917 if ( Float_Parse(args, &scale))
01918 {
01919 for (j = 0; j < count; j++)
01920 {
01921 itemFound = Menu_GetMatchingItemByNumber( (menuDef_t *) item->parent, j, name);
01922 if (itemFound != NULL)
01923 {
01924 rectTo.h = itemFound->window.rect.h * scale;
01925 rectTo.w = itemFound->window.rect.w * scale;
01926
01927 rectTo.x = itemFound->window.rect.x + ((itemFound->window.rect.h - rectTo.h)/2);
01928 rectTo.y = itemFound->window.rect.y + ((itemFound->window.rect.w - rectTo.w)/2);
01929
01930 Menu_TransitionItemByName((menuDef_t *) item->parent, name, 0, &rectTo, 1, 1);
01931 }
01932 }
01933 }
01934 }
01935
01936 return qtrue;
01937 }
01938
01939 qboolean Script_Orbit(itemDef_t *item, char **args)
01940 {
01941 const char *name;
01942 float cx, cy, x, y;
01943 int time;
01944
01945 if (String_Parse(args, &name))
01946 {
01947 if ( Float_Parse(args, &x) && Float_Parse(args, &y) && Float_Parse(args, &cx) && Float_Parse(args, &cy) && Int_Parse(args, &time) )
01948 {
01949 Menu_OrbitItemByName((menuDef_t *) item->parent, name, x, y, cx, cy, time);
01950 }
01951 }
01952
01953 return qtrue;
01954 }
01955
01956 qboolean Script_SetFocus(itemDef_t *item, char **args)
01957 {
01958 const char *name;
01959 itemDef_t *focusItem;
01960
01961 if (String_Parse(args, &name)) {
01962 focusItem = Menu_FindItemByName((menuDef_t *) item->parent, name);
01963 if (focusItem && !(focusItem->window.flags & WINDOW_DECORATION) && !(focusItem->window.flags & WINDOW_HASFOCUS)) {
01964 Menu_ClearFocus((menuDef_t *) item->parent);
01965
01966 #ifdef _XBOX
01967 Item_SetFocus(focusItem, 0,0);
01968 #else
01969 focusItem->window.flags |= WINDOW_HASFOCUS;
01970 #endif
01971
01972
01973
01974 if (focusItem->onFocus) {
01975 Item_RunScript(focusItem, focusItem->onFocus);
01976 }
01977 if (DC->Assets.itemFocusSound) {
01978 DC->startLocalSound( DC->Assets.itemFocusSound, CHAN_LOCAL_SOUND );
01979 }
01980 }
01981 }
01982
01983 return qtrue;
01984 }
01985
01986 qboolean Script_SetPlayerModel(itemDef_t *item, char **args)
01987 {
01988 const char *name;
01989 if (String_Parse(args, &name))
01990 {
01991 DC->setCVar("model", name);
01992 }
01993
01994 return qtrue;
01995 }
01996
01997
01998
01999
02000
02001
02002 qboolean ParseRect(const char **p, rectDef_t *r)
02003 {
02004 if (!COM_ParseFloat(p, &r->x))
02005 {
02006 if (!COM_ParseFloat(p, &r->y))
02007 {
02008 if (!COM_ParseFloat(p, &r->w))
02009 {
02010 if (!COM_ParseFloat(p, &r->h))
02011 {
02012 return qtrue;
02013 }
02014 }
02015 }
02016 }
02017 return qfalse;
02018 }
02019
02020
02021
02022
02023
02024
02025
02026
02027 qboolean Script_Transition2(itemDef_t *item, char **args)
02028 {
02029 const char *name;
02030 rectDef_t rectTo;
02031 int time;
02032 float amt;
02033
02034 if (String_Parse(args, &name))
02035 {
02036 if ( ParseRect((const char **) args, &rectTo) && Int_Parse(args, &time) && !COM_ParseFloat((const char **) args, &amt))
02037 {
02038 Menu_TransitionItemByName((menuDef_t *) item->parent, name, 0, &rectTo, time, amt);
02039 }
02040 else
02041 {
02042 Com_Printf(S_COLOR_YELLOW"WARNING: Script_Transition2: error parsing '%s'\n", name );
02043 }
02044 }
02045
02046 return qtrue;
02047 }
02048
02049 #ifdef _TRANS3
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062 qboolean Script_Transition3(itemDef_t *item, char **args)
02063 {
02064 const char *name;
02065 const char *value;
02066 float minx, miny, minz, maxx, maxy, maxz, fovtx, fovty;
02067 int time;
02068 float amt;
02069
02070 if (String_Parse(args, &name))
02071 {
02072 if (String_Parse( args, &value))
02073 {
02074 minx = atof(value);
02075 if (String_Parse( args, &value))
02076 {
02077 miny = atof(value);
02078 if (String_Parse( args, &value))
02079 {
02080 minz = atof(value);
02081 if (String_Parse( args, &value))
02082 {
02083 maxx = atof(value);
02084 if (String_Parse( args, &value))
02085 {
02086 maxy = atof(value);
02087 if (String_Parse( args, &value))
02088 {
02089 maxz = atof(value);
02090 if (String_Parse( args, &value))
02091 {
02092 fovtx = atof(value);
02093 if (String_Parse( args, &value))
02094 {
02095 fovty = atof(value);
02096
02097 if (String_Parse( args, &value))
02098 {
02099 time = atoi(value);
02100 if (String_Parse( args, &value))
02101 {
02102 amt = atof(value);
02103
02104 Menu_Transition3ItemByName((menuDef_t *) item->parent,
02105 name,
02106 minx, miny, minz,
02107 maxx, maxy, maxz,
02108 fovtx, fovty,
02109 time, amt);
02110
02111 return qtrue;
02112 }
02113 }
02114 }
02115 }
02116 }
02117 }
02118 }
02119 }
02120 }
02121 }
02122 }
02123 Com_Printf(S_COLOR_YELLOW"WARNING: Script_Transition2: error parsing '%s'\n", name );
02124 return qtrue;
02125 }
02126 #endif
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 qboolean Script_SetCvar(itemDef_t *item, char **args)
02151 {
02152 const char *cvar, *val;
02153 if (String_Parse(args, &cvar) && String_Parse(args, &val))
02154 {
02155 DC->setCVar(cvar, val);
02156 }
02157 return qtrue;
02158 }
02159
02160 qboolean Script_SetCvarToCvar(itemDef_t *item, char **args) {
02161 const char *cvar, *val;
02162 if (String_Parse(args, &cvar) && String_Parse(args, &val)) {
02163 char cvarBuf[1024];
02164 DC->getCVarString(val, cvarBuf, sizeof(cvarBuf));
02165 DC->setCVar(cvar, cvarBuf);
02166 }
02167 return qtrue;
02168 }
02169
02170 qboolean Script_Exec(itemDef_t *item, char **args) {
02171 const char *val;
02172 if (String_Parse(args, &val)) {
02173 DC->executeText(EXEC_APPEND, va("%s ; ", val));
02174 }
02175 return qtrue;
02176 }
02177
02178 qboolean Script_Play(itemDef_t *item, char **args) {
02179 const char *val;
02180 if (String_Parse(args, &val)) {
02181 DC->startLocalSound(DC->registerSound(val), CHAN_AUTO);
02182 }
02183 return qtrue;
02184 }
02185
02186 qboolean Script_playLooped(itemDef_t *item, char **args) {
02187 const char *val;
02188 if (String_Parse(args, &val)) {
02189 DC->stopBackgroundTrack();
02190 DC->startBackgroundTrack(val, val, qfalse);
02191 }
02192 return qtrue;
02193 }
02194
02195
02196 commandDef_t commandList[] =
02197 {
02198 {"fadein", &Script_FadeIn},
02199 {"fadeout", &Script_FadeOut},
02200 {"show", &Script_Show},
02201 {"hide", &Script_Hide},
02202 {"setcolor", &Script_SetColor},
02203 {"open", &Script_Open},
02204 {"close", &Script_Close},
02205 {"setasset", &Script_SetAsset},
02206 {"setbackground", &Script_SetBackground},
02207 {"setitemrectcvar", &Script_SetItemRectCvar},
02208 {"setitembackground", &Script_SetItemBackground},
02209 {"setitemtext", &Script_SetItemText},
02210 {"setitemcolor", &Script_SetItemColor},
02211 {"setitemcolorcvar", &Script_SetItemColorCvar},
02212 {"setitemrect", &Script_SetItemRect},
02213 {"setteamcolor", &Script_SetTeamColor},
02214 {"setfocus", &Script_SetFocus},
02215 {"setplayermodel", &Script_SetPlayerModel},
02216 {"transition", &Script_Transition},
02217 {"setcvar", &Script_SetCvar},
02218 {"setcvartocvar", &Script_SetCvarToCvar},
02219 {"exec", &Script_Exec},
02220 {"play", &Script_Play},
02221 {"playlooped", &Script_playLooped},
02222 {"orbit", &Script_Orbit},
02223 {"scale", &Script_Scale},
02224 {"disable", &Script_Disable},
02225 {"defer", &Script_Defer},
02226 {"rundeferred", &Script_RunDeferred},
02227 {"transition2", &Script_Transition2},
02228 };
02229
02230
02231 void Menu_SetItemBackground(const menuDef_t *menu,const char *itemName, const char *background)
02232 {
02233 itemDef_t *item;
02234 int j, count;
02235
02236 if (!menu)
02237 {
02238 return;
02239 }
02240
02241 count = Menu_ItemsMatchingGroup( (menuDef_t *) menu, itemName);
02242
02243 for (j = 0; j < count; j++)
02244 {
02245 item = Menu_GetMatchingItemByNumber( (menuDef_t *) menu, j, itemName);
02246 if (item != NULL)
02247 {
02248 item->window.background = DC->registerShaderNoMip(background);
02249 }
02250 }
02251 }
02252
02253
02254 void Menu_SetItemText(const menuDef_t *menu,const char *itemName, const char *text)
02255 {
02256 itemDef_t *item;
02257 int j, count;
02258
02259 if (!menu)
02260 {
02261 return;
02262 }
02263
02264 count = Menu_ItemsMatchingGroup( (menuDef_t *) menu, itemName);
02265
02266 for (j = 0; j < count; j++)
02267 {
02268 item = Menu_GetMatchingItemByNumber( (menuDef_t *) menu, j, itemName);
02269 if (item != NULL)
02270 {
02271 if (text[0] == '*')
02272 {
02273 item->text = NULL;
02274 item->cvar = text+1;
02275
02276 if ( item->typeData)
02277 {
02278 editFieldDef_t *editPtr;
02279 editPtr = (editFieldDef_t*)item->typeData;
02280 editPtr->minVal = -1;
02281 editPtr->maxVal = -1;
02282 editPtr->defVal = -1;
02283 }
02284 }
02285 else
02286 {
02287 item->text = text;
02288 if ( item->type == ITEM_TYPE_TEXTSCROLL )
02289 {
02290 textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
02291 if ( scrollPtr )
02292 {
02293 scrollPtr->startPos = 0;
02294 scrollPtr->endPos = 0;
02295 }
02296
02297 Item_TextScroll_BuildLines ( item );
02298 }
02299 }
02300 }
02301 }
02302 }
02303
02304 int scriptCommandCount = sizeof(commandList) / sizeof(commandDef_t);
02305
02306 void Item_RunScript(itemDef_t *item, const char *s)
02307 {
02308 char script[2048], *p;
02309 int i;
02310 qboolean bRan;
02311
02312 script[0] = 0;
02313
02314 if (item && s && s[0])
02315 {
02316 Q_strcat(script, 2048, s);
02317 p = script;
02318
02319 while (1)
02320 {
02321 const char *command;
02322
02323
02324 if (!String_Parse(&p, &command))
02325 {
02326 return;
02327 }
02328
02329 if (command[0] == ';' && command[1] == '\0')
02330 {
02331 continue;
02332 }
02333
02334 bRan = qfalse;
02335 for (i = 0; i < scriptCommandCount; i++)
02336 {
02337 if (Q_stricmp(command, commandList[i].name) == 0)
02338 {
02339
02340 if ( !commandList[i].handler(item, &p) )
02341 {
02342 return;
02343 }
02344
02345 bRan = qtrue;
02346 break;
02347 }
02348 }
02349
02350
02351 if (!bRan)
02352 {
02353 DC->runScript(&p);
02354 }
02355 }
02356 }
02357 }
02358
02359
02360 qboolean Item_EnableShowViaCvar(itemDef_t *item, int flag) {
02361 char script[2048], *p;
02362 if (item && item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest) {
02363 char buff[2048];
02364 DC->getCVarString(item->cvarTest, buff, sizeof(buff));
02365
02366 Q_strncpyz(script, item->enableCvar, 2048);
02367 p = script;
02368 while (1) {
02369 const char *val;
02370
02371 if (!String_Parse(&p, &val)) {
02372 return (item->cvarFlags & flag) ? qfalse : qtrue;
02373 }
02374
02375 if (val[0] == ';' && val[1] == '\0') {
02376 continue;
02377 }
02378
02379
02380 if (item->cvarFlags & flag) {
02381 if (Q_stricmp(buff, val) == 0) {
02382 return qtrue;
02383 }
02384 } else {
02385
02386 if (Q_stricmp(buff, val) == 0) {
02387 return qfalse;
02388 }
02389 }
02390
02391 }
02392 return (item->cvarFlags & flag) ? qfalse : qtrue;
02393 }
02394 return qtrue;
02395 }
02396
02397
02398
02399 qboolean Item_SetFocus(itemDef_t *item, float x, float y) {
02400 int i;
02401 itemDef_t *oldFocus;
02402 sfxHandle_t *sfx = &DC->Assets.itemFocusSound;
02403 qboolean playSound = qfalse;
02404 menuDef_t *parent;
02405
02406 if (item == NULL || item->window.flags & WINDOW_DECORATION || item->window.flags & WINDOW_HASFOCUS || !(item->window.flags & WINDOW_VISIBLE)) {
02407 return qfalse;
02408 }
02409
02410
02411 parent = (menuDef_t*)item->parent;
02412
02413
02414 if (item->disabled)
02415 {
02416 return qfalse;
02417 }
02418
02419
02420 if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
02421 return qfalse;
02422 }
02423
02424 if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW)) {
02425 return qfalse;
02426 }
02427
02428 oldFocus = Menu_ClearFocus((menuDef_t *) item->parent);
02429
02430 if (item->type == ITEM_TYPE_TEXT) {
02431 rectDef_t r;
02432 r = item->textRect;
02433 r.y -= r.h;
02434
02435
02436 #ifndef _XBOX
02437 if (Rect_ContainsPoint(&r, x, y))
02438 #endif
02439 {
02440 item->window.flags |= WINDOW_HASFOCUS;
02441 if (item->focusSound) {
02442 sfx = &item->focusSound;
02443 }
02444 playSound = qtrue;
02445 }
02446 #ifndef _XBOX
02447 else
02448 #endif
02449 {
02450 if (oldFocus) {
02451 oldFocus->window.flags |= WINDOW_HASFOCUS;
02452 if (oldFocus->onFocus) {
02453 Item_RunScript(oldFocus, oldFocus->onFocus);
02454 }
02455 }
02456 }
02457 } else {
02458 item->window.flags |= WINDOW_HASFOCUS;
02459 if (item->onFocus) {
02460 Item_RunScript(item, item->onFocus);
02461 }
02462 if (item->focusSound) {
02463 sfx = &item->focusSound;
02464 }
02465 playSound = qtrue;
02466 }
02467
02468 if (playSound && sfx) {
02469 DC->startLocalSound( *sfx, CHAN_LOCAL_SOUND );
02470 }
02471
02472 for (i = 0; i < parent->itemCount; i++) {
02473 if (parent->items[i] == item) {
02474 parent->cursorItem = i;
02475 break;
02476 }
02477 }
02478
02479 return qtrue;
02480 }
02481
02482 int Item_TextScroll_MaxScroll ( itemDef_t *item )
02483 {
02484 textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
02485
02486 int count = scrollPtr->iLineCount;
02487 int max = count - (int)(item->window.rect.h / scrollPtr->lineHeight) + 1;
02488
02489 if (max < 0)
02490 {
02491 return 0;
02492 }
02493
02494 return max;
02495 }
02496
02497 int Item_TextScroll_ThumbPosition ( itemDef_t *item )
02498 {
02499 float max, pos, size;
02500 textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
02501
02502 max = Item_TextScroll_MaxScroll ( item );
02503 size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2;
02504
02505 if (max > 0)
02506 {
02507 pos = (size-SCROLLBAR_SIZE) / (float) max;
02508 }
02509 else
02510 {
02511 pos = 0;
02512 }
02513
02514 pos *= scrollPtr->startPos;
02515
02516 return item->window.rect.y + 1 + SCROLLBAR_SIZE + pos;
02517 }
02518
02519 int Item_TextScroll_ThumbDrawPosition ( itemDef_t *item )
02520 {
02521 int min, max;
02522
02523 if (itemCapture == item)
02524 {
02525 min = item->window.rect.y + SCROLLBAR_SIZE + 1;
02526 max = item->window.rect.y + item->window.rect.h - 2*SCROLLBAR_SIZE - 1;
02527
02528 if (DC->cursory >= min + SCROLLBAR_SIZE/2 && DC->cursory <= max + SCROLLBAR_SIZE/2)
02529 {
02530 return DC->cursory - SCROLLBAR_SIZE/2;
02531 }
02532
02533 return Item_TextScroll_ThumbPosition(item);
02534 }
02535
02536 return Item_TextScroll_ThumbPosition(item);
02537 }
02538
02539 int Item_TextScroll_OverLB ( itemDef_t *item, float x, float y )
02540 {
02541 rectDef_t r;
02542 textScrollDef_t *scrollPtr;
02543 int thumbstart;
02544 int count;
02545
02546 scrollPtr = (textScrollDef_t*)item->typeData;
02547 count = scrollPtr->iLineCount;
02548
02549 r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
02550 r.y = item->window.rect.y;
02551 r.h = r.w = SCROLLBAR_SIZE;
02552 if (Rect_ContainsPoint(&r, x, y))
02553 {
02554 return WINDOW_LB_LEFTARROW;
02555 }
02556
02557 r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
02558 if (Rect_ContainsPoint(&r, x, y))
02559 {
02560 return WINDOW_LB_RIGHTARROW;
02561 }
02562
02563 thumbstart = Item_TextScroll_ThumbPosition(item);
02564 r.y = thumbstart;
02565 if (Rect_ContainsPoint(&r, x, y))
02566 {
02567 return WINDOW_LB_THUMB;
02568 }
02569
02570 r.y = item->window.rect.y + SCROLLBAR_SIZE;
02571 r.h = thumbstart - r.y;
02572 if (Rect_ContainsPoint(&r, x, y))
02573 {
02574 return WINDOW_LB_PGUP;
02575 }
02576
02577 r.y = thumbstart + SCROLLBAR_SIZE;
02578 r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
02579 if (Rect_ContainsPoint(&r, x, y))
02580 {
02581 return WINDOW_LB_PGDN;
02582 }
02583
02584 return 0;
02585 }
02586
02587 void Item_TextScroll_MouseEnter (itemDef_t *item, float x, float y)
02588 {
02589 item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN);
02590 item->window.flags |= Item_TextScroll_OverLB(item, x, y);
02591 }
02592
02593 qboolean Item_TextScroll_HandleKey ( itemDef_t *item, int key, qboolean down, qboolean force)
02594 {
02595 textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
02596 int max;
02597 int viewmax;
02598
02599 if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS))
02600 {
02601 max = Item_TextScroll_MaxScroll(item);
02602
02603 viewmax = (item->window.rect.h / scrollPtr->lineHeight);
02604 if ( key == A_CURSOR_UP || key == A_KP_8 )
02605 {
02606 scrollPtr->startPos--;
02607 if (scrollPtr->startPos < 0)
02608 {
02609 scrollPtr->startPos = 0;
02610 }
02611 return qtrue;
02612 }
02613
02614 if ( key == A_CURSOR_DOWN || key == A_KP_2 )
02615 {
02616 scrollPtr->startPos++;
02617 if (scrollPtr->startPos > max)
02618 {
02619 scrollPtr->startPos = max;
02620 }
02621
02622 return qtrue;
02623 }
02624
02625
02626 if (key == A_MOUSE1 || key == A_MOUSE2)
02627 {
02628 if (item->window.flags & WINDOW_LB_LEFTARROW)
02629 {
02630 scrollPtr->startPos--;
02631 if (scrollPtr->startPos < 0)
02632 {
02633 scrollPtr->startPos = 0;
02634 }
02635 }
02636 else if (item->window.flags & WINDOW_LB_RIGHTARROW)
02637 {
02638
02639 scrollPtr->startPos++;
02640 if (scrollPtr->startPos > max)
02641 {
02642 scrollPtr->startPos = max;
02643 }
02644 }
02645 else if (item->window.flags & WINDOW_LB_PGUP)
02646 {
02647
02648 scrollPtr->startPos -= viewmax;
02649 if (scrollPtr->startPos < 0)
02650 {
02651 scrollPtr->startPos = 0;
02652 }
02653 }
02654 else if (item->window.flags & WINDOW_LB_PGDN)
02655 {
02656
02657 scrollPtr->startPos += viewmax;
02658 if (scrollPtr->startPos > max)
02659 {
02660 scrollPtr->startPos = max;
02661 }
02662 }
02663 else if (item->window.flags & WINDOW_LB_THUMB)
02664 {
02665
02666 }
02667
02668 return qtrue;
02669 }
02670
02671 if ( key == A_HOME || key == A_KP_7)
02672 {
02673
02674 scrollPtr->startPos = 0;
02675 return qtrue;
02676 }
02677 if ( key == A_END || key == A_KP_1)
02678 {
02679
02680 scrollPtr->startPos = max;
02681 return qtrue;
02682 }
02683 if (key == A_PAGE_UP || key == A_KP_9 )
02684 {
02685 scrollPtr->startPos -= viewmax;
02686 if (scrollPtr->startPos < 0)
02687 {
02688 scrollPtr->startPos = 0;
02689 }
02690
02691 return qtrue;
02692 }
02693 if ( key == A_PAGE_DOWN || key == A_KP_3 )
02694 {
02695 scrollPtr->startPos += viewmax;
02696 if (scrollPtr->startPos > max)
02697 {
02698 scrollPtr->startPos = max;
02699 }
02700 return qtrue;
02701 }
02702 }
02703
02704 return qfalse;
02705 }
02706
02707 int Item_ListBox_MaxScroll(itemDef_t *item) {
02708 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
02709 int count = DC->feederCount(item->special);
02710 int max;
02711
02712 if (item->window.flags & WINDOW_HORIZONTAL) {
02713 max = count - (item->window.rect.w / listPtr->elementWidth) + 1;
02714 }
02715 else {
02716 max = count - (item->window.rect.h / listPtr->elementHeight) + 1;
02717 }
02718 if (max < 0) {
02719 return 0;
02720 }
02721 return max;
02722 }
02723
02724 int Item_ListBox_ThumbPosition(itemDef_t *item) {
02725 float max, pos, size;
02726 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
02727
02728 max = Item_ListBox_MaxScroll(item);
02729 if (item->window.flags & WINDOW_HORIZONTAL) {
02730 size = item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2;
02731 if (max > 0) {
02732 pos = (size-SCROLLBAR_SIZE) / (float) max;
02733 } else {
02734 pos = 0;
02735 }
02736 pos *= listPtr->startPos;
02737 return item->window.rect.x + 1 + SCROLLBAR_SIZE + pos;
02738 }
02739 else {
02740 size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2;
02741 if (max > 0) {
02742 pos = (size-SCROLLBAR_SIZE) / (float) max;
02743 } else {
02744 pos = 0;
02745 }
02746 pos *= listPtr->startPos;
02747 return item->window.rect.y + 1 + SCROLLBAR_SIZE + pos;
02748 }
02749 }
02750
02751 int Item_ListBox_ThumbDrawPosition(itemDef_t *item)
02752 {
02753 int min, max;
02754
02755 if (itemCapture == item)
02756 {
02757 if (item->window.flags & WINDOW_HORIZONTAL)
02758 {
02759 min = item->window.rect.x + SCROLLBAR_SIZE + 1;
02760 max = item->window.rect.x + item->window.rect.w - 2*SCROLLBAR_SIZE - 1;
02761 if (DC->cursorx >= min + SCROLLBAR_SIZE/2 && DC->cursorx <= max + SCROLLBAR_SIZE/2)
02762 {
02763 return DC->cursorx - SCROLLBAR_SIZE/2;
02764 }
02765 else
02766 {
02767 return Item_ListBox_ThumbPosition(item);
02768 }
02769 }
02770 else
02771 {
02772 min = item->window.rect.y + SCROLLBAR_SIZE + 1;
02773 max = item->window.rect.y + item->window.rect.h - 2*SCROLLBAR_SIZE - 1;
02774 if (DC->cursory >= min + SCROLLBAR_SIZE/2 && DC->cursory <= max + SCROLLBAR_SIZE/2)
02775 {
02776 return DC->cursory - SCROLLBAR_SIZE/2;
02777 }
02778 else
02779 {
02780 return Item_ListBox_ThumbPosition(item);
02781 }
02782 }
02783 }
02784 else
02785 {
02786 return Item_ListBox_ThumbPosition(item);
02787 }
02788 }
02789
02790 float Item_Slider_ThumbPosition(itemDef_t *item) {
02791 float value, range, x;
02792 editFieldDef_t *editDef = (editFieldDef_t *) item->typeData;
02793
02794 if (item->text) {
02795 x = item->textRect.x + item->textRect.w + 8;
02796 } else {
02797 x = item->window.rect.x;
02798 }
02799
02800 if (editDef == NULL && item->cvar) {
02801 return x;
02802 }
02803
02804 value = DC->getCVarValue(item->cvar);
02805
02806 if (value < editDef->minVal) {
02807 value = editDef->minVal;
02808 } else if (value > editDef->maxVal) {
02809 value = editDef->maxVal;
02810 }
02811
02812 range = editDef->maxVal - editDef->minVal;
02813 value -= editDef->minVal;
02814 value /= range;
02815
02816 value *= SLIDER_WIDTH;
02817 x += value;
02818
02819
02820 return x;
02821 }
02822
02823 int Item_Slider_OverSlider(itemDef_t *item, float x, float y) {
02824 rectDef_t r;
02825
02826 r.x = Item_Slider_ThumbPosition(item) - (SLIDER_THUMB_WIDTH / 2);
02827 r.y = item->window.rect.y - 2;
02828 r.w = SLIDER_THUMB_WIDTH;
02829 r.h = SLIDER_THUMB_HEIGHT;
02830
02831 if (Rect_ContainsPoint(&r, x, y)) {
02832 return WINDOW_LB_THUMB;
02833 }
02834 return 0;
02835 }
02836
02837 int Item_ListBox_OverLB(itemDef_t *item, float x, float y)
02838 {
02839 rectDef_t r;
02840 listBoxDef_t *listPtr;
02841 int thumbstart;
02842 int count;
02843
02844 count = DC->feederCount(item->special);
02845 listPtr = (listBoxDef_t*)item->typeData;
02846 if (item->window.flags & WINDOW_HORIZONTAL)
02847 {
02848
02849 r.x = item->window.rect.x;
02850 r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
02851 r.h = r.w = SCROLLBAR_SIZE;
02852 if (Rect_ContainsPoint(&r, x, y))
02853 {
02854 return WINDOW_LB_LEFTARROW;
02855 }
02856
02857
02858 r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
02859 if (Rect_ContainsPoint(&r, x, y))
02860 {
02861 return WINDOW_LB_RIGHTARROW;
02862 }
02863
02864
02865 thumbstart = Item_ListBox_ThumbPosition(item);
02866 r.x = thumbstart;
02867 if (Rect_ContainsPoint(&r, x, y))
02868 {
02869 return WINDOW_LB_THUMB;
02870 }
02871
02872 r.x = item->window.rect.x + SCROLLBAR_SIZE;
02873 r.w = thumbstart - r.x;
02874 if (Rect_ContainsPoint(&r, x, y))
02875 {
02876 return WINDOW_LB_PGUP;
02877 }
02878
02879 r.x = thumbstart + SCROLLBAR_SIZE;
02880 r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
02881 if (Rect_ContainsPoint(&r, x, y))
02882 {
02883 return WINDOW_LB_PGDN;
02884 }
02885 }
02886
02887 else
02888 {
02889
02890 if (( item->window.rect.w > (listPtr->elementWidth*2)) && (listPtr->elementStyle == LISTBOX_IMAGE))
02891 {
02892 r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
02893 r.y = item->window.rect.y;
02894 r.h = r.w = SCROLLBAR_SIZE;
02895 if (Rect_ContainsPoint(&r, x, y))
02896 {
02897 return WINDOW_LB_PGUP;
02898 }
02899
02900 r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
02901 if (Rect_ContainsPoint(&r, x, y))
02902 {
02903 return WINDOW_LB_PGDN;
02904 }
02905
02906 thumbstart = Item_ListBox_ThumbPosition(item);
02907 r.y = thumbstart;
02908 if (Rect_ContainsPoint(&r, x, y))
02909 {
02910 return WINDOW_LB_THUMB;
02911 }
02912
02913 }
02914 else
02915 {
02916 r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
02917 r.y = item->window.rect.y;
02918 r.h = r.w = SCROLLBAR_SIZE;
02919 if (Rect_ContainsPoint(&r, x, y))
02920 {
02921 return WINDOW_LB_LEFTARROW;
02922 }
02923
02924 r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
02925 if (Rect_ContainsPoint(&r, x, y))
02926 {
02927 return WINDOW_LB_RIGHTARROW;
02928 }
02929
02930 thumbstart = Item_ListBox_ThumbPosition(item);
02931 r.y = thumbstart;
02932 if (Rect_ContainsPoint(&r, x, y))
02933 {
02934 return WINDOW_LB_THUMB;
02935 }
02936
02937 r.y = item->window.rect.y + SCROLLBAR_SIZE;
02938 r.h = thumbstart - r.y;
02939 if (Rect_ContainsPoint(&r, x, y))
02940 {
02941 return WINDOW_LB_PGUP;
02942 }
02943
02944 r.y = thumbstart + SCROLLBAR_SIZE;
02945 r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
02946 if (Rect_ContainsPoint(&r, x, y))
02947 {
02948 return WINDOW_LB_PGDN;
02949 }
02950 }
02951 }
02952 return 0;
02953 }
02954
02955
02956 void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y)
02957 {
02958 rectDef_t r;
02959 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
02960
02961 item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN);
02962 item->window.flags |= Item_ListBox_OverLB(item, x, y);
02963
02964 if (item->window.flags & WINDOW_HORIZONTAL)
02965 {
02966 if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN)))
02967 {
02968
02969 if (listPtr->elementStyle == LISTBOX_IMAGE)
02970 {
02971 r.x = item->window.rect.x;
02972 r.y = item->window.rect.y;
02973 r.h = item->window.rect.h - SCROLLBAR_SIZE;
02974 r.w = item->window.rect.w - listPtr->drawPadding;
02975 if (Rect_ContainsPoint(&r, x, y))
02976 {
02977 listPtr->cursorPos = (int)((x - r.x) / listPtr->elementWidth) + listPtr->startPos;
02978 if (listPtr->cursorPos >= listPtr->endPos)
02979 {
02980 listPtr->cursorPos = listPtr->endPos;
02981 }
02982 }
02983 }
02984 else
02985 {
02986
02987 }
02988 }
02989 }
02990
02991 else if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN)))
02992 {
02993
02994 r.x = item->window.rect.x;
02995 r.y = item->window.rect.y;
02996 r.w = item->window.rect.w - SCROLLBAR_SIZE;
02997 r.h = item->window.rect.h - listPtr->drawPadding;
02998 if (Rect_ContainsPoint(&r, x, y))
02999 {
03000
03001 if (( item->window.rect.w > (listPtr->elementWidth*2)) && (listPtr->elementStyle == LISTBOX_IMAGE))
03002 {
03003 int row,column,rowLength;
03004
03005 row = (int)((y - 2 - r.y) / listPtr->elementHeight);
03006 rowLength = (int) r.w / listPtr->elementWidth;
03007 column = (int)((x - r.x) / listPtr->elementWidth);
03008
03009 listPtr->cursorPos = (row * rowLength)+column + listPtr->startPos;
03010 if (listPtr->cursorPos >= listPtr->endPos)
03011 {
03012 listPtr->cursorPos = listPtr->endPos;
03013 }
03014 }
03015
03016 else
03017 {
03018 listPtr->cursorPos = (int)((y - 2 - r.y) / listPtr->elementHeight) + listPtr->startPos;
03019 if (listPtr->cursorPos > listPtr->endPos)
03020 {
03021 listPtr->cursorPos = listPtr->endPos;
03022 }
03023 }
03024 }
03025 }
03026 }
03027
03028 void Item_MouseEnter(itemDef_t *item, float x, float y) {
03029
03030 rectDef_t r;
03031 if (item) {
03032 r = item->textRect;
03033 r.y -= r.h;
03034
03035
03036
03037 if (item->disabled)
03038 {
03039 return;
03040 }
03041
03042
03043 if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
03044 return;
03045 }
03046
03047 if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW)) {
03048 return;
03049 }
03050
03051
03052 #ifndef _XBOX
03053 if (Rect_ContainsPoint(&r, x, y))
03054 #else
03055 if (item->flags & WINDOW_HASFOCUS)
03056 #endif
03057 {
03058 if (!(item->window.flags & WINDOW_MOUSEOVERTEXT)) {
03059 Item_RunScript(item, item->mouseEnterText);
03060 item->window.flags |= WINDOW_MOUSEOVERTEXT;
03061 }
03062 if (!(item->window.flags & WINDOW_MOUSEOVER)) {
03063 Item_RunScript(item, item->mouseEnter);
03064 item->window.flags |= WINDOW_MOUSEOVER;
03065 }
03066
03067 } else {
03068
03069 if (item->window.flags & WINDOW_MOUSEOVERTEXT) {
03070
03071 Item_RunScript(item, item->mouseExitText);
03072 item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
03073 }
03074 if (!(item->window.flags & WINDOW_MOUSEOVER)) {
03075 Item_RunScript(item, item->mouseEnter);
03076 item->window.flags |= WINDOW_MOUSEOVER;
03077 }
03078
03079 if (item->type == ITEM_TYPE_LISTBOX) {
03080 Item_ListBox_MouseEnter(item, x, y);
03081 }
03082 else if ( item->type == ITEM_TYPE_TEXTSCROLL )
03083 {
03084 Item_TextScroll_MouseEnter ( item, x, y );
03085 }
03086 }
03087 }
03088 }
03089
03090 void Item_MouseLeave(itemDef_t *item) {
03091 if (item) {
03092 if (item->window.flags & WINDOW_MOUSEOVERTEXT) {
03093 Item_RunScript(item, item->mouseExitText);
03094 item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
03095 }
03096 Item_RunScript(item, item->mouseExit);
03097 item->window.flags &= ~(WINDOW_LB_RIGHTARROW | WINDOW_LB_LEFTARROW);
03098 }
03099 }
03100
03101 itemDef_t *Menu_HitTest(menuDef_t *menu, float x, float y) {
03102 int i;
03103 for (i = 0; i < menu->itemCount; i++) {
03104 if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) {
03105 return menu->items[i];
03106 }
03107 }
03108 return NULL;
03109 }
03110
03111 void Item_SetMouseOver(itemDef_t *item, qboolean focus) {
03112 if (item) {
03113 if (focus) {
03114 item->window.flags |= WINDOW_MOUSEOVER;
03115 } else {
03116 item->window.flags &= ~WINDOW_MOUSEOVER;
03117 }
03118 }
03119 }
03120
03121
03122 qboolean Item_OwnerDraw_HandleKey(itemDef_t *item, int key) {
03123 if (item && DC->ownerDrawHandleKey)
03124 {
03125
03126
03127 if( key == A_MOUSE1 || key == A_MOUSE2 )
03128 {
03129 switch( item->window.ownerDraw )
03130 {
03131 case UI_FORCE_SIDE:
03132 case UI_FORCE_RANK_HEAL:
03133 case UI_FORCE_RANK_LEVITATION:
03134 case UI_FORCE_RANK_SPEED:
03135 case UI_FORCE_RANK_PUSH:
03136 case UI_FORCE_RANK_PULL:
03137 case UI_FORCE_RANK_TELEPATHY:
03138 case UI_FORCE_RANK_GRIP:
03139 case UI_FORCE_RANK_LIGHTNING:
03140 case UI_FORCE_RANK_RAGE:
03141 case UI_FORCE_RANK_PROTECT:
03142 case UI_FORCE_RANK_ABSORB:
03143 case UI_FORCE_RANK_TEAM_HEAL:
03144 case UI_FORCE_RANK_TEAM_FORCE:
03145 case UI_FORCE_RANK_DRAIN:
03146 case UI_FORCE_RANK_SEE:
03147 case UI_FORCE_RANK_SABERATTACK:
03148 case UI_FORCE_RANK_SABERDEFEND:
03149 case UI_FORCE_RANK_SABERTHROW:
03150 if(!Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) )
03151 {
03152 return qfalse;
03153 }
03154 break;
03155 }
03156 }
03157
03158
03159 return DC->ownerDrawHandleKey(item->window.ownerDraw, item->window.ownerDrawFlags, &item->special, key);
03160 }
03161 return qfalse;
03162 }
03163
03164
03165 #ifdef _XBOX
03166
03167
03168
03169 qboolean Item_Button_HandleKey(itemDef_t *item, int key)
03170 {
03171 if ( key == A_CURSOR_RIGHT)
03172 {
03173 if (Item_HandleSelectionNext(item))
03174 {
03175
03176 return qtrue;
03177 }
03178 }
03179 else if ( key == A_CURSOR_LEFT)
03180 {
03181 if (Item_HandleSelectionPrev(item))
03182 {
03183
03184 return qtrue;
03185 }
03186 }
03187 return qfalse;
03188 }
03189
03190
03191
03192
03193
03194
03195 qboolean Item_Text_HandleKey(itemDef_t *item, int key)
03196 {
03197
03198 if ( key == A_CURSOR_RIGHT)
03199 {
03200 if (Item_HandleSelectionNext(item))
03201 {
03202
03203 return qtrue;
03204 }
03205 }
03206 else if ( key == A_CURSOR_LEFT)
03207 {
03208 if (Item_HandleSelectionPrev(item))
03209 {
03210
03211 return qtrue;
03212 }
03213 }
03214 return qfalse;
03215 }
03216
03217 #endif // _XBOX
03218
03219
03220 qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolean force) {
03221 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
03222 int count = DC->feederCount(item->special);
03223 int max, viewmax;
03224
03225 #ifndef _XBOX
03226 if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS))
03227 #else
03228 if (force || item->window.flags & WINDOW_HASFOCUS)
03229 #endif
03230 {
03231 max = Item_ListBox_MaxScroll(item);
03232 if (item->window.flags & WINDOW_HORIZONTAL) {
03233 viewmax = (item->window.rect.w / listPtr->elementWidth);
03234 if ( key == A_CURSOR_LEFT || key == A_KP_4 )
03235 {
03236 if (!listPtr->notselectable) {
03237 listPtr->cursorPos--;
03238 #ifdef _XBOX
03239 listPtr->startPos--;
03240 #endif
03241 if (listPtr->cursorPos < 0) {
03242 listPtr->cursorPos = 0;
03243 return qfalse;
03244 }
03245 if (listPtr->cursorPos < listPtr->startPos) {
03246 listPtr->startPos = listPtr->cursorPos;
03247
03248 #ifndef _XBOX
03249 return qfalse;
03250 #endif
03251 }
03252 if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
03253 listPtr->startPos = listPtr->cursorPos - viewmax + 1;
03254 }
03255 item->cursorPos = listPtr->cursorPos;
03256 DC->feederSelection(item->special, item->cursorPos, NULL);
03257 }
03258 else {
03259 listPtr->startPos--;
03260 if (listPtr->startPos < 0)
03261 listPtr->startPos = 0;
03262 }
03263 return qtrue;
03264 }
03265 if ( key == A_CURSOR_RIGHT || key == A_KP_6 )
03266 {
03267 if (!listPtr->notselectable) {
03268 listPtr->cursorPos++;
03269 if (listPtr->cursorPos < listPtr->startPos) {
03270 listPtr->startPos = listPtr->cursorPos;
03271
03272 #ifndef _XBOX
03273 return qfalse;
03274 #endif
03275 }
03276 if (listPtr->cursorPos >= count) {
03277 listPtr->cursorPos = count-1;
03278 return qfalse;
03279 }
03280 if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
03281 listPtr->startPos = listPtr->cursorPos - viewmax + 1;
03282 }
03283 item->cursorPos = listPtr->cursorPos;
03284 DC->feederSelection(item->special, item->cursorPos, NULL);
03285 }
03286 else {
03287 listPtr->startPos++;
03288 if (listPtr->startPos >= count)
03289 listPtr->startPos = count-1;
03290 }
03291 return qtrue;
03292 }
03293 }
03294
03295 else {
03296
03297
03298 if (( item->window.rect.w > (listPtr->elementWidth*2)) && (listPtr->elementStyle == LISTBOX_IMAGE))
03299 {
03300 viewmax = (item->window.rect.w / listPtr->elementWidth);
03301 }
03302 else
03303 {
03304 viewmax = (item->window.rect.h / listPtr->elementHeight);
03305 }
03306
03307 if ( key == A_CURSOR_UP || key == A_KP_8 )
03308 {
03309 if (!listPtr->notselectable) {
03310 listPtr->cursorPos--;
03311 if (listPtr->cursorPos < 0) {
03312 listPtr->cursorPos = 0;
03313 return qfalse;
03314 }
03315 if (listPtr->cursorPos < listPtr->startPos) {
03316 listPtr->startPos = listPtr->cursorPos;
03317
03318 #ifndef _XBOX
03319 return qfalse;
03320 #endif
03321 }
03322 if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
03323 listPtr->startPos = listPtr->cursorPos - viewmax + 1;
03324 }
03325 item->cursorPos = listPtr->cursorPos;
03326 DC->feederSelection(item->special, item->cursorPos, NULL);
03327 }
03328 else {
03329 listPtr->startPos--;
03330 if (listPtr->startPos < 0)
03331 listPtr->startPos = 0;
03332 }
03333 return qtrue;
03334 }
03335 if ( key == A_CURSOR_DOWN || key == A_KP_2 )
03336 {
03337 if (!listPtr->notselectable) {
03338 listPtr->cursorPos++;
03339 if (listPtr->cursorPos < listPtr->startPos) {
03340 listPtr->startPos = listPtr->cursorPos;
03341
03342 #ifndef _XBOX
03343 return qfalse;
03344 #endif
03345 }
03346 if (listPtr->cursorPos >= count) {
03347 listPtr->cursorPos = count-1;
03348 return qfalse;
03349 }
03350 if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
03351 listPtr->startPos = listPtr->cursorPos - viewmax + 1;
03352 }
03353 item->cursorPos = listPtr->cursorPos;
03354 DC->feederSelection(item->special, item->cursorPos, NULL);
03355 }
03356 else {
03357 listPtr->startPos++;
03358 if (listPtr->startPos > max)
03359 listPtr->startPos = max;
03360 }
03361 return qtrue;
03362 }
03363 }
03364
03365 if (key == A_MOUSE1 || key == A_MOUSE2) {
03366 if (item->window.flags & WINDOW_LB_LEFTARROW) {
03367 listPtr->startPos--;
03368 if (listPtr->startPos < 0) {
03369 listPtr->startPos = 0;
03370 }
03371 } else if (item->window.flags & WINDOW_LB_RIGHTARROW) {
03372
03373 listPtr->startPos++;
03374 if (listPtr->startPos > max) {
03375 listPtr->startPos = max;
03376 }
03377 } else if (item->window.flags & WINDOW_LB_PGUP) {
03378
03379 listPtr->startPos -= viewmax;
03380 if (listPtr->startPos < 0) {
03381 listPtr->startPos = 0;
03382 }
03383 } else if (item->window.flags & WINDOW_LB_PGDN) {
03384
03385 listPtr->startPos += viewmax;
03386 if (listPtr->startPos > (max)) {
03387 listPtr->startPos = (max);
03388 }
03389 } else if (item->window.flags & WINDOW_LB_THUMB) {
03390
03391 } else {
03392
03393 #ifdef _XBOX
03394 if (listPtr->doubleClick) {
03395 #else
03396 if (DC->realTime < lastListBoxClickTime && listPtr->doubleClick) {
03397 #endif
03398 Item_RunScript(item, listPtr->doubleClick);
03399 }
03400 lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY;
03401
03402 {
03403 int prePos = item->cursorPos;
03404
03405 item->cursorPos = listPtr->cursorPos;
03406
03407 if (!DC->feederSelection(item->special, item->cursorPos, item))
03408 {
03409 item->cursorPos = listPtr->cursorPos = prePos;
03410 }
03411 }
03412 }
03413 return qtrue;
03414 }
03415 if ( key == A_HOME || key == A_KP_7) {
03416
03417 listPtr->startPos = 0;
03418 return qtrue;
03419 }
03420 if ( key == A_END || key == A_KP_1) {
03421
03422 listPtr->startPos = max;
03423 return qtrue;
03424 }
03425 if (key == A_PAGE_UP || key == A_KP_9 ) {
03426
03427 if (!listPtr->notselectable) {
03428 listPtr->cursorPos -= viewmax;
03429 if (listPtr->cursorPos < 0) {
03430 listPtr->cursorPos = 0;
03431 }
03432 if (listPtr->cursorPos < listPtr->startPos) {
03433 listPtr->startPos = listPtr->cursorPos;
03434 }
03435 if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
03436 listPtr->startPos = listPtr->cursorPos - viewmax + 1;
03437 }
03438 item->cursorPos = listPtr->cursorPos;
03439 DC->feederSelection(item->special, item->cursorPos, NULL);
03440 }
03441 else {
03442 listPtr->startPos -= viewmax;
03443 if (listPtr->startPos < 0) {
03444 listPtr->startPos = 0;
03445 }
03446 }
03447 return qtrue;
03448 }
03449 if ( key == A_PAGE_DOWN || key == A_KP_3 ) {
03450
03451 if (!listPtr->notselectable) {
03452 listPtr->cursorPos += viewmax;
03453 if (listPtr->cursorPos < listPtr->startPos) {
03454 listPtr->startPos = listPtr->cursorPos;
03455 }
03456 if (listPtr->cursorPos >= count) {
03457 listPtr->cursorPos = count-1;
03458 }
03459 if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
03460 listPtr->startPos = listPtr->cursorPos - viewmax + 1;
03461 }
03462 item->cursorPos = listPtr->cursorPos;
03463 DC->feederSelection(item->special, item->cursorPos, NULL);
03464 }
03465 else {
03466 listPtr->startPos += viewmax;
03467 if (listPtr->startPos > max) {
03468 listPtr->startPos = max;
03469 }
03470 }
03471 return qtrue;
03472 }
03473 }
03474 return qfalse;
03475 }
03476
03477 qboolean Item_YesNo_HandleKey(itemDef_t *item, int key) {
03478
03479 #ifndef _XBOX
03480 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar)
03481 #else
03482 if (item->window.flags & WINDOW_HASFOCUS && item->cvar)
03483 #endif
03484 {
03485
03486
03487 #ifndef _XBOX
03488 if (key == A_MOUSE1 || key == A_ENTER || key == A_MOUSE2 || key == A_MOUSE3)
03489 #else
03490 if ( key == A_CURSOR_RIGHT || key == A_CURSOR_LEFT)
03491 #endif
03492
03493
03494 {
03495 DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
03496 return qtrue;
03497 }
03498 }
03499
03500 return qfalse;
03501
03502 }
03503
03504 int Item_Multi_CountSettings(itemDef_t *item) {
03505 multiDef_t *multiPtr = (multiDef_t*)item->typeData;
03506 if (multiPtr == NULL) {
03507 return 0;
03508 }
03509 return multiPtr->count;
03510 }
03511
03512 int Item_Multi_FindCvarByValue(itemDef_t *item) {
03513 char buff[2048];
03514 float value = 0;
03515 int i;
03516 multiDef_t *multiPtr = (multiDef_t*)item->typeData;
03517 if (multiPtr) {
03518 if (multiPtr->strDef) {
03519 DC->getCVarString(item->cvar, buff, sizeof(buff));
03520 } else {
03521 value = DC->getCVarValue(item->cvar);
03522 }
03523 for (i = 0; i < multiPtr->count; i++) {
03524 if (multiPtr->strDef) {
03525 if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0) {
03526 return i;
03527 }
03528 } else {
03529 if (multiPtr->cvarValue[i] == value) {
03530 return i;
03531 }
03532 }
03533 }
03534 }
03535 return 0;
03536 }
03537
03538 const char *Item_Multi_Setting(itemDef_t *item) {
03539 char buff[2048];
03540 float value = 0;
03541 int i;
03542 multiDef_t *multiPtr = (multiDef_t*)item->typeData;
03543 if (multiPtr)
03544 {
03545 if (multiPtr->strDef)
03546 {
03547 if (item->cvar)
03548 {
03549 DC->getCVarString(item->cvar, buff, sizeof(buff));
03550 }
03551 }
03552 else
03553 {
03554 if (item->cvar)
03555 {
03556 value = DC->getCVarValue(item->cvar);
03557 }
03558 }
03559
03560 for (i = 0; i < multiPtr->count; i++)
03561 {
03562 if (multiPtr->strDef)
03563 {
03564 if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0)
03565 {
03566 return multiPtr->cvarList[i];
03567 }
03568 }
03569 else
03570 {
03571 if (multiPtr->cvarValue[i] == value)
03572 {
03573 return multiPtr->cvarList[i];
03574 }
03575 }
03576 }
03577 }
03578 return "";
03579 }
03580
03581 qboolean Item_Multi_HandleKey(itemDef_t *item, int key)
03582 {
03583 multiDef_t *multiPtr = (multiDef_t*)item->typeData;
03584 if (multiPtr)
03585 {
03586
03587 #ifndef _XBOX
03588 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS)
03589 #else
03590 if (item->window.flags & WINDOW_HASFOCUS)
03591 #endif
03592 {
03593 #ifndef _XBOX
03594
03595 if (key == A_MOUSE1 || key == A_ENTER || key == A_MOUSE2 || key == A_MOUSE3)
03596 #else
03597
03598 if ( key == A_CURSOR_RIGHT || key == A_CURSOR_LEFT)
03599
03600 #endif
03601 {
03602 int current = Item_Multi_FindCvarByValue(item);
03603 int max = Item_Multi_CountSettings(item);
03604
03605 if (key == A_MOUSE2 || key == A_CURSOR_LEFT)
03606 {
03607 current--;
03608 if ( current < 0 )
03609 {
03610 current = max-1;
03611 }
03612 }
03613 else
03614 {
03615 current++;
03616 if ( current >= max )
03617 {
03618 current = 0;
03619 }
03620 }
03621
03622 if (multiPtr->strDef)
03623 {
03624 DC->setCVar(item->cvar, multiPtr->cvarStr[current]);
03625 }
03626 else
03627 {
03628 float value = multiPtr->cvarValue[current];
03629 if (((float)((int) value)) == value)
03630 {
03631 DC->setCVar(item->cvar, va("%i", (int) value ));
03632 }
03633 else
03634 {
03635 DC->setCVar(item->cvar, va("%f", value ));
03636 }
03637 }
03638 if (item->special)
03639 {
03640 DC->feederSelection(item->special, current, item);
03641 }
03642
03643 return qtrue;
03644 }
03645 }
03646 }
03647 return qfalse;
03648 }
03649
03650
03651 void Leaving_EditField(itemDef_t *item)
03652 {
03653
03654 if ((g_editingField==qtrue) && (item->type==ITEM_TYPE_EDITFIELD))
03655 {
03656 editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
03657 if (editPtr)
03658 {
03659 editPtr->paintOffset = 0;
03660 }
03661 }
03662 }
03663
03664 qboolean Item_TextField_HandleKey(itemDef_t *item, int key) {
03665 char buff[2048];
03666 int len;
03667 itemDef_t *newItem = NULL;
03668 editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
03669
03670 if (item->cvar) {
03671
03672 buff[0] = 0;
03673 DC->getCVarString(item->cvar, buff, sizeof(buff));
03674 len = strlen(buff);
03675 if (editPtr->maxChars && len > editPtr->maxChars) {
03676 len = editPtr->maxChars;
03677 }
03678 if ( key & K_CHAR_FLAG ) {
03679 key &= ~K_CHAR_FLAG;
03680
03681
03682 if (key == 'h' - 'a' + 1 ) {
03683 if ( item->cursorPos > 0 ) {
03684 memmove( &buff[item->cursorPos - 1], &buff[item->cursorPos], len + 1 - item->cursorPos);
03685 item->cursorPos--;
03686 if (item->cursorPos < editPtr->paintOffset) {
03687 editPtr->paintOffset--;
03688 }
03689 }
03690 DC->setCVar(item->cvar, buff);
03691 return qtrue;
03692 }
03693
03694
03695
03696
03697
03698 if ( key < 32 || !item->cvar) {
03699 return qtrue;
03700 }
03701
03702 if (item->type == ITEM_TYPE_NUMERICFIELD) {
03703 if (key < '0' || key > '9') {
03704 return qfalse;
03705 }
03706 }
03707
03708 if (!DC->getOverstrikeMode()) {
03709 if (( len == MAX_EDITFIELD - 1 ) || (editPtr->maxChars && len >= editPtr->maxChars)) {
03710 return qtrue;
03711 }
03712 memmove( &buff[item->cursorPos + 1], &buff[item->cursorPos], len + 1 - item->cursorPos );
03713 } else {
03714 if (editPtr->maxChars && item->cursorPos >= editPtr->maxChars) {
03715 return qtrue;
03716 }
03717 }
03718
03719 buff[item->cursorPos] = key;
03720
03721
03722 if (item->cursorPos+1 < 2048)
03723 {
03724 buff[item->cursorPos+1] = 0;
03725 }
03726 else
03727 {
03728 buff[item->cursorPos] = 0;
03729 }
03730
03731 DC->setCVar(item->cvar, buff);
03732
03733 if (item->cursorPos < len + 1) {
03734 item->cursorPos++;
03735 if (editPtr->maxPaintChars && item->cursorPos > editPtr->maxPaintChars) {
03736 editPtr->paintOffset++;
03737 }
03738 }
03739
03740 } else {
03741
03742 if ( key == A_DELETE || key == A_KP_PERIOD ) {
03743 if ( item->cursorPos < len ) {
03744 memmove( buff + item->cursorPos, buff + item->cursorPos + 1, len - item->cursorPos);
03745 DC->setCVar(item->cvar, buff);
03746 }
03747 return qtrue;
03748 }
03749
03750 if ( key == A_CURSOR_RIGHT || key == A_KP_6 )
03751 {
03752 if (editPtr->maxPaintChars && item->cursorPos >= editPtr->maxPaintChars && item->cursorPos < len) {
03753 item->cursorPos++;
03754 editPtr->paintOffset++;
03755 return qtrue;
03756 }
03757 if (item->cursorPos < len) {
03758 item->cursorPos++;
03759 }
03760 return qtrue;
03761 }
03762
03763 if ( key == A_CURSOR_LEFT || key == A_KP_4 )
03764 {
03765 if ( item->cursorPos > 0 ) {
03766 item->cursorPos--;
03767 }
03768 if (item->cursorPos < editPtr->paintOffset) {
03769 editPtr->paintOffset--;
03770 }
03771 return qtrue;
03772 }
03773
03774 if ( key == A_HOME || key == A_KP_7) {
03775 item->cursorPos = 0;
03776 editPtr->paintOffset = 0;
03777 return qtrue;
03778 }
03779
03780 if ( key == A_END || key == A_KP_1) {
03781 item->cursorPos = len;
03782 if(item->cursorPos > editPtr->maxPaintChars) {
03783 editPtr->paintOffset = len - editPtr->maxPaintChars;
03784 }
03785 return qtrue;
03786 }
03787
03788 if ( key == A_INSERT || key == A_KP_0 ) {
03789 DC->setOverstrikeMode(!DC->getOverstrikeMode());
03790 return qtrue;
03791 }
03792 }
03793
03794 if (key == A_TAB || key == A_CURSOR_DOWN || key == A_KP_2)
03795 {
03796
03797 Leaving_EditField(item);
03798 g_editingField = qfalse;
03799 newItem = Menu_SetNextCursorItem((menuDef_t *) item->parent);
03800 if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD))
03801 {
03802 g_editItem = newItem;
03803 g_editingField = qtrue;
03804 }
03805 }
03806
03807 if (key == A_CURSOR_UP || key == A_KP_8)
03808 {
03809
03810 Leaving_EditField(item);
03811
03812 g_editingField = qfalse;
03813 newItem = Menu_SetPrevCursorItem((menuDef_t *) item->parent);
03814 if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD))
03815 {
03816 g_editItem = newItem;
03817 g_editingField = qtrue;
03818 }
03819 }
03820
03821 if ( key == A_ENTER || key == A_KP_ENTER || key == A_ESCAPE) {
03822 return qfalse;
03823 }
03824
03825 return qtrue;
03826 }
03827 return qfalse;
03828
03829 }
03830
03831 static void Scroll_TextScroll_AutoFunc (void *p)
03832 {
03833 scrollInfo_t *si = (scrollInfo_t*)p;
03834
03835 if (DC->realTime > si->nextScrollTime)
03836 {
03837
03838
03839
03840 Item_TextScroll_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
03841 si->nextScrollTime = DC->realTime + si->adjustValue;
03842 }
03843
03844 if (DC->realTime > si->nextAdjustTime)
03845 {
03846 si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
03847 if (si->adjustValue > SCROLL_TIME_FLOOR)
03848 {
03849 si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
03850 }
03851 }
03852 }
03853
03854 static void Scroll_TextScroll_ThumbFunc(void *p)
03855 {
03856 scrollInfo_t *si = (scrollInfo_t*)p;
03857 rectDef_t r;
03858 int pos;
03859 int max;
03860
03861 textScrollDef_t *scrollPtr = (textScrollDef_t*)si->item->typeData;
03862
03863 if (DC->cursory != si->yStart)
03864 {
03865 r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1;
03866 r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1;
03867 r.h = si->item->window.rect.h - (SCROLLBAR_SIZE*2) - 2;
03868 r.w = SCROLLBAR_SIZE;
03869 max = Item_TextScroll_MaxScroll(si->item);
03870
03871 pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * max / (r.h - SCROLLBAR_SIZE);
03872 if (pos < 0)
03873 {
03874 pos = 0;
03875 }
03876 else if (pos > max)
03877 {
03878 pos = max;
03879 }
03880
03881 scrollPtr->startPos = pos;
03882 si->yStart = DC->cursory;
03883 }
03884
03885 if (DC->realTime > si->nextScrollTime)
03886 {
03887
03888
03889
03890 Item_TextScroll_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
03891 si->nextScrollTime = DC->realTime + si->adjustValue;
03892 }
03893
03894 if (DC->realTime > si->nextAdjustTime)
03895 {
03896 si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
03897 if (si->adjustValue > SCROLL_TIME_FLOOR)
03898 {
03899 si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
03900 }
03901 }
03902 }
03903
03904 static void Scroll_ListBox_AutoFunc(void *p) {
03905 scrollInfo_t *si = (scrollInfo_t*)p;
03906 if (DC->realTime > si->nextScrollTime) {
03907
03908
03909
03910 Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
03911 si->nextScrollTime = DC->realTime + si->adjustValue;
03912 }
03913
03914 if (DC->realTime > si->nextAdjustTime) {
03915 si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
03916 if (si->adjustValue > SCROLL_TIME_FLOOR) {
03917 si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
03918 }
03919 }
03920 }
03921
03922 static void Scroll_ListBox_ThumbFunc(void *p) {
03923 scrollInfo_t *si = (scrollInfo_t*)p;
03924 rectDef_t r;
03925 int pos, max;
03926
03927 listBoxDef_t *listPtr = (listBoxDef_t*)si->item->typeData;
03928 if (si->item->window.flags & WINDOW_HORIZONTAL) {
03929 if (DC->cursorx == si->xStart) {
03930 return;
03931 }
03932 r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1;
03933 r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_SIZE - 1;
03934 r.h = SCROLLBAR_SIZE;
03935 r.w = si->item->window.rect.w - (SCROLLBAR_SIZE*2) - 2;
03936 max = Item_ListBox_MaxScroll(si->item);
03937
03938 pos = (DC->cursorx - r.x - SCROLLBAR_SIZE/2) * max / (r.w - SCROLLBAR_SIZE);
03939 if (pos < 0) {
03940 pos = 0;
03941 }
03942 else if (pos > max) {
03943 pos = max;
03944 }
03945 listPtr->startPos = pos;
03946 si->xStart = DC->cursorx;
03947 }
03948 else if (DC->cursory != si->yStart) {
03949
03950 r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1;
03951 r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1;
03952 r.h = si->item->window.rect.h - (SCROLLBAR_SIZE*2) - 2;
03953 r.w = SCROLLBAR_SIZE;
03954 max = Item_ListBox_MaxScroll(si->item);
03955
03956
03957 if (( si->item->window.rect.w > (listPtr->elementWidth*2)) && (listPtr->elementStyle == LISTBOX_IMAGE))
03958 {
03959 int rowLength, rowMax;
03960 rowLength = si->item->window.rect.w / listPtr->elementWidth;
03961 rowMax = max / rowLength;
03962
03963 pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * rowMax / (r.h - SCROLLBAR_SIZE);
03964 pos *= rowLength;
03965 }
03966 else
03967 {
03968 pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * max / (r.h - SCROLLBAR_SIZE);
03969 }
03970
03971 if (pos < 0) {
03972 pos = 0;
03973 }
03974 else if (pos > max) {
03975 pos = max;
03976 }
03977 listPtr->startPos = pos;
03978 si->yStart = DC->cursory;
03979 }
03980
03981 if (DC->realTime > si->nextScrollTime) {
03982
03983
03984
03985 Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
03986 si->nextScrollTime = DC->realTime + si->adjustValue;
03987 }
03988
03989 if (DC->realTime > si->nextAdjustTime) {
03990 si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
03991 if (si->adjustValue > SCROLL_TIME_FLOOR) {
03992 si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
03993 }
03994 }
03995 }
03996
03997 static void Scroll_Slider_ThumbFunc(void *p) {
03998 float x, value, cursorx;
03999 scrollInfo_t *si = (scrollInfo_t*)p;
04000 editFieldDef_t *editDef = (editFieldDef_t *) si->item->typeData;
04001
04002 if (si->item->text) {
04003 x = si->item->textRect.x + si->item->textRect.w + 8;
04004 } else {
04005 x = si->item->window.rect.x;
04006 }
04007
04008 cursorx = DC->cursorx;
04009
04010 if (cursorx < x) {
04011 cursorx = x;
04012 } else if (cursorx > x + SLIDER_WIDTH) {
04013 cursorx = x + SLIDER_WIDTH;
04014 }
04015 value = cursorx - x;
04016 value /= SLIDER_WIDTH;
04017 value *= (editDef->maxVal - editDef->minVal);
04018 value += editDef->minVal;
04019 DC->setCVar(si->item->cvar, va("%f", value));
04020 }
04021
04022 void Item_StartCapture(itemDef_t *item, int key)
04023 {
04024 int flags;
04025 switch (item->type)
04026 {
04027 case ITEM_TYPE_EDITFIELD:
04028 case ITEM_TYPE_NUMERICFIELD:
04029 case ITEM_TYPE_LISTBOX:
04030 {
04031 flags = Item_ListBox_OverLB(item, DC->cursorx, DC->cursory);
04032 if (flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW)) {
04033 scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
04034 scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
04035 scrollInfo.adjustValue = SCROLL_TIME_START;
04036 scrollInfo.scrollKey = key;
04037 scrollInfo.scrollDir = (flags & WINDOW_LB_LEFTARROW) ? qtrue : qfalse;
04038 scrollInfo.item = item;
04039 captureData = &scrollInfo;
04040 captureFunc = &Scroll_ListBox_AutoFunc;
04041 itemCapture = item;
04042 } else if (flags & WINDOW_LB_THUMB) {
04043 scrollInfo.scrollKey = key;
04044 scrollInfo.item = item;
04045 scrollInfo.xStart = DC->cursorx;
04046 scrollInfo.yStart = DC->cursory;
04047 captureData = &scrollInfo;
04048 captureFunc = &Scroll_ListBox_ThumbFunc;
04049 itemCapture = item;
04050 }
04051 break;
04052 }
04053
04054 case ITEM_TYPE_TEXTSCROLL:
04055 flags = Item_TextScroll_OverLB (item, DC->cursorx, DC->cursory);
04056 if (flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW))
04057 {
04058 scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
04059 scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
04060 scrollInfo.adjustValue = SCROLL_TIME_START;
04061 scrollInfo.scrollKey = key;
04062 scrollInfo.scrollDir = (flags & WINDOW_LB_LEFTARROW) ? qtrue : qfalse;
04063 scrollInfo.item = item;
04064 captureData = &scrollInfo;
04065 captureFunc = &Scroll_TextScroll_AutoFunc;
04066 itemCapture = item;
04067 }
04068 else if (flags & WINDOW_LB_THUMB)
04069 {
04070 scrollInfo.scrollKey = key;
04071 scrollInfo.item = item;
04072 scrollInfo.xStart = DC->cursorx;
04073 scrollInfo.yStart = DC->cursory;
04074 captureData = &scrollInfo;
04075 captureFunc = &Scroll_TextScroll_ThumbFunc;
04076 itemCapture = item;
04077 }
04078 break;
04079
04080 case ITEM_TYPE_SLIDER:
04081 {
04082 flags = Item_Slider_OverSlider(item, DC->cursorx, DC->cursory);
04083 if (flags & WINDOW_LB_THUMB) {
04084 scrollInfo.scrollKey = key;
04085 scrollInfo.item = item;
04086 scrollInfo.xStart = DC->cursorx;
04087 scrollInfo.yStart = DC->cursory;
04088 captureData = &scrollInfo;
04089 captureFunc = &Scroll_Slider_ThumbFunc;
04090 itemCapture = item;
04091 }
04092 break;
04093 }
04094 }
04095 }
04096
04097 void Item_StopCapture(itemDef_t *item) {
04098
04099 }
04100
04101 qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) {
04102 float x, value, width, work;
04103
04104
04105
04106 #ifndef _XBOX
04107 if (item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
04108 if (key == A_MOUSE1 || key == A_ENTER || key == A_MOUSE2 || key == A_MOUSE3) {
04109 editFieldDef_t *editDef = (editFieldDef_t *) item->typeData;
04110 if (editDef) {
04111 rectDef_t testRect;
04112 width = SLIDER_WIDTH;
04113 if (item->text) {
04114 x = item->textRect.x + item->textRect.w + 8;
04115 } else {
04116 x = item->window.rect.x;
04117 }
04118
04119 testRect = item->window.rect;
04120 testRect.x = x;
04121 value = (float)SLIDER_THUMB_WIDTH / 2;
04122 testRect.x -= value;
04123
04124 testRect.w = (SLIDER_WIDTH + (float)SLIDER_THUMB_WIDTH / 2);
04125
04126 if (Rect_ContainsPoint(&testRect, DC->cursorx, DC->cursory)) {
04127 work = DC->cursorx - x;
04128 value = work / width;
04129 value *= (editDef->maxVal - editDef->minVal);
04130
04131
04132 value += editDef->minVal;
04133 DC->setCVar(item->cvar, va("%f", value));
04134 return qtrue;
04135 }
04136 }
04137 }
04138 }
04139 #else //def _XBOX
04140
04141 if (item->window.flags & WINDOW_HASFOCUS && item->cvar)
04142 {
04143 if (key == A_CURSOR_LEFT)
04144 {
04145 editFieldDef_t *editDef = (editFieldDef_s *) item->typeData;
04146 if (editDef)
04147 {
04148 value = DC->getCVarValue(item->cvar);
04149 value -= (editDef->maxVal-editDef->minVal)/TICK_COUNT;
04150 if ( value < editDef->minVal)
04151 value = editDef->minVal;
04152 DC->setCVar(item->cvar, va("%f", value));
04153 return qtrue;
04154 }
04155 }
04156 if (key == A_CURSOR_RIGHT)
04157 {
04158 editFieldDef_t *editDef = (editFieldDef_s *) item->typeData;
04159 if (editDef)
04160 {
04161 value = DC->getCVarValue(item->cvar);
04162 value += (editDef->maxVal-editDef->minVal)/TICK_COUNT;
04163 if ( value > editDef->maxVal)
04164 value = editDef->maxVal;
04165 DC->setCVar(item->cvar, va("%f", value));
04166 return qtrue;
04167 }
04168 }
04169 }
04170 #endif
04171 DC->Print("slider handle key exit\n");
04172 return qfalse;
04173 }
04174
04175
04176 qboolean Item_HandleKey(itemDef_t *item, int key, qboolean down) {
04177
04178 if (itemCapture) {
04179 Item_StopCapture(itemCapture);
04180 itemCapture = NULL;
04181 captureFunc = 0;
04182 captureData = NULL;
04183 } else {
04184
04185 if ( down && ( key == A_MOUSE1 || key == A_MOUSE2 || key == A_MOUSE3 ) ) {
04186 Item_StartCapture(item, key);
04187 }
04188 }
04189
04190 if (!down) {
04191 return qfalse;
04192 }
04193
04194 switch (item->type) {
04195 case ITEM_TYPE_BUTTON:
04196 #ifdef _XBOX
04197 return Item_Button_HandleKey(item, key);
04198 #else
04199 return qfalse;
04200 #endif
04201 break;
04202 case ITEM_TYPE_RADIOBUTTON:
04203 return qfalse;
04204 break;
04205 case ITEM_TYPE_CHECKBOX:
04206 return qfalse;
04207 break;
04208 case ITEM_TYPE_EDITFIELD:
04209 case ITEM_TYPE_NUMERICFIELD:
04210 if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_ENTER)
04211 {
04212 editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
04213
04214 if (item->cvar && editPtr)
04215 {
04216 editPtr->paintOffset = 0;
04217 }
04218
04219
04220 }
04221 return qfalse;
04222 break;
04223 case ITEM_TYPE_COMBO:
04224 return qfalse;
04225 break;
04226 case ITEM_TYPE_LISTBOX:
04227 return Item_ListBox_HandleKey(item, key, down, qfalse);
04228 break;
04229 case ITEM_TYPE_TEXTSCROLL:
04230 return Item_TextScroll_HandleKey(item, key, down, qfalse);
04231 break;
04232 case ITEM_TYPE_YESNO:
04233 return Item_YesNo_HandleKey(item, key);
04234 break;
04235 case ITEM_TYPE_MULTI:
04236 return Item_Multi_HandleKey(item, key);
04237 break;
04238 case ITEM_TYPE_OWNERDRAW:
04239 return Item_OwnerDraw_HandleKey(item, key);
04240 break;
04241 case ITEM_TYPE_BIND:
04242 return Item_Bind_HandleKey(item, key, down);
04243 break;
04244 case ITEM_TYPE_SLIDER:
04245 return Item_Slider_HandleKey(item, key, down);
04246 break;
04247 #ifdef _XBOX
04248 case ITEM_TYPE_TEXT:
04249 return Item_Text_HandleKey(item, key);
04250 break;
04251 #endif
04252
04253
04254
04255 default:
04256 return qfalse;
04257 break;
04258 }
04259
04260
04261 }
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271 qboolean Item_HandleAccept(itemDef_t * item)
04272 {
04273 if (item->accept)
04274 {
04275 Item_RunScript(item, item->accept);
04276 return qtrue;
04277 }
04278 return qfalse;
04279 }
04280
04281 #ifdef _XBOX // Xbox-only event handlers
04282
04283
04284
04285
04286
04287
04288
04289
04290 qboolean Item_HandleSelectionNext(itemDef_t * item)
04291 {
04292 if (item->selectionNext)
04293 {
04294 Item_RunScript(item, item->selectionNext);
04295 return qtrue;
04296 }
04297 return qfalse;
04298 }
04299
04300
04301
04302
04303
04304
04305
04306
04307 qboolean Item_HandleSelectionPrev(itemDef_t * item)
04308 {
04309 if (item->selectionPrev)
04310 {
04311 Item_RunScript(item, item->selectionPrev);
04312 return qtrue;
04313 }
04314 return qfalse;
04315 }
04316
04317
04318 #endif // _XBOX
04319
04320
04321 void Item_Action(itemDef_t *item) {
04322 if (item) {
04323 Item_RunScript(item, item->action);
04324 }
04325 }
04326
04327
04328
04329 itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu) {
04330 qboolean wrapped = qfalse;
04331 int oldCursor = menu->cursorItem;
04332
04333 if (menu->cursorItem < 0) {
04334 menu->cursorItem = menu->itemCount-1;
04335 wrapped = qtrue;
04336 }
04337
04338 while (menu->cursorItem > -1)
04339 {
04340 menu->cursorItem--;
04341 if (menu->cursorItem < 0) {
04342 if (wrapped)
04343 {
04344 break;
04345 }
04346 wrapped = qtrue;
04347 menu->cursorItem = menu->itemCount -1;
04348 }
04349
04350 if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory)) {
04351 Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1);
04352 return menu->items[menu->cursorItem];
04353 }
04354 }
04355 menu->cursorItem = oldCursor;
04356 return NULL;
04357
04358 }
04359
04360 itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu) {
04361
04362 qboolean wrapped = qfalse;
04363 int oldCursor = menu->cursorItem;
04364
04365
04366 if (menu->cursorItem == -1) {
04367 menu->cursorItem = 0;
04368 wrapped = qtrue;
04369 }
04370
04371 while (menu->cursorItem < menu->itemCount) {
04372
04373 menu->cursorItem++;
04374 if (menu->cursorItem >= menu->itemCount && !wrapped) {
04375 wrapped = qtrue;
04376 menu->cursorItem = 0;
04377 }
04378 if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory)) {
04379 Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1);
04380 return menu->items[menu->cursorItem];
04381 }
04382
04383 }
04384
04385 menu->cursorItem = oldCursor;
04386 return NULL;
04387 }
04388
04389 static void Window_CloseCinematic(windowDef_t *window) {
04390 if (window->style == WINDOW_STYLE_CINEMATIC && window->cinematic >= 0) {
04391 DC->stopCinematic(window->cinematic);
04392 window->cinematic = -1;
04393 }
04394 }
04395
04396 static void Menu_CloseCinematics(menuDef_t *menu) {
04397 if (menu) {
04398 int i;
04399 Window_CloseCinematic(&menu->window);
04400 for (i = 0; i < menu->itemCount; i++) {
04401 Window_CloseCinematic(&menu->items[i]->window);
04402 if (menu->items[i]->type == ITEM_TYPE_OWNERDRAW) {
04403 DC->stopCinematic(0-menu->items[i]->window.ownerDraw);
04404 }
04405 }
04406 }
04407 }
04408
04409 static void Display_CloseCinematics() {
04410 int i;
04411 for (i = 0; i < menuCount; i++) {
04412 Menu_CloseCinematics(&Menus[i]);
04413 }
04414 }
04415
04416 void Menus_Activate(menuDef_t *menu) {
04417
04418
04419 #ifdef _XBOX
04420 DC->setCVar("ui_hideAcallout" ,"0");
04421 DC->setCVar("ui_hideBcallout" ,"0");
04422 DC->setCVar("ui_hideCcallout" ,"0");
04423 #endif
04424
04425 menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE);
04426 if (menu->onOpen) {
04427 itemDef_t item;
04428 item.parent = menu;
04429 Item_RunScript(&item, menu->onOpen);
04430 }
04431
04432 if (menu->soundName && *menu->soundName) {
04433
04434 DC->startBackgroundTrack(menu->soundName, menu->soundName, qfalse);
04435 }
04436
04437 menu->appearanceTime = 0;
04438 Display_CloseCinematics();
04439
04440 }
04441
04442 int Display_VisibleMenuCount() {
04443 int i, count;
04444 count = 0;
04445 for (i = 0; i < menuCount; i++) {
04446 if (Menus[i].window.flags & (WINDOW_FORCED | WINDOW_VISIBLE)) {
04447 count++;
04448 }
04449 }
04450 return count;
04451 }
04452
04453 void Menus_HandleOOBClick(menuDef_t *menu, int key, qboolean down) {
04454 if (menu) {
04455
04456 #ifdef _XBOX
04457 Menu_HandleMouseMove(menu, DC->cursorx, DC->cursory);
04458 Menu_HandleKey(menu, key, down);
04459 return;
04460 #endif
04461 int i;
04462
04463
04464
04465 if (down && menu->window.flags & WINDOW_OOB_CLICK) {
04466 Menu_RunCloseScript(menu);
04467 menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
04468 }
04469
04470 for (i = 0; i < menuCount; i++) {
04471 if (Menu_OverActiveItem(&Menus[i], DC->cursorx, DC->cursory)) {
04472 Menu_RunCloseScript(menu);
04473 menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
04474 Menus_Activate(&Menus[i]);
04475 Menu_HandleMouseMove(&Menus[i], DC->cursorx, DC->cursory);
04476 Menu_HandleKey(&Menus[i], key, down);
04477 }
04478 }
04479
04480 if (Display_VisibleMenuCount() == 0) {
04481 if (DC->Pause) {
04482 DC->Pause(qfalse);
04483 }
04484 }
04485 Display_CloseCinematics();
04486 }
04487 }
04488
04489
04490 void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) {
04491 int i;
04492 itemDef_t *item = NULL;
04493 qboolean inHandler = qfalse;
04494
04495 if (inHandler) {
04496 return;
04497 }
04498
04499 inHandler = qtrue;
04500 if (g_waitingForKey && down) {
04501 Item_Bind_HandleKey(g_bindItem, key, down);
04502 inHandler = qfalse;
04503 return;
04504 }
04505
04506 if (g_editingField && down)
04507 {
04508 if (!Item_TextField_HandleKey(g_editItem, key))
04509 {
04510 g_editingField = qfalse;
04511 g_editItem = NULL;
04512 inHandler = qfalse;
04513 return;
04514 }
04515 else if (key == A_MOUSE1 || key == A_MOUSE2 || key == A_MOUSE3)
04516 {
04517
04518 Leaving_EditField(g_editItem);
04519 g_editingField = qfalse;
04520 g_editItem = NULL;
04521 Display_MouseMove(NULL, DC->cursorx, DC->cursory);
04522 }
04523 else if (key == A_TAB || key == A_CURSOR_UP || key == A_CURSOR_DOWN)
04524 {
04525 return;
04526 }
04527 }
04528
04529 if (menu == NULL) {
04530 inHandler = qfalse;
04531 return;
04532 }
04533
04534
04535 #ifndef _XBOX
04536 if (down && !(menu->window.flags & WINDOW_POPUP) && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory))
04537 #else
04538 if (down)
04539 #endif
04540 {
04541 static qboolean inHandleKey = qfalse;
04542
04543 if (!inHandleKey && ( key == A_MOUSE1 || key == A_MOUSE2 || key == A_MOUSE3 ) ) {
04544 inHandleKey = qtrue;
04545 Menus_HandleOOBClick(menu, key, down);
04546 inHandleKey = qfalse;
04547 inHandler = qfalse;
04548 return;
04549 }
04550 }
04551
04552
04553 for (i = 0; i < menu->itemCount; i++) {
04554 if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
04555 item = menu->items[i];
04556 }
04557 }
04558
04559
04560 if (item && item->disabled)
04561 {
04562 return;
04563 }
04564
04565 if (item != NULL) {
04566 if (Item_HandleKey(item, key, down))
04567 {
04568
04569 #ifdef _XBOX
04570 if (key == A_MOUSE1 || key == A_MOUSE2 ||(item->type == ITEM_TYPE_MULTI && (key == A_CURSOR_RIGHT || key == A_CURSOR_LEFT)))
04571 {
04572 #endif
04573
04574 if (!item->disabled)
04575 {
04576 Item_Action(item);
04577 }
04578 #ifdef _XBOX
04579 }
04580 #endif
04581 inHandler = qfalse;
04582 return;
04583 }
04584 }
04585
04586 if (!down) {
04587 inHandler = qfalse;
04588 return;
04589 }
04590
04591
04592 switch ( key ) {
04593
04594 case A_F11:
04595 if (DC->getCVarValue("developer")) {
04596 debugMode ^= 1;
04597 }
04598 break;
04599
04600 case A_F12:
04601 if (DC->getCVarValue("developer")) {
04602 DC->executeText(EXEC_APPEND, "screenshot\n");
04603 }
04604 break;
04605 case A_KP_8:
04606 case A_CURSOR_UP:
04607 Menu_SetPrevCursorItem(menu);
04608 break;
04609
04610 case A_ESCAPE:
04611 if (!g_waitingForKey && menu->onESC) {
04612 itemDef_t it;
04613 it.parent = menu;
04614 Item_RunScript(&it, menu->onESC);
04615 }
04616 g_waitingForKey = qfalse;
04617 break;
04618 case A_TAB:
04619 case A_KP_2:
04620 case A_CURSOR_DOWN:
04621 Menu_SetNextCursorItem(menu);
04622 break;
04623
04624 case A_MOUSE1:
04625 case A_MOUSE2:
04626 if (item) {
04627 if (item->type == ITEM_TYPE_TEXT) {
04628
04629 #ifndef _XBOX
04630 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
04631 #endif
04632 {
04633 Item_Action(item);
04634 }
04635 } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) {
04636
04637 #ifndef _XBOX
04638 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
04639 #endif
04640 {
04641 Item_Action(item);
04642 item->cursorPos = 0;
04643 g_editingField = qtrue;
04644 g_editItem = item;
04645 DC->setOverstrikeMode(qtrue);
04646 }
04647 }
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659 else if ( item->type == ITEM_TYPE_MULTI || item->type == ITEM_TYPE_YESNO || item->type == ITEM_TYPE_SLIDER)
04660 {
04661 if (Item_HandleAccept(item))
04662 {
04663
04664 return;
04665 }
04666 else if (menu->onAccept)
04667 {
04668 itemDef_t it;
04669 it.parent = menu;
04670 Item_RunScript(&it, menu->onAccept);
04671 }
04672 }
04673
04674 else {
04675
04676 #ifndef _XBOX
04677 if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
04678 #endif
04679 {
04680
04681 Item_Action(item);
04682 }
04683 }
04684 }
04685 break;
04686
04687 case A_JOY0:
04688 case A_JOY1:
04689 case A_JOY2:
04690 case A_JOY3:
04691 case A_JOY4:
04692 case A_AUX0:
04693 case A_AUX1:
04694 case A_AUX2:
04695 case A_AUX3:
04696 case A_AUX4:
04697 case A_AUX5:
04698 case A_AUX6:
04699 case A_AUX7:
04700 case A_AUX8:
04701 case A_AUX9:
04702 case A_AUX10:
04703 case A_AUX11:
04704 case A_AUX12:
04705 case A_AUX13:
04706 case A_AUX14:
04707 case A_AUX15:
04708 case A_AUX16:
04709 break;
04710 case A_KP_ENTER:
04711 case A_ENTER:
04712 if (item) {
04713 if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) {
04714 item->cursorPos = 0;
04715 g_editingField = qtrue;
04716 g_editItem = item;
04717 DC->setOverstrikeMode(qtrue);
04718 } else {
04719 Item_Action(item);
04720 }
04721 }
04722 break;
04723 }
04724 inHandler = qfalse;
04725 }
04726
04727 void ToWindowCoords(float *x, float *y, windowDef_t *window) {
04728 if (window->border != 0) {
04729 *x += window->borderSize;
04730 *y += window->borderSize;
04731 }
04732 *x += window->rect.x;
04733 *y += window->rect.y;
04734 }
04735
04736 void Rect_ToWindowCoords(rectDef_t *rect, windowDef_t *window) {
04737 ToWindowCoords(&rect->x, &rect->y, window);
04738 }
04739
04740 void Item_SetTextExtents(itemDef_t *item, int *width, int *height, const char *text) {
04741 const char *textPtr = (text) ? text : item->text;
04742
04743 if (textPtr == NULL ) {
04744 return;
04745 }
04746
04747 *width = item->textRect.w;
04748 *height = item->textRect.h;
04749
04750
04751 if (*width == 0 || (item->type == ITEM_TYPE_OWNERDRAW && item->textalignment == ITEM_ALIGN_CENTER)
04752 #ifndef CGAME
04753 || (item->text && item->text[0]=='@' && item->asset != se_language.modificationCount )
04754 #endif
04755 )
04756 {
04757 int originalWidth = DC->textWidth(textPtr, item->textscale, item->iMenuFont);
04758
04759 if (item->type == ITEM_TYPE_OWNERDRAW && (item->textalignment == ITEM_ALIGN_CENTER || item->textalignment == ITEM_ALIGN_RIGHT))
04760 {
04761 originalWidth += DC->ownerDrawWidth(item->window.ownerDraw, item->textscale);
04762 }
04763 else if (item->type == ITEM_TYPE_EDITFIELD && item->textalignment == ITEM_ALIGN_CENTER && item->cvar)
04764 {
04765 char buff[256];
04766 DC->getCVarString(item->cvar, buff, 256);
04767 originalWidth += DC->textWidth(buff, item->textscale, item->iMenuFont);
04768 }
04769
04770 *width = DC->textWidth(textPtr, item->textscale, item->iMenuFont);
04771 *height = DC->textHeight(textPtr, item->textscale, item->iMenuFont);
04772
04773 item->textRect.w = *width;
04774 item->textRect.h = *height;
04775 item->textRect.x = item->textalignx;
04776 item->textRect.y = item->textaligny;
04777 if (item->textalignment == ITEM_ALIGN_RIGHT) {
04778 item->textRect.x = item->textalignx - originalWidth;
04779 } else if (item->textalignment == ITEM_ALIGN_CENTER) {
04780 item->textRect.x = item->textalignx - originalWidth / 2;
04781 }
04782
04783 ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
04784 #ifndef CGAME
04785 if (item->text && item->text[0]=='@' )
04786 {
04787 item->asset = se_language.modificationCount;
04788 }
04789 #endif
04790 }
04791 }
04792
04793 void Item_TextColor(itemDef_t *item, vec4_t *newColor) {
04794 vec4_t lowLight;
04795 menuDef_t *parent = (menuDef_t*)item->parent;
04796
04797 Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount);
04798
04799 if (item->window.flags & WINDOW_HASFOCUS) {
04800 lowLight[0] = 0.8 * parent->focusColor[0];
04801 lowLight[1] = 0.8 * parent->focusColor[1];
04802 lowLight[2] = 0.8 * parent->focusColor[2];
04803 lowLight[3] = 0.8 * parent->focusColor[3];
04804 LerpColor(parent->focusColor,lowLight,*newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
04805 } else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1)) {
04806 lowLight[0] = 0.8 * item->window.foreColor[0];
04807 lowLight[1] = 0.8 * item->window.foreColor[1];
04808 lowLight[2] = 0.8 * item->window.foreColor[2];
04809 lowLight[3] = 0.8 * item->window.foreColor[3];
04810 LerpColor(item->window.foreColor,lowLight,*newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
04811 } else {
04812 memcpy(newColor, &item->window.foreColor, sizeof(vec4_t));
04813
04814 }
04815
04816 if (item->disabled)
04817 {
04818 memcpy(newColor, &parent->disableColor, sizeof(vec4_t));
04819 }
04820
04821 if (item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest) {
04822 if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
04823 memcpy(newColor, &parent->disableColor, sizeof(vec4_t));
04824 }
04825 }
04826 }
04827
04828 void Item_Text_AutoWrapped_Paint(itemDef_t *item) {
04829 char text[2048];
04830 const char *p, *textPtr, *newLinePtr;
04831 char buff[2048];
04832 int height, len, textWidth, newLine, newLineWidth;
04833 float y;
04834 vec4_t color;
04835
04836 textWidth = 0;
04837 newLinePtr = NULL;
04838
04839 if (item->text == NULL) {
04840 if (item->cvar == NULL) {
04841 return;
04842 }
04843 else {
04844 DC->getCVarString(item->cvar, text, sizeof(text));
04845 textPtr = text;
04846 }
04847 }
04848 else {
04849 textPtr = item->text;
04850 }
04851 if (*textPtr == '@')
04852 {
04853 trap_SP_GetStringTextString( &textPtr[1], text, sizeof(text));
04854 textPtr = text;
04855 }
04856 if (*textPtr == '\0') {
04857 return;
04858 }
04859 Item_TextColor(item, &color);
04860
04861
04862
04863
04864
04865 height = DC->textHeight(textPtr, item->textscale, item->iMenuFont);
04866
04867 y = item->textaligny;
04868 len = 0;
04869 buff[0] = '\0';
04870 newLine = 0;
04871 newLineWidth = 0;
04872 p = textPtr;
04873 while (p) {
04874 if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\0') {
04875 newLine = len;
04876 newLinePtr = p+1;
04877 newLineWidth = textWidth;
04878 }
04879 textWidth = DC->textWidth(buff, item->textscale, 0);
04880 if ( (newLine && textWidth > item->window.rect.w) || *p == '\n' || *p == '\0') {
04881 if (len) {
04882 if (item->textalignment == ITEM_ALIGN_LEFT) {
04883 item->textRect.x = item->textalignx;
04884 } else if (item->textalignment == ITEM_ALIGN_RIGHT) {
04885 item->textRect.x = item->textalignx - newLineWidth;
04886 } else if (item->textalignment == ITEM_ALIGN_CENTER) {
04887 item->textRect.x = item->textalignx - newLineWidth / 2;
04888 }
04889 item->textRect.y = y;
04890 ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
04891
04892 buff[newLine] = '\0';
04893 DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle, item->iMenuFont);
04894 }
04895 if (*p == '\0') {
04896 break;
04897 }
04898
04899 y += height + 5;
04900 p = newLinePtr;
04901 len = 0;
04902 newLine = 0;
04903 newLineWidth = 0;
04904 continue;
04905 }
04906 buff[len++] = *p++;
04907 buff[len] = '\0';
04908 }
04909 }
04910
04911 void Item_Text_Wrapped_Paint(itemDef_t *item) {
04912 char text[1024];
04913 const char *p, *start, *textPtr;
04914 char buff[1024];
04915 int width, height;
04916 float x, y;
04917 vec4_t color;
04918
04919
04920
04921
04922 if (item->text == NULL) {
04923 if (item->cvar == NULL) {
04924 return;
04925 }
04926 else {
04927 DC->getCVarString(item->cvar, text, sizeof(text));
04928 textPtr = text;
04929 }
04930 }
04931 else {
04932 textPtr = item->text;
04933 }
04934 if (*textPtr == '@')
04935 {
04936 trap_SP_GetStringTextString( &textPtr[1], text, sizeof(text));
04937 textPtr = text;
04938 }
04939 if (*textPtr == '\0') {
04940 return;
04941 }
04942
04943 Item_TextColor(item, &color);
04944 Item_SetTextExtents(item, &width, &height, textPtr);
04945
04946 x = item->textRect.x;
04947 y = item->textRect.y;
04948 start = textPtr;
04949 p = strchr(textPtr, '\r');
04950 while (p && *p) {
04951 strncpy(buff, start, p-start+1);
04952 buff[p-start] = '\0';
04953 DC->drawText(x, y, item->textscale, color, buff, 0, 0, item->textStyle, item->iMenuFont);
04954 y += height + 2;
04955 start += p - start + 1;
04956 p = strchr(p+1, '\r');
04957 }
04958 DC->drawText(x, y, item->textscale, color, start, 0, 0, item->textStyle, item->iMenuFont);
04959 }
04960
04961 void Item_Text_Paint(itemDef_t *item) {
04962 char text[1024];
04963 const char *textPtr;
04964 int height, width;
04965 vec4_t color;
04966
04967 if (item->window.flags & WINDOW_WRAPPED) {
04968 Item_Text_Wrapped_Paint(item);
04969 return;
04970 }
04971 if (item->window.flags & WINDOW_AUTOWRAPPED) {
04972 Item_Text_AutoWrapped_Paint(item);
04973 return;
04974 }
04975
04976 if (item->text == NULL) {
04977 if (item->cvar == NULL) {
04978 return;
04979 }
04980 else {
04981 DC->getCVarString(item->cvar, text, sizeof(text));
04982 textPtr = text;
04983 }
04984 }
04985 else {
04986 textPtr = item->text;
04987 }
04988 if (*textPtr == '@')
04989 {
04990 trap_SP_GetStringTextString( &textPtr[1], text, sizeof(text));
04991 textPtr = text;
04992 }
04993
04994
04995 Item_SetTextExtents(item, &width, &height, textPtr);
04996
04997 if (*textPtr == '\0') {
04998 return;
04999 }
05000
05001
05002 Item_TextColor(item, &color);
05003
05004 DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, 0, item->textStyle, item->iMenuFont);
05005
05006 if (item->text2)
05007 {
05008 textPtr = item->text2;
05009 if (*textPtr == '@')
05010 {
05011 trap_SP_GetStringTextString( &textPtr[1], text, sizeof(text));
05012 textPtr = text;
05013 }
05014 Item_TextColor(item, &color);
05015 DC->drawText(item->textRect.x + item->text2alignx, item->textRect.y + item->text2aligny, item->textscale, color, textPtr, 0, 0, item->textStyle,item->iMenuFont);
05016 }
05017 }
05018
05019
05020
05021
05022
05023
05024 void Item_TextField_Paint(itemDef_t *item) {
05025 char buff[1024];
05026 vec4_t newColor, lowLight;
05027 int offset;
05028 menuDef_t *parent = (menuDef_t*)item->parent;
05029 editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
05030
05031 Item_Text_Paint(item);
05032
05033 buff[0] = '\0';
05034
05035 if (item->cvar) {
05036 DC->getCVarString(item->cvar, buff, sizeof(buff));
05037 if (buff[0] == '@')
05038 {
05039 trap_SP_GetStringTextString( &buff[1], buff, sizeof(buff));
05040 }
05041 }
05042
05043 parent = (menuDef_t*)item->parent;
05044
05045 if (item->window.flags & WINDOW_HASFOCUS) {
05046 lowLight[0] = 0.8 * parent->focusColor[0];
05047 lowLight[1] = 0.8 * parent->focusColor[1];
05048 lowLight[2] = 0.8 * parent->focusColor[2];
05049 lowLight[3] = 0.8 * parent->focusColor[3];
05050 LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
05051 } else {
05052 memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
05053 }
05054
05055 offset = (item->text && *item->text) ? 8 : 0;
05056 if (item->window.flags & WINDOW_HASFOCUS && g_editingField) {
05057 char cursor = DC->getOverstrikeMode() ? '_' : '|';
05058 DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset , cursor, item->window.rect.w, item->textStyle, item->iMenuFont);
05059 } else {
05060 DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, 0, item->window.rect.w, item->textStyle,item->iMenuFont);
05061 }
05062 }
05063
05064 void Item_YesNo_Paint(itemDef_t *item) {
05065 char sYES[20];
05066 char sNO[20];
05067 vec4_t newColor, lowLight;
05068 float value;
05069 menuDef_t *parent = (menuDef_t*)item->parent;
05070 const char *yesnovalue;
05071
05072 value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
05073
05074 if (item->window.flags & WINDOW_HASFOCUS) {
05075 lowLight[0] = 0.8 * parent->focusColor[0];
05076 lowLight[1] = 0.8 * parent->focusColor[1];
05077 lowLight[2] = 0.8 * parent->focusColor[2];
05078 lowLight[3] = 0.8 * parent->focusColor[3];
05079 LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
05080 } else {
05081 memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
05082 }
05083
05084
05085 trap_SP_GetStringTextString("MENUS_YES",sYES, sizeof(sYES));
05086 trap_SP_GetStringTextString("MENUS_NO", sNO, sizeof(sNO));
05087
05088
05089 if (item->invertYesNo)
05090 yesnovalue = (value == 0) ? sYES : sNO;
05091 else
05092 yesnovalue = (value != 0) ? sYES : sNO;
05093
05094 if (item->text)
05095 {
05096 Item_Text_Paint(item);
05097
05098 #ifdef _XBOX
05099 if (item->xoffset == 0)
05100 DC->drawText(item->textRect.x + item->textRect.w + item->xoffset + 8, item->textRect.y, item->textscale, newColor, yesnovalue, 0, 0,item->textStyle, item->iMenuFont);
05101 else
05102 #endif
05103 DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, yesnovalue, 0, 0, item->textStyle, item->iMenuFont);
05104
05105 }
05106 else
05107 {
05108
05109 #ifdef _XBOX
05110 DC->drawText(item->textRect.x + item->xoffset, item->textRect.y, item->textscale, newColor, yesnovalue , 0, 0, item->textStyle, item->iMenuFont);
05111 #else
05112 DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, yesnovalue , 0, 0, item->textStyle, item->iMenuFont);
05113 #endif
05114 }
05115
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126 }
05127
05128 void Item_Multi_Paint(itemDef_t *item) {
05129 vec4_t newColor, lowLight;
05130 const char *text = "";
05131 menuDef_t *parent = (menuDef_t*)item->parent;
05132 char temp[MAX_STRING_CHARS];
05133
05134 if (item->window.flags & WINDOW_HASFOCUS) {
05135 lowLight[0] = 0.8 * parent->focusColor[0];
05136 lowLight[1] = 0.8 * parent->focusColor[1];
05137 lowLight[2] = 0.8 * parent->focusColor[2];
05138 lowLight[3] = 0.8 * parent->focusColor[3];
05139 LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
05140 } else {
05141 memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
05142 }
05143
05144 text = Item_Multi_Setting(item);
05145 if (*text == '@')
05146 {
05147 trap_SP_GetStringTextString( &text[1] , temp, sizeof(temp));
05148 text = temp;
05149 }
05150
05151 else if (*text == '*')
05152 {
05153 DC->getCVarString(&text[1], temp, sizeof(temp));
05154 text = temp;
05155 }
05156
05157 if (item->text) {
05158 Item_Text_Paint(item);
05159
05160 #ifdef _XBOX
05161 if ( item->xoffset)
05162 DC->drawText(item->textRect.x + item->textRect.w + item->xoffset, item->textRect.y, item->textscale, newColor, text, 0,0, item->textStyle, item->iMenuFont);
05163 else
05164 #endif
05165 DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle,item->iMenuFont);
05166 } else {
05167
05168 DC->drawText(item->textRect.x+item->xoffset, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle,item->iMenuFont);
05169 }
05170 }
05171
05172
05173 typedef struct {
05174 char *command;
05175 int id;
05176 int defaultbind1;
05177 int defaultbind2;
05178 int bind1;
05179 int bind2;
05180 } bind_t;
05181
05182 typedef struct
05183 {
05184 char* name;
05185 float defaultvalue;
05186 float value;
05187 } configcvar_t;
05188
05189
05190 static bind_t g_bindings[] =
05191 {
05192 {"+scores", A_TAB, -1, -1, -1},
05193 {"+button2", A_ENTER, -1, -1, -1},
05194 {"+speed", A_SHIFT, -1, -1, -1},
05195 {"+forward", A_CURSOR_UP, -1, -1, -1},
05196 {"+back", A_CURSOR_DOWN, -1, -1, -1},
05197 {"+moveleft", ',', -1, -1, -1},
05198 {"+moveright", '.', -1, -1, -1},
05199 {"+moveup", A_SPACE, -1, -1, -1},
05200 {"+movedown", 'c', -1, -1, -1},
05201 {"+left", A_CURSOR_LEFT, -1, -1, -1},
05202 {"+right", A_CURSOR_RIGHT, -1, -1, -1},
05203 {"+strafe", A_ALT, -1, -1, -1},
05204 {"+lookup", A_PAGE_DOWN, -1, -1, -1},
05205 {"+lookdown", A_DELETE, -1, -1, -1},
05206 {"+mlook", '/', -1, -1, -1},
05207 {"centerview", A_END, -1, -1, -1},
05208
05209 {"weapon 1", '1', -1, -1, -1},
05210 {"weapon 2", '2', -1, -1, -1},
05211 {"weapon 3", '3', -1, -1, -1},
05212 {"weapon 4", '4', -1, -1, -1},
05213 {"weapon 5", '5', -1, -1, -1},
05214 {"weapon 6", '6', -1, -1, -1},
05215 {"weapon 7", '7', -1, -1, -1},
05216 {"weapon 8", '8', -1, -1, -1},
05217 {"weapon 9", '9', -1, -1, -1},
05218 {"weapon 10", '0', -1, -1, -1},
05219 {"saberAttackCycle", 'l', -1, -1, -1},
05220 {"weapon 11", -1, -1, -1, -1},
05221 {"weapon 12", -1, -1, -1, -1},
05222 {"weapon 13", -1, -1, -1, -1},
05223 {"+attack", A_CTRL, -1, -1, -1},
05224 {"+altattack", -1, -1, -1, -1},
05225 {"+use", -1, -1, -1, -1},
05226 {"engage_duel", 'h', -1, -1, -1},
05227 {"taunt", 'u', -1, -1, -1},
05228 {"bow", -1, -1, -1, -1},
05229 {"meditate", -1, -1, -1, -1},
05230 {"flourish", -1, -1, -1, -1},
05231 {"gloat", -1, -1, -1, -1},
05232 {"weapprev", '[', -1, -1, -1},
05233 {"weapnext", ']', -1, -1, -1},
05234 {"prevTeamMember", 'w', -1, -1, -1},
05235 {"nextTeamMember", 'r', -1, -1, -1},
05236 {"nextOrder", 't', -1, -1, -1},
05237 {"confirmOrder", 'y', -1, -1, -1},
05238 {"denyOrder", 'n', -1, -1, -1},
05239 {"taskOffense", 'o', -1, -1, -1},
05240 {"taskDefense", 'd', -1, -1, -1},
05241 {"taskPatrol", 'p', -1, -1, -1},
05242 {"taskCamp", 'c', -1, -1, -1},
05243 {"taskFollow", 'f', -1, -1, -1},
05244 {"taskRetrieve", 'v', -1, -1, -1},
05245 {"taskEscort", 'e', -1, -1, -1},
05246 {"taskOwnFlag", 'i', -1, -1, -1},
05247 {"taskSuicide", 'k', -1, -1, -1},
05248 {"tauntKillInsult", -1, -1, -1, -1},
05249 {"tauntPraise", -1, -1, -1, -1},
05250 {"tauntTaunt", -1, -1, -1, -1},
05251 {"tauntDeathInsult",-1, -1, -1, -1},
05252 {"tauntGauntlet", -1, -1, -1, -1},
05253 {"scoresUp", A_INSERT, -1, -1, -1},
05254 {"scoresDown", A_DELETE, -1, -1, -1},
05255 {"messagemode", -1, -1, -1, -1},
05256 {"messagemode2", -1, -1, -1, -1},
05257 {"messagemode3", -1, -1, -1, -1},
05258 {"messagemode4", -1, -1, -1, -1},
05259 {"+use", -1, -1, -1, -1},
05260 {"+force_jump", -1, -1, -1, -1},
05261 {"force_throw", A_F1, -1, -1, -1},
05262 {"force_pull", A_F2, -1, -1, -1},
05263 {"force_speed", A_F3, -1, -1, -1},
05264 {"force_distract", A_F4, -1, -1, -1},
05265 {"force_heal", A_F5, -1, -1, -1},
05266 {"+force_grip", A_F6, -1, -1, -1},
05267 {"+force_lightning",A_F7, -1, -1, -1},
05268
05269 {"+force_drain", -1, -1, -1, -1},
05270 {"force_rage", -1, -1, -1, -1},
05271 {"force_protect", -1, -1, -1, -1},
05272 {"force_absorb", -1, -1, -1, -1},
05273 {"force_healother", -1, -1, -1, -1},
05274 {"force_forcepowerother", -1, -1, -1, -1},
05275 {"force_seeing", -1, -1, -1, -1},
05276
05277 {"+useforce", -1, -1, -1, -1},
05278 {"forcenext", -1, -1, -1, -1},
05279 {"forceprev", -1, -1, -1, -1},
05280 {"invnext", -1, -1, -1, -1},
05281 {"invprev", -1, -1, -1, -1},
05282 {"use_seeker", -1, -1, -1, -1},
05283 {"use_field", -1, -1, -1, -1},
05284 {"use_bacta", -1, -1, -1, -1},
05285 {"use_electrobinoculars", -1, -1, -1, -1},
05286 {"use_sentry", -1, -1, -1, -1},
05287 {"cg_thirdperson !",-1, -1, -1, -1},
05288 {"automap_button", -1, -1, -1, -1},
05289 {"automap_toggle", -1, -1, -1, -1},
05290 {"voicechat", -1, -1, -1, -1},
05291
05292 };
05293
05294
05295 static const int g_bindCount = sizeof(g_bindings) / sizeof(bind_t);
05296
05297
05298
05299
05300
05301
05302 static void Controls_GetKeyAssignment (char *command, int *twokeys)
05303 {
05304 int count;
05305 int j;
05306 char b[256];
05307
05308 twokeys[0] = twokeys[1] = -1;
05309 count = 0;
05310
05311 for ( j = 0; j < MAX_KEYS; j++ )
05312 {
05313 DC->getBindingBuf( j, b, 256 );
05314 if ( *b == 0 ) {
05315 continue;
05316 }
05317 if ( !Q_stricmp( b, command ) ) {
05318 twokeys[count] = j;
05319 count++;
05320 if (count == 2) {
05321 break;
05322 }
05323 }
05324 }
05325 }
05326
05327
05328
05329
05330
05331
05332 void Controls_GetConfig( void )
05333 {
05334 int i;
05335 int twokeys[2];
05336
05337
05338 for (i=0; i < g_bindCount; i++)
05339 {
05340
05341 Controls_GetKeyAssignment(g_bindings[i].command, twokeys);
05342
05343 g_bindings[i].bind1 = twokeys[0];
05344 g_bindings[i].bind2 = twokeys[1];
05345 }
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355 }
05356
05357
05358
05359
05360
05361
05362 void Controls_SetConfig(qboolean restart)
05363 {
05364 int i;
05365
05366
05367 for (i=0; i < g_bindCount; i++)
05368 {
05369 if (g_bindings[i].bind1 != -1)
05370 {
05371 DC->setBinding( g_bindings[i].bind1, g_bindings[i].command );
05372
05373 if (g_bindings[i].bind2 != -1)
05374 DC->setBinding( g_bindings[i].bind2, g_bindings[i].command );
05375 }
05376 }
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393 }
05394
05395
05396 int BindingIDFromName(const char *name) {
05397 int i;
05398 for (i=0; i < g_bindCount; i++)
05399 {
05400 if (Q_stricmp(name, g_bindings[i].command) == 0) {
05401 return i;
05402 }
05403 }
05404 return -1;
05405 }
05406
05407 char g_nameBind1[32];
05408 char g_nameBind2[32];
05409
05410 void BindingFromName(const char *cvar) {
05411 int i, b1, b2;
05412 char sOR[32];
05413
05414
05415
05416 for (i=0; i < g_bindCount; i++)
05417 {
05418 if (Q_stricmp(cvar, g_bindings[i].command) == 0) {
05419 b1 = g_bindings[i].bind1;
05420 if (b1 == -1) {
05421 break;
05422 }
05423 DC->keynumToStringBuf( b1, g_nameBind1, 32 );
05424
05425
05426 b2 = g_bindings[i].bind2;
05427 if (b2 != -1)
05428 {
05429 DC->keynumToStringBuf( b2, g_nameBind2, 32 );
05430
05431
05432 trap_SP_GetStringTextString("MENUS_KEYBIND_OR",sOR, sizeof(sOR));
05433
05434 strcat( g_nameBind1, va(" %s ",sOR));
05435 strcat( g_nameBind1, g_nameBind2 );
05436 }
05437 return;
05438 }
05439 }
05440 strcpy(g_nameBind1, "???");
05441 }
05442
05443 void Item_Slider_Paint(itemDef_t *item) {
05444 vec4_t newColor, lowLight;
05445 float x, y, value;
05446 menuDef_t *parent = (menuDef_t*)item->parent;
05447
05448 value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
05449
05450 if (item->window.flags & WINDOW_HASFOCUS) {
05451 lowLight[0] = 0.8 * parent->focusColor[0];
05452 lowLight[1] = 0.8 * parent->focusColor[1];
05453 lowLight[2] = 0.8 * parent->focusColor[2];
05454 lowLight[3] = 0.8 * parent->focusColor[3];
05455 LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
05456 } else {
05457 memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
05458 }
05459
05460 y = item->window.rect.y;
05461 if (item->text) {
05462 Item_Text_Paint(item);
05463 x = item->textRect.x + item->textRect.w + 8;
05464 } else {
05465 x = item->window.rect.x;
05466 }
05467 DC->setColor(newColor);
05468 DC->drawHandlePic( x, y, SLIDER_WIDTH, SLIDER_HEIGHT, DC->Assets.sliderBar );
05469
05470 x = Item_Slider_ThumbPosition(item);
05471 DC->drawHandlePic( x - (SLIDER_THUMB_WIDTH / 2), y - 2, SLIDER_THUMB_WIDTH, SLIDER_THUMB_HEIGHT, DC->Assets.sliderThumb );
05472
05473 }
05474
05475 void Item_Bind_Paint(itemDef_t *item)
05476 {
05477 vec4_t newColor, lowLight;
05478 float value;
05479 int maxChars = 0;
05480 float textScale,textWidth;
05481 int textHeight,yAdj,startingXPos;
05482
05483
05484 menuDef_t *parent = (menuDef_t*)item->parent;
05485 editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
05486 if (editPtr)
05487 {
05488 maxChars = editPtr->maxPaintChars;
05489 }
05490
05491 value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
05492
05493 if (item->window.flags & WINDOW_HASFOCUS)
05494 {
05495 if (g_bindItem == item)
05496 {
05497 lowLight[0] = 0.8f * 1.0f;
05498 lowLight[1] = 0.8f * 0.0f;
05499 lowLight[2] = 0.8f * 0.0f;
05500 lowLight[3] = 0.8f * 1.0f;
05501 }
05502 else
05503 {
05504 lowLight[0] = 0.8f * parent->focusColor[0];
05505 lowLight[1] = 0.8f * parent->focusColor[1];
05506 lowLight[2] = 0.8f * parent->focusColor[2];
05507 lowLight[3] = 0.8f * parent->focusColor[3];
05508 }
05509 LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
05510 }
05511 else
05512 {
05513 memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
05514 }
05515
05516 if (item->text)
05517 {
05518 Item_Text_Paint(item);
05519 BindingFromName(item->cvar);
05520
05521
05522 textScale = item->textscale;
05523 textWidth = DC->textWidth(g_nameBind1,(float) textScale, item->iMenuFont);
05524 startingXPos = (item->textRect.x + item->textRect.w + 8);
05525
05526 while ((startingXPos + textWidth) >= SCREEN_WIDTH)
05527 {
05528 textScale -= .05f;
05529 textWidth = DC->textWidth(g_nameBind1,(float) textScale, item->iMenuFont);
05530 }
05531
05532
05533 yAdj = 0;
05534 if (textScale != item->textscale)
05535 {
05536 textHeight = DC->textHeight(g_nameBind1, item->textscale, item->iMenuFont);
05537 yAdj = textHeight - DC->textHeight(g_nameBind1, textScale, item->iMenuFont);
05538 }
05539
05540 DC->drawText(startingXPos, item->textRect.y + yAdj, textScale, newColor, g_nameBind1, 0, maxChars, item->textStyle,item->iMenuFont);
05541 }
05542 else
05543 {
05544 DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME" : "FIXME", 0, maxChars, item->textStyle,item->iMenuFont);
05545 }
05546 }
05547
05548 qboolean Display_KeyBindPending() {
05549 return g_waitingForKey;
05550 }
05551
05552 qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) {
05553 int id;
05554 int i;
05555
05556 if (key == A_MOUSE1 && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey)
05557 {
05558 if (down) {
05559 g_waitingForKey = qtrue;
05560 g_bindItem = item;
05561 }
05562 return qtrue;
05563 }
05564 else if (key == A_ENTER && !g_waitingForKey)
05565 {
05566 if (down)
05567 {
05568 g_waitingForKey = qtrue;
05569 g_bindItem = item;
05570 }
05571 return qtrue;
05572 }
05573 else
05574 {
05575 if (!g_waitingForKey || g_bindItem == NULL) {
05576 return qfalse;
05577 }
05578
05579 if (key & K_CHAR_FLAG) {
05580 return qtrue;
05581 }
05582
05583 switch (key)
05584 {
05585 case A_ESCAPE:
05586 g_waitingForKey = qfalse;
05587 return qtrue;
05588
05589 case A_BACKSPACE:
05590 id = BindingIDFromName(item->cvar);
05591 if (id != -1)
05592 {
05593 if ( g_bindings[id].bind1 != -1 )
05594 {
05595 DC->setBinding ( g_bindings[id].bind1, "" );
05596 }
05597
05598 if ( g_bindings[id].bind2 != -1 )
05599 {
05600 DC->setBinding ( g_bindings[id].bind2, "" );
05601 }
05602
05603 g_bindings[id].bind1 = -1;
05604 g_bindings[id].bind2 = -1;
05605 }
05606 Controls_SetConfig(qtrue);
05607 g_waitingForKey = qfalse;
05608 g_bindItem = NULL;
05609 return qtrue;
05610
05611 case '`':
05612 return qtrue;
05613 }
05614 }
05615
05616 if (key != -1)
05617 {
05618
05619 for (i=0; i < g_bindCount; i++)
05620 {
05621
05622 if (g_bindings[i].bind2 == key) {
05623 g_bindings[i].bind2 = -1;
05624 }
05625
05626 if (g_bindings[i].bind1 == key)
05627 {
05628 g_bindings[i].bind1 = g_bindings[i].bind2;
05629 g_bindings[i].bind2 = -1;
05630 }
05631 }
05632 }
05633
05634
05635 id = BindingIDFromName(item->cvar);
05636
05637 if (id != -1) {
05638 if (key == -1) {
05639 if( g_bindings[id].bind1 != -1 ) {
05640 DC->setBinding( g_bindings[id].bind1, "" );
05641 g_bindings[id].bind1 = -1;
05642 }
05643 if( g_bindings[id].bind2 != -1 ) {
05644 DC->setBinding( g_bindings[id].bind2, "" );
05645 g_bindings[id].bind2 = -1;
05646 }
05647 }
05648 else if (g_bindings[id].bind1 == -1) {
05649 g_bindings[id].bind1 = key;
05650 }
05651 else if (g_bindings[id].bind1 != key && g_bindings[id].bind2 == -1) {
05652 g_bindings[id].bind2 = key;
05653 }
05654 else {
05655 DC->setBinding( g_bindings[id].bind1, "" );
05656 DC->setBinding( g_bindings[id].bind2, "" );
05657 g_bindings[id].bind1 = key;
05658 g_bindings[id].bind2 = -1;
05659 }
05660 }
05661
05662 Controls_SetConfig(qtrue);
05663 g_waitingForKey = qfalse;
05664
05665 return qtrue;
05666 }
05667
05668 void UI_ScaleModelAxis(refEntity_t *ent)
05669
05670 {
05671 if (ent->modelScale[0] && ent->modelScale[0] != 1.0f)
05672 {
05673 VectorScale( ent->axis[0], ent->modelScale[0] , ent->axis[0] );
05674 ent->nonNormalizedAxes = qtrue;
05675 }
05676 if (ent->modelScale[1] && ent->modelScale[1] != 1.0f)
05677 {
05678 VectorScale( ent->axis[1], ent->modelScale[1] , ent->axis[1] );
05679 ent->nonNormalizedAxes = qtrue;
05680 }
05681 if (ent->modelScale[2] && ent->modelScale[2] != 1.0f)
05682 {
05683 VectorScale( ent->axis[2], ent->modelScale[2] , ent->axis[2] );
05684 ent->nonNormalizedAxes = qtrue;
05685 }
05686 }
05687
05688 #ifndef CGAME
05689 #include "../namespace_end.h"
05690 extern void UI_SaberAttachToChar( itemDef_t *item );
05691 #include "../namespace_begin.h"
05692 #endif
05693
05694 void Item_Model_Paint(itemDef_t *item)
05695 {
05696 float x, y, w, h;
05697 refdef_t refdef;
05698 refEntity_t ent;
05699 vec3_t mins, maxs, origin;
05700 vec3_t angles;
05701 modelDef_t *modelPtr = (modelDef_t*)item->typeData;
05702
05703 if (modelPtr == NULL)
05704 {
05705 return;
05706 }
05707
05708
05709 #ifndef CGAME
05710 if (uiInfo.moveAnimTime && (uiInfo.moveAnimTime < uiInfo.uiDC.realTime))
05711 {
05712 modelDef_t *modelPtr;
05713 modelPtr = (modelDef_t*)item->typeData;
05714 if (modelPtr)
05715 {
05716 char modelPath[MAX_QPATH];
05717
05718 Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", UI_Cvar_VariableString ( "ui_char_model" ) );
05719
05720 switch( modelPtr->g2anim )
05721 {
05722 case BOTH_FORCEWALLREBOUND_FORWARD:
05723 case BOTH_FORCEJUMP1:
05724 ItemParse_model_g2anim_go( item, animTable[BOTH_FORCEINAIR1].name );
05725 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05726 if ( !uiInfo.moveAnimTime )
05727 {
05728 uiInfo.moveAnimTime = 500;
05729 }
05730 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05731 break;
05732 case BOTH_FORCEINAIR1:
05733 ItemParse_model_g2anim_go( item, animTable[BOTH_FORCELAND1].name );
05734 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05735 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05736 break;
05737 case BOTH_FORCEWALLRUNFLIP_START:
05738 ItemParse_model_g2anim_go( item, animTable[BOTH_FORCEWALLRUNFLIP_END].name );
05739 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05740 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05741 break;
05742 case BOTH_FORCELONGLEAP_START:
05743 ItemParse_model_g2anim_go( item, animTable[BOTH_FORCELONGLEAP_LAND].name );
05744 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05745 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05746 break;
05747 case BOTH_KNOCKDOWN3:
05748 trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveJumpSound, CHAN_LOCAL );
05749 ItemParse_model_g2anim_go( item, animTable[BOTH_FORCE_GETUP_F1].name );
05750 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05751 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05752 break;
05753 case BOTH_KNOCKDOWN2:
05754 trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveJumpSound, CHAN_LOCAL );
05755 ItemParse_model_g2anim_go( item, animTable[BOTH_GETUP_BROLL_F].name );
05756 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05757 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05758 break;
05759 case BOTH_KNOCKDOWN1:
05760 trap_S_StartLocalSound( uiInfo.uiDC.Assets.moveRollSound, CHAN_LOCAL );
05761 ItemParse_model_g2anim_go( item, animTable[BOTH_GETUP_BROLL_R].name );
05762 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05763 uiInfo.moveAnimTime += uiInfo.uiDC.realTime;
05764 break;
05765 default:
05766 ItemParse_model_g2anim_go( item, uiInfo.movesBaseAnim );
05767 ItemParse_asset_model_go( item, modelPath, &uiInfo.moveAnimTime );
05768 uiInfo.moveAnimTime = 0;
05769 break;
05770 }
05771
05772 UI_UpdateCharacterSkin();
05773
05774
05775 UI_SaberAttachToChar( item );
05776 }
05777 }
05778 #endif
05779
05780
05781 memset( &refdef, 0, sizeof( refdef ) );
05782
05783 refdef.rdflags = RDF_NOWORLDMODEL;
05784 AxisClear( refdef.viewaxis );
05785 x = item->window.rect.x+1;
05786 y = item->window.rect.y+1;
05787 w = item->window.rect.w-2;
05788 h = item->window.rect.h-2;
05789
05790 refdef.x = x * DC->xscale;
05791 refdef.y = y * DC->yscale;
05792 refdef.width = w * DC->xscale;
05793 refdef.height = h * DC->yscale;
05794
05795 if (item->ghoul2)
05796 {
05797 VectorCopy(modelPtr->g2mins, mins);
05798 VectorCopy(modelPtr->g2maxs, maxs);
05799
05800 if (!mins[0] && !mins[1] && !mins[2] &&
05801 !maxs[0] && !maxs[1] && !maxs[2])
05802 {
05803 VectorSet(mins, -16, -16, -24);
05804 VectorSet(maxs, 16, 16, 32);
05805 }
05806 }
05807 else
05808 {
05809 DC->modelBounds( item->asset, mins, maxs );
05810 }
05811
05812 origin[2] = -0.5 * ( mins[2] + maxs[2] );
05813 origin[1] = 0.5 * ( mins[1] + maxs[1] );
05814
05815
05816 if (qtrue)
05817 {
05818 float len = 0.5 * ( maxs[2] - mins[2] );
05819 origin[0] = len / 0.268;
05820
05821 }
05822 else
05823 {
05824 origin[0] = item->textscale;
05825 }
05826 refdef.fov_x = (modelPtr->fov_x) ? modelPtr->fov_x : (int)((float)refdef.width / 640.0f * 90.0f);
05827 refdef.fov_y = (modelPtr->fov_y) ? modelPtr->fov_y : atan2( refdef.height, refdef.width / tan( refdef.fov_x / 360 * M_PI ) ) * ( 360 / M_PI );
05828
05829
05830
05831
05832 DC->clearScene();
05833
05834 refdef.time = DC->realTime;
05835
05836
05837
05838 memset( &ent, 0, sizeof(ent) );
05839
05840
05841 if ( (item->flags&ITF_ISANYSABER) && !(item->flags&ITF_ISCHARACTER) )
05842 {
05843 if (modelPtr->rotationSpeed)
05844 {
05845 VectorSet( angles, modelPtr->angle+(float)refdef.time/modelPtr->rotationSpeed, 0, 90 );
05846 }
05847 else
05848 {
05849 VectorSet( angles, modelPtr->angle, 0, 90 );
05850 }
05851 }
05852 else if (modelPtr->rotationSpeed)
05853 {
05854 VectorSet( angles, 0, modelPtr->angle + (float)refdef.time/modelPtr->rotationSpeed, 0 );
05855 }
05856 else
05857 {
05858 VectorSet( angles, 0, modelPtr->angle, 0 );
05859 }
05860
05861 AnglesToAxis( angles, ent.axis );
05862
05863 if (item->ghoul2)
05864 {
05865 ent.ghoul2 = item->ghoul2;
05866 ent.radius = 1000;
05867 ent.customSkin = modelPtr->g2skin;
05868
05869 VectorCopy(modelPtr->g2scale, ent.modelScale);
05870 UI_ScaleModelAxis(&ent);
05871 #ifndef CGAME
05872 if ( (item->flags&ITF_ISCHARACTER) )
05873 {
05874 ent.shaderRGBA[0] = ui_char_color_red.integer;
05875 ent.shaderRGBA[1] = ui_char_color_green.integer;
05876 ent.shaderRGBA[2] = ui_char_color_blue.integer;
05877 ent.shaderRGBA[3] = 255;
05878
05879 }
05880 if ( item->flags&ITF_ISANYSABER )
05881 {
05882 UI_SaberDrawBlades( item, origin, angles );
05883 }
05884 #endif
05885 }
05886 else
05887 {
05888 ent.hModel = item->asset;
05889 }
05890 VectorCopy( origin, ent.origin );
05891 VectorCopy( ent.origin, ent.oldorigin );
05892
05893
05894 VectorCopy( origin, ent.lightingOrigin );
05895 ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;
05896
05897 DC->addRefEntityToScene( &ent );
05898 DC->renderScene( &refdef );
05899
05900 }
05901
05902
05903 void Item_Image_Paint(itemDef_t *item) {
05904 if (item == NULL) {
05905 return;
05906 }
05907 DC->drawHandlePic(item->window.rect.x+1, item->window.rect.y+1, item->window.rect.w-2, item->window.rect.h-2, item->asset);
05908 }
05909
05910
05911 void Item_TextScroll_Paint(itemDef_t *item)
05912 {
05913 char cvartext[1024];
05914 float x, y, size, count, thumb;
05915 int i;
05916 textScrollDef_t *scrollPtr = (textScrollDef_t*)item->typeData;
05917
05918 count = scrollPtr->iLineCount;
05919
05920
05921 x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1;
05922 y = item->window.rect.y + 1;
05923 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp);
05924 y += SCROLLBAR_SIZE - 1;
05925
05926 scrollPtr->endPos = scrollPtr->startPos;
05927 size = item->window.rect.h - (SCROLLBAR_SIZE * 2);
05928 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, size+1, DC->Assets.scrollBar);
05929 y += size - 1;
05930 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown);
05931
05932
05933 thumb = Item_TextScroll_ThumbDrawPosition(item);
05934 if (thumb > y - SCROLLBAR_SIZE - 1)
05935 {
05936 thumb = y - SCROLLBAR_SIZE - 1;
05937 }
05938 DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
05939
05940 if (item->cvar)
05941 {
05942 DC->getCVarString(item->cvar, cvartext, sizeof(cvartext));
05943 item->text = cvartext;
05944 Item_TextScroll_BuildLines ( item );
05945 }
05946
05947
05948 size = item->window.rect.h - 2;
05949 x = item->window.rect.x + item->textalignx + 1;
05950 y = item->window.rect.y + item->textaligny + 1;
05951
05952 for (i = scrollPtr->startPos; i < count; i++)
05953 {
05954 const char *text;
05955
05956 text = scrollPtr->pLines[i];
05957 if (!text)
05958 {
05959 continue;
05960 }
05961
05962 DC->drawText(x + 4, y, item->textscale, item->window.foreColor, text, 0, 0, item->textStyle, item->iMenuFont);
05963
05964 size -= scrollPtr->lineHeight;
05965 if (size < scrollPtr->lineHeight)
05966 {
05967 scrollPtr->drawPadding = scrollPtr->lineHeight - size;
05968 break;
05969 }
05970
05971 scrollPtr->endPos++;
05972 y += scrollPtr->lineHeight;
05973 }
05974 }
05975
05976 #define COLOR_MAX 255.0f
05977
05978
05979 void Item_ListBox_Paint(itemDef_t *item) {
05980 float x, y, sizeWidth, count, i, i2,sizeHeight, thumb;
05981 int startPos;
05982 qhandle_t image;
05983 qhandle_t optionalImage1, optionalImage2, optionalImage3;
05984 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
05985
05986 int numlines;
05987
05988
05989
05990
05991
05992
05993 count = DC->feederCount(item->special);
05994
05995
05996 #ifdef _XBOX
05997 listPtr->startPos = listPtr->cursorPos;
05998
05999 #endif
06000
06001 if (listPtr->startPos > (count?count-1:count))
06002 {
06003 listPtr->startPos = 0;
06004 }
06005
06006 if (item->cursorPos > (count?count-1:count))
06007 {
06008 item->cursorPos = (count?count-1:count);
06009
06010 DC->feederSelection( item->special, item->cursorPos, NULL );
06011 }
06012
06013
06014
06015
06016 if (item->window.flags & WINDOW_HORIZONTAL)
06017 {
06018 #ifdef _DEBUG
06019 const char *text;
06020 #endif
06021
06022
06023 if (!listPtr->scrollhidden)
06024 {
06025
06026
06027 if (Item_ListBox_MaxScroll(item) > 0)
06028 {
06029 x = item->window.rect.x + 1;
06030 y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE - 1;
06031 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft);
06032 x += SCROLLBAR_SIZE - 1;
06033 sizeWidth = item->window.rect.w - (SCROLLBAR_SIZE * 2);
06034 DC->drawHandlePic(x, y, sizeWidth+1, SCROLLBAR_SIZE, DC->Assets.scrollBar);
06035 x += sizeWidth - 1;
06036 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight);
06037
06038 thumb = Item_ListBox_ThumbDrawPosition(item);
06039 if (thumb > x - SCROLLBAR_SIZE - 1) {
06040 thumb = x - SCROLLBAR_SIZE - 1;
06041 }
06042 DC->drawHandlePic(thumb, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
06043 }
06044 else if (listPtr->startPos > 0)
06045 {
06046 listPtr->startPos = 0;
06047 }
06048 }
06049
06050
06051 listPtr->endPos = listPtr->startPos;
06052 sizeWidth = item->window.rect.w - 2;
06053
06054
06055 if (listPtr->elementStyle == LISTBOX_IMAGE)
06056 {
06057
06058 x = item->window.rect.x + 1;
06059 y = item->window.rect.y + 1;
06060 for (i = listPtr->startPos; i < count; i++)
06061 {
06062
06063
06064 image = DC->feederItemImage(item->special, i);
06065 if (image)
06066 {
06067 #ifndef CGAME
06068 if (item->window.flags & WINDOW_PLAYERCOLOR)
06069 {
06070 vec4_t color;
06071
06072 color[0] = ui_char_color_red.integer/COLOR_MAX;
06073 color[1] = ui_char_color_green.integer/COLOR_MAX;
06074 color[2] = ui_char_color_blue.integer/COLOR_MAX;
06075 color[3] = 1.0f;
06076 DC->setColor(color);
06077 }
06078 #endif
06079 DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
06080 }
06081
06082 if (i == item->cursorPos)
06083 {
06084 DC->drawRect(x, y, listPtr->elementWidth-1, listPtr->elementHeight-1, item->window.borderSize, item->window.borderColor);
06085 }
06086
06087 sizeWidth -= listPtr->elementWidth;
06088 if (sizeWidth < listPtr->elementWidth)
06089 {
06090 listPtr->drawPadding = sizeWidth;
06091 break;
06092 }
06093 x += listPtr->elementWidth;
06094 listPtr->endPos++;
06095
06096 }
06097 }
06098 else
06099 {
06100
06101 }
06102
06103 #ifdef _DEBUG
06104
06105 text = DC->feederItemText(item->special, item->cursorPos, 0, &optionalImage1, &optionalImage2, &optionalImage3);
06106 if (text)
06107 {
06108 DC->drawText(item->window.rect.x, item->window.rect.y+item->window.rect.h, item->textscale, item->window.foreColor, text, 0, 0, item->textStyle, item->iMenuFont);
06109 }
06110 #endif
06111
06112 }
06113
06114 else
06115 {
06116
06117 numlines = item->window.rect.h / listPtr->elementHeight;
06118
06119
06120 if (!listPtr->scrollhidden)
06121 {
06122
06123
06124 x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1;
06125 y = item->window.rect.y + 1;
06126 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp);
06127 y += SCROLLBAR_SIZE - 1;
06128
06129 listPtr->endPos = listPtr->startPos;
06130 sizeHeight = item->window.rect.h - (SCROLLBAR_SIZE * 2);
06131 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, sizeHeight+1, DC->Assets.scrollBar);
06132 y += sizeHeight - 1;
06133 DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown);
06134
06135 thumb = Item_ListBox_ThumbDrawPosition(item);
06136 if (thumb > y - SCROLLBAR_SIZE - 1) {
06137 thumb = y - SCROLLBAR_SIZE - 1;
06138 }
06139 DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
06140 }
06141
06142
06143
06144 sizeWidth = item->window.rect.w - 2;
06145 sizeHeight = item->window.rect.h - 2;
06146
06147 if (listPtr->elementStyle == LISTBOX_IMAGE)
06148 {
06149
06150 if ( item->window.rect.w > (listPtr->elementWidth*2) )
06151 {
06152 startPos = listPtr->startPos;
06153 x = item->window.rect.x + 1;
06154 y = item->window.rect.y + 1;
06155
06156 for (i2 = startPos; i2 < count; i2++)
06157 {
06158 x = item->window.rect.x + 1;
06159 sizeWidth = item->window.rect.w - 2;
06160
06161 for (i = startPos; i < count; i++)
06162 {
06163
06164
06165 image = DC->feederItemImage(item->special, i);
06166 if (image)
06167 {
06168 #ifndef CGAME
06169 if (item->window.flags & WINDOW_PLAYERCOLOR)
06170 {
06171 vec4_t color;
06172
06173 color[0] = ui_char_color_red.integer/COLOR_MAX;
06174 color[1] = ui_char_color_green.integer/COLOR_MAX;
06175 color[2] = ui_char_color_blue.integer/COLOR_MAX;
06176 color[3] = 1.0f;
06177 DC->setColor(color);
06178 }
06179 #endif
06180 DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
06181 }
06182
06183 if (i == item->cursorPos)
06184 {
06185 DC->drawRect(x, y, listPtr->elementWidth-1, listPtr->elementHeight-1, item->window.borderSize, item->window.borderColor);
06186 }
06187
06188 sizeWidth -= listPtr->elementWidth;
06189 if (sizeWidth < listPtr->elementWidth)
06190 {
06191 listPtr->drawPadding = sizeWidth;
06192 break;
06193 }
06194 x += listPtr->elementWidth;
06195 listPtr->endPos++;
06196 }
06197
06198 sizeHeight -= listPtr->elementHeight;
06199 if (sizeHeight < listPtr->elementHeight)
06200 {
06201 listPtr->drawPadding = sizeHeight;
06202 break;
06203 }
06204
06205
06206 listPtr->endPos++;
06207 startPos = listPtr->endPos;
06208 y += listPtr->elementHeight;
06209
06210 }
06211 }
06212
06213 else
06214 {
06215 x = item->window.rect.x + 1;
06216 y = item->window.rect.y + 1;
06217 for (i = listPtr->startPos; i < count; i++)
06218 {
06219
06220
06221 image = DC->feederItemImage(item->special, i);
06222 if (image)
06223 {
06224 DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
06225 }
06226
06227 if (i == item->cursorPos)
06228 {
06229 DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, item->window.borderSize, item->window.borderColor);
06230 }
06231
06232 listPtr->endPos++;
06233 sizeHeight -= listPtr->elementHeight;
06234 if (sizeHeight < listPtr->elementHeight)
06235 {
06236 listPtr->drawPadding = listPtr->elementHeight - sizeHeight;
06237 break;
06238 }
06239 y += listPtr->elementHeight;
06240
06241 }
06242 }
06243 }
06244 else
06245 {
06246 x = item->window.rect.x + 1;
06247 y = item->window.rect.y + 1;
06248
06249 y = item->window.rect.y + 1 - listPtr->elementHeight;
06250 #ifdef _XBOX
06251 i = listPtr->startPos - (numlines/2);
06252 #else
06253 i = listPtr->startPos;
06254 #endif
06255
06256 for (; i < count; i++)
06257
06258 {
06259 const char *text;
06260
06261
06262 if (listPtr->numColumns > 0) {
06263 int j;
06264
06265 for (j = 0; j < listPtr->numColumns; j++)
06266 {
06267 char temp[MAX_STRING_CHARS];
06268 int imageStartX = listPtr->columnInfo[j].pos;
06269 text = DC->feederItemText(item->special, i, j, &optionalImage1, &optionalImage2, &optionalImage3);
06270
06271 if( !text )
06272 {
06273 continue;
06274 }
06275
06276 if (text[0]=='@')
06277 {
06278 trap_SP_GetStringTextString( &text[1] , temp, sizeof(temp));
06279 text = temp;
06280 }
06281
06282
06283
06284
06285
06286
06287
06288 if ( text )
06289 {
06290
06291 #ifdef _XBOX
06292 float fScaleA = item->textscale;
06293 #endif
06294 int textyOffset;
06295 #ifdef _XBOX
06296 textyOffset = DC->textHeight (text, fScaleA, item->iMenuFont);
06297 textyOffset *= -1;
06298 textyOffset /=2;
06299 textyOffset += listPtr->elementHeight/2;
06300 #else
06301 textyOffset = 0;
06302 #endif
06303
06304
06305 DC->drawText(x + 4 + listPtr->columnInfo[j].pos, y + listPtr->elementHeight+ textyOffset + item->textaligny, item->textscale, item->window.foreColor, text, 0,listPtr->columnInfo[j].maxChars, item->textStyle, item->iMenuFont);
06306
06307
06308
06309 }
06310 if ( j < listPtr->numColumns - 1 )
06311 {
06312 imageStartX = listPtr->columnInfo[j+1].pos;
06313 }
06314 DC->setColor( NULL );
06315 if (optionalImage3 >= 0)
06316 {
06317 DC->drawHandlePic(imageStartX - listPtr->elementHeight*3, y+listPtr->elementHeight+2, listPtr->elementHeight, listPtr->elementHeight, optionalImage3);
06318 }
06319 if (optionalImage2 >= 0)
06320 {
06321 DC->drawHandlePic(imageStartX - listPtr->elementHeight*2, y+listPtr->elementHeight+2, listPtr->elementHeight, listPtr->elementHeight, optionalImage2);
06322 }
06323 if (optionalImage1 >= 0)
06324 {
06325 DC->drawHandlePic(imageStartX - listPtr->elementHeight, y+listPtr->elementHeight+2, listPtr->elementHeight, listPtr->elementHeight, optionalImage1);
06326 }
06327 }
06328 }
06329 else
06330 {
06331 #ifdef _XBOX
06332 if (i >= 0)
06333 {
06334 #endif
06335 text = DC->feederItemText(item->special, i, 0, &optionalImage1, &optionalImage2, &optionalImage3 );
06336 if ( optionalImage1 >= 0 || optionalImage2 >= 0 || optionalImage3 >= 0)
06337 {
06338
06339 }
06340 else if (text)
06341 {
06342
06343 DC->drawText(x + 4, y + item->textaligny, item->textscale, item->window.foreColor, text, 0, 0, item->textStyle, item->iMenuFont);
06344 }
06345 #ifdef _XBOX
06346 }
06347 #endif
06348 }
06349
06350 if (i == item->cursorPos)
06351 {
06352 DC->fillRect(x + 2, y + listPtr->elementHeight + 2, item->window.rect.w - SCROLLBAR_SIZE - 4, listPtr->elementHeight, item->window.outlineColor);
06353 }
06354
06355 sizeHeight -= listPtr->elementHeight;
06356 if (sizeHeight < listPtr->elementHeight)
06357 {
06358 listPtr->drawPadding = listPtr->elementHeight - sizeHeight;
06359 break;
06360 }
06361 listPtr->endPos++;
06362 y += listPtr->elementHeight;
06363
06364 }
06365 }
06366 }
06367 }
06368
06369
06370 void Item_OwnerDraw_Paint(itemDef_t *item) {
06371 menuDef_t *parent;
06372
06373 if (item == NULL) {
06374 return;
06375 }
06376 parent = (menuDef_t*)item->parent;
06377
06378 if (DC->ownerDrawItem) {
06379 vec4_t color, lowLight;
06380 menuDef_t *parent = (menuDef_t*)item->parent;
06381 Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount);
06382 memcpy(&color, &item->window.foreColor, sizeof(color));
06383 if (item->numColors > 0 && DC->getValue) {
06384
06385 int i;
06386 float f = DC->getValue(item->window.ownerDraw);
06387 for (i = 0; i < item->numColors; i++) {
06388 if (f >= item->colorRanges[i].low && f <= item->colorRanges[i].high) {
06389 memcpy(&color, &item->colorRanges[i].color, sizeof(color));
06390 break;
06391 }
06392 }
06393 }
06394
06395 if (item->window.flags & WINDOW_HASFOCUS) {
06396 lowLight[0] = 0.8 * parent->focusColor[0];
06397 lowLight[1] = 0.8 * parent->focusColor[1];
06398 lowLight[2] = 0.8 * parent->focusColor[2];
06399 lowLight[3] = 0.8 * parent->focusColor[3];
06400 LerpColor(parent->focusColor,lowLight,color,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
06401 } else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1)) {
06402 lowLight[0] = 0.8 * item->window.foreColor[0];
06403 lowLight[1] = 0.8 * item->window.foreColor[1];
06404 lowLight[2] = 0.8 * item->window.foreColor[2];
06405 lowLight[3] = 0.8 * item->window.foreColor[3];
06406 LerpColor(item->window.foreColor,lowLight,color,0.5+0.5*sin((float)(DC->realTime / PULSE_DIVISOR)));
06407 }
06408
06409 if (item->disabled)
06410 {
06411 memcpy(color, parent->disableColor, sizeof(vec4_t));
06412 }
06413
06414 if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
06415 memcpy(color, parent->disableColor, sizeof(vec4_t));
06416 }
06417
06418 if (item->text) {
06419 Item_Text_Paint(item);
06420 if (item->text[0]) {
06421
06422 DC->ownerDrawItem(item->textRect.x + item->textRect.w + 8, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle,item->iMenuFont);
06423 } else {
06424 DC->ownerDrawItem(item->textRect.x + item->textRect.w, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle,item->iMenuFont);
06425 }
06426 } else {
06427 DC->ownerDrawItem(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, item->textalignx, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle,item->iMenuFont);
06428 }
06429 }
06430 }
06431
06432
06433 void Item_Paint(itemDef_t *item)
06434 {
06435 vec4_t red;
06436 menuDef_t *parent = (menuDef_t*)item->parent;
06437 int xPos,textWidth;
06438 vec4_t color = {1, 1, 1, 1};
06439
06440 red[0] = red[3] = 1;
06441 red[1] = red[2] = 0;
06442
06443 if (item == NULL)
06444 {
06445 return;
06446 }
06447
06448 if (item->window.flags & WINDOW_ORBITING)
06449 {
06450 if (DC->realTime > item->window.nextTime)
06451 {
06452 float rx, ry, a, c, s, w, h;
06453
06454 item->window.nextTime = DC->realTime + item->window.offsetTime;
06455
06456 w = item->window.rectClient.w / 2;
06457 h = item->window.rectClient.h / 2;
06458 rx = item->window.rectClient.x + w - item->window.rectEffects.x;
06459 ry = item->window.rectClient.y + h - item->window.rectEffects.y;
06460 a = 3 * M_PI / 180;
06461 c = cos(a);
06462 s = sin(a);
06463 item->window.rectClient.x = (rx * c - ry * s) + item->window.rectEffects.x - w;
06464 item->window.rectClient.y = (rx * s + ry * c) + item->window.rectEffects.y - h;
06465 Item_UpdatePosition(item);
06466 }
06467 }
06468
06469
06470 if (item->window.flags & WINDOW_INTRANSITION)
06471 {
06472 if (DC->realTime > item->window.nextTime)
06473 {
06474 int done = 0;
06475 item->window.nextTime = DC->realTime + item->window.offsetTime;
06476
06477
06478 if (item->window.rectClient.x == item->window.rectEffects.x)
06479 {
06480 done++;
06481 }
06482 else
06483 {
06484 if (item->window.rectClient.x < item->window.rectEffects.x)
06485 {
06486 item->window.rectClient.x += item->window.rectEffects2.x;
06487 if (item->window.rectClient.x > item->window.rectEffects.x)
06488 {
06489 item->window.rectClient.x = item->window.rectEffects.x;
06490 done++;
06491 }
06492 }
06493 else
06494 {
06495 item->window.rectClient.x -= item->window.rectEffects2.x;
06496 if (item->window.rectClient.x < item->window.rectEffects.x)
06497 {
06498 item->window.rectClient.x = item->window.rectEffects.x;
06499 done++;
06500 }
06501 }
06502 }
06503
06504 if (item->window.rectClient.y == item->window.rectEffects.y)
06505 {
06506 done++;
06507 }
06508 else
06509 {
06510 if (item->window.rectClient.y < item->window.rectEffects.y)
06511 {
06512 item->window.rectClient.y += item->window.rectEffects2.y;
06513 if (item->window.rectClient.y > item->window.rectEffects.y)
06514 {
06515 item->window.rectClient.y = item->window.rectEffects.y;
06516 done++;
06517 }
06518 }
06519 else
06520 {
06521 item->window.rectClient.y -= item->window.rectEffects2.y;
06522 if (item->window.rectClient.y < item->window.rectEffects.y)
06523 {
06524 item->window.rectClient.y = item->window.rectEffects.y;
06525 done++;
06526 }
06527 }
06528 }
06529
06530 if (item->window.rectClient.w == item->window.rectEffects.w)
06531 {
06532 done++;
06533 }
06534 else
06535 {
06536 if (item->window.rectClient.w < item->window.rectEffects.w)
06537 {
06538 item->window.rectClient.w += item->window.rectEffects2.w;
06539 if (item->window.rectClient.w > item->window.rectEffects.w)
06540 {
06541 item->window.rectClient.w = item->window.rectEffects.w;
06542 done++;
06543 }
06544 }
06545 else
06546 {
06547 item->window.rectClient.w -= item->window.rectEffects2.w;
06548 if (item->window.rectClient.w < item->window.rectEffects.w)
06549 {
06550 item->window.rectClient.w = item->window.rectEffects.w;
06551 done++;
06552 }
06553 }
06554 }
06555
06556 if (item->window.rectClient.h == item->window.rectEffects.h)
06557 {
06558 done++;
06559 }
06560 else
06561 {
06562 if (item->window.rectClient.h < item->window.rectEffects.h)
06563 {
06564 item->window.rectClient.h += item->window.rectEffects2.h;
06565 if (item->window.rectClient.h > item->window.rectEffects.h)
06566 {
06567 item->window.rectClient.h = item->window.rectEffects.h;
06568 done++;
06569 }
06570 }
06571 else
06572 {
06573 item->window.rectClient.h -= item->window.rectEffects2.h;
06574 if (item->window.rectClient.h < item->window.rectEffects.h)
06575 {
06576 item->window.rectClient.h = item->window.rectEffects.h;
06577 done++;
06578 }
06579 }
06580 }
06581
06582 Item_UpdatePosition(item);
06583
06584 if (done == 4)
06585 {
06586 item->window.flags &= ~WINDOW_INTRANSITION;
06587 }
06588
06589 }
06590 }
06591
06592 #ifdef _TRANS3
06593
06594
06595 if (item->window.flags & WINDOW_INTRANSITIONMODEL)
06596 {
06597 if ( item->type == ITEM_TYPE_MODEL)
06598 {
06599
06600
06601
06602
06603 modelDef_t * modelptr = (modelDef_t *)item->typeData;
06604
06605 if (DC->realTime > item->window.nextTime)
06606 {
06607 int done = 0;
06608 item->window.nextTime = DC->realTime + item->window.offsetTime;
06609
06610
06611
06612 if (modelptr->g2maxs[0] == modelptr->g2maxs2[0])
06613 {
06614 done++;
06615 }
06616 else
06617 {
06618 if (modelptr->g2maxs[0] < modelptr->g2maxs2[0])
06619 {
06620 modelptr->g2maxs[0] += modelptr->g2maxsEffect[0];
06621 if (modelptr->g2maxs[0] > modelptr->g2maxs2[0])
06622 {
06623 modelptr->g2maxs[0] = modelptr->g2maxs2[0];
06624 done++;
06625 }
06626 }
06627 else
06628 {
06629 modelptr->g2maxs[0] -= modelptr->g2maxsEffect[0];
06630 if (modelptr->g2maxs[0] < modelptr->g2maxs2[0])
06631 {
06632 modelptr->g2maxs[0] = modelptr->g2maxs2[0];
06633 done++;
06634 }
06635 }
06636 }
06637
06638 if (modelptr->g2maxs[1] == modelptr->g2maxs2[1])
06639 {
06640 done++;
06641 }
06642 else
06643 {
06644 if (modelptr->g2maxs[1] < modelptr->g2maxs2[1])
06645 {
06646 modelptr->g2maxs[1] += modelptr->g2maxsEffect[1];
06647 if (modelptr->g2maxs[1] > modelptr->g2maxs2[1])
06648 {
06649 modelptr->g2maxs[1] = modelptr->g2maxs2[1];
06650 done++;
06651 }
06652 }
06653 else
06654 {
06655 modelptr->g2maxs[1] -= modelptr->g2maxsEffect[1];
06656 if (modelptr->g2maxs[1] < modelptr->g2maxs2[1])
06657 {
06658 modelptr->g2maxs[1] = modelptr->g2maxs2[1];
06659 done++;
06660 }
06661 }
06662 }
06663
06664
06665
06666
06667 if (modelptr->g2maxs[2] == modelptr->g2maxs2[2])
06668 {
06669 done++;
06670 }
06671 else
06672 {
06673 if (modelptr->g2maxs[2] < modelptr->g2maxs2[2])
06674 {
06675 modelptr->g2maxs[2] += modelptr->g2maxsEffect[2];
06676 if (modelptr->g2maxs[2] > modelptr->g2maxs2[2])
06677 {
06678 modelptr->g2maxs[2] = modelptr->g2maxs2[2];
06679 done++;
06680 }
06681 }
06682 else
06683 {
06684 modelptr->g2maxs[2] -= modelptr->g2maxsEffect[2];
06685 if (modelptr->g2maxs[2] < modelptr->g2maxs2[2])
06686 {
06687 modelptr->g2maxs[2] = modelptr->g2maxs2[2];
06688 done++;
06689 }
06690 }
06691 }
06692
06693
06694 if (modelptr->g2mins[0] == modelptr->g2mins2[0])
06695 {
06696 done++;
06697 }
06698 else
06699 {
06700 if (modelptr->g2mins[0] < modelptr->g2mins2[0])
06701 {
06702 modelptr->g2mins[0] += modelptr->g2minsEffect[0];
06703 if (modelptr->g2mins[0] > modelptr->g2mins2[0])
06704 {
06705 modelptr->g2mins[0] = modelptr->g2mins2[0];
06706 done++;
06707 }
06708 }
06709 else
06710 {
06711 modelptr->g2mins[0] -= modelptr->g2minsEffect[0];
06712 if (modelptr->g2mins[0] < modelptr->g2mins2[0])
06713 {
06714 modelptr->g2mins[0] = modelptr->g2mins2[0];
06715 done++;
06716 }
06717 }
06718 }
06719
06720 if (modelptr->g2mins[1] == modelptr->g2mins2[1])
06721 {
06722 done++;
06723 }
06724 else
06725 {
06726 if (modelptr->g2mins[1] < modelptr->g2mins2[1])
06727 {
06728 modelptr->g2mins[1] += modelptr->g2minsEffect[1];
06729 if (modelptr->g2mins[1] > modelptr->g2mins2[1])
06730 {
06731 modelptr->g2mins[1] = modelptr->g2mins2[1];
06732 done++;
06733 }
06734 }
06735 else
06736 {
06737 modelptr->g2mins[1] -= modelptr->g2minsEffect[1];
06738 if (modelptr->g2mins[1] < modelptr->g2mins2[1])
06739 {
06740 modelptr->g2mins[1] = modelptr->g2mins2[1];
06741 done++;
06742 }
06743 }
06744 }
06745
06746
06747
06748
06749 if (modelptr->g2mins[2] == modelptr->g2mins2[2])
06750 {
06751 done++;
06752 }
06753 else
06754 {
06755 if (modelptr->g2mins[2] < modelptr->g2mins2[2])
06756 {
06757 modelptr->g2mins[2] += modelptr->g2minsEffect[2];
06758 if (modelptr->g2mins[2] > modelptr->g2mins2[2])
06759 {
06760 modelptr->g2mins[2] = modelptr->g2mins2[2];
06761 done++;
06762 }
06763 }
06764 else
06765 {
06766 modelptr->g2mins[2] -= modelptr->g2minsEffect[2];
06767 if (modelptr->g2mins[2] < modelptr->g2mins2[2])
06768 {
06769 modelptr->g2mins[2] = modelptr->g2mins2[2];
06770 done++;
06771 }
06772 }
06773 }
06774
06775
06776
06777
06778 if (modelptr->fov_x == modelptr->fov_x2)
06779 {
06780 done++;
06781 }
06782 else
06783 {
06784 if (modelptr->fov_x < modelptr->fov_x2)
06785 {
06786 modelptr->fov_x += modelptr->fov_Effectx;
06787 if (modelptr->fov_x > modelptr->fov_x2)
06788 {
06789 modelptr->fov_x = modelptr->fov_x2;
06790 done++;
06791 }
06792 }
06793 else
06794 {
06795 modelptr->fov_x -= modelptr->fov_Effectx;
06796 if (modelptr->fov_x < modelptr->fov_x2)
06797 {
06798 modelptr->fov_x = modelptr->fov_x2;
06799 done++;
06800 }
06801 }
06802 }
06803
06804
06805 if (modelptr->fov_y == modelptr->fov_y2)
06806 {
06807 done++;
06808 }
06809 else
06810 {
06811 if (modelptr->fov_y < modelptr->fov_y2)
06812 {
06813 modelptr->fov_y += modelptr->fov_Effecty;
06814 if (modelptr->fov_y > modelptr->fov_y2)
06815 {
06816 modelptr->fov_y = modelptr->fov_y2;
06817 done++;
06818 }
06819 }
06820 else
06821 {
06822 modelptr->fov_y -= modelptr->fov_Effecty;
06823 if (modelptr->fov_y < modelptr->fov_y2)
06824 {
06825 modelptr->fov_y = modelptr->fov_y2;
06826 done++;
06827 }
06828 }
06829 }
06830
06831 if (done == 5)
06832 {
06833 item->window.flags &= ~WINDOW_INTRANSITIONMODEL;
06834 }
06835
06836 }
06837 }
06838 }
06839 #endif
06840
06841
06842
06843
06844 if (item->window.ownerDrawFlags && DC->ownerDrawVisible) {
06845 if (!DC->ownerDrawVisible(item->window.ownerDrawFlags)) {
06846 item->window.flags &= ~WINDOW_VISIBLE;
06847 } else {
06848 item->window.flags |= WINDOW_VISIBLE;
06849 }
06850 }
06851
06852 if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE)) {
06853 if (!Item_EnableShowViaCvar(item, CVAR_SHOW)) {
06854 return;
06855 }
06856 }
06857
06858 if (item->window.flags & WINDOW_TIMEDVISIBLE) {
06859
06860 }
06861
06862 if (!(item->window.flags & WINDOW_VISIBLE))
06863 {
06864 return;
06865 }
06866
06867
06868
06869 #ifndef _XBOX
06870 if (item->window.flags & WINDOW_MOUSEOVER)
06871 #else
06872 if (item->window.flags & WINDOW_HASFOCUS)
06873 #endif
06874 {
06875 if (item->descText && !Display_KeyBindPending())
06876 {
06877
06878 #ifndef _XBOX
06879
06880
06881
06882
06883
06884
06885
06886
06887 #endif
06888
06889 {
06890 const char *textPtr = item->descText;
06891 if (*textPtr == '@')
06892 {
06893 char temp[MAX_STRING_CHARS];
06894 trap_SP_GetStringTextString( &textPtr[1] , temp, sizeof(temp));
06895 textPtr = temp;
06896 }
06897
06898 Item_TextColor(item, &color);
06899
06900 {
06901 float fDescScale = parent->descScale ? parent->descScale : 1;
06902 float fDescScaleCopy = fDescScale;
06903 int iYadj = 0;
06904 while (1)
06905 {
06906 textWidth = DC->textWidth(textPtr,fDescScale, FONT_SMALL2);
06907
06908 if (parent->descAlignment == ITEM_ALIGN_RIGHT)
06909 {
06910 xPos = parent->descX - textWidth;
06911 }
06912 else if (parent->descAlignment == ITEM_ALIGN_CENTER)
06913 {
06914 xPos = parent->descX - (textWidth/2);
06915 }
06916 else
06917 {
06918 xPos = parent->descX;
06919 }
06920
06921 if (parent->descAlignment == ITEM_ALIGN_CENTER)
06922 {
06923
06924
06925 if (xPos + textWidth > (SCREEN_WIDTH-4)) {
06926 fDescScale -= 0.001f;
06927 continue;
06928 }
06929 }
06930
06931
06932
06933 if (fDescScale != fDescScaleCopy)
06934 {
06935 int iOriginalTextHeight = DC->textHeight(textPtr, fDescScaleCopy, FONT_MEDIUM);
06936 iYadj = iOriginalTextHeight - DC->textHeight(textPtr, fDescScale, FONT_MEDIUM);
06937 }
06938
06939 DC->drawText(xPos, parent->descY + iYadj, fDescScale, parent->descColor, textPtr, 0, 0, item->textStyle, FONT_SMALL2);
06940 break;
06941 }
06942 }
06943 }
06944 }
06945 }
06946
06947
06948 Window_Paint(&item->window, parent->fadeAmount , parent->fadeClamp, parent->fadeCycle);
06949
06950
06951 if (debugMode)
06952 {
06953 vec4_t color;
06954 color[1] = color[3] = 1;
06955 color[0] = color[2] = 0;
06956 DC->drawRect(
06957 item->window.rect.x,
06958 item->window.rect.y,
06959 item->window.rect.w,
06960 item->window.rect.h,
06961 1,
06962 color);
06963 }
06964
06965
06966
06967 switch (item->type) {
06968 case ITEM_TYPE_OWNERDRAW:
06969 Item_OwnerDraw_Paint(item);
06970 break;
06971 case ITEM_TYPE_TEXT:
06972 case ITEM_TYPE_BUTTON:
06973 Item_Text_Paint(item);
06974 break;
06975 case ITEM_TYPE_RADIOBUTTON:
06976 break;
06977 case ITEM_TYPE_CHECKBOX:
06978 break;
06979 case ITEM_TYPE_EDITFIELD:
06980 case ITEM_TYPE_NUMERICFIELD:
06981 Item_TextField_Paint(item);
06982 break;
06983 case ITEM_TYPE_COMBO:
06984 break;
06985 case ITEM_TYPE_LISTBOX:
06986 Item_ListBox_Paint(item);
06987 break;
06988 case ITEM_TYPE_TEXTSCROLL:
06989 Item_TextScroll_Paint ( item );
06990 break;
06991
06992
06993
06994 case ITEM_TYPE_MODEL:
06995 Item_Model_Paint(item);
06996 break;
06997 case ITEM_TYPE_YESNO:
06998 Item_YesNo_Paint(item);
06999 break;
07000 case ITEM_TYPE_MULTI:
07001 Item_Multi_Paint(item);
07002 break;
07003 case ITEM_TYPE_BIND:
07004 Item_Bind_Paint(item);
07005 break;
07006 case ITEM_TYPE_SLIDER:
07007 Item_Slider_Paint(item);
07008 break;
07009 default:
07010 break;
07011 }
07012
07013 }
07014
07015 void Menu_Init(menuDef_t *menu) {
07016 memset(menu, 0, sizeof(menuDef_t));
07017 menu->cursorItem = -1;
07018 menu->fadeAmount = DC->Assets.fadeAmount;
07019 menu->fadeClamp = DC->Assets.fadeClamp;
07020 menu->fadeCycle = DC->Assets.fadeCycle;
07021 Window_Init(&menu->window);
07022 }
07023
07024 itemDef_t *Menu_GetFocusedItem(menuDef_t *menu) {
07025 int i;
07026 if (menu) {
07027 for (i = 0; i < menu->itemCount; i++) {
07028 if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
07029 return menu->items[i];
07030 }
07031 }
07032 }
07033 return NULL;
07034 }
07035
07036 menuDef_t *Menu_GetFocused() {
07037 int i;
07038 for (i = 0; i < menuCount; i++) {
07039 if (Menus[i].window.flags & WINDOW_HASFOCUS && Menus[i].window.flags & WINDOW_VISIBLE) {
07040 return &Menus[i];
07041 }
07042 }
07043 return NULL;
07044 }
07045
07046 void Menu_ScrollFeeder(menuDef_t *menu, int feeder, qboolean down) {
07047 if (menu) {
07048 int i;
07049 for (i = 0; i < menu->itemCount; i++) {
07050 if (menu->items[i]->special == feeder) {
07051 Item_ListBox_HandleKey(menu->items[i], (down) ? A_CURSOR_DOWN : A_CURSOR_UP, qtrue, qtrue);
07052 return;
07053 }
07054 }
07055 }
07056 }
07057
07058
07059
07060 void Menu_SetFeederSelection(menuDef_t *menu, int feeder, int index, const char *name) {
07061 if (menu == NULL) {
07062 if (name == NULL) {
07063 menu = Menu_GetFocused();
07064 } else {
07065 menu = Menus_FindByName(name);
07066 }
07067 }
07068
07069 if (menu) {
07070 int i;
07071 for (i = 0; i < menu->itemCount; i++) {
07072 if (menu->items[i]->special == feeder) {
07073 if (index == 0) {
07074 listBoxDef_t *listPtr = (listBoxDef_t*)menu->items[i]->typeData;
07075 listPtr->cursorPos = 0;
07076 listPtr->startPos = 0;
07077 }
07078 menu->items[i]->cursorPos = index;
07079 DC->feederSelection(menu->items[i]->special, menu->items[i]->cursorPos, NULL);
07080 return;
07081 }
07082 }
07083 }
07084 }
07085
07086 qboolean Menus_AnyFullScreenVisible() {
07087 int i;
07088 for (i = 0; i < menuCount; i++) {
07089 if (Menus[i].window.flags & WINDOW_VISIBLE && Menus[i].fullScreen) {
07090 return qtrue;
07091 }
07092 }
07093 return qfalse;
07094 }
07095
07096 menuDef_t *Menus_ActivateByName(const char *p) {
07097 int i;
07098 menuDef_t *m = NULL;
07099 menuDef_t *focus = Menu_GetFocused();
07100 for (i = 0; i < menuCount; i++) {
07101 if (Q_stricmp(Menus[i].window.name, p) == 0) {
07102 m = &Menus[i];
07103 Menus_Activate(m);
07104 if (openMenuCount < MAX_OPEN_MENUS && focus != NULL) {
07105 menuStack[openMenuCount++] = focus;
07106 }
07107 } else {
07108 Menus[i].window.flags &= ~WINDOW_HASFOCUS;
07109 }
07110 }
07111 Display_CloseCinematics();
07112
07113
07114 Menu_HandleMouseMove ( m, DC->cursorx, DC->cursory );
07115
07116 return m;
07117 }
07118
07119
07120 void Item_Init(itemDef_t *item) {
07121 memset(item, 0, sizeof(itemDef_t));
07122 item->textscale = 0.55f;
07123 Window_Init(&item->window);
07124 }
07125
07126 void Menu_HandleMouseMove(menuDef_t *menu, float x, float y) {
07127
07128
07129 #ifdef _XBOX
07130 return ;
07131 #endif
07132
07133
07134
07135 int i, pass;
07136 qboolean focusSet = qfalse;
07137
07138 itemDef_t *overItem;
07139 if (menu == NULL) {
07140 return;
07141 }
07142
07143 if (!(menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) {
07144 return;
07145 }
07146
07147 if (itemCapture) {
07148
07149 return;
07150 }
07151
07152 if (g_waitingForKey || g_editingField) {
07153 return;
07154 }
07155
07156
07157
07158 for (pass = 0; pass < 2; pass++) {
07159 for (i = 0; i < menu->itemCount; i++) {
07160
07161
07162
07163 if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) {
07164 continue;
07165 }
07166
07167 if (menu->items[i]->disabled)
07168 {
07169 continue;
07170 }
07171
07172
07173 if (menu->items[i]->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_ENABLE)) {
07174 continue;
07175 }
07176
07177 if (menu->items[i]->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_SHOW)) {
07178 continue;
07179 }
07180
07181
07182
07183 if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) {
07184 if (pass == 1) {
07185 overItem = menu->items[i];
07186 if (overItem->type == ITEM_TYPE_TEXT && overItem->text) {
07187 if (!Rect_ContainsPoint(&overItem->window.rect, x, y)) {
07188 continue;
07189 }
07190 }
07191
07192 if (IsVisible(overItem->window.flags)) {
07193
07194 Item_MouseEnter(overItem, x, y);
07195
07196
07197
07198 if (!focusSet) {
07199 focusSet = Item_SetFocus(overItem, x, y);
07200 }
07201 }
07202 }
07203 } else if (menu->items[i]->window.flags & WINDOW_MOUSEOVER) {
07204 Item_MouseLeave(menu->items[i]);
07205 Item_SetMouseOver(menu->items[i], qfalse);
07206 }
07207 }
07208 }
07209
07210 }
07211
07212 void Menu_Paint(menuDef_t *menu, qboolean forcePaint) {
07213 int i;
07214
07215 if (menu == NULL) {
07216 return;
07217 }
07218
07219 if (!(menu->window.flags & WINDOW_VISIBLE) && !forcePaint) {
07220 return;
07221 }
07222
07223 if (menu->window.ownerDrawFlags && DC->ownerDrawVisible && !DC->ownerDrawVisible(menu->window.ownerDrawFlags)) {
07224 return;
07225 }
07226
07227 if (forcePaint) {
07228 menu->window.flags |= WINDOW_FORCED;
07229 }
07230
07231
07232 if (menu->fullScreen) {
07233
07234
07235 DC->drawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, menu->window.background );
07236 } else if (menu->window.background) {
07237
07238
07239 }
07240
07241
07242 Window_Paint(&menu->window, menu->fadeAmount, menu->fadeClamp, menu->fadeCycle );
07243
07244
07245 for (i = 0; i < menu->itemCount; i++)
07246 {
07247 if (!menu->items[i]->appearanceSlot)
07248 {
07249 Item_Paint(menu->items[i]);
07250 }
07251 else
07252 {
07253 if (menu->appearanceTime < DC->realTime)
07254 {
07255 menu->appearanceTime = DC->realTime + menu->appearanceIncrement;
07256 menu->appearanceCnt++;
07257 }
07258
07259 if (menu->items[i]->appearanceSlot<=menu->appearanceCnt)
07260 {
07261 Item_Paint(menu->items[i]);
07262 }
07263 }
07264 }
07265
07266 if (debugMode) {
07267 vec4_t color;
07268 color[0] = color[2] = color[3] = 1;
07269 color[1] = 0;
07270 DC->drawRect(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, 1, color);
07271 }
07272 }
07273
07274
07275
07276
07277
07278
07279 void Item_ValidateTypeData(itemDef_t *item)
07280 {
07281 if (item->typeData)
07282 {
07283 return;
07284 }
07285
07286 if (item->type == ITEM_TYPE_LISTBOX)
07287 {
07288 item->typeData = UI_Alloc(sizeof(listBoxDef_t));
07289 memset(item->typeData, 0, sizeof(listBoxDef_t));
07290 }
07291 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_TEXT)
07292 {
07293 item->typeData = UI_Alloc(sizeof(editFieldDef_t));
07294 memset(item->typeData, 0, sizeof(editFieldDef_t));
07295 if (item->type == ITEM_TYPE_EDITFIELD)
07296 {
07297 if (!((editFieldDef_t *) item->typeData)->maxPaintChars)
07298 {
07299 ((editFieldDef_t *) item->typeData)->maxPaintChars = MAX_EDITFIELD;
07300 }
07301 }
07302 }
07303 else if (item->type == ITEM_TYPE_MULTI)
07304 {
07305 item->typeData = UI_Alloc(sizeof(multiDef_t));
07306 }
07307 else if (item->type == ITEM_TYPE_MODEL)
07308 {
07309 item->typeData = UI_Alloc(sizeof(modelDef_t));
07310 memset(item->typeData, 0, sizeof(modelDef_t));
07311 }
07312 else if (item->type == ITEM_TYPE_TEXTSCROLL )
07313 {
07314 item->typeData = UI_Alloc(sizeof(textScrollDef_t));
07315 }
07316 }
07317
07318
07319
07320
07321
07322
07323
07324 #define KEYWORDHASH_SIZE 512
07325
07326 typedef struct keywordHash_s
07327 {
07328 char *keyword;
07329 qboolean (*func)(itemDef_t *item, int handle);
07330 struct keywordHash_s *next;
07331 } keywordHash_t;
07332
07333 int KeywordHash_Key(char *keyword) {
07334 int register hash, i;
07335
07336 hash = 0;
07337 for (i = 0; keyword[i] != '\0'; i++) {
07338 if (keyword[i] >= 'A' && keyword[i] <= 'Z')
07339 hash += (keyword[i] + ('a' - 'A')) * (119 + i);
07340 else
07341 hash += keyword[i] * (119 + i);
07342 }
07343 hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (KEYWORDHASH_SIZE-1);
07344 return hash;
07345 }
07346
07347 void KeywordHash_Add(keywordHash_t *table[], keywordHash_t *key) {
07348 int hash;
07349
07350 hash = KeywordHash_Key(key->keyword);
07351
07352
07353
07354
07355
07356 key->next = table[hash];
07357 table[hash] = key;
07358 }
07359
07360 keywordHash_t *KeywordHash_Find(keywordHash_t *table[], char *keyword)
07361 {
07362 keywordHash_t *key;
07363 int hash;
07364
07365 hash = KeywordHash_Key(keyword);
07366 for (key = table[hash]; key; key = key->next) {
07367 if (!Q_stricmp(key->keyword, keyword))
07368 return key;
07369 }
07370 return NULL;
07371 }
07372
07373
07374
07375
07376
07377
07378
07379
07380 qboolean ItemParse_name( itemDef_t *item, int handle ) {
07381 if (!PC_String_Parse(handle, &item->window.name)) {
07382 return qfalse;
07383 }
07384 return qtrue;
07385 }
07386
07387
07388 qboolean ItemParse_focusSound( itemDef_t *item, int handle ) {
07389 pc_token_t token;
07390 if (!trap_PC_ReadToken(handle, &token)) {
07391 return qfalse;
07392 }
07393 item->focusSound = DC->registerSound(token.string);
07394 return qtrue;
07395 }
07396
07397
07398
07399 qboolean ItemParse_text( itemDef_t *item, int handle ) {
07400 if (!PC_String_Parse(handle, &item->text)) {
07401 return qfalse;
07402 }
07403 return qtrue;
07404 }
07405
07406
07407
07408
07409
07410
07411
07412 qboolean ItemParse_descText( itemDef_t *item, int handle)
07413 {
07414
07415 if (!PC_String_Parse(handle, &item->descText))
07416 {
07417 return qfalse;
07418 }
07419
07420 return qtrue;
07421
07422 }
07423
07424
07425
07426
07427
07428
07429
07430
07431 qboolean ItemParse_text2( itemDef_t *item, int handle)
07432 {
07433
07434 if (!PC_String_Parse(handle, &item->text2))
07435 {
07436 return qfalse;
07437 }
07438
07439 return qtrue;
07440
07441 }
07442
07443
07444
07445
07446
07447
07448 qboolean ItemParse_text2alignx( itemDef_t *item, int handle)
07449 {
07450 if (!PC_Float_Parse(handle, &item->text2alignx))
07451 {
07452 return qfalse;
07453 }
07454 return qtrue;
07455 }
07456
07457
07458
07459
07460
07461
07462 qboolean ItemParse_text2aligny( itemDef_t *item, int handle)
07463 {
07464 if (!PC_Float_Parse(handle, &item->text2aligny))
07465 {
07466 return qfalse;
07467 }
07468 return qtrue;
07469 }
07470
07471
07472 qboolean ItemParse_group( itemDef_t *item, int handle ) {
07473 if (!PC_String_Parse(handle, &item->window.group)) {
07474 return qfalse;
07475 }
07476 return qtrue;
07477 }
07478
07479 typedef struct uiG2PtrTracker_s uiG2PtrTracker_t;
07480
07481 struct uiG2PtrTracker_s
07482 {
07483 void *ghoul2;
07484 uiG2PtrTracker_t *next;
07485 };
07486
07487 uiG2PtrTracker_t *ui_G2PtrTracker = NULL;
07488
07489
07490
07491
07492 void UI_InsertG2Pointer(void *ghoul2)
07493 {
07494 uiG2PtrTracker_t **nextFree = &ui_G2PtrTracker;
07495
07496 while ((*nextFree) && (*nextFree)->ghoul2)
07497 {
07498 nextFree = &((*nextFree)->next);
07499 }
07500
07501 if (!nextFree)
07502 {
07503 assert(0);
07504 return;
07505 }
07506
07507 if (!(*nextFree))
07508 {
07509 (*nextFree) = (uiG2PtrTracker_t *)BG_Alloc(sizeof(uiG2PtrTracker_t));
07510 (*nextFree)->next = NULL;
07511 }
07512
07513 (*nextFree)->ghoul2 = ghoul2;
07514 }
07515
07516
07517 void UI_ClearG2Pointer(void *ghoul2)
07518 {
07519 uiG2PtrTracker_t *next = ui_G2PtrTracker;
07520
07521 if (!ghoul2)
07522 {
07523 return;
07524 }
07525
07526 while (next)
07527 {
07528 if (next->ghoul2 == ghoul2)
07529 {
07530 next->ghoul2 = NULL;
07531 break;
07532 }
07533
07534 next = next->next;
07535 }
07536 }
07537
07538
07539 void UI_CleanupGhoul2(void)
07540 {
07541 uiG2PtrTracker_t *next = ui_G2PtrTracker;
07542
07543 while (next)
07544 {
07545 if (next->ghoul2 && trap_G2_HaveWeGhoul2Models(next->ghoul2))
07546 {
07547 trap_G2API_CleanGhoul2Models(&next->ghoul2);
07548 }
07549
07550 next = next->next;
07551 }
07552
07553 #ifdef _XBOX
07554 ui_G2PtrTracker = NULL;
07555 #endif
07556 }
07557
07558
07559 int UI_ParseAnimationFile(const char *filename, animation_t *animset, qboolean isHumanoid);
07560
07561
07562
07563
07564
07565
07566
07567 qboolean ItemParse_asset_model_go( itemDef_t *item, const char *name,int *runTimeLength )
07568 {
07569 #ifndef CGAME
07570 int g2Model;
07571 modelDef_t *modelPtr;
07572 Item_ValidateTypeData(item);
07573 modelPtr = (modelDef_t*)item->typeData;
07574 *runTimeLength =0.0f;
07575
07576 if (!Q_stricmp(&name[strlen(name) - 4], ".glm"))
07577 {
07578 if ( item->ghoul2 )
07579 {
07580 UI_ClearG2Pointer(item->ghoul2);
07581 trap_G2API_CleanGhoul2Models(&item->ghoul2);
07582 item->flags &= ~ITF_G2VALID;
07583 }
07584
07585 g2Model = trap_G2API_InitGhoul2Model(&item->ghoul2, name, 0, modelPtr->g2skin, 0, 0, 0);
07586 if (g2Model >= 0)
07587 {
07588 UI_InsertG2Pointer(item->ghoul2);
07589 item->flags |= ITF_G2VALID;
07590
07591 if (modelPtr->g2anim)
07592 {
07593
07594
07595 char GLAName[MAX_QPATH];
07596
07597 GLAName[0] = 0;
07598 trap_G2API_GetGLAName(item->ghoul2, 0, GLAName);
07599
07600 if (GLAName[0])
07601 {
07602 int animIndex;
07603 char *slash;
07604
07605 slash = Q_strrchr( GLAName, '/' );
07606
07607 if ( slash )
07608 {
07609 strcpy(slash, "/animation.cfg");
07610
07611 animIndex = UI_ParseAnimationFile(GLAName, NULL, qfalse);
07612 if (animIndex != -1)
07613 {
07614 animation_t *anim = &bgAllAnims[animIndex].anims[modelPtr->g2anim];
07615
07616 int sFrame = anim->firstFrame;
07617 int eFrame = anim->firstFrame + anim->numFrames;
07618 int flags = BONE_ANIM_OVERRIDE_FREEZE;
07619 int time = DC->realTime;
07620 float animSpeed = 50.0f / anim->frameLerp;
07621 int blendTime = 150;
07622
07623 if (anim->loopFrames != -1)
07624 {
07625 flags |= BONE_ANIM_OVERRIDE_LOOP;
07626 }
07627
07628 trap_G2API_SetBoneAnim(item->ghoul2, 0, "model_root", sFrame, eFrame, flags, animSpeed, time, -1, blendTime);
07629 *runTimeLength =((anim->frameLerp * (anim->numFrames-2)));
07630 }
07631 }
07632 }
07633 }
07634
07635 if ( modelPtr->g2skin )
07636 {
07637
07638
07639
07640 trap_G2API_SetSkin(item->ghoul2, 0, modelPtr->g2skin, modelPtr->g2skin);
07641 }
07642 }
07643
07644
07645
07646
07647
07648
07649 }
07650 else if(!(item->asset))
07651 {
07652 item->asset = DC->registerModel(name);
07653 item->flags &= ~ITF_G2VALID;
07654 }
07655 #endif
07656 return qtrue;
07657 }
07658
07659 qboolean ItemParse_asset_model( itemDef_t *item, int handle ) {
07660 const char *temp;
07661 modelDef_t *modelPtr;
07662 int animRunLength;
07663 pc_token_t token;
07664
07665 Item_ValidateTypeData(item);
07666 modelPtr = (modelDef_t*)item->typeData;
07667
07668 if (!trap_PC_ReadToken(handle, &token)) {
07669 return qfalse;
07670 }
07671 temp = token.string;
07672
07673 #ifndef CGAME
07674 if (!stricmp(token.string,"ui_char_model") )
07675 {
07676 char modelPath[MAX_QPATH];
07677 char ui_char_model[MAX_QPATH];
07678 trap_Cvar_VariableStringBuffer("ui_char_model", ui_char_model, sizeof(ui_char_model) );
07679 Com_sprintf( modelPath, sizeof( modelPath ), "models/players/%s/model.glm", ui_char_model );
07680 temp = modelPath;
07681 }
07682 #endif
07683 return (ItemParse_asset_model_go( item, temp, &animRunLength ));
07684 }
07685
07686
07687 qboolean ItemParse_asset_shader( itemDef_t *item, int handle ) {
07688 pc_token_t token;
07689 if (!trap_PC_ReadToken(handle, &token)) {
07690 return qfalse;
07691 }
07692 item->asset = DC->registerShaderNoMip(token.string);
07693 return qtrue;
07694 }
07695
07696
07697 qboolean ItemParse_model_origin( itemDef_t *item, int handle ) {
07698 modelDef_t *modelPtr;
07699 Item_ValidateTypeData(item);
07700 modelPtr = (modelDef_t*)item->typeData;
07701
07702 if (PC_Float_Parse(handle, &modelPtr->origin[0])) {
07703 if (PC_Float_Parse(handle, &modelPtr->origin[1])) {
07704 if (PC_Float_Parse(handle, &modelPtr->origin[2])) {
07705 return qtrue;
07706 }
07707 }
07708 }
07709 return qfalse;
07710 }
07711
07712
07713 qboolean ItemParse_model_fovx( itemDef_t *item, int handle ) {
07714 modelDef_t *modelPtr;
07715 Item_ValidateTypeData(item);
07716 modelPtr = (modelDef_t*)item->typeData;
07717
07718 if (!PC_Float_Parse(handle, &modelPtr->fov_x)) {
07719 return qfalse;
07720 }
07721 return qtrue;
07722 }
07723
07724
07725 qboolean ItemParse_model_fovy( itemDef_t *item, int handle ) {
07726 modelDef_t *modelPtr;
07727 Item_ValidateTypeData(item);
07728 modelPtr = (modelDef_t*)item->typeData;
07729
07730 if (!PC_Float_Parse(handle, &modelPtr->fov_y)) {
07731 return qfalse;
07732 }
07733 return qtrue;
07734 }
07735
07736
07737 qboolean ItemParse_model_rotation( itemDef_t *item, int handle ) {
07738 modelDef_t *modelPtr;
07739 Item_ValidateTypeData(item);
07740 modelPtr = (modelDef_t*)item->typeData;
07741
07742 if (!PC_Int_Parse(handle, &modelPtr->rotationSpeed)) {
07743 return qfalse;
07744 }
07745 return qtrue;
07746 }
07747
07748
07749 qboolean ItemParse_model_angle( itemDef_t *item, int handle ) {
07750 modelDef_t *modelPtr;
07751 Item_ValidateTypeData(item);
07752 modelPtr = (modelDef_t*)item->typeData;
07753
07754 if (!PC_Int_Parse(handle, &modelPtr->angle)) {
07755 return qfalse;
07756 }
07757 return qtrue;
07758 }
07759
07760
07761 qboolean ItemParse_model_g2mins( itemDef_t *item, int handle ) {
07762 modelDef_t *modelPtr;
07763 Item_ValidateTypeData(item);
07764 modelPtr = (modelDef_t*)item->typeData;
07765
07766 if (PC_Float_Parse(handle, &modelPtr->g2mins[0])) {
07767 if (PC_Float_Parse(handle, &modelPtr->g2mins[1])) {
07768 if (PC_Float_Parse(handle, &modelPtr->g2mins[2])) {
07769 return qtrue;
07770 }
07771 }
07772 }
07773 return qfalse;
07774 }
07775
07776
07777 qboolean ItemParse_model_g2maxs( itemDef_t *item, int handle ) {
07778 modelDef_t *modelPtr;
07779 Item_ValidateTypeData(item);
07780 modelPtr = (modelDef_t*)item->typeData;
07781
07782 if (PC_Float_Parse(handle, &modelPtr->g2maxs[0])) {
07783 if (PC_Float_Parse(handle, &modelPtr->g2maxs[1])) {
07784 if (PC_Float_Parse(handle, &modelPtr->g2maxs[2])) {
07785 return qtrue;
07786 }
07787 }
07788 }
07789 return qfalse;
07790 }
07791
07792
07793 qboolean ItemParse_model_g2scale( itemDef_t *item, int handle ) {
07794 modelDef_t *modelPtr;
07795 Item_ValidateTypeData(item);
07796 modelPtr = (modelDef_t*)item->typeData;
07797
07798 if (PC_Float_Parse(handle, &modelPtr->g2scale[0])) {
07799 if (PC_Float_Parse(handle, &modelPtr->g2scale[1])) {
07800 if (PC_Float_Parse(handle, &modelPtr->g2scale[2])) {
07801 return qtrue;
07802 }
07803 }
07804 }
07805 return qfalse;
07806 }
07807
07808
07809 qhandle_t trap_R_RegisterSkin( const char *name );
07810
07811 qboolean ItemParse_model_g2skin( itemDef_t *item, int handle ) {
07812 modelDef_t *modelPtr;
07813 pc_token_t token;
07814
07815 Item_ValidateTypeData(item);
07816 modelPtr = (modelDef_t*)item->typeData;
07817
07818 if (!trap_PC_ReadToken(handle, &token)) {
07819 return qfalse;
07820 }
07821
07822 if (!token.string[0])
07823 {
07824 return qtrue;
07825 }
07826
07827 modelPtr->g2skin = trap_R_RegisterSkin(token.string);
07828
07829 return qtrue;
07830 }
07831
07832
07833 qboolean ItemParse_model_g2anim( itemDef_t *item, int handle ) {
07834 modelDef_t *modelPtr;
07835 pc_token_t token;
07836 int i = 0;
07837
07838 Item_ValidateTypeData(item);
07839 modelPtr = (modelDef_t*)item->typeData;
07840
07841 if (!trap_PC_ReadToken(handle, &token)) {
07842 return qfalse;
07843 }
07844
07845 if ( !token.string[0])
07846 {
07847 return qtrue;
07848 }
07849
07850 while (i < MAX_ANIMATIONS)
07851 {
07852 if (!Q_stricmp(token.string, animTable[i].name))
07853 {
07854 modelPtr->g2anim = i;
07855 return qtrue;
07856 }
07857 i++;
07858 }
07859
07860 Com_Printf("Could not find '%s' in the anim table\n", token.string);
07861 return qtrue;
07862 }
07863
07864
07865 qboolean ItemParse_model_g2skin_go( itemDef_t *item, const char *skinName )
07866 {
07867
07868 modelDef_t *modelPtr;
07869 int defSkin;
07870
07871
07872 Item_ValidateTypeData(item);
07873 modelPtr = (modelDef_t*)item->typeData;
07874
07875 if (!skinName || !skinName[0])
07876 {
07877 modelPtr->g2skin = 0;
07878 trap_G2API_SetSkin(item->ghoul2, 0, 0, 0);
07879
07880 return qtrue;
07881 }
07882
07883
07884 if ( item->ghoul2 )
07885 {
07886 defSkin = trap_R_RegisterSkin(skinName);
07887 trap_G2API_SetSkin(item->ghoul2, 0, defSkin, defSkin);
07888 }
07889
07890 return qtrue;
07891 }
07892
07893
07894 qboolean ItemParse_model_g2anim_go( itemDef_t *item, const char *animName )
07895 {
07896 modelDef_t *modelPtr;
07897 int i = 0;
07898
07899 Item_ValidateTypeData(item);
07900 modelPtr = (modelDef_t*)item->typeData;
07901
07902 if (!animName || !animName[0])
07903 {
07904 return qtrue;
07905 }
07906
07907 while (i < MAX_ANIMATIONS)
07908 {
07909 if (!Q_stricmp(animName, animTable[i].name))
07910 {
07911 modelPtr->g2anim = animTable[i].id;
07912 return qtrue;
07913 }
07914 i++;
07915 }
07916
07917 Com_Printf("Could not find '%s' in the anim table\n", animName);
07918 return qtrue;
07919 }
07920
07921
07922 qboolean ItemParse_rectcvar( itemDef_t *item, int handle )
07923 {
07924 char cvarBuf[1024];
07925 const char *holdVal;
07926 char *holdBuf;
07927
07928
07929 pc_token_t token;
07930 if (!trap_PC_ReadToken(handle, &token))
07931 {
07932 return qfalse;
07933 }
07934
07935
07936 DC->getCVarString(token.string, cvarBuf, sizeof(cvarBuf));
07937
07938 holdBuf = cvarBuf;
07939 if (String_Parse(&holdBuf,&holdVal))
07940 {
07941 item->window.rectClient.x = atof(holdVal);
07942 if (String_Parse(&holdBuf,&holdVal))
07943 {
07944 item->window.rectClient.y = atof(holdVal);
07945 if (String_Parse(&holdBuf,&holdVal))
07946 {
07947 item->window.rectClient.w = atof(holdVal);
07948 if (String_Parse(&holdBuf,&holdVal))
07949 {
07950 item->window.rectClient.h = atof(holdVal);
07951 return qtrue;
07952 }
07953 }
07954 }
07955 }
07956
07957
07958 return qtrue;
07959 }
07960
07961
07962 qboolean ItemParse_rect( itemDef_t *item, int handle ) {
07963 if (!PC_Rect_Parse(handle, &item->window.rectClient)) {
07964 return qfalse;
07965 }
07966 return qtrue;
07967 }
07968
07969
07970
07971
07972
07973
07974
07975 qboolean ItemParse_flag( itemDef_t *item, int handle)
07976 {
07977 int i;
07978 pc_token_t token;
07979
07980 if (!trap_PC_ReadToken(handle, &token))
07981 {
07982 return qfalse;
07983 }
07984
07985 i=0;
07986 while (styles[i])
07987 {
07988 if (Q_stricmp(token.string,itemFlags[i].string)==0)
07989 {
07990 item->window.flags |= itemFlags[i].value;
07991 break;
07992 }
07993 i++;
07994 }
07995
07996 if (itemFlags[i].string == NULL)
07997 {
07998 Com_Printf(va( S_COLOR_YELLOW "Unknown item style value '%s'",token.string));
07999 }
08000
08001 return qtrue;
08002 }
08003
08004
08005
08006
08007
08008
08009
08010 qboolean ItemParse_style( itemDef_t *item, int handle)
08011 {
08012 if (!PC_Int_Parse(handle, &item->window.style))
08013 {
08014 Com_Printf(S_COLOR_YELLOW "Unknown item style value");
08015 return qfalse;
08016 }
08017
08018 return qtrue;
08019 }
08020
08021
08022
08023 qboolean ItemParse_decoration( itemDef_t *item, int handle ) {
08024 item->window.flags |= WINDOW_DECORATION;
08025 return qtrue;
08026 }
08027
08028
08029 qboolean ItemParse_notselectable( itemDef_t *item, int handle ) {
08030 listBoxDef_t *listPtr;
08031 Item_ValidateTypeData(item);
08032 listPtr = (listBoxDef_t*)item->typeData;
08033 if (item->type == ITEM_TYPE_LISTBOX && listPtr) {
08034 listPtr->notselectable = qtrue;
08035 }
08036 return qtrue;
08037 }
08038
08039
08040
08041
08042
08043
08044
08045 qboolean ItemParse_scrollhidden( itemDef_t *item , int handle)
08046 {
08047 listBoxDef_t *listPtr;
08048 Item_ValidateTypeData(item);
08049 listPtr = (listBoxDef_t*)item->typeData;
08050
08051 if (item->type == ITEM_TYPE_LISTBOX && listPtr)
08052 {
08053 listPtr->scrollhidden = qtrue;
08054 }
08055 return qtrue;
08056 }
08057
08058
08059
08060
08061
08062
08063 qboolean ItemParse_wrapped( itemDef_t *item, int handle ) {
08064 item->window.flags |= WINDOW_WRAPPED;
08065 return qtrue;
08066 }
08067
08068
08069 qboolean ItemParse_autowrapped( itemDef_t *item, int handle ) {
08070 item->window.flags |= WINDOW_AUTOWRAPPED;
08071 return qtrue;
08072 }
08073
08074
08075
08076 qboolean ItemParse_horizontalscroll( itemDef_t *item, int handle ) {
08077 item->window.flags |= WINDOW_HORIZONTAL;
08078 return qtrue;
08079 }
08080
08081
08082
08083
08084
08085
08086
08087 qboolean ItemParse_type( itemDef_t *item, int handle )
08088 {
08089
08090
08091 if (!PC_Int_Parse(handle, &item->type))
08092 {
08093 return qfalse;
08094 }
08095 Item_ValidateTypeData(item);
08096 return qtrue;
08097 }
08098
08099
08100
08101 qboolean ItemParse_elementwidth( itemDef_t *item, int handle ) {
08102 listBoxDef_t *listPtr;
08103
08104 Item_ValidateTypeData(item);
08105 listPtr = (listBoxDef_t*)item->typeData;
08106 if (!PC_Float_Parse(handle, &listPtr->elementWidth)) {
08107 return qfalse;
08108 }
08109 return qtrue;
08110 }
08111
08112
08113
08114 qboolean ItemParse_elementheight( itemDef_t *item, int handle ) {
08115 listBoxDef_t *listPtr;
08116
08117 Item_ValidateTypeData(item);
08118 listPtr = (listBoxDef_t*)item->typeData;
08119 if (!PC_Float_Parse(handle, &listPtr->elementHeight)) {
08120 return qfalse;
08121 }
08122 return qtrue;
08123 }
08124
08125
08126 qboolean ItemParse_feeder( itemDef_t *item, int handle ) {
08127 if (!PC_Float_Parse(handle, &item->special)) {
08128 return qfalse;
08129 }
08130 return qtrue;
08131 }
08132
08133
08134
08135 qboolean ItemParse_elementtype( itemDef_t *item, int handle ) {
08136 listBoxDef_t *listPtr;
08137
08138 Item_ValidateTypeData(item);
08139 if (!item->typeData)
08140 return qfalse;
08141 listPtr = (listBoxDef_t*)item->typeData;
08142 if (!PC_Int_Parse(handle, &listPtr->elementStyle)) {
08143 return qfalse;
08144 }
08145 return qtrue;
08146 }
08147
08148
08149 qboolean ItemParse_columns( itemDef_t *item, int handle ) {
08150 int num, i;
08151 listBoxDef_t *listPtr;
08152
08153 Item_ValidateTypeData(item);
08154 if (!item->typeData)
08155 return qfalse;
08156 listPtr = (listBoxDef_t*)item->typeData;
08157 if (PC_Int_Parse(handle, &num)) {
08158 if (num > MAX_LB_COLUMNS) {
08159 num = MAX_LB_COLUMNS;
08160 }
08161 listPtr->numColumns = num;
08162 for (i = 0; i < num; i++) {
08163 int pos, width, maxChars;
08164
08165 if (PC_Int_Parse(handle, &pos) && PC_Int_Parse(handle, &width) && PC_Int_Parse(handle, &maxChars)) {
08166 listPtr->columnInfo[i].pos = pos;
08167 listPtr->columnInfo[i].width = width;
08168 listPtr->columnInfo[i].maxChars = maxChars;
08169 } else {
08170 return qfalse;
08171 }
08172 }
08173 } else {
08174 return qfalse;
08175 }
08176 return qtrue;
08177 }
08178
08179 qboolean ItemParse_border( itemDef_t *item, int handle ) {
08180 if (!PC_Int_Parse(handle, &item->window.border)) {
08181 return qfalse;
08182 }
08183 return qtrue;
08184 }
08185
08186 qboolean ItemParse_bordersize( itemDef_t *item, int handle ) {
08187 if (!PC_Float_Parse(handle, &item->window.borderSize)) {
08188 return qfalse;
08189 }
08190 return qtrue;
08191 }
08192
08193 qboolean ItemParse_visible( itemDef_t *item, int handle ) {
08194 int i;
08195
08196 if (!PC_Int_Parse(handle, &i)) {
08197 return qfalse;
08198 }
08199 if (i) {
08200 item->window.flags |= WINDOW_VISIBLE;
08201 }
08202 return qtrue;
08203 }
08204
08205 qboolean ItemParse_ownerdraw( itemDef_t *item, int handle ) {
08206 if (!PC_Int_Parse(handle, &item->window.ownerDraw)) {
08207 return qfalse;
08208 }
08209 item->type = ITEM_TYPE_OWNERDRAW;
08210 return qtrue;
08211 }
08212
08213 qboolean ItemParse_align( itemDef_t *item, int handle ) {
08214 if (!PC_Int_Parse(handle, &item->alignment)) {
08215 return qfalse;
08216 }
08217 return qtrue;
08218 }
08219
08220
08221
08222
08223
08224
08225
08226
08227 qboolean ItemParse_isCharacter( itemDef_t *item, int handle )
08228 {
08229 int flag;
08230
08231 if (PC_Int_Parse(handle, &flag))
08232 {
08233 if ( flag )
08234 {
08235 item->flags |= ITF_ISCHARACTER;
08236 }
08237 else
08238 {
08239 item->flags &= ~ITF_ISCHARACTER;
08240 }
08241 return qtrue;
08242 }
08243 return qfalse;
08244 }
08245
08246
08247
08248
08249
08250
08251
08252 qboolean ItemParse_textalign( itemDef_t *item, int handle )
08253 {
08254 if (!PC_Int_Parse(handle, &item->textalignment))
08255 {
08256 Com_Printf(S_COLOR_YELLOW "Unknown text alignment value");
08257
08258 return qfalse;
08259 }
08260
08261 return qtrue;
08262 }
08263
08264 qboolean ItemParse_textalignx( itemDef_t *item, int handle ) {
08265 if (!PC_Float_Parse(handle, &item->textalignx)) {
08266 return qfalse;
08267 }
08268 return qtrue;
08269 }
08270
08271 qboolean ItemParse_textaligny( itemDef_t *item, int handle ) {
08272 if (!PC_Float_Parse(handle, &item->textaligny)) {
08273 return qfalse;
08274 }
08275 return qtrue;
08276 }
08277
08278 qboolean ItemParse_textscale( itemDef_t *item, int handle ) {
08279 if (!PC_Float_Parse(handle, &item->textscale)) {
08280 return qfalse;
08281 }
08282 return qtrue;
08283 }
08284
08285 qboolean ItemParse_textstyle( itemDef_t *item, int handle ) {
08286 if (!PC_Int_Parse(handle, &item->textStyle)) {
08287 return qfalse;
08288 }
08289 return qtrue;
08290 }
08291
08292
08293
08294
08295
08296
08297
08298 qboolean ItemParse_invertyesno( itemDef_t *item, int handle)
08299 {
08300 if (!PC_Int_Parse(handle, &item->invertYesNo))
08301 {
08302 return qfalse;
08303 }
08304 return qtrue;
08305 }
08306
08307
08308
08309
08310
08311
08312 qboolean ItemParse_xoffset( itemDef_t *item, int handle)
08313 {
08314 if (PC_Int_Parse(handle, &item->xoffset))
08315 {
08316 return qfalse;
08317 }
08318 return qtrue;
08319 }
08320
08321
08322 qboolean ItemParse_backcolor( itemDef_t *item, int handle ) {
08323 int i;
08324 float f;
08325
08326 for (i = 0; i < 4; i++) {
08327 if (!PC_Float_Parse(handle, &f)) {
08328 return qfalse;
08329 }
08330 item->window.backColor[i] = f;
08331 }
08332 return qtrue;
08333 }
08334
08335 qboolean ItemParse_forecolor( itemDef_t *item, int handle ) {
08336 int i;
08337 float f;
08338
08339 for (i = 0; i < 4; i++) {
08340 if (!PC_Float_Parse(handle, &f)) {
08341 return qfalse;
08342 }
08343
08344 if (f < 0)
08345 {
08346 item->window.flags |= WINDOW_PLAYERCOLOR;
08347 return qtrue;
08348 }
08349
08350 item->window.foreColor[i] = f;
08351 item->window.flags |= WINDOW_FORECOLORSET;
08352 }
08353 return qtrue;
08354 }
08355
08356 qboolean ItemParse_bordercolor( itemDef_t *item, int handle ) {
08357 int i;
08358 float f;
08359
08360 for (i = 0; i < 4; i++) {
08361 if (!PC_Float_Parse(handle, &f)) {
08362 return qfalse;
08363 }
08364 item->window.borderColor[i] = f;
08365 }
08366 return qtrue;
08367 }
08368
08369 qboolean ItemParse_outlinecolor( itemDef_t *item, int handle ) {
08370 if (!PC_Color_Parse(handle, &item->window.outlineColor)){
08371 return qfalse;
08372 }
08373 return qtrue;
08374 }
08375
08376 qboolean ItemParse_background( itemDef_t *item, int handle ) {
08377 pc_token_t token;
08378
08379 if (!trap_PC_ReadToken(handle, &token)) {
08380 return qfalse;
08381 }
08382 item->window.background = DC->registerShaderNoMip(token.string);
08383 return qtrue;
08384 }
08385
08386 qboolean ItemParse_cinematic( itemDef_t *item, int handle ) {
08387 if (!PC_String_Parse(handle, &item->window.cinematicName)) {
08388 return qfalse;
08389 }
08390 return qtrue;
08391 }
08392
08393 qboolean ItemParse_doubleClick( itemDef_t *item, int handle ) {
08394 listBoxDef_t *listPtr;
08395
08396 Item_ValidateTypeData(item);
08397 if (!item->typeData) {
08398 return qfalse;
08399 }
08400
08401 listPtr = (listBoxDef_t*)item->typeData;
08402
08403 if (!PC_Script_Parse(handle, &listPtr->doubleClick)) {
08404 return qfalse;
08405 }
08406 return qtrue;
08407 }
08408
08409 qboolean ItemParse_onFocus( itemDef_t *item, int handle ) {
08410 if (!PC_Script_Parse(handle, &item->onFocus)) {
08411 return qfalse;
08412 }
08413 return qtrue;
08414 }
08415
08416 qboolean ItemParse_leaveFocus( itemDef_t *item, int handle ) {
08417 if (!PC_Script_Parse(handle, &item->leaveFocus)) {
08418 return qfalse;
08419 }
08420 return qtrue;
08421 }
08422
08423 qboolean ItemParse_mouseEnter( itemDef_t *item, int handle ) {
08424 if (!PC_Script_Parse(handle, &item->mouseEnter)) {
08425 return qfalse;
08426 }
08427 return qtrue;
08428 }
08429
08430 qboolean ItemParse_mouseExit( itemDef_t *item, int handle ) {
08431 if (!PC_Script_Parse(handle, &item->mouseExit)) {
08432 return qfalse;
08433 }
08434 return qtrue;
08435 }
08436
08437 qboolean ItemParse_mouseEnterText( itemDef_t *item, int handle ) {
08438 if (!PC_Script_Parse(handle, &item->mouseEnterText)) {
08439 return qfalse;
08440 }
08441 return qtrue;
08442 }
08443
08444 qboolean ItemParse_mouseExitText( itemDef_t *item, int handle ) {
08445 if (!PC_Script_Parse(handle, &item->mouseExitText)) {
08446 return qfalse;
08447 }
08448 return qtrue;
08449 }
08450
08451 qboolean ItemParse_action( itemDef_t *item, int handle ) {
08452 if (!PC_Script_Parse(handle, &item->action)) {
08453 return qfalse;
08454 }
08455 return qtrue;
08456 }
08457
08458 qboolean ItemParse_special( itemDef_t *item, int handle ) {
08459 if (!PC_Float_Parse(handle, &item->special)) {
08460 return qfalse;
08461 }
08462 return qtrue;
08463 }
08464
08465 qboolean ItemParse_cvarTest( itemDef_t *item, int handle ) {
08466 if (!PC_String_Parse(handle, &item->cvarTest)) {
08467 return qfalse;
08468 }
08469 return qtrue;
08470 }
08471
08472 qboolean ItemParse_cvar( itemDef_t *item, int handle )
08473 {
08474 Item_ValidateTypeData(item);
08475 if (!PC_String_Parse(handle, &item->cvar))
08476 {
08477 return qfalse;
08478 }
08479
08480 if ( item->typeData)
08481 {
08482 editFieldDef_t *editPtr;
08483
08484 switch ( item->type )
08485 {
08486 case ITEM_TYPE_EDITFIELD:
08487 case ITEM_TYPE_NUMERICFIELD:
08488 case ITEM_TYPE_YESNO:
08489 case ITEM_TYPE_BIND:
08490 case ITEM_TYPE_SLIDER:
08491 case ITEM_TYPE_TEXT:
08492 editPtr = (editFieldDef_t*)item->typeData;
08493 editPtr->minVal = -1;
08494 editPtr->maxVal = -1;
08495 editPtr->defVal = -1;
08496 break;
08497 }
08498 }
08499 return qtrue;
08500 }
08501
08502 qboolean ItemParse_font( itemDef_t *item, int handle )
08503 {
08504 Item_ValidateTypeData(item);
08505 if (!PC_Int_Parse(handle, &item->iMenuFont))
08506 {
08507 return qfalse;
08508 }
08509 return qtrue;
08510 }
08511
08512
08513 qboolean ItemParse_maxChars( itemDef_t *item, int handle ) {
08514 editFieldDef_t *editPtr;
08515 int maxChars;
08516
08517 Item_ValidateTypeData(item);
08518 if (!item->typeData)
08519 return qfalse;
08520
08521 if (!PC_Int_Parse(handle, &maxChars)) {
08522 return qfalse;
08523 }
08524 editPtr = (editFieldDef_t*)item->typeData;
08525 editPtr->maxChars = maxChars;
08526 return qtrue;
08527 }
08528
08529 qboolean ItemParse_maxPaintChars( itemDef_t *item, int handle ) {
08530 editFieldDef_t *editPtr;
08531 int maxChars;
08532
08533 Item_ValidateTypeData(item);
08534 if (!item->typeData)
08535 return qfalse;
08536
08537 if (!PC_Int_Parse(handle, &maxChars)) {
08538 return qfalse;
08539 }
08540 editPtr = (editFieldDef_t*)item->typeData;
08541 editPtr->maxPaintChars = maxChars;
08542 return qtrue;
08543 }
08544
08545 qboolean ItemParse_maxLineChars( itemDef_t *item, int handle )
08546 {
08547 textScrollDef_t *scrollPtr;
08548 int maxChars;
08549
08550 Item_ValidateTypeData(item);
08551 if (!item->typeData)
08552 return qfalse;
08553
08554 if (!PC_Int_Parse(handle, &maxChars))
08555 {
08556 return qfalse;
08557 }
08558
08559 scrollPtr = (textScrollDef_t*)item->typeData;
08560 scrollPtr->maxLineChars = maxChars;
08561
08562 return qtrue;
08563 }
08564
08565 qboolean ItemParse_lineHeight( itemDef_t *item, int handle )
08566 {
08567 textScrollDef_t *scrollPtr;
08568 int height;
08569
08570 Item_ValidateTypeData(item);
08571 if (!item->typeData)
08572 return qfalse;
08573
08574 if (!PC_Int_Parse(handle, &height))
08575 {
08576 return qfalse;
08577 }
08578
08579 scrollPtr = (textScrollDef_t*)item->typeData;
08580 scrollPtr->lineHeight = height;
08581
08582 return qtrue;
08583 }
08584
08585 qboolean ItemParse_cvarFloat( itemDef_t *item, int handle ) {
08586 editFieldDef_t *editPtr;
08587
08588 Item_ValidateTypeData(item);
08589 if (!item->typeData)
08590 return qfalse;
08591 editPtr = (editFieldDef_t*)item->typeData;
08592 if (PC_String_Parse(handle, &item->cvar) &&
08593 PC_Float_Parse(handle, &editPtr->defVal) &&
08594 PC_Float_Parse(handle, &editPtr->minVal) &&
08595 PC_Float_Parse(handle, &editPtr->maxVal)) {
08596 return qtrue;
08597 }
08598 return qfalse;
08599 }
08600
08601 char currLanguage[32][128];
08602 static const char languageString[32] = "@MENUS_MYLANGUAGE";
08603
08604 qboolean ItemParse_cvarStrList( itemDef_t *item, int handle ) {
08605 pc_token_t token;
08606 multiDef_t *multiPtr;
08607 int pass;
08608
08609 Item_ValidateTypeData(item);
08610 if (!item->typeData)
08611 return qfalse;
08612 multiPtr = (multiDef_t*)item->typeData;
08613 multiPtr->count = 0;
08614 multiPtr->strDef = qtrue;
08615
08616 if (!trap_PC_ReadToken(handle, &token))
08617 {
08618 return qfalse;
08619 }
08620
08621 if (!Q_stricmp(token.string,"feeder") && item->special == FEEDER_PLAYER_SPECIES)
08622 {
08623 #ifndef CGAME
08624 for (; multiPtr->count < uiInfo.playerSpeciesCount; multiPtr->count++)
08625 {
08626 multiPtr->cvarList[multiPtr->count] = String_Alloc(strupr(va("@MENUS_%s",uiInfo.playerSpecies[multiPtr->count].Name )));
08627 multiPtr->cvarStr[multiPtr->count] = uiInfo.playerSpecies[multiPtr->count].Name;
08628 }
08629 #endif
08630 return qtrue;
08631 }
08632
08633 if (!Q_stricmp(token.string,"feeder") && item->special == FEEDER_LANGUAGES)
08634 {
08635 #ifndef CGAME
08636 for (; multiPtr->count < uiInfo.languageCount; multiPtr->count++)
08637 {
08638
08639 trap_GetLanguageName( (const int) multiPtr->count,(char *) currLanguage[multiPtr->count] );
08640 multiPtr->cvarList[multiPtr->count] = languageString;
08641
08642 trap_GetLanguageName( (const int) multiPtr->count,(char *) currLanguage[multiPtr->count] );
08643 multiPtr->cvarStr[multiPtr->count] = currLanguage[multiPtr->count];
08644 }
08645 #endif
08646 return qtrue;
08647 }
08648
08649 if (*token.string != '{') {
08650 return qfalse;
08651 }
08652
08653 pass = 0;
08654 while ( 1 ) {
08655 char* psString;
08656
08657
08658
08659
08660
08661
08662 if (!PC_String_Parse(handle, (const char **)&psString))
08663 {
08664 PC_SourceError(handle, "end of file inside menu item\n");
08665 return qfalse;
08666 }
08667
08668
08669 if ((int)psString > 0)
08670 {
08671 if (*psString == '}') {
08672 return qtrue;
08673 }
08674
08675 if (*psString == ',' || *psString == ';') {
08676 continue;
08677 }
08678 }
08679
08680 if (pass == 0) {
08681 multiPtr->cvarList[multiPtr->count] = psString;
08682 pass = 1;
08683 } else {
08684 multiPtr->cvarStr[multiPtr->count] = psString;
08685 pass = 0;
08686 multiPtr->count++;
08687 if (multiPtr->count >= MAX_MULTI_CVARS) {
08688 return qfalse;
08689 }
08690 }
08691
08692 }
08693 return qfalse;
08694 }
08695
08696 qboolean ItemParse_cvarFloatList( itemDef_t *item, int handle )
08697 {
08698 pc_token_t token;
08699 multiDef_t *multiPtr;
08700
08701 Item_ValidateTypeData(item);
08702 if (!item->typeData)
08703 {
08704 return qfalse;
08705 }
08706
08707 multiPtr = (multiDef_t*)item->typeData;
08708 multiPtr->count = 0;
08709 multiPtr->strDef = qfalse;
08710
08711 if (!trap_PC_ReadToken(handle, &token))
08712 {
08713 return qfalse;
08714 }
08715
08716 if (*token.string != '{')
08717 {
08718 return qfalse;
08719 }
08720
08721 while ( 1 )
08722 {
08723 char* string;
08724
08725 if ( !PC_String_Parse ( handle, (const char **)&string ) )
08726 {
08727 PC_SourceError(handle, "end of file inside menu item\n");
08728 return qfalse;
08729 }
08730
08731
08732 if ((int)string > 0)
08733 {
08734 if (*string == '}')
08735 {
08736 return qtrue;
08737 }
08738
08739 if (*string == ',' || *string == ';')
08740 {
08741 continue;
08742 }
08743 }
08744
08745 multiPtr->cvarList[multiPtr->count] = string;
08746 if (!PC_Float_Parse(handle, &multiPtr->cvarValue[multiPtr->count]))
08747 {
08748 return qfalse;
08749 }
08750
08751 multiPtr->count++;
08752 if (multiPtr->count >= MAX_MULTI_CVARS)
08753 {
08754 return qfalse;
08755 }
08756
08757 }
08758 return qfalse;
08759 }
08760
08761
08762
08763 qboolean ItemParse_addColorRange( itemDef_t *item, int handle ) {
08764 colorRangeDef_t color;
08765
08766 if (PC_Float_Parse(handle, &color.low) &&
08767 PC_Float_Parse(handle, &color.high) &&
08768 PC_Color_Parse(handle, &color.color) ) {
08769 if (item->numColors < MAX_COLOR_RANGES) {
08770 memcpy(&item->colorRanges[item->numColors], &color, sizeof(color));
08771 item->numColors++;
08772 }
08773 return qtrue;
08774 }
08775 return qfalse;
08776 }
08777
08778 qboolean ItemParse_ownerdrawFlag( itemDef_t *item, int handle ) {
08779 int i;
08780 if (!PC_Int_Parse(handle, &i)) {
08781 return qfalse;
08782 }
08783 item->window.ownerDrawFlags |= i;
08784 return qtrue;
08785 }
08786
08787 qboolean ItemParse_enableCvar( itemDef_t *item, int handle ) {
08788 if (PC_Script_Parse(handle, &item->enableCvar)) {
08789 item->cvarFlags = CVAR_ENABLE;
08790 return qtrue;
08791 }
08792 return qfalse;
08793 }
08794
08795 qboolean ItemParse_disableCvar( itemDef_t *item, int handle ) {
08796 if (PC_Script_Parse(handle, &item->enableCvar)) {
08797 item->cvarFlags = CVAR_DISABLE;
08798 return qtrue;
08799 }
08800 return qfalse;
08801 }
08802
08803 qboolean ItemParse_showCvar( itemDef_t *item, int handle ) {
08804 if (PC_Script_Parse(handle, &item->enableCvar)) {
08805 item->cvarFlags = CVAR_SHOW;
08806 return qtrue;
08807 }
08808 return qfalse;
08809 }
08810
08811 qboolean ItemParse_hideCvar( itemDef_t *item, int handle ) {
08812 if (PC_Script_Parse(handle, &item->enableCvar)) {
08813 item->cvarFlags = CVAR_HIDE;
08814 return qtrue;
08815 }
08816 return qfalse;
08817 }
08818
08819
08820
08821
08822
08823
08824 qboolean ItemParse_Appearance_slot( itemDef_t *item, int handle )
08825 {
08826 if (!PC_Int_Parse(handle, &item->appearanceSlot))
08827 {
08828 return qfalse;
08829 }
08830 return qtrue;
08831 }
08832
08833 qboolean ItemParse_isSaber( itemDef_t *item, int handle )
08834 {
08835 #ifndef CGAME
08836
08837 int i;
08838
08839 if (PC_Int_Parse(handle, &i))
08840 {
08841 if ( i )
08842 {
08843 item->flags |= ITF_ISSABER;
08844 UI_CacheSaberGlowGraphics();
08845 if ( !ui_saber_parms_parsed )
08846 {
08847 UI_SaberLoadParms();
08848 }
08849 }
08850 else
08851 {
08852 item->flags &= ~ITF_ISSABER;
08853 }
08854
08855 return qtrue;
08856 }
08857 #endif
08858 return qfalse;
08859 }
08860
08861
08862
08863
08864
08865 qboolean ItemParse_isSaber2( itemDef_t *item, int handle )
08866 {
08867 #ifndef CGAME
08868 int i;
08869 if (PC_Int_Parse(handle, &i))
08870 {
08871 if ( i )
08872 {
08873 item->flags |= ITF_ISSABER2;
08874 UI_CacheSaberGlowGraphics();
08875 if ( !ui_saber_parms_parsed )
08876 {
08877 UI_SaberLoadParms();
08878 }
08879 }
08880 else
08881 {
08882 item->flags &= ~ITF_ISSABER2;
08883 }
08884
08885 return qtrue;
08886 }
08887 #endif
08888
08889 return qfalse;
08890 }
08891
08892 keywordHash_t itemParseKeywords[] = {
08893 {"action", ItemParse_action, NULL },
08894 {"addColorRange", ItemParse_addColorRange, NULL },
08895 {"align", ItemParse_align, NULL },
08896 {"autowrapped", ItemParse_autowrapped, NULL },
08897 {"appearance_slot", ItemParse_Appearance_slot, NULL },
08898 {"asset_model", ItemParse_asset_model, NULL },
08899 {"asset_shader", ItemParse_asset_shader, NULL },
08900 {"backcolor", ItemParse_backcolor, NULL },
08901 {"background", ItemParse_background, NULL },
08902 {"border", ItemParse_border, NULL },
08903 {"bordercolor", ItemParse_bordercolor, NULL },
08904 {"bordersize", ItemParse_bordersize, NULL },
08905 {"cinematic", ItemParse_cinematic, NULL },
08906 {"columns", ItemParse_columns, NULL },
08907 {"cvar", ItemParse_cvar, NULL },
08908 {"cvarFloat", ItemParse_cvarFloat, NULL },
08909 {"cvarFloatList", ItemParse_cvarFloatList, NULL },
08910 {"cvarStrList", ItemParse_cvarStrList, NULL },
08911 {"cvarTest", ItemParse_cvarTest, NULL },
08912 {"desctext", ItemParse_descText, NULL },
08913 {"decoration", ItemParse_decoration, NULL },
08914 {"disableCvar", ItemParse_disableCvar, NULL },
08915 {"doubleclick", ItemParse_doubleClick, NULL },
08916 {"elementheight", ItemParse_elementheight, NULL },
08917 {"elementtype", ItemParse_elementtype, NULL },
08918 {"elementwidth", ItemParse_elementwidth, NULL },
08919 {"enableCvar", ItemParse_enableCvar, NULL },
08920 {"feeder", ItemParse_feeder, NULL },
08921 {"flag", ItemParse_flag, NULL },
08922 {"focusSound", ItemParse_focusSound, NULL },
08923 {"font", ItemParse_font, NULL },
08924 {"forecolor", ItemParse_forecolor, NULL },
08925 {"group", ItemParse_group, NULL },
08926 {"hideCvar", ItemParse_hideCvar, NULL },
08927 {"horizontalscroll", ItemParse_horizontalscroll, NULL },
08928 {"isCharacter", ItemParse_isCharacter, NULL },
08929 {"isSaber", ItemParse_isSaber, NULL },
08930 {"isSaber2", ItemParse_isSaber2, NULL },
08931 {"leaveFocus", ItemParse_leaveFocus, NULL },
08932 {"maxChars", ItemParse_maxChars, NULL },
08933 {"maxPaintChars", ItemParse_maxPaintChars, NULL },
08934 {"model_angle", ItemParse_model_angle, NULL },
08935 {"model_fovx", ItemParse_model_fovx, NULL },
08936 {"model_fovy", ItemParse_model_fovy, NULL },
08937 {"model_origin", ItemParse_model_origin, NULL },
08938 {"model_rotation", ItemParse_model_rotation, NULL },
08939
08940 {"model_g2mins", ItemParse_model_g2mins, NULL },
08941 {"model_g2maxs", ItemParse_model_g2maxs, NULL },
08942 {"model_g2scale", ItemParse_model_g2scale, NULL },
08943 {"model_g2skin", ItemParse_model_g2skin, NULL },
08944 {"model_g2anim", ItemParse_model_g2anim, NULL },
08945
08946 {"mouseEnter", ItemParse_mouseEnter, NULL },
08947 {"mouseEnterText", ItemParse_mouseEnterText, NULL },
08948 {"mouseExit", ItemParse_mouseExit, NULL },
08949 {"mouseExitText", ItemParse_mouseExitText, NULL },
08950 {"name", ItemParse_name, NULL },
08951 {"notselectable", ItemParse_notselectable, NULL },
08952 {"onFocus", ItemParse_onFocus, NULL },
08953 {"outlinecolor", ItemParse_outlinecolor, NULL },
08954 {"ownerdraw", ItemParse_ownerdraw, NULL },
08955 {"ownerdrawFlag", ItemParse_ownerdrawFlag, NULL },
08956 {"rect", ItemParse_rect, NULL },
08957 {"rectcvar", ItemParse_rectcvar, NULL },
08958 {"showCvar", ItemParse_showCvar, NULL },
08959 {"special", ItemParse_special, NULL },
08960 {"style", ItemParse_style, NULL },
08961 {"text", ItemParse_text, NULL },
08962 {"textalign", ItemParse_textalign, NULL },
08963 {"textalignx", ItemParse_textalignx, NULL },
08964 {"textaligny", ItemParse_textaligny, NULL },
08965 {"textscale", ItemParse_textscale, NULL },
08966 {"textstyle", ItemParse_textstyle, NULL },
08967 {"text2", ItemParse_text2, NULL },
08968 {"text2alignx", ItemParse_text2alignx, NULL },
08969 {"text2aligny", ItemParse_text2aligny, NULL },
08970 {"type", ItemParse_type, NULL },
08971 {"visible", ItemParse_visible, NULL },
08972 {"wrapped", ItemParse_wrapped, NULL },
08973
08974
08975 {"maxLineChars", ItemParse_maxLineChars, NULL },
08976 {"lineHeight", ItemParse_lineHeight, NULL },
08977 {"invertyesno", ItemParse_invertyesno, NULL },
08978
08979 {"scrollhidden", ItemParse_scrollhidden, NULL },
08980 {"xoffset ", ItemParse_xoffset, NULL },
08981
08982
08983
08984
08985 {0, 0, 0 }
08986 };
08987
08988 keywordHash_t *itemParseKeywordHash[KEYWORDHASH_SIZE];
08989
08990
08991
08992
08993
08994
08995 void Item_SetupKeywordHash(void) {
08996 int i;
08997
08998 memset(itemParseKeywordHash, 0, sizeof(itemParseKeywordHash));
08999 for (i = 0; itemParseKeywords[i].keyword; i++) {
09000 KeywordHash_Add(itemParseKeywordHash, &itemParseKeywords[i]);
09001 }
09002 }
09003
09004
09005
09006
09007
09008
09009 qboolean Item_Parse(int handle, itemDef_t *item) {
09010 pc_token_t token;
09011 keywordHash_t *key;
09012
09013
09014 if (!trap_PC_ReadToken(handle, &token))
09015 return qfalse;
09016 if (*token.string != '{') {
09017 return qfalse;
09018 }
09019 while ( 1 ) {
09020 if (!trap_PC_ReadToken(handle, &token)) {
09021 PC_SourceError(handle, "end of file inside menu item\n");
09022 return qfalse;
09023 }
09024
09025 if (*token.string == '}') {
09026 return qtrue;
09027 }
09028
09029 key = KeywordHash_Find(itemParseKeywordHash, token.string);
09030 if (!key) {
09031 PC_SourceError(handle, "unknown menu item keyword %s", token.string);
09032 continue;
09033 }
09034 if ( !key->func(item, handle) ) {
09035 PC_SourceError(handle, "couldn't parse menu item keyword %s", token.string);
09036 return qfalse;
09037 }
09038 }
09039 return qfalse;
09040 }
09041
09042 static void Item_TextScroll_BuildLines ( itemDef_t* item )
09043 {
09044 char text[2048];
09045
09046 #if 1
09047
09048
09049
09050 textScrollDef_t* scrollPtr = (textScrollDef_t*) item->typeData;
09051 const char *psText = item->text;
09052 int iBoxWidth = item->window.rect.w - SCROLLBAR_SIZE - 10;
09053
09054
09055
09056
09057 const char *psCurrentTextReadPos;
09058 const char *psReadPosAtLineStart;
09059 const char *psBestLineBreakSrcPos;
09060 const char *psLastGood_s;
09061 qboolean bIsTrailingPunctuation;
09062 unsigned int uiLetter;
09063
09064 if (*psText == '@')
09065 {
09066 trap_SP_GetStringTextString( &psText[1], text, sizeof(text));
09067 psText = text;
09068 }
09069
09070 psCurrentTextReadPos = psText;
09071 psReadPosAtLineStart = psCurrentTextReadPos;
09072 psBestLineBreakSrcPos = psCurrentTextReadPos;
09073
09074 scrollPtr->iLineCount = 0;
09075 memset((char*)scrollPtr->pLines,0,sizeof(scrollPtr->pLines));
09076
09077 while (*psCurrentTextReadPos && (scrollPtr->iLineCount < MAX_TEXTSCROLL_LINES) )
09078 {
09079 char sLineForDisplay[2048];
09080
09081
09082
09083 psCurrentTextReadPos = psReadPosAtLineStart;
09084 sLineForDisplay[0] = '\0';
09085 while ( *psCurrentTextReadPos )
09086 {
09087 int iAdvanceCount;
09088 psLastGood_s = psCurrentTextReadPos;
09089
09090
09091
09092 uiLetter = trap_AnyLanguage_ReadCharFromString(psCurrentTextReadPos, &iAdvanceCount, &bIsTrailingPunctuation);
09093 psCurrentTextReadPos += iAdvanceCount;
09094
09095
09096
09097 if (uiLetter == 32 && sLineForDisplay[0] == '\0')
09098 {
09099 psReadPosAtLineStart++;
09100 continue;
09101 }
09102
09103 if (uiLetter > 255)
09104 {
09105 Q_strcat(sLineForDisplay, sizeof(sLineForDisplay),va("%c%c",uiLetter >> 8, uiLetter & 0xFF));
09106 }
09107 else
09108 {
09109 Q_strcat(sLineForDisplay, sizeof(sLineForDisplay),va("%c",uiLetter & 0xFF));
09110 }
09111
09112 if (uiLetter == '\n')
09113 {
09114
09115
09116 sLineForDisplay[ strlen(sLineForDisplay)-1 ] = '\0';
09117 psReadPosAtLineStart = psCurrentTextReadPos;
09118 psBestLineBreakSrcPos = psCurrentTextReadPos;
09119
09120
09121
09122 scrollPtr->pLines[ scrollPtr->iLineCount ] = String_Alloc ( sLineForDisplay );
09123 break;
09124 }
09125 else
09126 if ( DC->textWidth( sLineForDisplay, item->textscale, item->iMenuFont ) >= iBoxWidth )
09127 {
09128
09129
09130 if (uiLetter > 255 && bIsTrailingPunctuation && !trap_Language_UsesSpaces())
09131 {
09132
09133
09134
09135 uiLetter = uiLetter;
09136 }
09137 else
09138 {
09139 if (psBestLineBreakSrcPos == psReadPosAtLineStart)
09140 {
09141
09142
09143
09144
09145
09146
09147
09148 psBestLineBreakSrcPos = psLastGood_s;
09149 }
09150
09151 sLineForDisplay[ psBestLineBreakSrcPos - psReadPosAtLineStart ] = '\0';
09152 psReadPosAtLineStart = psCurrentTextReadPos = psBestLineBreakSrcPos;
09153
09154
09155
09156 scrollPtr->pLines[ scrollPtr->iLineCount ] = String_Alloc( sLineForDisplay );
09157 break;
09158 }
09159 }
09160
09161
09162
09163 if (bIsTrailingPunctuation || uiLetter == ' ' || (uiLetter > 255 && !trap_Language_UsesSpaces()))
09164 {
09165 psBestLineBreakSrcPos = psCurrentTextReadPos;
09166 }
09167 }
09168
09170
09171 if (scrollPtr->pLines[ scrollPtr->iLineCount ] == NULL && strlen(sLineForDisplay))
09172 {
09173
09174
09175 scrollPtr->pLines[ scrollPtr->iLineCount ] = String_Alloc( sLineForDisplay );
09176 }
09177
09178 scrollPtr->iLineCount++;
09179 }
09180
09181 #else
09182
09183
09184 int width;
09185 char* lineStart;
09186 char* lineEnd;
09187 float w;
09188 float cw;
09189
09190 textScrollDef_t* scrollPtr = (textScrollDef_t*) item->typeData;
09191
09192 scrollPtr->iLineCount = 0;
09193 width = scrollPtr->maxLineChars;
09194 lineStart = (char*)item->text;
09195 lineEnd = lineStart;
09196 w = 0;
09197
09198
09199 while ( scrollPtr->iLineCount < MAX_TEXTSCROLL_LINES )
09200 {
09201
09202 if ( *lineEnd == '\0')
09203 {
09204 if ( lineStart < lineEnd )
09205 {
09206 scrollPtr->pLines[ scrollPtr->iLineCount++ ] = lineStart;
09207 }
09208
09209 break;
09210 }
09211
09212
09213 else if ( *lineEnd == '\n' )
09214 {
09215 *lineEnd = '\0';
09216 scrollPtr->pLines[ scrollPtr->iLineCount++ ] = lineStart;
09217 lineStart = lineEnd + 1;
09218 lineEnd = lineStart;
09219 w = 0;
09220 continue;
09221 }
09222
09223
09224 cw = DC->textWidth ( va("%c", *lineEnd), item->textscale, item->iMenuFont );
09225
09226
09227 if ( w + cw > (item->window.rect.w - SCROLLBAR_SIZE - 10) )
09228 {
09229
09230 while ( *lineEnd != ' ' && *lineEnd != '\t' && lineEnd > lineStart )
09231 {
09232 lineEnd--;
09233 }
09234
09235 *lineEnd = '\0';
09236 scrollPtr->pLines[ scrollPtr->iLineCount++ ] = lineStart;
09237
09238
09239 lineEnd++;
09240 while ( (*lineEnd == ' ' || *lineEnd == '\t') && *lineEnd )
09241 {
09242 lineEnd++;
09243 }
09244
09245 lineStart = lineEnd;
09246 w = 0;
09247 }
09248 else
09249 {
09250 w += cw;
09251 lineEnd++;
09252 }
09253 }
09254 #endif
09255 }
09256
09257
09258
09259 void Item_InitControls(itemDef_t *item)
09260 {
09261 if (item == NULL)
09262 {
09263 return;
09264 }
09265
09266 switch ( item->type )
09267 {
09268 case ITEM_TYPE_LISTBOX:
09269 {
09270 listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
09271 item->cursorPos = 0;
09272 if (listPtr)
09273 {
09274 listPtr->cursorPos = 0;
09275 listPtr->startPos = 0;
09276 listPtr->endPos = 0;
09277 listPtr->cursorPos = 0;
09278 }
09279
09280 break;
09281 }
09282 }
09283 }
09284
09285
09286
09287
09288
09289
09290
09291 qboolean MenuParse_font( itemDef_t *item, int handle ) {
09292 menuDef_t *menu = (menuDef_t*)item;
09293 if (!PC_String_Parse(handle, &menu->font)) {
09294 return qfalse;
09295 }
09296 if (!DC->Assets.fontRegistered) {
09297
09298 DC->Assets.qhMediumFont = DC->RegisterFont(menu->font);
09299 DC->Assets.fontRegistered = qtrue;
09300 }
09301 return qtrue;
09302 }
09303
09304 qboolean MenuParse_name( itemDef_t *item, int handle ) {
09305 menuDef_t *menu = (menuDef_t*)item;
09306 if (!PC_String_Parse(handle, &menu->window.name)) {
09307 return qfalse;
09308 }
09309 if (Q_stricmp(menu->window.name, "main") == 0) {
09310
09311
09312 }
09313 return qtrue;
09314 }
09315
09316 qboolean MenuParse_fullscreen( itemDef_t *item, int handle ) {
09317 menuDef_t *menu = (menuDef_t*)item;
09318 if (!PC_Int_Parse(handle, (int*) &menu->fullScreen)) {
09319 return qfalse;
09320 }
09321 return qtrue;
09322 }
09323
09324 qboolean MenuParse_rect( itemDef_t *item, int handle ) {
09325 menuDef_t *menu = (menuDef_t*)item;
09326 if (!PC_Rect_Parse(handle, &menu->window.rect)) {
09327 return qfalse;
09328 }
09329 return qtrue;
09330 }
09331
09332
09333
09334
09335
09336
09337 qboolean MenuParse_style( itemDef_t *item, int handle)
09338 {
09339 menuDef_t *menu = (menuDef_t*)item;
09340
09341 if (!PC_Int_Parse(handle, &menu->window.style))
09342 {
09343 Com_Printf(S_COLOR_YELLOW "Unknown menu style value");
09344 return qfalse;
09345 }
09346
09347 return qtrue;
09348 }
09349
09350 qboolean MenuParse_visible( itemDef_t *item, int handle ) {
09351 int i;
09352 menuDef_t *menu = (menuDef_t*)item;
09353
09354 if (!PC_Int_Parse(handle, &i)) {
09355 return qfalse;
09356 }
09357 if (i) {
09358 menu->window.flags |= WINDOW_VISIBLE;
09359 }
09360 return qtrue;
09361 }
09362
09363 qboolean MenuParse_onOpen( itemDef_t *item, int handle ) {
09364 menuDef_t *menu = (menuDef_t*)item;
09365 if (!PC_Script_Parse(handle, &menu->onOpen)) {
09366 return qfalse;
09367 }
09368 return qtrue;
09369 }
09370
09371 qboolean MenuParse_onClose( itemDef_t *item, int handle ) {
09372 menuDef_t *menu = (menuDef_t*)item;
09373 if (!PC_Script_Parse(handle, &menu->onClose)) {
09374 return qfalse;
09375 }
09376 return qtrue;
09377 }
09378
09379
09380
09381
09382
09383
09384
09385 qboolean MenuParse_onAccept( itemDef_t *item, int handle )
09386 {
09387 menuDef_t *menu = (menuDef_t*)item;
09388
09389 if (!PC_Script_Parse(handle, &menu->onAccept))
09390 {
09391 return qfalse;
09392 }
09393 return qtrue;
09394 }
09395
09396 qboolean MenuParse_onESC( itemDef_t *item, int handle ) {
09397 menuDef_t *menu = (menuDef_t*)item;
09398 if (!PC_Script_Parse(handle, &menu->onESC)) {
09399 return qfalse;
09400 }
09401 return qtrue;
09402 }
09403
09404
09405
09406 qboolean MenuParse_border( itemDef_t *item, int handle ) {
09407 menuDef_t *menu = (menuDef_t*)item;
09408 if (!PC_Int_Parse(handle, &menu->window.border)) {
09409 return qfalse;
09410 }
09411 return qtrue;
09412 }
09413
09414 qboolean MenuParse_borderSize( itemDef_t *item, int handle ) {
09415 menuDef_t *menu = (menuDef_t*)item;
09416 if (!PC_Float_Parse(handle, &menu->window.borderSize)) {
09417 return qfalse;
09418 }
09419 return qtrue;
09420 }
09421
09422 qboolean MenuParse_backcolor( itemDef_t *item, int handle ) {
09423 int i;
09424 float f;
09425 menuDef_t *menu = (menuDef_t*)item;
09426
09427 for (i = 0; i < 4; i++) {
09428 if (!PC_Float_Parse(handle, &f)) {
09429 return qfalse;
09430 }
09431 menu->window.backColor[i] = f;
09432 }
09433 return qtrue;
09434 }
09435
09436
09437
09438
09439
09440
09441 qboolean MenuParse_descAlignment( itemDef_t *item, int handle )
09442 {
09443 menuDef_t *menu = (menuDef_t*)item;
09444
09445 if (!PC_Int_Parse(handle, &menu->descAlignment))
09446 {
09447 Com_Printf(S_COLOR_YELLOW "Unknown desc alignment value");
09448 return qfalse;
09449 }
09450
09451 return qtrue;
09452 }
09453
09454
09455
09456
09457
09458
09459 qboolean MenuParse_descX( itemDef_t *item, int handle )
09460 {
09461 menuDef_t *menu = (menuDef_t*)item;
09462
09463 if (!PC_Int_Parse(handle, &menu->descX))
09464 {
09465 return qfalse;
09466 }
09467 return qtrue;
09468 }
09469
09470
09471
09472
09473
09474
09475 qboolean MenuParse_descY( itemDef_t *item, int handle )
09476 {
09477 menuDef_t *menu = (menuDef_t*)item;
09478
09479 if (!PC_Int_Parse(handle, &menu->descY))
09480 {
09481 return qfalse;
09482 }
09483 return qtrue;
09484 }
09485
09486
09487
09488
09489
09490
09491 qboolean MenuParse_descScale( itemDef_t *item, int handle)
09492 {
09493 menuDef_t *menu = (menuDef_t*)item;
09494
09495 if (!PC_Float_Parse(handle, &menu->descScale))
09496 {
09497 return qfalse;
09498 }
09499 return qtrue;
09500 }
09501
09502
09503
09504
09505
09506
09507 qboolean MenuParse_descColor( itemDef_t *item, int handle)
09508 {
09509 int i;
09510 float f;
09511 menuDef_t *menu = (menuDef_t*)item;
09512
09513 for (i = 0; i < 4; i++)
09514 {
09515 if (!PC_Float_Parse(handle, &f))
09516 {
09517 return qfalse;
09518 }
09519 menu->descColor[i] = f;
09520 }
09521 return qtrue;
09522 }
09523
09524 qboolean MenuParse_forecolor( itemDef_t *item, int handle ) {
09525 int i;
09526 float f;
09527 menuDef_t *menu = (menuDef_t*)item;
09528
09529 for (i = 0; i < 4; i++) {
09530 if (!PC_Float_Parse(handle, &f)) {
09531 return qfalse;
09532 }
09533 if (f < 0)
09534 {
09535 menu->window.flags |= WINDOW_PLAYERCOLOR;
09536 return qtrue;
09537 }
09538 menu->window.foreColor[i] = f;
09539 menu->window.flags |= WINDOW_FORECOLORSET;
09540 }
09541 return qtrue;
09542 }
09543
09544 qboolean MenuParse_bordercolor( itemDef_t *item, int handle ) {
09545 int i;
09546 float f;
09547 menuDef_t *menu = (menuDef_t*)item;
09548
09549 for (i = 0; i < 4; i++) {
09550 if (!PC_Float_Parse(handle, &f)) {
09551 return qfalse;
09552 }
09553 menu->window.borderColor[i] = f;
09554 }
09555 return qtrue;
09556 }
09557
09558 qboolean MenuParse_focuscolor( itemDef_t *item, int handle ) {
09559 int i;
09560 float f;
09561 menuDef_t *menu = (menuDef_t*)item;
09562
09563 for (i = 0; i < 4; i++) {
09564 if (!PC_Float_Parse(handle, &f)) {
09565 return qfalse;
09566 }
09567 menu->focusColor[i] = f;
09568 }
09569 return qtrue;
09570 }
09571
09572 qboolean MenuParse_disablecolor( itemDef_t *item, int handle ) {
09573 int i;
09574 float f;
09575 menuDef_t *menu = (menuDef_t*)item;
09576 for (i = 0; i < 4; i++) {
09577 if (!PC_Float_Parse(handle, &f)) {
09578 return qfalse;
09579 }
09580 menu->disableColor[i] = f;
09581 }
09582 return qtrue;
09583 }
09584
09585
09586 qboolean MenuParse_outlinecolor( itemDef_t *item, int handle ) {
09587 menuDef_t *menu = (menuDef_t*)item;
09588 if (!PC_Color_Parse(handle, &menu->window.outlineColor)){
09589 return qfalse;
09590 }
09591 return qtrue;
09592 }
09593
09594 qboolean MenuParse_background( itemDef_t *item, int handle ) {
09595 pc_token_t token;
09596 menuDef_t *menu = (menuDef_t*)item;
09597
09598 if (!trap_PC_ReadToken(handle, &token)) {
09599 return qfalse;
09600 }
09601 menu->window.background = DC->registerShaderNoMip(token.string);
09602 return qtrue;
09603 }
09604
09605 qboolean MenuParse_cinematic( itemDef_t *item, int handle ) {
09606 menuDef_t *menu = (menuDef_t*)item;
09607
09608 if (!PC_String_Parse(handle, &menu->window.cinematicName)) {
09609 return qfalse;
09610 }
09611 return qtrue;
09612 }
09613
09614 qboolean MenuParse_ownerdrawFlag( itemDef_t *item, int handle ) {
09615 int i;
09616 menuDef_t *menu = (menuDef_t*)item;
09617
09618 if (!PC_Int_Parse(handle, &i)) {
09619 return qfalse;
09620 }
09621 menu->window.ownerDrawFlags |= i;
09622 return qtrue;
09623 }
09624
09625 qboolean MenuParse_ownerdraw( itemDef_t *item, int handle ) {
09626 menuDef_t *menu = (menuDef_t*)item;
09627
09628 if (!PC_Int_Parse(handle, &menu->window.ownerDraw)) {
09629 return qfalse;
09630 }
09631 return qtrue;
09632 }
09633
09634
09635
09636 qboolean MenuParse_popup( itemDef_t *item, int handle ) {
09637 menuDef_t *menu = (menuDef_t*)item;
09638 menu->window.flags |= WINDOW_POPUP;
09639 return qtrue;
09640 }
09641
09642
09643 qboolean MenuParse_outOfBounds( itemDef_t *item, int handle ) {
09644 menuDef_t *menu = (menuDef_t*)item;
09645
09646 menu->window.flags |= WINDOW_OOB_CLICK;
09647 return qtrue;
09648 }
09649
09650 qboolean MenuParse_soundLoop( itemDef_t *item, int handle ) {
09651 menuDef_t *menu = (menuDef_t*)item;
09652
09653 if (!PC_String_Parse(handle, &menu->soundName)) {
09654 return qfalse;
09655 }
09656 return qtrue;
09657 }
09658
09659 qboolean MenuParse_fadeClamp( itemDef_t *item, int handle ) {
09660 menuDef_t *menu = (menuDef_t*)item;
09661
09662 if (!PC_Float_Parse(handle, &menu->fadeClamp)) {
09663 return qfalse;
09664 }
09665 return qtrue;
09666 }
09667
09668 qboolean MenuParse_fadeAmount( itemDef_t *item, int handle ) {
09669 menuDef_t *menu = (menuDef_t*)item;
09670
09671 if (!PC_Float_Parse(handle, &menu->fadeAmount)) {
09672 return qfalse;
09673 }
09674 return qtrue;
09675 }
09676
09677
09678 qboolean MenuParse_fadeCycle( itemDef_t *item, int handle ) {
09679 menuDef_t *menu = (menuDef_t*)item;
09680
09681 if (!PC_Int_Parse(handle, &menu->fadeCycle)) {
09682 return qfalse;
09683 }
09684 return qtrue;
09685 }
09686
09687
09688 qboolean MenuParse_itemDef( itemDef_t *item, int handle ) {
09689 menuDef_t *menu = (menuDef_t*)item;
09690 if (menu->itemCount < MAX_MENUITEMS) {
09691 menu->items[menu->itemCount] = (itemDef_t *) UI_Alloc(sizeof(itemDef_t));
09692 Item_Init(menu->items[menu->itemCount]);
09693 if (!Item_Parse(handle, menu->items[menu->itemCount])) {
09694 return qfalse;
09695 }
09696 Item_InitControls(menu->items[menu->itemCount]);
09697 menu->items[menu->itemCount++]->parent = menu;
09698 }
09699 return qtrue;
09700 }
09701
09702
09703
09704
09705
09706 qboolean MenuParse_appearanceIncrement( itemDef_t *item, int handle )
09707 {
09708 menuDef_t *menu = (menuDef_t*)item;
09709
09710 if (!PC_Float_Parse(handle, &menu->appearanceIncrement))
09711 {
09712 return qfalse;
09713 }
09714 return qtrue;
09715 }
09716
09717 keywordHash_t menuParseKeywords[] = {
09718 {"appearanceIncrement", MenuParse_appearanceIncrement, NULL },
09719 {"backcolor", MenuParse_backcolor, NULL },
09720 {"background", MenuParse_background, NULL },
09721 {"border", MenuParse_border, NULL },
09722 {"bordercolor", MenuParse_bordercolor, NULL },
09723 {"borderSize", MenuParse_borderSize, NULL },
09724 {"cinematic", MenuParse_cinematic, NULL },
09725 {"descAlignment", MenuParse_descAlignment,NULL },
09726 {"desccolor", MenuParse_descColor, NULL },
09727 {"descX", MenuParse_descX, NULL },
09728 {"descY", MenuParse_descY, NULL },
09729 {"descScale", MenuParse_descScale, NULL },
09730 {"disablecolor", MenuParse_disablecolor, NULL },
09731 {"fadeAmount", MenuParse_fadeAmount, NULL },
09732 {"fadeClamp", MenuParse_fadeClamp, NULL },
09733 {"fadeCycle", MenuParse_fadeCycle, NULL },
09734 {"focuscolor", MenuParse_focuscolor, NULL },
09735 {"font", MenuParse_font, NULL },
09736 {"forecolor", MenuParse_forecolor, NULL },
09737 {"fullscreen", MenuParse_fullscreen, NULL },
09738 {"itemDef", MenuParse_itemDef, NULL },
09739 {"name", MenuParse_name, NULL },
09740 {"onClose", MenuParse_onClose, NULL },
09741
09742 {"onAccept", MenuParse_onAccept, NULL },
09743
09744 {"onESC", MenuParse_onESC, NULL },
09745 {"outOfBoundsClick", MenuParse_outOfBounds, NULL },
09746 {"onOpen", MenuParse_onOpen, NULL },
09747 {"outlinecolor", MenuParse_outlinecolor, NULL },
09748 {"ownerdraw", MenuParse_ownerdraw, NULL },
09749 {"ownerdrawFlag", MenuParse_ownerdrawFlag,NULL },
09750 {"popup", MenuParse_popup, NULL },
09751 {"rect", MenuParse_rect, NULL },
09752 {"soundLoop", MenuParse_soundLoop, NULL },
09753 {"style", MenuParse_style, NULL },
09754 {"visible", MenuParse_visible, NULL },
09755 {0, 0, 0 }
09756 };
09757
09758 keywordHash_t *menuParseKeywordHash[KEYWORDHASH_SIZE];
09759
09760
09761
09762
09763
09764
09765 void Menu_SetupKeywordHash(void) {
09766 int i;
09767
09768 memset(menuParseKeywordHash, 0, sizeof(menuParseKeywordHash));
09769 for (i = 0; menuParseKeywords[i].keyword; i++) {
09770 KeywordHash_Add(menuParseKeywordHash, &menuParseKeywords[i]);
09771 }
09772 }
09773
09774
09775
09776
09777
09778
09779 qboolean Menu_Parse(int handle, menuDef_t *menu) {
09780 pc_token_t token;
09781 keywordHash_t *key;
09782
09783 if (!trap_PC_ReadToken(handle, &token))
09784 return qfalse;
09785 if (*token.string != '{') {
09786 return qfalse;
09787 }
09788
09789 while ( 1 ) {
09790 if (!trap_PC_ReadToken(handle, &token)) {
09791 PC_SourceError(handle, "end of file inside menu\n");
09792 return qfalse;
09793 }
09794
09795 if (*token.string == '}') {
09796 return qtrue;
09797 }
09798
09799 key = KeywordHash_Find(menuParseKeywordHash, token.string);
09800 if (!key) {
09801 PC_SourceError(handle, "unknown menu keyword %s", token.string);
09802 continue;
09803 }
09804 if ( !key->func((itemDef_t*)menu, handle) ) {
09805 PC_SourceError(handle, "couldn't parse menu keyword %s", token.string);
09806 return qfalse;
09807 }
09808 }
09809 return qfalse;
09810 }
09811
09812
09813
09814
09815
09816
09817 void Menu_New(int handle) {
09818 menuDef_t *menu = &Menus[menuCount];
09819
09820 if (menuCount < MAX_MENUS) {
09821 Menu_Init(menu);
09822 if (Menu_Parse(handle, menu)) {
09823 Menu_PostParse(menu);
09824 menuCount++;
09825 }
09826 }
09827 }
09828
09829 int Menu_Count() {
09830 return menuCount;
09831 }
09832
09833 void Menu_PaintAll() {
09834 int i;
09835 if (captureFunc) {
09836 captureFunc(captureData);
09837 }
09838
09839 for (i = 0; i < Menu_Count(); i++) {
09840 Menu_Paint(&Menus[i], qfalse);
09841 }
09842
09843 if (debugMode) {
09844 vec4_t v = {1, 1, 1, 1};
09845 DC->drawText(5, 25, .75, v, va("fps: %f", DC->FPS), 0, 0, 0, 0);
09846 DC->drawText(5, 45, .75, v, va("x: %d y:%d", DC->cursorx,DC->cursory), 0, 0, 0, 0);
09847 }
09848 }
09849
09850 void Menu_Reset() {
09851 menuCount = 0;
09852 }
09853
09854 displayContextDef_t *Display_GetContext() {
09855 return DC;
09856 }
09857
09858 void *Display_CaptureItem(int x, int y) {
09859 int i;
09860
09861 for (i = 0; i < menuCount; i++) {
09862
09863
09864 if (Rect_ContainsPoint(&Menus[i].window.rect, x, y)) {
09865 return &Menus[i];
09866 }
09867 }
09868 return NULL;
09869 }
09870
09871
09872
09873 qboolean Display_MouseMove(void *p, int x, int y) {
09874
09875
09876 #ifdef _XBOX
09877 return qtrue;
09878 #endif
09879
09880 int i;
09881 menuDef_t *menu = (menuDef_t *) p;
09882
09883 if (menu == NULL) {
09884 menu = Menu_GetFocused();
09885 if (menu) {
09886 if (menu->window.flags & WINDOW_POPUP) {
09887 Menu_HandleMouseMove(menu, x, y);
09888 return qtrue;
09889 }
09890 }
09891 for (i = 0; i < menuCount; i++) {
09892 Menu_HandleMouseMove(&Menus[i], x, y);
09893 }
09894 } else {
09895 menu->window.rect.x += x;
09896 menu->window.rect.y += y;
09897 Menu_UpdatePosition(menu);
09898 }
09899 return qtrue;
09900
09901 }
09902
09903 int Display_CursorType(int x, int y) {
09904 int i;
09905 for (i = 0; i < menuCount; i++) {
09906 rectDef_t r2;
09907 r2.x = Menus[i].window.rect.x - 3;
09908 r2.y = Menus[i].window.rect.y - 3;
09909 r2.w = r2.h = 7;
09910 if (Rect_ContainsPoint(&r2, x, y)) {
09911 return CURSOR_SIZER;
09912 }
09913 }
09914 return CURSOR_ARROW;
09915 }
09916
09917
09918 void Display_HandleKey(int key, qboolean down, int x, int y) {
09919 menuDef_t *menu = (menuDef_t *) Display_CaptureItem(x, y);
09920 if (menu == NULL) {
09921 menu = Menu_GetFocused();
09922 }
09923 if (menu) {
09924 Menu_HandleKey(menu, key, down );
09925 }
09926 }
09927
09928 static void Window_CacheContents(windowDef_t *window) {
09929 if (window) {
09930 if (window->cinematicName) {
09931 int cin = DC->playCinematic(window->cinematicName, 0, 0, 0, 0);
09932 DC->stopCinematic(cin);
09933 }
09934 }
09935 }
09936
09937
09938 static void Item_CacheContents(itemDef_t *item) {
09939 if (item) {
09940 Window_CacheContents(&item->window);
09941 }
09942
09943 }
09944
09945 static void Menu_CacheContents(menuDef_t *menu) {
09946 if (menu) {
09947 int i;
09948 Window_CacheContents(&menu->window);
09949 for (i = 0; i < menu->itemCount; i++) {
09950 Item_CacheContents(menu->items[i]);
09951 }
09952
09953 if (menu->soundName && *menu->soundName) {
09954 DC->registerSound(menu->soundName);
09955 }
09956 }
09957
09958 }
09959
09960 void Display_CacheAll() {
09961 int i;
09962 for (i = 0; i < menuCount; i++) {
09963 Menu_CacheContents(&Menus[i]);
09964 }
09965 }
09966
09967
09968 static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y) {
09969 if (menu && menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)) {
09970
09971 #ifdef _XBOX
09972 return qtrue;
09973 #endif
09974 if (Rect_ContainsPoint(&menu->window.rect, x, y)) {
09975 int i;
09976 for (i = 0; i < menu->itemCount; i++) {
09977
09978
09979
09980 if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) {
09981 continue;
09982 }
09983
09984 if (menu->items[i]->window.flags & WINDOW_DECORATION) {
09985 continue;
09986 }
09987
09988 if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) {
09989 itemDef_t *overItem = menu->items[i];
09990 if (overItem->type == ITEM_TYPE_TEXT && overItem->text) {
09991 if (Rect_ContainsPoint(&overItem->window.rect, x, y)) {
09992 return qtrue;
09993 } else {
09994 continue;
09995 }
09996 } else {
09997 return qtrue;
09998 }
09999 }
10000 }
10001
10002 }
10003 }
10004 return qfalse;
10005 }
10006
10007
10008 #ifdef _XBOX
10009
10010 void G_DemoStart()
10011 {
10012
10013
10014 g_runningDemo = true;
10015
10016
10017
10018
10019 extern void Menus_CloseAll();
10020
10021 Menus_CloseAll();
10022
10023 trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
10024 #ifndef CGAME
10025 trap_Key_ClearStates();
10026 #endif
10027 trap_Cvar_Set( "cl_paused", "0" );
10028
10029
10030
10031 }
10032
10033
10034
10035 const char *attractMovieNames[] = {
10036 "jk1",
10037 "jk2",
10038 "jk3",
10039 "jk4",
10040 "jk5",
10041 };
10042
10043 extern int trap_Milliseconds( void );
10044
10045 const int numAttractMovies = sizeof(attractMovieNames) / sizeof(attractMovieNames[0]);
10046 static int curAttractMovie = 0;
10047
10048 void G_DemoFrame()
10049 {
10050 bool keypressed = false;
10051 if (g_runningDemo)
10052 {
10053 while (!keypressed)
10054 keypressed = CIN_PlayAllFrames( "atvi.bik", 0, 0, 640, 480, 0, true );
10055 G_DemoEnd();
10056
10057
10058
10059 }
10060 else
10061 {
10062 menuDef_t* curMenu = Menu_GetFocused();
10063
10064 if (curMenu && curMenu->window.name &&
10065 (!Q_stricmp(curMenu->window.name , "mainMenu") ||
10066 !Q_stricmp(curMenu->window.name, "splashMenu")))
10067 {
10068 if (!g_demoLastKeypress)
10069 g_demoLastKeypress = trap_Milliseconds();
10070 else if (g_demoLastKeypress + DEMO_TIME_MAX < trap_Milliseconds())
10071 G_DemoStart();
10072 }
10073 else
10074 {
10075 g_demoLastKeypress = trap_Milliseconds();
10076 }
10077 }
10078 }
10079
10080 void G_DemoKeypress()
10081 {
10082 g_demoLastKeypress = trap_Milliseconds();
10083
10084
10085
10086
10087 }
10088
10089
10090 void G_DemoEnd()
10091 {
10092
10093 if (!g_runningDemo)
10094 return;
10095
10096 CIN_CloseAllVideos();
10097
10098 Menus_CloseAll();
10099 g_ReturnToSplash = true;
10100 g_runningDemo = qfalse;
10101 G_DemoKeypress();
10102 trap_Key_SetCatcher( trap_Key_GetCatcher() & KEYCATCH_UI );
10103 #ifndef CGAME
10104 trap_Key_ClearStates();
10105 #endif
10106 trap_Cvar_Set( "cl_paused", "0" );
10107
10108
10109
10110
10111 }
10112
10113 void PlayDemo()
10114 {
10115
10116 G_DemoStart();
10117 CIN_PlayAllFrames( attractMovieNames[curAttractMovie], 0, 0, 640, 480, 0, true );
10118 curAttractMovie = (curAttractMovie + 1) % numAttractMovies;
10119
10120
10121 G_DemoEnd();
10122 }
10123
10124 void UpdateDemoTimer()
10125 {
10126 g_demoLastKeypress = trap_Milliseconds();
10127 }
10128
10129 bool TestDemoTimer()
10130 {
10131
10132 return false;
10133
10134
10135 menuDef_t* curMenu = Menu_GetFocused();
10136 if (curMenu && curMenu->window.name &&
10137 (!Q_stricmp(curMenu->window.name , "mainMenu") ||
10138 !Q_stricmp(curMenu->window.name, "splashMenu")))
10139 {
10140 if (!g_demoLastKeypress)
10141 g_demoLastKeypress = trap_Milliseconds();
10142 else if (g_demoLastKeypress + DEMO_TIME_MAX < trap_Milliseconds())
10143 return true;
10144 }
10145 return false;
10146 }
10147
10148
10149
10150
10151 #endif // _XBOX
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163 #include "../namespace_end.h"