mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-29 14:17:57 +03:00
716 lines
21 KiB
C++
716 lines
21 KiB
C++
/*
|
||
===========================================================================
|
||
Copyright (C) 2010-2012 Michael Rieder
|
||
|
||
This file is part of OpenMohaa source code.
|
||
|
||
OpenMohaa source code is free software; you can redistribute it
|
||
and/or modify it under the terms of the GNU General Public License as
|
||
published by the Free Software Foundation; either version 2 of the License,
|
||
or (at your option) any later version.
|
||
|
||
OpenMohaa source code is distributed in the hope that it will be
|
||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with OpenMohaa source code; if not, write to the Free Software
|
||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
===========================================================================
|
||
*/
|
||
|
||
#include <glb_local.h>
|
||
#include "ui_local.h"
|
||
|
||
#define PARSE_PTR COM_Parse(ptr)
|
||
|
||
#define FILE_HASH_SIZE 64
|
||
uiMenulist_t* hashTable[ FILE_HASH_SIZE ];
|
||
|
||
static long generateHashValue( const char *fname ) {
|
||
int i;
|
||
long hash;
|
||
char letter;
|
||
|
||
hash = 0;
|
||
i = 0;
|
||
while (fname[i] != '\0') {
|
||
letter = tolower(fname[i]);
|
||
hash+=(long)(letter)*(i+119);
|
||
i++;
|
||
}
|
||
hash &= (FILE_HASH_SIZE-1);
|
||
return hash;
|
||
}
|
||
|
||
void UI_ClearHashTable( void )
|
||
{
|
||
memset( hashTable, 0, sizeof( hashTable ) );
|
||
}
|
||
|
||
void UI_ParseMenuResource( const char *token, char **ptr, uiResource_t *res, int *offset ) {
|
||
const char *var;
|
||
int i;
|
||
|
||
if ( !Q_strncmp( token, "name", 4 ) ) {
|
||
Q_strncpyz( res->name, PARSE_PTR, UI_MAX_NAME );
|
||
}
|
||
else if ( !Q_strncmp( token, "rect", 4 ) ) {
|
||
res->rect[0] = offset[0] + atoi( PARSE_PTR );
|
||
res->rect[1] = offset[1] + atoi( PARSE_PTR );
|
||
|
||
for (i=2;i<4;i++)
|
||
res->rect[i] = atoi( PARSE_PTR );
|
||
}
|
||
else if ( !Q_strncmp( token, "fgcolor", 7 ) ) {
|
||
for (i=0;i<4;i++)
|
||
res->fgcolor[i] = atof( PARSE_PTR );
|
||
}
|
||
else if ( !Q_strncmp( token, "bgcolor", 7 ) ) {
|
||
for (i=0;i<4;i++)
|
||
res->bgcolor[i] = atof( PARSE_PTR );
|
||
}
|
||
else if ( !Q_strncmp( token, "borderstyle", 11 ) ) {
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp(var,"RAISED",6) )
|
||
res->borderstyle = UI_BORDER_RAISED;
|
||
else if ( !Q_strncmp(var,"INDENT_BORDER",13) )
|
||
res->borderstyle = UI_BORDER_INDENT;
|
||
else if ( !Q_strncmp(var,"3D_BORDER",9) )
|
||
res->borderstyle = UI_BORDER_3D;
|
||
else res->borderstyle = UI_BORDER_NONE;
|
||
}
|
||
else if ( !Q_strncmp( token, "shader", 6 ) ) {
|
||
res->shader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "enabledcvar", 11 ) ) {
|
||
res->enablewithcvar = qtrue;
|
||
res->enabledcvar = uii.Cvar_Get( PARSE_PTR, "", 0 );
|
||
}
|
||
else if ( !Q_strncmp( token, "stuffcommand", 12 ) ) {
|
||
res->stuffcommand = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Com_sprintf( res->stuffcommand, UI_MAX_NAME, "%s\n", PARSE_PTR );
|
||
|
||
}
|
||
else if ( !Q_strncmp( token, "hovershader", 11 ) ) {
|
||
res->hoverDraw = qtrue;
|
||
res->hoverShader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "clicksound", 10 ) ) {
|
||
res->clicksound = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->clicksound, PARSE_PTR, UI_MAX_NAME );
|
||
}
|
||
else if ( !Q_strncmp( token, "hovercommand", 12 ) ) {
|
||
res->hovercommand = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->hovercommand, PARSE_PTR, UI_MAX_NAME );
|
||
}
|
||
else if ( !Q_strncmp( token, "linkcvartoshader", 16 ) ) {
|
||
res->linkcvartoshader = qtrue;
|
||
}
|
||
else if ( !Q_strncmp( token, "linkcvar", 8 ) ) {
|
||
res->linkcvarname = (char*)UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->linkcvarname, PARSE_PTR, UI_MAX_NAME );
|
||
res->linkcvar = uii.Cvar_Get( res->linkcvarname, "", 0 );
|
||
}
|
||
else if ( !Q_strncmp( token, "font", 4 ) ) {
|
||
// uii.R_RegisterFont( PARSE_PTR, 0, &res->font );
|
||
PARSE_PTR;
|
||
res->font = &uis.menuFont;
|
||
}
|
||
else if ( !Q_strncmp( token, "title", 5 ) ) {
|
||
res->title = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->title, PARSE_PTR, UI_MAX_NAME );
|
||
}
|
||
else if ( !Q_strncmp( token, "textalign", 9 )||!Q_strncmp( token, "align", 5 ) ) {
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp(var,"left",4) )
|
||
res->align = UI_ALIGN_LEFT;
|
||
else if ( !Q_strncmp(var,"center",128) )
|
||
res->align = UI_ALIGN_CENTER;
|
||
else if ( !Q_strncmp(var,"right",5) )
|
||
res->align = UI_ALIGN_RIGHT;
|
||
}
|
||
else if ( !Q_strncmp( token, "checked_shader", 14 ) ) {
|
||
res->checked_shader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "unchecked_shader", 16 ) ) {
|
||
res->unchecked_shader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "menushader", 10 ) ) {
|
||
PARSE_PTR;
|
||
res->menushader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "selmenushader", 13 ) ) {
|
||
PARSE_PTR;
|
||
res->selmenushader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "linkstring", 10 ) ) {
|
||
if ( res->selentries >= UI_MAX_SELECT ) {
|
||
Com_Printf( "Too many select entries %i\n", res->selentries );
|
||
PARSE_PTR;
|
||
PARSE_PTR;
|
||
return;
|
||
}
|
||
res->linkstring1[res->selentries] = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
res->linkstring2[res->selentries] = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->linkstring1[res->selentries], PARSE_PTR, UI_MAX_NAME );
|
||
Q_strncpyz( res->linkstring2[res->selentries], PARSE_PTR, UI_MAX_NAME );
|
||
res->selentries++;
|
||
}
|
||
else if ( !Q_strncmp( token, "addpopup", 8 ) ) {
|
||
PARSE_PTR;
|
||
if ( res->selentries >= UI_MAX_SELECT ) {
|
||
Com_Printf( "Too many select entries %i\n", res->selentries );
|
||
PARSE_PTR;
|
||
PARSE_PTR;
|
||
PARSE_PTR;
|
||
return;
|
||
}
|
||
res->linkstring1[ res->selentries ] = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->linkstring1[res->selentries], PARSE_PTR, UI_MAX_NAME );
|
||
PARSE_PTR;
|
||
res->linkstring2[ res->selentries ] = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Com_sprintf( res->linkstring2[res->selentries], UI_MAX_NAME, "%s\n", PARSE_PTR );
|
||
res->selentries++;
|
||
}
|
||
else if ( !Q_strncmp( token, "ordernumber", 11 ) ) {
|
||
res->ordernumber = atoi(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "slidertype", 10 ) ) {
|
||
res->ordernumber = atoi(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "setrange", 8 ) ) {
|
||
res->flRange[0] = atof(PARSE_PTR);
|
||
res->flRange[1] = atof(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "stepsize", 8 ) ) {
|
||
res->flStepsize = atof(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "rendermodel", 11 ) ) {
|
||
res->rendermodel = (qboolean)atoi(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "modeloffset", 128 ) ) {
|
||
sscanf(PARSE_PTR,"%f %f %f",&res->modeloffset[0],&res->modeloffset[1],&res->modeloffset[2]);
|
||
}
|
||
else if ( !Q_strncmp( token, "modelrotateoffset", 17 ) ) {
|
||
sscanf(PARSE_PTR,"%f %f %f",&res->modelrotateoffset[0],&res->modelrotateoffset[1],&res->modelrotateoffset[2]);
|
||
}
|
||
else if ( !Q_strncmp( token, "modelangles", 11 ) ) {
|
||
sscanf(PARSE_PTR,"%f %f %f",&res->modelangles[0],&res->modelangles[1],&res->modelangles[2]);
|
||
}
|
||
else if ( !Q_strncmp( token, "modelscale", 10 ) ) {
|
||
res->modelscale = atof(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "modelanim", 9 ) ) {
|
||
res->modelanim = ( char * )UI_Alloc( UI_MAX_NAME );
|
||
Q_strncpyz( res->modelanim, PARSE_PTR, UI_MAX_NAME );
|
||
}
|
||
else if ( !Q_strncmp( token, "fadein", 6 ) ) {
|
||
res->fadein = atof( PARSE_PTR );
|
||
}
|
||
else if ( !Q_strncmp( token, "statbar_shader_flash", 20 ) ) {
|
||
res->statbarshaderflash = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "statbar_shader", 14 ) ) {
|
||
res->statbarshader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "statbar_tileshader", 14 ) ) {
|
||
res->statbartileshader = uii.Rend_RegisterMaterial( str( PARSE_PTR ) );
|
||
}
|
||
else if ( !Q_strncmp( token, "statbar_endangles", 17 ) ) {
|
||
res->statbarendangles[0] = atoi( PARSE_PTR );
|
||
res->statbarendangles[1] = atoi( PARSE_PTR );
|
||
}
|
||
else if ( !Q_strncmp( token, "statbar_rotatorsize", 19 ) ) {
|
||
res->rotatorsize[0] = atof( PARSE_PTR );
|
||
res->rotatorsize[1] = atof( PARSE_PTR );
|
||
}
|
||
else if ( !Q_strncmp( token, "statbar", 7 ) ) {
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp(var,"compass",7) )
|
||
res->statbar = STATBAR_COMPASS;
|
||
else if ( !Q_strncmp(var,"horizontal",10) ) {
|
||
res->statbar = STATBAR_HORIZONTAL;
|
||
res->statbarRange[0] = atof(PARSE_PTR);
|
||
res->statbarRange[1] = atof(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp(var,"vertical_stagger_even",21) )
|
||
res->statbar = STATBAR_VERTICAL_STAGGER_EVEN;
|
||
else if ( !Q_strncmp(var,"vertical_stagger_odd",20) )
|
||
res->statbar = STATBAR_VERTICAL_STAGGER_ODD;
|
||
else if ( !Q_strncmp(var,"vertical",8) )
|
||
res->statbar = STATBAR_VERTICAL;
|
||
else if ( !Q_strncmp(var,"headingspinner",14) ) {
|
||
res->statbar = STATBAR_HEADING_SPINNER;
|
||
res->statbarRange[0] = atof(PARSE_PTR);
|
||
res->statbarRange[1] = atof(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp(var,"rotator",7) ) {
|
||
res->statbar = STATBAR_ROTATOR;
|
||
res->statbarRange[0] = atof(PARSE_PTR);
|
||
res->statbarRange[1] = atof(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp(var,"spinner",7) ) {
|
||
res->statbar = STATBAR_SPINNER;
|
||
res->statbarRange[0] = atof(PARSE_PTR);
|
||
res->statbarRange[1] = atof(PARSE_PTR);
|
||
}
|
||
else Com_Printf( "UI_ParseMenuResource: unknown statbar %s\n", var );
|
||
}
|
||
else if ( !Q_strncmp( token, "maxplayerstat", 128 ) ) {
|
||
res->maxplayerstat = (statIndex_t)atoi(PARSE_PTR);
|
||
res->statvar = qtrue;
|
||
}
|
||
else if ( !Q_strncmp( token, "playerstat", 10 ) ) {
|
||
res->playerstat = (statIndex_t)atoi(PARSE_PTR);
|
||
res->statvar = qtrue;
|
||
}
|
||
else if ( !Q_strncmp( token, "itemstat", 8 ) ) {
|
||
res->itemstat = (statIndex_t)atoi(PARSE_PTR);
|
||
res->statvar = qtrue;
|
||
}
|
||
else if ( !Q_strncmp( token, "invmodelhand", 12 ) ) {
|
||
res->invmodelhand = atoi(PARSE_PTR);
|
||
}
|
||
else if ( !Q_strncmp( token, "resource", 8 ) ) {
|
||
Com_Printf( "UI_ParseMenuResource: new resource not expected: forgot }?\n" );
|
||
}
|
||
else {
|
||
Com_Printf( "UI_ParseMenuResource: unknown token %s\n", token );
|
||
}
|
||
}
|
||
|
||
qboolean UI_ParseMenuToken( const char *token, char **ptr, uiMenu_t *menu ) {
|
||
const char *var;
|
||
int i;
|
||
uiResource_t *res;
|
||
|
||
if ( !Q_strncmp( token, "menu", 4 ) ) {
|
||
Q_strncpyz( menu->name, PARSE_PTR, sizeof(menu->name));
|
||
menu->size[0] = atoi( PARSE_PTR );
|
||
menu->size[1] = atoi( PARSE_PTR );
|
||
var = COM_Parse( ptr );
|
||
if ( !Q_strncmp( var, "FROM_TOP", 8 ))
|
||
menu->motion = UI_FROM_TOP;
|
||
else if ( !Q_strncmp( var, "FROM_TOP", 8 ))
|
||
menu->motion = UI_FROM_BOTTOM;
|
||
else if ( !Q_strncmp( var, "FROM_BOTTOM", 8 ))
|
||
menu->motion = UI_FROM_LEFT;
|
||
else if ( !Q_strncmp( var, "FROM_LEFT", 8 ))
|
||
menu->motion = UI_FROM_RIGHT;
|
||
else if ( !Q_strncmp( var, "NONE", 8 ))
|
||
menu->motion = UI_NONE;
|
||
menu->time = atoi( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "end.", 4 ) ) {
|
||
return qtrue;
|
||
}
|
||
else if ( !Q_strncmp( token, "include", 7 ) ) {
|
||
Q_strncpyz( menu->include, PARSE_PTR, UI_MAX_NAME );
|
||
UI_LoadINC( menu->include, menu, qfalse );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "postinclude", 11 ) ) {
|
||
Q_strncpyz( menu->postinclude, PARSE_PTR, UI_MAX_NAME );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "align", 5 ) ) {
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp( var, "left", 128 ) ) {
|
||
menu->align[0] = UI_ALIGN_LEFT;
|
||
menu->offset[0] = 0;
|
||
}
|
||
else if ( !Q_strncmp( var, "centerx", 128 ) ) {
|
||
menu->align[0] = UI_ALIGN_CENTER;
|
||
menu->offset[0] = 320 - menu->size[0]/2;
|
||
}
|
||
else if ( !Q_strncmp( var, "right", 128 ) ) {
|
||
menu->align[0] = UI_ALIGN_RIGHT;
|
||
menu->offset[0] = 640 - menu->size[0];
|
||
}
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp( var, "top", 128 ) ) {
|
||
menu->align[1] = UI_ALIGN_LEFT;
|
||
menu->offset[1] = 0;
|
||
}
|
||
else if ( !Q_strncmp( var, "centery", 128 ) ) {
|
||
menu->align[1] = UI_ALIGN_CENTER;
|
||
menu->offset[1] = 240 - menu->size[1]/2;;
|
||
}
|
||
else if ( !Q_strncmp( var, "bottom", 128 ) ) {
|
||
menu->align[1] = UI_ALIGN_RIGHT;
|
||
menu->offset[1] = 480 - menu->size[1];
|
||
}
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "vidmode", 7 ) ) {
|
||
menu->vidmode = atoi( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "fadein", 7 ) ) {
|
||
menu->fadein = atof( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "fgcolor", 7 ) ) {
|
||
for ( i=0;i<4;i++ )
|
||
menu->fgcolor[i] = atof( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "bgcolor", 7 ) ) {
|
||
for ( i=0;i<4;i++ )
|
||
menu->bgcolor[i] = atof( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "borderstyle", 11 ) ) {
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp(var,"RAISED",6) )
|
||
menu->borderstyle = UI_BORDER_RAISED;
|
||
else menu->borderstyle = UI_BORDER_NONE;
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "bgfill", 6 ) ) {
|
||
for ( i=0;i<4;i++ )
|
||
menu->bgfill[i] = atof( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "fullscreen", 10 ) ) {
|
||
menu->fullscreen = (qboolean)atoi( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "virtualres", 10 ) ) {
|
||
menu->virtualres = (qboolean)atoi( PARSE_PTR );
|
||
return qfalse;
|
||
}
|
||
else if ( !Q_strncmp( token, "resource", 8 ) ) {
|
||
menu->resPtr++;
|
||
if ( menu->resPtr >= UI_MAX_RESOURCES ) {
|
||
Com_Printf( "UI_ParseMenuToken: more than %i resources!\n", UI_MAX_RESOURCES );
|
||
menu->resPtr--;
|
||
return qfalse;
|
||
}
|
||
res = &menu->resources[menu->resPtr];
|
||
res->font = &uis.menuFont;
|
||
// uii.R_RegisterFont( "facfont-20", 0, &res->font ); //load standard font for resource
|
||
|
||
var = PARSE_PTR;
|
||
if ( !Q_strncmp( var, "Label", 5 ) )
|
||
res->type = UI_RES_LABEL;
|
||
else if ( !Q_strncmp( var, "Button", 6 ) )
|
||
res->type = UI_RES_BUTTON;
|
||
else if ( !Q_strncmp( var, "Field", 5 ) )
|
||
res->type = UI_RES_FIELD;
|
||
else if ( !Q_strncmp( var, "CheckBox", 8 ) )
|
||
res->type = UI_RES_CHECKBOX;
|
||
else if ( !Q_strncmp( var, "PulldownMenuContainer", 21 ) )
|
||
res->type = UI_RES_PULLDOWN;
|
||
else if ( !Q_strncmp( var, "Slider", 6 ) )
|
||
res->type = UI_RES_SLIDER;
|
||
else if ( !Q_strncmp( var, "FAKKServerList", 14 ) ) {
|
||
res->type = UI_RES_SERVERLIST;
|
||
res->selectedListEntry = -1;
|
||
}
|
||
else if ( !Q_strncmp( var, "FAKKBindList", 12 ) )
|
||
// su44: that's used in ui/controls.urc
|
||
res->type = UI_RES_BINDLIST;
|
||
else if ( !Q_strncmp( var, "LANGameClass", 12 ) ) {
|
||
res->type = UI_RES_LANSERVERLIST;
|
||
res->selectedListEntry = -1;
|
||
}
|
||
else
|
||
Com_Printf( "UI_ParseMenuToken: unknown menu resource type %s\n", var );
|
||
|
||
var = PARSE_PTR ;
|
||
if ( *var == '{' ) {
|
||
var = PARSE_PTR;
|
||
while (*var != '}') {
|
||
UI_ParseMenuResource( var, ptr, res, menu->offset );
|
||
var = PARSE_PTR;
|
||
if (*var ==0) {
|
||
Com_Memset( res, 0, sizeof(uiResource_t) );
|
||
menu->resPtr--;
|
||
return qfalse;
|
||
}
|
||
}
|
||
// "startnew" and "changemap" buttons are equal. we skip changemap
|
||
// sigh sigh sigh
|
||
if (!Q_strncmp(res->name,"changemap",UI_MAX_NAME)) {
|
||
Com_Memset( res, 0, sizeof(uiResource_t) );
|
||
menu->resPtr--;
|
||
}
|
||
return qfalse;
|
||
}
|
||
Com_Printf( "UI_ParseMenuToken: error loading resource\n" );
|
||
return qfalse;
|
||
}
|
||
else {
|
||
Com_Printf( "UI_ParseMenuToken: unknown token %s\n", token );
|
||
return qfalse;
|
||
}
|
||
}
|
||
|
||
void UI_LoadINC( const char *name, uiMenu_t *menu, qboolean post ) {
|
||
fileHandle_t f;
|
||
int len;
|
||
char filename[MAX_QPATH];
|
||
char buffer[UI_MAX_URCSIZE];
|
||
const char *token;
|
||
char *ptr;
|
||
uiResource_t *res;
|
||
const char *var;
|
||
|
||
Q_strncpyz( filename, name, sizeof( filename ) );
|
||
if ( post == qfalse )
|
||
COM_DefaultExtension( filename, sizeof( filename ), ".inc" );
|
||
|
||
len = uii.FS_FOpenFile( filename, &f, FS_READ);
|
||
if (!f) {
|
||
Com_Printf( "couldn't load include file %s\n", name );
|
||
return;
|
||
}
|
||
if ( len > UI_MAX_URCSIZE ) {
|
||
Com_Printf( "Include file too large, %i KB. Max size is %i KB\n", len/1024, UI_MAX_URCSIZE/1024 );
|
||
return;
|
||
}
|
||
|
||
uii.FS_Read( buffer, len, f );
|
||
buffer[len] = 0;
|
||
|
||
ptr = buffer;
|
||
token = COM_Parse( &ptr );
|
||
|
||
if ( post == qtrue ) {
|
||
if (!Q_strncmp(token, "menu",4)) {
|
||
COM_Parse( &ptr );
|
||
token = COM_Parse(&ptr);
|
||
}
|
||
}
|
||
|
||
while (*token) {
|
||
if ( !Q_strncmp( token, "resource", 8 ) ) {
|
||
menu->resPtr++;
|
||
if ( menu->resPtr >= UI_MAX_RESOURCES ) {
|
||
Com_Printf( "UI_ParseMenuToken: more than %i resources!\n", UI_MAX_RESOURCES );
|
||
menu->resPtr--;
|
||
return;
|
||
}
|
||
res = &menu->resources[menu->resPtr];
|
||
res->font = &uis.menuFont;
|
||
// uii.R_RegisterFont( "facfont-20", 0, &res->font ); //load standard font for resource
|
||
|
||
var = COM_Parse( &ptr );
|
||
if ( !Q_strncmp( var, "Label", 5 ) )
|
||
res->type = UI_RES_LABEL;
|
||
else if ( !Q_strncmp( var, "Button", 6 ) )
|
||
res->type = UI_RES_BUTTON;
|
||
else if ( !Q_strncmp( var, "Field", 5 ) )
|
||
res->type = UI_RES_FIELD;
|
||
else if ( !Q_strncmp( var, "CheckBox", 8 ) )
|
||
res->type = UI_RES_CHECKBOX;
|
||
else if ( !Q_strncmp( var, "PulldownMenuContainer", 21 ) )
|
||
res->type = UI_RES_PULLDOWN;
|
||
else if ( !Q_strncmp( var, "Slider", 6 ) )
|
||
res->type = UI_RES_SLIDER;
|
||
else Com_Printf( "UI_ParseMenuToken: unknown menu resource type %s\n", var );
|
||
|
||
var = COM_Parse( &ptr ) ;
|
||
if ( *var == '{' ) {
|
||
var = COM_Parse( &ptr );
|
||
while (*var != '}') {
|
||
UI_ParseMenuResource( var, &ptr, res, menu->offset );
|
||
var = COM_Parse( &ptr );
|
||
if (*var ==0) {
|
||
Com_Memset( res, 0, sizeof(uiResource_t) );
|
||
menu->resPtr--;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
token = COM_Parse( &ptr );
|
||
}
|
||
|
||
uii.FS_FCloseFile( f );
|
||
}
|
||
|
||
void UI_LoadURC( const char *name, uiMenu_t *menu ) {
|
||
fileHandle_t f;
|
||
int len;
|
||
char filename[MAX_QPATH];
|
||
char buffer[UI_MAX_URCSIZE];
|
||
const char *token;
|
||
char *ptr;
|
||
qboolean end;
|
||
|
||
uiMenulist_t* menulist;
|
||
long hash;
|
||
qboolean found;
|
||
|
||
Q_strncpyz( filename, "ui/", MAX_QPATH );
|
||
hash = generateHashValue(name);
|
||
found = qfalse;
|
||
for (menulist=hashTable[hash] ; menulist ; menulist=menulist->next) {
|
||
if (!Q_stricmp(name, menulist->name)) {
|
||
found = qtrue;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( found == qtrue )
|
||
Q_strncpyz( filename + 3, menulist->file, MAX_QPATH-3 );
|
||
else {
|
||
Q_strncpyz( filename + 3, name, MAX_QPATH-3 );
|
||
}
|
||
COM_DefaultExtension( filename, MAX_QPATH, ".urc" );
|
||
|
||
len = uii.FS_FOpenFile( filename, &f, FS_READ );
|
||
if (!f) {
|
||
Com_Printf( "couldn't load URC menu %s. file not found.\n", name );
|
||
return;
|
||
}
|
||
if ( len >= UI_MAX_URCSIZE ) {
|
||
Com_Printf( "URC file too large, %i KB. Max size is %i KB\n", len/1024, UI_MAX_URCSIZE/1024 );
|
||
return;
|
||
}
|
||
|
||
memset(menu,0,sizeof(uiMenu_t)); // su44 was here
|
||
|
||
uii.FS_Read( buffer, len, f );
|
||
buffer[len] = 0;
|
||
|
||
ptr = buffer;
|
||
token = COM_Parse( &ptr );
|
||
|
||
menu->resPtr = -1;
|
||
while (*token) {
|
||
end = UI_ParseMenuToken( token, &ptr, menu );
|
||
token = COM_Parse( &ptr );
|
||
}
|
||
if (!end)
|
||
Com_Printf( "UI_LoadURC hit end of file without end statement\n" );
|
||
|
||
uii.FS_FCloseFile( f );
|
||
if ( menu->postinclude[0] )
|
||
UI_LoadINC( menu->postinclude, menu, qtrue );
|
||
}
|
||
|
||
void UI_PushMenu( const char *name ) {
|
||
uiMenu_t *menu;
|
||
|
||
uis.MSP++;
|
||
if ( uis.MSP >= UI_MAX_MENUS ) {
|
||
Com_Printf( "UI_PushMenu: Menu Stack Overflow (%i).\n", UI_MAX_MENUS );
|
||
uis.MSP--;
|
||
return;
|
||
}
|
||
|
||
if ( !Q_strncmp( name, "main", 4 ) )
|
||
uis.stack[uis.MSP] = &uis.main;
|
||
else if ( !Q_strncmp( name, "connecting", 10 ) )
|
||
uis.stack[uis.MSP] = &uis.connecting;
|
||
else {
|
||
uis.CP++;
|
||
if ( uis.CP >= UI_MAX_MENUS ) {
|
||
Com_Printf( "UI_PushMenu: Menu Cache Overflow (%i).\n", UI_MAX_MENUS );
|
||
uis.CP--;
|
||
return;
|
||
}
|
||
menu = &uis.cache[uis.CP];
|
||
Com_Memset( menu, 0, sizeof(uiMenu_t) );
|
||
|
||
UI_LoadURC( name, menu );
|
||
|
||
menu->standard = qfalse;
|
||
uis.stack[uis.MSP] = menu;
|
||
}
|
||
|
||
// if ( !(uii.Key_GetCatcher() & KEYCATCH_UI) )
|
||
uii.Key_SetCatcher( KEYCATCH_UI );
|
||
}
|
||
|
||
void UI_PopMenu( void ) {
|
||
|
||
if ( uis.MSP >= 0 ) {
|
||
|
||
if ( uis.stack[uis.MSP]->standard == qfalse )
|
||
uis.CP--;
|
||
uis.MSP--;
|
||
}
|
||
if ( uis.MSP == -1 ) {
|
||
uii.Key_SetCatcher( uii.Key_GetCatcher() & ~KEYCATCH_UI );
|
||
uii.Key_ClearStates();
|
||
}
|
||
}
|
||
|
||
#define MENULIST_BUFSIZE 2*MAX_STRING_CHARS
|
||
void UI_FindMenus( void ) {
|
||
char *filelist, *namelist;
|
||
char *ptr, *ptr2;
|
||
int i, numFiles, fnameLen, nameptr;
|
||
char filebuf[MAX_QPATH];
|
||
|
||
filelist = (char*)UI_Alloc( MENULIST_BUFSIZE );
|
||
namelist = (char*)UI_Alloc( MENULIST_BUFSIZE );
|
||
|
||
numFiles = uii.FS_GetFileList( "ui", ".urc", filelist, MENULIST_BUFSIZE );
|
||
|
||
ptr = filelist;
|
||
nameptr = 0;
|
||
for (i = 0; i < numFiles; i++, ptr += fnameLen+1) {
|
||
uiMenulist_t *ml;
|
||
fileHandle_t f;
|
||
int hash;
|
||
Q_strncpyz( filebuf, "ui/", sizeof(filebuf) );
|
||
Q_strncpyz( filebuf + 3, ptr, sizeof( filebuf )-3 );
|
||
uii.FS_FOpenFile( filebuf, &f, FS_READ );
|
||
uii.FS_Read( filebuf, sizeof(filebuf), f );
|
||
uii.FS_FCloseFile( f );
|
||
ptr2 = filebuf;
|
||
|
||
if ( !Q_strncmp( COM_Parse(&ptr2), "menu", MAX_QPATH ) ){
|
||
Q_strncpyz( namelist+nameptr, COM_Parse(&ptr2), MENULIST_BUFSIZE-nameptr );
|
||
}
|
||
else {
|
||
Com_Printf( "Menu name not recognized in %s\n", ptr );
|
||
continue;
|
||
}
|
||
hash = generateHashValue( namelist + nameptr );
|
||
/*ml = hashTable[ hash ];
|
||
if ( ml ) {
|
||
while( ml->next )<29>
|
||
ml = ml->next;
|
||
ml->next = &uis.menuList[uis.MLP];
|
||
ml = ml->next;
|
||
}
|
||
else{
|
||
ml = &uis.menuList[uis.MLP];
|
||
hashTable[ hash ] = ml;
|
||
}*/
|
||
ml = &uis.menuList[ uis.MLP ];
|
||
if( !hashTable[ hash ] )
|
||
{
|
||
ml->next = NULL;
|
||
}
|
||
else
|
||
{
|
||
ml->next = hashTable[ hash ];
|
||
}
|
||
hashTable[ hash ] = ml;
|
||
ml->file = ptr;
|
||
ml->name = namelist+nameptr;
|
||
|
||
fnameLen = strlen(ptr);
|
||
nameptr += strlen(namelist+nameptr)+1;
|
||
if ( nameptr >= MENULIST_BUFSIZE ) {
|
||
Com_Printf( "Too many menus in place. Namebuffer overrun!\n" );
|
||
return;
|
||
}
|
||
uis.MLP++;
|
||
if ( uis.MLP >= UI_MAX_FILES ) {
|
||
Com_Printf( "Too many menus in place.\n" );
|
||
return;
|
||
}
|
||
}
|
||
}
|