mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-10 15:21:34 +00:00
a39565b783
... not quite content with where the project files lie but it is ok for now. ... compiling works fine so far (only tested mingw32 right now)
2153 lines
64 KiB
C
2153 lines
64 KiB
C
// Copyright (C) 1999-2000 Id Software, Inc.
|
|
//
|
|
//=================================================
|
|
//
|
|
// TiM: Just a reference for my whacky jargon in here
|
|
// Character = the player model as a whole group (ie kulhane )
|
|
// Model = the .model file used to build the character ( ie admiral, cadet etc)
|
|
// Skin = the skinset field in the .model file, dictating which .skins to use (ie red/teal/gold... )
|
|
// ADDENDUM: Skin = the .skinset file linked to the .model file
|
|
//
|
|
//=================================================
|
|
#include "ui_local.h"
|
|
|
|
#define PIC_ARROW_UP "menu/common/arrow_up_16.tga"
|
|
#define PIC_ARROW_DOWN "menu/common/arrow_dn_16.tga"
|
|
|
|
#define LOW_MEMORY (5 * 1024 * 1024)
|
|
|
|
#define MAX_PLAYERNAMELENGTH 21
|
|
|
|
#define MAX_RACES 64
|
|
#define MAX_GENDERS 64
|
|
|
|
static void PlayerModel_BuildList( void );
|
|
static void PlayerModel_SetMenuItems( void );
|
|
static void PlayerModel_MenuInit(int menuFrom);
|
|
|
|
//yes... a lot
|
|
#define MAX_PLAYERCHARS 256
|
|
#define MAX_PLAYERMODELS 64
|
|
#define MAX_PLAYERSKINS 32
|
|
|
|
#define MAX_MENULISTITEMS 12
|
|
|
|
#define MIN_SCROLLHEIGHT 8
|
|
#define MAX_SCROLLRANGE 236
|
|
#define MAX_SCROLLTOP 108
|
|
|
|
#define ID_MENUCHAR0 0
|
|
#define ID_MENUCHAR1 1
|
|
#define ID_MENUCHAR2 2
|
|
#define ID_MENUCHAR3 3
|
|
#define ID_MENUCHAR4 4
|
|
#define ID_MENUCHAR5 5
|
|
#define ID_MENUCHAR6 6
|
|
#define ID_MENUCHAR7 7
|
|
#define ID_MENUCHAR8 8
|
|
#define ID_MENUCHAR9 9
|
|
#define ID_MENUCHAR10 10
|
|
#define ID_MENUCHAR11 11
|
|
|
|
#define ID_UPARROW 100
|
|
#define ID_DNARROW 101
|
|
#define ID_BACK 102
|
|
#define ID_MAINMENU 103
|
|
#define ID_INGAMEMENU 104
|
|
|
|
#define ID_APPLY 105
|
|
|
|
#define ID_MODELSET 106
|
|
#define ID_SKINSET 107
|
|
|
|
#define ID_RACEFILTER 108
|
|
#define ID_GENDERFILTER 109
|
|
|
|
#define ID_SCROLLBAR 110
|
|
|
|
#define ID_SETTINGS 20
|
|
|
|
typedef struct
|
|
{
|
|
int orgChar;
|
|
int orgModel;
|
|
int orgSkin;
|
|
} storedData_t;
|
|
|
|
typedef struct
|
|
{
|
|
char charName[36];
|
|
int race;
|
|
int gender;
|
|
int index;
|
|
} charData_t;
|
|
|
|
typedef struct
|
|
{
|
|
qboolean mouseDown;
|
|
qboolean doubleStep;
|
|
|
|
int yStart;
|
|
} scrollData_t;
|
|
|
|
typedef struct
|
|
{
|
|
char filterName[32];
|
|
int filterIndex;
|
|
} filterData_t;
|
|
|
|
typedef struct
|
|
{
|
|
menuframework_s menu;
|
|
int prevMenu;
|
|
menubitmap_s mainmenu;
|
|
menubitmap_s back;
|
|
menubitmap_s player;
|
|
|
|
menubitmap_s charMenu[MAX_MENULISTITEMS];
|
|
|
|
menubitmap_s upArrow;
|
|
menubitmap_s dnArrow;
|
|
|
|
menulist_s charModel;
|
|
menulist_s charSkin;
|
|
|
|
menulist_s raceFilter;
|
|
menulist_s genderFilter;
|
|
|
|
menubitmap_s apply;
|
|
|
|
menubitmap_s data;
|
|
menubitmap_s model;
|
|
|
|
menuaction_s scrollBar;
|
|
|
|
qhandle_t corner_ll_4_4;
|
|
qhandle_t corner_ll_4_18;
|
|
qhandle_t corner_lr_4_18;
|
|
qhandle_t corner_lr_18_4;
|
|
qhandle_t corner_ur_18_18;
|
|
|
|
qhandle_t playerIcon;
|
|
|
|
//menutext_s modelname;
|
|
//menutext_s skinname;
|
|
//menutext_s skinnameviewed;
|
|
menutext_s playername;
|
|
playerInfo_t playerinfo;
|
|
|
|
int numChars;
|
|
charData_t charNames[MAX_PLAYERCHARS]/*[128]*/;
|
|
char modelNames[MAX_PLAYERMODELS][32];
|
|
char skinNames[MAX_PLAYERMODELS][MAX_PLAYERSKINS][32];
|
|
//To save loading time, and the fact that loading data from txt files on the fly per spin cycle,
|
|
//can sometimes overload EF if the user gets button happy, We'll make it all data is loaded and consolidated on character choosing
|
|
|
|
//TiM - I think this is wasteful as all heck, but it can't be helped
|
|
//The model functions need the data stored as uniform char arrays,
|
|
//and the spin controls need them stored as char pointers. O_o
|
|
//But not only that, but since these are memory pointers, applying strUpr
|
|
//To them destroys the case in the arrays above.
|
|
//Hacky this may be, but there's no way around it without some totally Carmack-coding
|
|
//Raven had to do this too, so it's an inherent flaw in Q3 coding
|
|
char charNamesUpr[MAX_PLAYERCHARS][64];
|
|
char modelNamesUpr[MAX_PLAYERMODELS][64];
|
|
char skinNamesUpr[MAX_PLAYERMODELS][MAX_PLAYERSKINS][64];
|
|
|
|
char* modelList[MAX_PLAYERMODELS];
|
|
char* skinList[MAX_PLAYERSKINS];
|
|
|
|
char modelData[64];
|
|
char modelName[32];
|
|
|
|
//char raceNames[MAX_RACES][32];
|
|
filterData_t raceList[MAX_RACES];
|
|
char* raceNames[MAX_RACES];
|
|
int numRaces;
|
|
|
|
filterData_t genderList[MAX_GENDERS];
|
|
char* genderNames[MAX_GENDERS];
|
|
int numGenders;
|
|
|
|
int selectedChar;
|
|
int scrollOffset;
|
|
|
|
storedData_t storedData; //Original Skin Data
|
|
|
|
scrollData_t scrollData;
|
|
} playermodel_t;
|
|
|
|
static playermodel_t s_playermodel;
|
|
|
|
static int QDECL FilterList_Compare( const void *ptr1, const void *ptr2 );
|
|
static int QDECL CharMediaList_Compare( const void *ptr1, const void *ptr2 );
|
|
static void PlayerModel_DrawLoading( void );
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_CheckInArray
|
|
TiM: When building an array of races etc,
|
|
run it through this list to prevent multiple redundancy
|
|
Mental Note: Study Pointer Arithmetic more....
|
|
=================
|
|
*/
|
|
|
|
static int PlayerModel_CheckInFilter( char* string, filterData_t *filter, int width, int *num ) {
|
|
int i=0;
|
|
|
|
while( filter[i].filterName[0] && i < width ) {
|
|
if ( !Q_stricmp( filter[i].filterName, string ) ) {
|
|
//Com_Printf( S_COLOR_RED "String %s already in cell %i\n", array[i], i );
|
|
return i;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
if ( !filter[i].filterName[0] && i < width )
|
|
{
|
|
Q_strncpyz( filter[i].filterName, string, 32 );
|
|
filter[i].filterIndex = i;
|
|
|
|
*num = *num + 1; //aah I see. You can't call *num++ since that increments the address, not the value XD
|
|
}
|
|
|
|
//Com_Printf( S_COLOR_RED "Added %s to cell %i", array[i], i );
|
|
|
|
return i;
|
|
}
|
|
|
|
//static int PlayerModel_CheckInArray( char* string, void *array, size_t length ) {
|
|
// int i=0;
|
|
// char *str=NULL;
|
|
//
|
|
// for (i = 0; i < length; i++ ) {
|
|
// str = ((char **)array)[i]; //funky, yet awesome use of the void type lol
|
|
//
|
|
// Com_Printf( S_COLOR_RED ": %s\n", str );
|
|
//
|
|
// if ( !str )
|
|
// break;
|
|
//
|
|
// if ( !Q_stricmp( str, string ) ) {
|
|
// return i;
|
|
// }
|
|
// }
|
|
//
|
|
// if ( i < length )
|
|
// {
|
|
// Q_strncpyz( ((char **)array)[i], string, length );
|
|
// }
|
|
//
|
|
// return i;
|
|
//}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_LoadAvailableModels
|
|
TiM: Loads a list of all the .model
|
|
files there are in a character's directory.
|
|
|
|
NB: In Spin Control menu types, the number
|
|
of elements is calced on init only. Each
|
|
time we refresh this, we'll need to update ourselves.
|
|
=================
|
|
*/
|
|
static int PlayerModel_LoadAvailableModels( void ) {
|
|
int i;
|
|
int j;
|
|
int numFiles;
|
|
char fileList[4096]; //Hopefully, this will never be exceeded ROFL
|
|
char* filePtr;
|
|
int fileLen;
|
|
int strLen;
|
|
char* temp;
|
|
char fileRoute[MAX_QPATH];
|
|
|
|
if ( s_playermodel.selectedChar == -1 )
|
|
return -1;
|
|
|
|
Com_sprintf( fileRoute, MAX_QPATH,
|
|
"models/players_rpgx/%s",
|
|
s_playermodel.charNames[s_playermodel.selectedChar].charName );
|
|
|
|
//Get our num files
|
|
memset( &fileList, 0, sizeof ( fileList ) );
|
|
numFiles = trap_FS_GetFileList( fileRoute, ".model", fileList, sizeof(fileList) );
|
|
|
|
if ( numFiles <=0 )
|
|
return -1;
|
|
|
|
//Convert to ptr for easier manip
|
|
filePtr = fileList;
|
|
|
|
memset( &s_playermodel.modelNames, 0, sizeof( s_playermodel.modelNames ) );
|
|
memset( &s_playermodel.modelNamesUpr, 0, sizeof( s_playermodel.modelNamesUpr ) );
|
|
memset( s_playermodel.modelList, 0, sizeof( s_playermodel.modelList ) );
|
|
|
|
//iterate thru all the null terminations in this thing
|
|
/**
|
|
* RPG-X | Phenix | 27/03/2007
|
|
* Made for loop in reverse to correctly order the models. (Task#39)
|
|
*/
|
|
j = 0;
|
|
for ( i = 0; j < MAX_PLAYERMODELS && i < numFiles; i++, filePtr += fileLen+1 ) {
|
|
fileLen = strlen( filePtr );
|
|
|
|
if ( !fileLen || !filePtr )
|
|
break;
|
|
|
|
//TiM - this shouldn't be possible
|
|
if ( strchr(filePtr,'/') || strchr(filePtr,'\\') )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
temp = filePtr;
|
|
|
|
//TiM: Strip extension
|
|
strLen = strlen( temp );
|
|
if ( strLen > 6 && !Q_stricmp( temp + strLen - 6, ".model" ) ) {
|
|
temp[strLen-6] = '\0';
|
|
}
|
|
|
|
Q_strncpyz( s_playermodel.modelNames[j], temp, sizeof ( s_playermodel.modelNames[j] ) );
|
|
j++;
|
|
}
|
|
|
|
//sort the models, then feed them to the rest of the variables
|
|
qsort( s_playermodel.modelNames, j, sizeof( s_playermodel.modelNames[0] ), CharMediaList_Compare );
|
|
|
|
for ( i = 0; i < j; i++ )
|
|
{
|
|
//TiM: A bit of a hacky ovveride here.
|
|
//Make it so 'main' is set by default
|
|
if ( !Q_stricmp( s_playermodel.modelNames[i], DEFAULT_MODEL ) ) {
|
|
s_playermodel.charModel.curvalue = i;
|
|
}
|
|
|
|
Q_strncpyz( s_playermodel.modelNamesUpr[i], s_playermodel.modelNames[i], sizeof( s_playermodel.modelNamesUpr[i] ) );
|
|
s_playermodel.modelList[i] = Q_strupr( s_playermodel.modelNamesUpr[i] );
|
|
}
|
|
|
|
return j;
|
|
}
|
|
|
|
/*
|
|
================
|
|
PlayerModel_LoadAvailableSkins
|
|
TiM: Access our selected .model file, get the skin name framework and
|
|
fill the skin array with all the skins we found.
|
|
|
|
Hoi... this could get complicated... O_o
|
|
================
|
|
*/
|
|
static void PlayerModel_LoadAvailableSkins( void ) {
|
|
int j=0;
|
|
int i=0;
|
|
int fileLen;
|
|
char fileBuffer[20000];
|
|
int numFiles;
|
|
char fileListBuffer[10000];
|
|
char* filePtr;
|
|
fileHandle_t f;
|
|
char filePath[MAX_QPATH];
|
|
char* token;
|
|
char skinSetFrame[MAX_QPATH];
|
|
int strLen;
|
|
char* star;
|
|
int numSkins=0;
|
|
int starFlags;
|
|
char skins[MAX_PLAYERSKINS][64];
|
|
|
|
if ( s_playermodel.selectedChar == -1 )
|
|
return;
|
|
|
|
/*memset( s_playermodel.skinNames, 0, sizeof( s_playermodel.skinNames ) );
|
|
memset( s_playermodel.skinNamesUpr, 0, sizeof( s_playermodel.skinNamesUpr ) );
|
|
*/
|
|
|
|
//TiM: Ugh, this is the only way to ensure completely flushing out the skins list on each model
|
|
for ( i = 0; i < MAX_PLAYERMODELS; i++ )
|
|
{
|
|
for( j = 0; j < MAX_PLAYERSKINS; j++ )
|
|
{
|
|
s_playermodel.skinNames[i][j][0] = '\0';
|
|
s_playermodel.skinNamesUpr[i][j][0] = '\0';
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < MAX_PLAYERSKINS; i++ )
|
|
{
|
|
s_playermodel.skinList[i] = NULL;
|
|
skins[i][0] = '\0';
|
|
}
|
|
|
|
Com_sprintf( filePath, MAX_QPATH, "models/players_rpgx/%s", s_playermodel.charNames[s_playermodel.selectedChar].charName );
|
|
|
|
//first load the list of .skinset files we have
|
|
numFiles = trap_FS_GetFileList( filePath,
|
|
".skinset", fileListBuffer, sizeof(fileListBuffer) );
|
|
|
|
if ( numFiles <= 0 )
|
|
{
|
|
Com_Printf( S_COLOR_RED "ERROR: No Skinset files found!\n" );
|
|
return;
|
|
}
|
|
|
|
filePtr = fileListBuffer;
|
|
|
|
j=0;
|
|
for ( i = 0; i < MAX_PLAYERSKINS && i < numFiles; i++, filePtr += strLen + 1 )
|
|
{
|
|
strLen = strlen( filePtr );
|
|
|
|
if ( !strLen )
|
|
break;
|
|
|
|
//TiM - this shouldn't be possible
|
|
if ( strchr(filePtr,'/') || strchr(filePtr,'\\') )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
token = filePtr;
|
|
|
|
if ( strLen > 8 && !Q_stricmp( token + (strLen - 8), ".skinset" ) )
|
|
{
|
|
token[strLen - 8] = '\0';
|
|
}
|
|
|
|
Q_strncpyz( skins[j], token, sizeof( skins[j] ) );
|
|
|
|
//Com_Printf( S_COLOR_RED "%s\n", skins[j] );
|
|
j++;
|
|
}
|
|
//Com_Printf( "Model Break\n", skins[j] );
|
|
|
|
//Com_Printf( "%s\n", s_playermodel.modelNames[2] );
|
|
j = 0;
|
|
while ( j < MAX_PLAYERMODELS )
|
|
{
|
|
if ( !s_playermodel.modelNames[j][0] )
|
|
break;
|
|
|
|
Com_sprintf( filePath, sizeof( filePath ),
|
|
"models/players_rpgx/%s/%s.model",
|
|
s_playermodel.charNames[s_playermodel.selectedChar].charName,
|
|
s_playermodel.modelNames[j] );
|
|
|
|
//load the .model data into our active buffer
|
|
fileLen = trap_FS_FOpenFile( filePath, &f, FS_READ);
|
|
|
|
if ( fileLen <= 0 ) {
|
|
Com_Printf( S_COLOR_RED "File not found: %s\n", filePath );
|
|
return;
|
|
}
|
|
|
|
if ( fileLen > 20000 ) {
|
|
Com_Printf( S_COLOR_RED "File exceeded maximum size: %s\n", filePath );
|
|
return;
|
|
}
|
|
|
|
memset( &fileBuffer, 0, sizeof( fileBuffer ) );
|
|
trap_FS_Read( fileBuffer, sizeof( fileBuffer ), f );
|
|
|
|
trap_FS_FCloseFile( f );
|
|
|
|
if ( !fileBuffer[0] )
|
|
return;
|
|
|
|
filePtr = fileBuffer;
|
|
|
|
COM_BeginParseSession();
|
|
|
|
memset( skinSetFrame, 0, sizeof( skinSetFrame ) );
|
|
while ( 1 ) {
|
|
|
|
token = COM_Parse( &filePtr );
|
|
if ( !token || !filePtr )
|
|
break;
|
|
|
|
if ( !Q_stricmp( token, "skinSet" ) ) {
|
|
if ( COM_ParseString( &filePtr, &token ) ) {
|
|
continue;
|
|
}
|
|
|
|
Q_strncpyz( skinSetFrame, token, sizeof( skinSetFrame ) );
|
|
break;
|
|
}
|
|
}
|
|
|
|
//set a default one if nothing found
|
|
if ( !skinSetFrame[0] )
|
|
{
|
|
Com_sprintf( skinSetFrame, sizeof( skinSetFrame ), "%s_*", s_playermodel.modelNames[j]);
|
|
}
|
|
|
|
if ( !strchr( skinSetFrame, '*' ) )
|
|
{
|
|
Com_Printf( S_COLOR_RED "ERROR: No '*' in skinset define for character: %s/%s\n", s_playermodel.charNames[s_playermodel.selectedChar].charName, s_playermodel.modelNames[j] );
|
|
continue;
|
|
}
|
|
|
|
//okay... this is tricky.
|
|
//basically, we're starting off with a possible
|
|
//"main_*, "*_main", or "ma_*_in" set up, where we have to see
|
|
//if a file name like "red_main" is valid, and if it is, isolate the "red" from it
|
|
star = strstr( skinSetFrame, "*" );
|
|
|
|
////star is at the end
|
|
if ( (int)(star - skinSetFrame) + 1 == (int)strlen(skinSetFrame) )
|
|
{
|
|
Q_strncpyz( filePath, skinSetFrame, sizeof( filePath ) );
|
|
filePath[strlen(filePath)-1] = '\0';
|
|
|
|
starFlags = 1;
|
|
}
|
|
//star is at the front
|
|
else if ( (int)(star - skinSetFrame) == 0 )
|
|
{
|
|
star++; //QVMNOTE
|
|
Q_strncpyz( filePath, star, sizeof( filePath ) );
|
|
starFlags = 2;
|
|
}
|
|
else
|
|
starFlags = 0;
|
|
|
|
for ( i = 0; i < MAX_PLAYERSKINS; i++ )
|
|
{
|
|
if ( !skins[i] || !skins[i][0] )
|
|
break;
|
|
|
|
////star is at the end
|
|
if ( starFlags == 1 )
|
|
{
|
|
if ( strstr( skins[i], filePath ) != NULL )
|
|
{
|
|
Q_strncpyz( s_playermodel.skinNames[j][numSkins], skins[i] + strlen(filePath), sizeof( s_playermodel.skinNames[j][numSkins] ) );
|
|
//Q_strncpyz( s_playermodel.skinNamesUpr[j][numSkins], skins[i] + strlen(filePath), sizeof( s_playermodel.skinNamesUpr[j][numSkins] ) );
|
|
numSkins++;
|
|
}
|
|
}
|
|
//star is at the front
|
|
else if ( starFlags == 2 )
|
|
{
|
|
if ( (token = strstr( skins[i], filePath ) ) != NULL )
|
|
{
|
|
Q_strncpyz( s_playermodel.skinNames[j][numSkins], skins[i], (int)(strlen(skins[i]) - strlen(token))+1 );
|
|
//Q_strncpyz( s_playermodel.skinNamesUpr[j][numSkins], skins[i], (int)(strlen(skins[i]) - strlen(token))+1 );
|
|
numSkins++;
|
|
}
|
|
}
|
|
//else
|
|
//TiM | Come back to this later...
|
|
//For now, document it as the star must be at the front or back
|
|
}
|
|
|
|
qsort( s_playermodel.skinNames[j], numSkins, sizeof( s_playermodel.skinNames[j][0] ), CharMediaList_Compare );
|
|
|
|
for ( i = 0; i < numSkins; i++ )
|
|
{
|
|
Q_strncpyz( s_playermodel.skinNamesUpr[j][i], s_playermodel.skinNames[j][i], sizeof( s_playermodel.skinNamesUpr[j][i] ) );
|
|
//Com_Printf( S_COLOR_BLUE "%s\n", s_playermodel.skinNamesUpr[j][i] );
|
|
}
|
|
|
|
numSkins=0;
|
|
j++;
|
|
}
|
|
}
|
|
|
|
static int QDECL CharMediaList_Compare( const void *ptr1, const void *ptr2 )
|
|
{
|
|
const char *str1, *str2;
|
|
char chr1, chr2;
|
|
|
|
str1 = (const char *)ptr1;
|
|
str2 = (const char *)ptr2;
|
|
|
|
//Com_Printf( "STR1: %s STR2: %s\n", str1, str2 );
|
|
|
|
//default data always comes first
|
|
//Actually... we came this far, let's just make it all alphabetic
|
|
/*if ( !Q_stricmp( str1, DEFAULT_SKIN ) || !Q_stricmp( str1, DEFAULT_MODEL ) )
|
|
{
|
|
return -1;
|
|
}
|
|
else if ( !Q_stricmp( str2, DEFAULT_SKIN ) || !Q_stricmp( str2, DEFAULT_MODEL ) )
|
|
{
|
|
return 1;
|
|
}*/
|
|
|
|
chr1 = *str1;
|
|
chr2 = *str2;
|
|
|
|
//double check they're lower-case. case matters
|
|
if ( chr1 >= 'A' && chr1 <= 'Z' ) chr1 += 32;
|
|
if ( chr2 >= 'A' && chr2 <= 'Z' ) chr2 += 32;
|
|
|
|
//cascade the alphabetical list
|
|
while( chr1 == chr2 && chr1 && chr2)
|
|
{
|
|
chr1 = *(str1++);
|
|
chr2 = *(str2++);
|
|
}
|
|
|
|
//based off of their ASCII order.
|
|
return ((int)chr1 - (int)chr2);
|
|
}
|
|
|
|
static int QDECL FilterList_Compare( const void *ptr1, const void *ptr2 )
|
|
{
|
|
const char *str1, *str2;
|
|
char chr1, chr2;
|
|
|
|
str1 = ((filterData_t *)ptr1)->filterName;
|
|
str2 = ((filterData_t *)ptr2)->filterName;
|
|
|
|
//hacky override. Make sure 'All' comes first.
|
|
if ( !Q_stricmp( str1, "ALL" ) )
|
|
return -1;
|
|
|
|
chr1 = *str1;
|
|
chr2 = *str2;
|
|
|
|
//double check they're lower-case. case matters
|
|
if ( chr1 >= 'A' && chr1 <= 'Z' ) chr1 += 32;
|
|
if ( chr2 >= 'A' && chr2 <= 'Z' ) chr2 += 32;
|
|
|
|
//cascade the alphabetical list
|
|
while( chr1 == chr2 && chr1 && chr2)
|
|
{
|
|
if ( *(str1+1) == '\0' || *(str2+1) == '\0' )
|
|
break;
|
|
|
|
chr1 = *(str1++);
|
|
chr2 = *(str2++);
|
|
}
|
|
|
|
//based off of their ASCII order.
|
|
return ((int)chr1 - (int)chr2);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_PopulateSkinsList
|
|
=================
|
|
*/
|
|
static int PlayerModel_PopulateSkinsList ( void ) {
|
|
int i;
|
|
int j;
|
|
|
|
if ( !s_playermodel.skinNames[s_playermodel.charModel.curvalue][0][0] ) {
|
|
Com_Printf( S_COLOR_RED "ERROR: No valid skins found.\n" );
|
|
return -1;
|
|
}
|
|
|
|
//just to ensure complete erasure of previous entries
|
|
for( i = 0; i < MAX_PLAYERSKINS; i++ )
|
|
s_playermodel.skinList[i] = NULL;
|
|
|
|
/**
|
|
* RPG-X | Phenix | 27/03/2007
|
|
* For loop reversed to output list in alphabetical order. (Task #39)
|
|
* RPG-X | TiM | 30/4/2007
|
|
* Reverted as it was causing an error with skin names not matching
|
|
*/
|
|
j = 0;
|
|
//for ( i = (MAX_PLAYERSKINS - 1); i >= 0; i-- )
|
|
for ( i = 0; i < MAX_PLAYERSKINS; i++ )
|
|
{
|
|
if ( s_playermodel.skinNames[s_playermodel.charModel.curvalue][i][0] ) //!
|
|
{
|
|
if ( !Q_stricmp( s_playermodel.skinNames[s_playermodel.charModel.curvalue][i], DEFAULT_SKIN ) )
|
|
s_playermodel.charSkin.curvalue = j; //j;
|
|
|
|
s_playermodel.skinList[j] = s_playermodel.skinNamesUpr[s_playermodel.charModel.curvalue][i];
|
|
|
|
Q_strupr( s_playermodel.skinList[j] );
|
|
|
|
j++;
|
|
}
|
|
}
|
|
|
|
return j;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_OffsetCharList
|
|
|
|
TiM: Called whenever we scroll the model list.
|
|
So it'll cycle the value of each one up and down.
|
|
The parameter is a pointer so the updated
|
|
value will be passed through the scope to the calling
|
|
code area. :)
|
|
==================
|
|
*/
|
|
|
|
static void PlayerModel_OffsetCharList( int* offset ) {
|
|
char* buffer; //intermediate value so performing strupr won't pwn our case sensitive data
|
|
int i;
|
|
|
|
if ( *offset < 0 ) {
|
|
*offset = 0;
|
|
}
|
|
|
|
if ( ( s_playermodel.numChars > MAX_MENULISTITEMS) && (*offset > (s_playermodel.numChars - MAX_MENULISTITEMS ) ) ) {
|
|
*offset = (s_playermodel.numChars - MAX_MENULISTITEMS );
|
|
}
|
|
|
|
for ( i = 0; i < MAX_MENULISTITEMS; i++ ) {
|
|
buffer = s_playermodel.charNamesUpr[i + *offset];
|
|
//Q_strncpyz( buffer, s_playermodel.charNames[i + *offset], sizeof ( buffer ) );
|
|
|
|
//Com_Printf( "Buffer - %s, %s\n", buffer, s_playermodel.charNames[1] );
|
|
|
|
if ( !buffer[0] ) {
|
|
if ( s_playermodel.charMenu[i].generic.flags & ( QMF_INACTIVE | QMF_HIDDEN ) ) {
|
|
break;
|
|
}
|
|
else {
|
|
s_playermodel.charMenu[i].generic.flags = ( QMF_INACTIVE | QMF_HIDDEN );
|
|
continue;
|
|
}
|
|
}
|
|
|
|
s_playermodel.charMenu[i].generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
s_playermodel.charMenu[i].textPtr = buffer;
|
|
|
|
Q_strupr( s_playermodel.charMenu[i].textPtr );
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_RebuildCharMenu
|
|
|
|
TiM: Called when we scroll the races/gender button.
|
|
Rebuild the main list based on the new parameters
|
|
=================
|
|
*/
|
|
static void PlayerModel_RebuildCharMenu( void ) {
|
|
int i;
|
|
qboolean raceValid=qfalse;
|
|
qboolean genderValid=qfalse;
|
|
|
|
s_playermodel.numChars = 0;
|
|
memset( &s_playermodel.charNamesUpr, 0, sizeof( s_playermodel.charNamesUpr ) );
|
|
|
|
i = 0;
|
|
while ( i < MAX_PLAYERCHARS ) {
|
|
if ( !s_playermodel.charNames[i].charName[0] )
|
|
break;
|
|
|
|
raceValid = s_playermodel.raceFilter.curvalue == 0 ||
|
|
( s_playermodel.raceList[s_playermodel.raceFilter.curvalue].filterIndex == s_playermodel.charNames[i].race );
|
|
|
|
genderValid = s_playermodel.genderFilter.curvalue == 0 ||
|
|
( s_playermodel.genderList[s_playermodel.genderFilter.curvalue].filterIndex == s_playermodel.charNames[i].gender );
|
|
|
|
//Com_Printf( "Char %s valid: %i %i\n", s_playermodel.charNames[i].charName, raceValid, genderValid );
|
|
|
|
if ( raceValid && genderValid )
|
|
{
|
|
Q_strncpyz( s_playermodel.charNamesUpr[s_playermodel.numChars], s_playermodel.charNames[i].charName, sizeof( s_playermodel.charNamesUpr[s_playermodel.numChars] ) );
|
|
|
|
if ( s_playermodel.raceFilter.curvalue == 0 && s_playermodel.genderFilter.curvalue == 0 )
|
|
s_playermodel.charNames[s_playermodel.numChars].index = -1;
|
|
else
|
|
s_playermodel.charNames[s_playermodel.numChars].index = i;
|
|
|
|
s_playermodel.numChars++;
|
|
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
if ( s_playermodel.numChars < MAX_MENULISTITEMS ) {
|
|
s_playermodel.upArrow.generic.flags = ( QMF_INACTIVE | QMF_GRAYED );
|
|
s_playermodel.dnArrow.generic.flags = ( QMF_INACTIVE | QMF_GRAYED );
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.upArrow.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
s_playermodel.dnArrow.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
|
|
s_playermodel.scrollOffset = 0;
|
|
PlayerModel_OffsetCharList( &s_playermodel.scrollOffset );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_SpinPlayer
|
|
=================
|
|
*/
|
|
static void PlayerModel_SpinPlayer( void* ptr, int event)
|
|
{
|
|
if ( event == QM_ACTIVATED )
|
|
{
|
|
uis.spinView = qtrue;
|
|
uis.cursorpx = uis.cursorx;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_UpdateModel
|
|
=================
|
|
*/
|
|
static void PlayerModel_UpdateModel( void )
|
|
{
|
|
vec3_t viewangles;
|
|
vec3_t moveangles;
|
|
|
|
memset( &s_playermodel.playerinfo, 0, sizeof(playerInfo_t) );
|
|
|
|
viewangles[YAW] = uis.lastYaw;
|
|
viewangles[PITCH] = 0;
|
|
viewangles[ROLL] = 0;
|
|
VectorClear( moveangles );
|
|
|
|
UI_PlayerInfo_SetModel( &s_playermodel.playerinfo, s_playermodel.modelData );
|
|
UI_PlayerInfo_SetInfo( &s_playermodel.playerinfo, BOTH_WALK1, BOTH_WALK1, viewangles, moveangles, WP_0, trap_Cvar_VariableValue( "height" ), trap_Cvar_VariableValue( "weight" ), qfalse );
|
|
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_SaveChanges
|
|
=================
|
|
*/
|
|
static void PlayerModel_SaveChanges( void )
|
|
{
|
|
trap_Cvar_Set( "model", va("%s/%s/%s",
|
|
s_playermodel.charNames[s_playermodel.selectedChar].charName,
|
|
s_playermodel.modelNames[s_playermodel.charModel.curvalue],
|
|
s_playermodel.skinNames[s_playermodel.charModel.curvalue][s_playermodel.charSkin.curvalue] ) );
|
|
|
|
//Set backup data
|
|
s_playermodel.storedData.orgChar = s_playermodel.selectedChar;
|
|
s_playermodel.storedData.orgModel = s_playermodel.charModel.curvalue;
|
|
s_playermodel.storedData.orgSkin = s_playermodel.charSkin.curvalue;
|
|
|
|
Q_strncpyz( s_playermodel.modelData, UI_Cvar_VariableString( "model" ), sizeof ( s_playermodel.modelData ) );
|
|
PlayerModel_UpdateModel( );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
PlayerModel_CheckForChange
|
|
==================
|
|
*/
|
|
static void PlayerModel_CheckForChange( void ) {
|
|
qboolean enableSaveButton=qfalse;
|
|
|
|
if ( s_playermodel.storedData.orgChar != s_playermodel.selectedChar )
|
|
enableSaveButton = qtrue;
|
|
|
|
if ( s_playermodel.storedData.orgModel != s_playermodel.charModel.curvalue )
|
|
enableSaveButton = qtrue;
|
|
|
|
if ( s_playermodel.storedData.orgSkin != s_playermodel.charSkin.curvalue )
|
|
enableSaveButton = qtrue;
|
|
|
|
if ( s_playermodel.charSkin.numitems == 0 )
|
|
enableSaveButton = qfalse;
|
|
|
|
if ( s_playermodel.charModel.numitems == 0 )
|
|
enableSaveButton = qfalse;
|
|
|
|
if ( enableSaveButton ) {
|
|
s_playermodel.apply.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
else {
|
|
s_playermodel.apply.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_SetupScrollBar
|
|
=================
|
|
*/
|
|
static void PlayerModel_SetupScrollBar( menuaction_s *bar )
|
|
{
|
|
int height;
|
|
|
|
//first make sure it's worth enabling this at all
|
|
if ( s_playermodel.numChars <= MAX_MENULISTITEMS )
|
|
{
|
|
bar->generic.flags = QMF_INACTIVE | QMF_HIDDEN;
|
|
return;
|
|
}
|
|
|
|
//show the bar
|
|
bar->generic.flags &= ~(QMF_INACTIVE | QMF_HIDDEN);
|
|
|
|
//calculate the necessary height of the bar
|
|
//by default, assume 1 pixel per offset
|
|
height = ( MAX_SCROLLRANGE) - ( s_playermodel.numChars - MAX_MENULISTITEMS );
|
|
|
|
//ensure box doesn't get too small
|
|
if ( height < MIN_SCROLLHEIGHT )
|
|
{
|
|
//double the step in that case
|
|
//a bit hacky, but no need for 3 since the limit isn't that high
|
|
height = ( MAX_SCROLLRANGE ) - ( s_playermodel.numChars * 0.5 - MAX_MENULISTITEMS );
|
|
s_playermodel.scrollData.doubleStep = qtrue;
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.scrollData.doubleStep = qfalse;
|
|
}
|
|
|
|
//reset to top
|
|
bar->generic.y = bar->generic.top = MAX_SCROLLTOP;
|
|
|
|
bar->height = height;
|
|
bar->generic.bottom = bar->generic.y + height;
|
|
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_UpdateScrollBar
|
|
=================
|
|
*/
|
|
static void PlayerModel_UpdateScrollBar( menuaction_s *bar )
|
|
{
|
|
bar->generic.y = MAX_SCROLLTOP + s_playermodel.scrollOffset*(s_playermodel.scrollData.doubleStep ? 0.5 : 1);
|
|
bar->generic.top = bar->generic.y;
|
|
bar->generic.bottom = bar->generic.top + bar->height;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_MenuEvent
|
|
=================
|
|
*/
|
|
static void PlayerModel_MenuEvent( void* ptr, int event )
|
|
{
|
|
|
|
if (event != QM_ACTIVATED)
|
|
return;
|
|
|
|
switch (((menucommon_s*)ptr)->id)
|
|
{
|
|
case ID_BACK:
|
|
//PlayerModel_SaveChanges();
|
|
UI_PopMenu();
|
|
break;
|
|
|
|
case ID_MAINMENU:
|
|
//PlayerModel_SaveChanges();
|
|
UI_MainMenu();
|
|
break;
|
|
|
|
case ID_INGAMEMENU:
|
|
//PlayerModel_SaveChanges();
|
|
UI_InGameMenu();
|
|
break;
|
|
|
|
case ID_SETTINGS:
|
|
UI_PopMenu();
|
|
//PlayerModel_SaveChanges();
|
|
UI_PlayerSettingsMenu(s_playermodel.prevMenu);
|
|
break;
|
|
|
|
case ID_DNARROW:
|
|
s_playermodel.scrollOffset++;
|
|
PlayerModel_OffsetCharList( &s_playermodel.scrollOffset );
|
|
|
|
if ( !(s_playermodel.scrollBar.generic.flags & QMF_INACTIVE ) )
|
|
PlayerModel_UpdateScrollBar( &s_playermodel.scrollBar );
|
|
break;
|
|
|
|
case ID_UPARROW:
|
|
s_playermodel.scrollOffset--;
|
|
PlayerModel_OffsetCharList( &s_playermodel.scrollOffset );
|
|
|
|
if ( !(s_playermodel.scrollBar.generic.flags & QMF_INACTIVE ) )
|
|
PlayerModel_UpdateScrollBar( &s_playermodel.scrollBar );
|
|
break;
|
|
|
|
case ID_MODELSET:
|
|
s_playermodel.charSkin.numitems = PlayerModel_PopulateSkinsList();
|
|
|
|
if ( s_playermodel.charSkin.numitems != -1 )
|
|
{
|
|
s_playermodel.charSkin.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.skinList[0] = "NONE";
|
|
s_playermodel.charSkin.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
s_playermodel.charSkin.numitems = 0;
|
|
}
|
|
break;
|
|
|
|
case ID_APPLY:
|
|
PlayerModel_SaveChanges();
|
|
break;
|
|
|
|
case ID_GENDERFILTER:
|
|
PlayerModel_RebuildCharMenu();
|
|
PlayerModel_SetupScrollBar( &s_playermodel.scrollBar );
|
|
break;
|
|
|
|
case ID_RACEFILTER:
|
|
PlayerModel_RebuildCharMenu();
|
|
PlayerModel_SetupScrollBar( &s_playermodel.scrollBar );
|
|
break;
|
|
|
|
case ID_MENUCHAR0:
|
|
case ID_MENUCHAR1:
|
|
case ID_MENUCHAR2:
|
|
case ID_MENUCHAR3:
|
|
case ID_MENUCHAR4:
|
|
case ID_MENUCHAR5:
|
|
case ID_MENUCHAR6:
|
|
case ID_MENUCHAR7:
|
|
case ID_MENUCHAR8:
|
|
case ID_MENUCHAR9:
|
|
case ID_MENUCHAR10:
|
|
case ID_MENUCHAR11:
|
|
{
|
|
int temp;
|
|
int oldChar = s_playermodel.selectedChar;
|
|
|
|
s_playermodel.selectedChar = ( ((menucommon_s*)ptr)->id - ID_MENUCHAR0 ) + s_playermodel.scrollOffset;
|
|
temp = s_playermodel.selectedChar;
|
|
|
|
if ( s_playermodel.charNames[ s_playermodel.selectedChar ].index >= 0 ) {
|
|
s_playermodel.selectedChar = s_playermodel.charNames[ s_playermodel.selectedChar ].index;
|
|
}
|
|
|
|
//Com_Printf( S_COLOR_RED "%i %i\n", s_playermodel.selectedChar, s_playermodel.charNames[ s_playermodel.selectedChar ].index );
|
|
|
|
//safety net. Without this, if a player held down 'enter', the game would overflow trying to load the same file over and over really fast. bad, really bad lol
|
|
if ( oldChar == s_playermodel.selectedChar && s_playermodel.selectedChar != -1 )
|
|
break;
|
|
|
|
//Reset the spin controls to 0.
|
|
//Without this, if we load a char with less models+skins than our last one, the game would crash
|
|
//since it'd be trying to parse NULL string data
|
|
s_playermodel.charModel.curvalue = 0;
|
|
s_playermodel.charSkin.curvalue = 0;
|
|
|
|
s_playermodel.playerIcon = trap_R_RegisterShaderNoMip( va( "models/players_rpgx/%s/model_icon.jpg", s_playermodel.charNames[s_playermodel.selectedChar].charName ) );
|
|
|
|
Q_strncpyz( s_playermodel.modelName, s_playermodel.charNamesUpr[ temp ], sizeof( s_playermodel.modelName ) );
|
|
|
|
s_playermodel.charModel.numitems = PlayerModel_LoadAvailableModels();
|
|
if ( s_playermodel.charModel.numitems != -1 )
|
|
{
|
|
s_playermodel.charModel.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
|
|
PlayerModel_LoadAvailableSkins();
|
|
s_playermodel.charSkin.numitems = PlayerModel_PopulateSkinsList();
|
|
|
|
if ( s_playermodel.charSkin.numitems != -1 )
|
|
{
|
|
s_playermodel.charSkin.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.skinList[0] = "NONE";
|
|
s_playermodel.charSkin.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
s_playermodel.charSkin.numitems = 0;
|
|
}
|
|
}
|
|
//reset the spin control
|
|
else
|
|
{
|
|
s_playermodel.modelList[0] = "NONE";
|
|
s_playermodel.charModel.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
s_playermodel.charModel.numitems = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
PlayerModel_CheckForChange();
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_MenuKey
|
|
=================
|
|
*/
|
|
static sfxHandle_t PlayerModel_MenuKey( int key )
|
|
{
|
|
switch( key )
|
|
{
|
|
case K_MOUSE1:
|
|
if ( Menu_ItemAtCursor( &s_playermodel.menu ) == &s_playermodel.scrollBar )
|
|
{
|
|
uis.activemenu->noNewSelecting = qtrue;
|
|
s_playermodel.scrollData.mouseDown = qtrue;
|
|
s_playermodel.scrollData.yStart = uis.cursory;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return ( Menu_DefaultKey( &s_playermodel.menu, key ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_DrawPlayer
|
|
=================
|
|
*/
|
|
static void PlayerModel_DrawPlayer( void *self )
|
|
{
|
|
menubitmap_s* b;
|
|
vec3_t origin = {-40, 2.5, -4 }; //-3.8
|
|
|
|
b = (menubitmap_s*) self;
|
|
|
|
if( trap_MemoryRemaining() <= LOW_MEMORY ) {
|
|
UI_DrawProportionalString( b->generic.x, b->generic.y + b->height / 2, "LOW MEMORY", UI_LEFT, color_red );
|
|
return;
|
|
}
|
|
|
|
UI_DrawPlayer( (float)b->generic.x, (float)b->generic.y, (float)b->width, (float)b->height, origin, &s_playermodel.playerinfo, (int)(uis.realtime/1.5) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_BuildList
|
|
|
|
Heavily modifed by TiM
|
|
All we'll take into account now
|
|
is a valid directory name,
|
|
and that it contains a .model file
|
|
We'll work the rest out later
|
|
=================
|
|
*/
|
|
|
|
static int QDECL PlayerListOrder_Compare( const void *ptr1, const void *ptr2 );
|
|
|
|
static void PlayerModel_BuildList( void )
|
|
{
|
|
int numdirs;
|
|
int numfiles;
|
|
char dirlist[8192];
|
|
char filelist[128]; //2048
|
|
char* dirptr;
|
|
int i, j;
|
|
int dirlen;
|
|
charData_t *tempBuff;
|
|
//int offset;
|
|
int temp;
|
|
|
|
s_playermodel.selectedChar = -1;
|
|
s_playermodel.numChars = 0;
|
|
|
|
// iterate directory of all player models
|
|
numdirs = trap_FS_GetFileList("models/players_rpgx", "/", dirlist, sizeof(dirlist) );
|
|
dirptr = dirlist;
|
|
|
|
///Com_Printf("%i folders found\n", numdirs );
|
|
|
|
for (i=0; i<numdirs && s_playermodel.numChars < MAX_PLAYERCHARS; i++,dirptr+=dirlen+1)
|
|
{
|
|
dirlen = strlen(dirptr);
|
|
|
|
if ( !dirptr ) {
|
|
break;
|
|
}
|
|
|
|
if (dirlen && dirptr[dirlen-1]=='/')
|
|
dirptr[dirlen-1]='\0';
|
|
|
|
//I'm guessing this is for non-PK3'd files
|
|
if (!strcmp(dirptr,".") || !strcmp(dirptr,".."))
|
|
continue;
|
|
|
|
// TiM : Check for .model files. That's all we need
|
|
numfiles = 0; //Just to be sure
|
|
numfiles = trap_FS_GetFileList( va("models/players_rpgx/%s",dirptr), ".model", filelist, 128 );
|
|
|
|
temp = qfalse;
|
|
if ( numfiles > 0 && dirptr[0] )
|
|
{
|
|
//TiM - Don't do duplicate chars (Since it caches PK3 and non PK3 ones as separate instances )
|
|
for ( j = 0; j < s_playermodel.numChars; j++ )
|
|
{
|
|
tempBuff = &s_playermodel.charNames[j];
|
|
|
|
if ( !Q_stricmp( tempBuff->charName, dirptr ) ){
|
|
temp = qtrue;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( temp )
|
|
continue;
|
|
|
|
tempBuff = &s_playermodel.charNames[s_playermodel.numChars];
|
|
Q_strncpyz( tempBuff->charName, dirptr, sizeof( tempBuff[s_playermodel.numChars].charName ) );
|
|
tempBuff->index = -1;
|
|
|
|
//TiM - Load data on the races if at all possible
|
|
if ( trap_FS_GetFileList( va("models/players_rpgx/%s",dirptr), "race.cfg", filelist, 128 ) > 0 )
|
|
{
|
|
fileHandle_t f;
|
|
char buffer[1024];
|
|
char* filePtr;
|
|
int fileLength;
|
|
char* token;
|
|
char filePath[MAX_QPATH];
|
|
|
|
Com_sprintf( filePath, sizeof(filePath), "models/players_rpgx/%s/race.cfg", dirptr );
|
|
fileLength = trap_FS_FOpenFile( filePath, &f, FS_READ );
|
|
|
|
//Com_Printf( S_COLOR_RED "File %s loaded.\n", dirptr );
|
|
|
|
if ( !fileLength ) {
|
|
continue;
|
|
}
|
|
//Com_Printf( S_COLOR_RED "We have length.\n" );
|
|
|
|
if ( fileLength > sizeof( buffer ) - 1 ) {
|
|
continue;
|
|
}
|
|
//Com_Printf( S_COLOR_RED "Good size.\n" );
|
|
|
|
memset( &buffer, 0, sizeof( buffer ) );
|
|
trap_FS_Read( buffer, fileLength, f );
|
|
//Com_Printf( S_COLOR_RED "Loaded data...\n" );
|
|
|
|
trap_FS_FCloseFile( f );
|
|
|
|
if ( !buffer[0] ) {
|
|
continue;
|
|
}
|
|
|
|
//Format is 'Race Gender'. Race must precede Gender
|
|
filePtr = buffer;
|
|
|
|
COM_BeginParseSession();
|
|
|
|
token = COM_Parse( &filePtr );
|
|
if ( !token )
|
|
continue;
|
|
|
|
//Com_Printf( S_COLOR_RED "Race %s Loaded\n", token );
|
|
|
|
//tempBuff->race = PlayerModel_CheckInArray( token, s_playermodel.raceNames, MAX_RACES );
|
|
|
|
//big dirty hack
|
|
/*for( k=0; k < MAX_RACES; k++ )
|
|
{
|
|
if ( !s_playermodel.raceNames[k].raceName[0] )
|
|
{
|
|
Q_strncpyz( s_playermodel.raceNames[k].raceName, token, sizeof( s_playermodel.raceNames[k].raceName ) );
|
|
tempBuff->race = s_playermodel.raceNames[k].raceIndex = k;
|
|
s_playermodel.numRaces++;
|
|
|
|
break;
|
|
}
|
|
|
|
if ( !Q_stricmp( s_playermodel.raceNames[k].raceName, token ) )
|
|
{
|
|
tempBuff->race = s_playermodel.raceNames[k].raceIndex = k;
|
|
break;
|
|
}
|
|
}*/
|
|
|
|
tempBuff->race = PlayerModel_CheckInFilter( token, s_playermodel.raceList, MAX_RACES, &s_playermodel.numRaces );
|
|
//Com_Printf( S_COLOR_RED "Number of races now: %i\n", s_playermodel.numRaces );
|
|
|
|
token = COM_Parse( &filePtr );
|
|
if ( !token )
|
|
continue;
|
|
//Com_Printf( S_COLOR_RED "Gender %s loaded\n", token );
|
|
|
|
//tempBuff->gender = PlayerModel_CheckInArray( token, s_playermodel.genderNames, MAX_GENDERS );
|
|
tempBuff->gender = PlayerModel_CheckInFilter( token, s_playermodel.genderList, MAX_GENDERS, &s_playermodel.numGenders );
|
|
|
|
//Com_Printf( S_COLOR_RED "%i\n", tempBuff[i].gender );
|
|
}
|
|
|
|
s_playermodel.numChars++;
|
|
tempBuff = &s_playermodel.charNames[ s_playermodel.numChars ];
|
|
}
|
|
}
|
|
|
|
//TiM - Flip the array so it's the right order
|
|
/*
|
|
* RPG-X | Phenix | 27/03/2007
|
|
* Removed code for Task#39 (List was fliped to be Z-A!!!!)*/
|
|
//for ( i = 0; i < s_playermodel.numChars; i++ ) {
|
|
// offset = ( ( s_playermodel.numChars - i ) - 1);
|
|
|
|
// Q_strncpyz( s_playermodel.charNames[i].charName,
|
|
// tempBuff[offset].charName,
|
|
// sizeof( s_playermodel.charNames[i].charName ) );
|
|
|
|
// s_playermodel.charNames[i].race = tempBuff[offset].race;
|
|
// s_playermodel.charNames[i].gender = tempBuff[offset].gender;
|
|
// s_playermodel.charNames[i].index = tempBuff[offset].index;
|
|
|
|
// Q_strncpyz( s_playermodel.charNamesUpr[i], s_playermodel.charNames[i].charName, sizeof( s_playermodel.charNamesUpr[i] ) );
|
|
//}
|
|
|
|
//RPG-X | TiM | 30-4-2007
|
|
//This loop obviously isn't working well enough.
|
|
//Bringing out the big guns. Using the Windows/Q3
|
|
//Binary data sorting function, qsort.
|
|
|
|
//sorting function located below
|
|
qsort( s_playermodel.charNames, s_playermodel.numChars, sizeof( charData_t ), PlayerListOrder_Compare );
|
|
|
|
//copy to the upper case list for rendering to the menu
|
|
for ( i = 0; i < s_playermodel.numChars; i++ )
|
|
Q_strncpyz( s_playermodel.charNamesUpr[i], s_playermodel.charNames[i].charName, sizeof( s_playermodel.charNamesUpr[i] ) );
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerListOrder_Compare
|
|
|
|
TiM - 30-4-2007
|
|
Called in the above
|
|
qsort function.
|
|
Re-orders the player
|
|
list based on alphabetical
|
|
name.
|
|
=================
|
|
*/
|
|
static int QDECL PlayerListOrder_Compare( const void *ptr1, const void *ptr2 )
|
|
{
|
|
char *chr1, *chr2;
|
|
int delta;
|
|
|
|
//extract the first characters of the name from each entry
|
|
chr1 = ((charData_t *)ptr1)->charName;
|
|
chr2 = ((charData_t *)ptr2)->charName;
|
|
|
|
//double check they're lower-case. case matters
|
|
if ( *chr1 >= 'A' && *chr1 <= 'Z' ) *chr1 += 32;
|
|
if ( *chr2 >= 'A' && *chr2 <= 'Z' ) *chr2 += 32;
|
|
|
|
//based off of their ASCII order.
|
|
delta = (int)*chr1 - (int)*chr2;
|
|
|
|
//if characters weren't the same
|
|
if ( delta != 0 )
|
|
return delta;
|
|
|
|
//else loop through the rest
|
|
while ( chr1 && chr2 && delta == 0 )
|
|
{
|
|
delta = (int)*chr1 - (int)*chr2;
|
|
|
|
chr1++;
|
|
chr2++;
|
|
}
|
|
|
|
return delta;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_SetMenuItems
|
|
=================
|
|
*/
|
|
static void PlayerModel_SetMenuItems( void )
|
|
{
|
|
int i;
|
|
char* temp;
|
|
//char model[64];
|
|
char model[32];
|
|
char skin[32];
|
|
|
|
// name
|
|
trap_Cvar_VariableStringBuffer( "name", s_playermodel.playername.string, MAX_PLAYERNAMELENGTH );
|
|
|
|
// model
|
|
trap_Cvar_VariableStringBuffer( "model", s_playermodel.modelData, 64 );
|
|
|
|
if ( ( temp = strchr( s_playermodel.modelData, '/' ) ) == NULL )
|
|
{
|
|
Q_strncpyz( s_playermodel.modelName, s_playermodel.modelData, sizeof( s_playermodel.modelName ) );
|
|
Q_strncpyz( model, DEFAULT_MODEL, 32 );
|
|
Q_strncpyz( skin, DEFAULT_SKIN, 32);
|
|
}
|
|
else
|
|
{
|
|
int len;
|
|
char* tempSkin;
|
|
//
|
|
len = strlen( temp );
|
|
Q_strncpyz( s_playermodel.modelName, s_playermodel.modelData, (strlen(s_playermodel.modelData) - strlen(temp)) + 1 );
|
|
|
|
//*temp++;
|
|
temp++;
|
|
if ( ( tempSkin = strchr( temp, '/' ) ) == NULL ) {
|
|
if ( !temp || !temp[1] )
|
|
Q_strncpyz( model, DEFAULT_MODEL, 32 );
|
|
else
|
|
Q_strncpyz( model, temp, 32 );
|
|
|
|
Q_strncpyz( skin, DEFAULT_SKIN, 32 );
|
|
}
|
|
else {
|
|
len = strlen( tempSkin );
|
|
//*tempSkin++;
|
|
tempSkin++;
|
|
|
|
Q_strncpyz( model, temp, (strlen( temp ) - len) + 1 );
|
|
|
|
if ( !tempSkin || !tempSkin[1] )
|
|
Q_strncpyz( skin, DEFAULT_SKIN, 32 );
|
|
else
|
|
Q_strncpyz( skin, tempSkin, 32 );
|
|
}
|
|
}
|
|
|
|
//Com_Printf( S_COLOR_RED "Load model is %s %s %s\n", s_playermodel.modelName, model, skin );
|
|
|
|
// find model in our list
|
|
for (i=0; i<s_playermodel.numChars; i++)
|
|
{
|
|
if ( !Q_stricmp( s_playermodel.modelName, s_playermodel.charNames[i].charName ) ) {
|
|
s_playermodel.selectedChar = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//try to register the current shader icon
|
|
if ( s_playermodel.selectedChar != -1 ) {
|
|
s_playermodel.playerIcon = trap_R_RegisterShaderNoMip( va( "models/players_rpgx/%s/model_icon", s_playermodel.modelName ) );
|
|
|
|
//If we're exceeded the list, update it so we're at the top
|
|
if ( s_playermodel.selectedChar > MAX_MENULISTITEMS ) {
|
|
s_playermodel.scrollOffset = (s_playermodel.selectedChar - MAX_MENULISTITEMS)+1;
|
|
PlayerModel_OffsetCharList( &s_playermodel.scrollOffset );
|
|
}
|
|
|
|
s_playermodel.charModel.numitems = PlayerModel_LoadAvailableModels( );
|
|
|
|
if ( s_playermodel.charModel.numitems != -1 )
|
|
{
|
|
s_playermodel.charModel.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.charModel.numitems = 0;
|
|
s_playermodel.charModel.generic.flags = QMF_GRAYED | QMF_INACTIVE;
|
|
s_playermodel.modelList[0] = "NONE";
|
|
}
|
|
|
|
//TiM - Switch the spin controls to the right value;
|
|
for ( i=0; i < s_playermodel.charModel.numitems; i++ ) {
|
|
if ( !Q_stricmp( s_playermodel.modelList[i], model ) ) {
|
|
s_playermodel.charModel.curvalue = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
PlayerModel_LoadAvailableSkins( );
|
|
s_playermodel.charSkin.numitems = PlayerModel_PopulateSkinsList();
|
|
|
|
if ( s_playermodel.charSkin.numitems != -1 )
|
|
{
|
|
s_playermodel.charSkin.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.charSkin.numitems = 0;
|
|
s_playermodel.charSkin.generic.flags = QMF_GRAYED | QMF_INACTIVE;
|
|
s_playermodel.skinList[0] = "NONE";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for ( i=0; i < s_playermodel.charSkin.numitems; i++ ) {
|
|
if ( !Q_stricmp( s_playermodel.skinList[i], skin ) ) {
|
|
s_playermodel.charSkin.curvalue = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//Set backup data
|
|
s_playermodel.storedData.orgChar = s_playermodel.selectedChar;
|
|
s_playermodel.storedData.orgModel = s_playermodel.charModel.curvalue;
|
|
s_playermodel.storedData.orgSkin = s_playermodel.charSkin.curvalue;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_DrawScrollBar
|
|
=================
|
|
*/
|
|
static void PlayerModel_DrawScrollBar( void *self )
|
|
{
|
|
qboolean focus;
|
|
menuaction_s *bar;
|
|
int *y;
|
|
int color;
|
|
int newY;
|
|
int dif;
|
|
|
|
bar = (menuaction_s *)self;
|
|
|
|
focus = ( Menu_ItemAtCursor( bar->generic.parent ) == bar );
|
|
|
|
if ( focus )
|
|
color = bar->color2;
|
|
else
|
|
color = bar->color;
|
|
|
|
trap_R_SetColor( colorTable[ color ] );
|
|
UI_DrawHandlePic( bar->generic.x, bar->generic.y, bar->width, bar->height, uis.whiteShader);
|
|
trap_R_SetColor( NULL );
|
|
|
|
if ( !s_playermodel.scrollData.mouseDown )
|
|
return;
|
|
|
|
if ( !trap_Key_IsDown( K_MOUSE1 ) )
|
|
{
|
|
s_playermodel.scrollData.mouseDown = qfalse;
|
|
uis.activemenu->noNewSelecting = qfalse;
|
|
return;
|
|
}
|
|
|
|
if ( uis.cursory == s_playermodel.scrollData.yStart )
|
|
return;
|
|
|
|
y = &bar->generic.y;
|
|
|
|
newY = *y + (uis.cursory - s_playermodel.scrollData.yStart);
|
|
|
|
if ( newY+bar->height > MAX_SCROLLTOP + MAX_SCROLLRANGE )
|
|
newY = (MAX_SCROLLTOP + MAX_SCROLLRANGE) - bar->height;
|
|
|
|
if ( newY < MAX_SCROLLTOP )
|
|
newY = MAX_SCROLLTOP;
|
|
|
|
dif = newY - *y;
|
|
|
|
s_playermodel.scrollOffset += dif * (s_playermodel.scrollData.doubleStep ? 2 : 1);
|
|
PlayerModel_OffsetCharList( &s_playermodel.scrollOffset );
|
|
|
|
*y = newY;
|
|
bar->generic.top = *y;
|
|
bar->generic.bottom = *y + bar->height;
|
|
|
|
s_playermodel.scrollData.yStart = uis.cursory;
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
PlayerSettingsMenu_Graphics
|
|
=================
|
|
*/
|
|
void PlayerModelMenu_Graphics (void)
|
|
{
|
|
int i;
|
|
|
|
// Draw the basic screen layout
|
|
UI_MenuFrame2(&s_playermodel.menu);
|
|
|
|
trap_R_SetColor( colorTable[CT_LTBROWN1]);
|
|
UI_DrawHandlePic(30,203, 47, 186, uis.whiteShader); // Middle left line
|
|
|
|
trap_R_SetColor( colorTable[CT_LTORANGE]);
|
|
|
|
//TiM - Frame around the models selection list
|
|
UI_DrawHandlePic( 96, 50, 8, -32, s_playermodel.corner_ll_4_18); // UL Corner
|
|
UI_DrawHandlePic( 96, 369, 8, 8, s_playermodel.corner_ll_4_4); // LL Corner
|
|
UI_DrawHandlePic( 238, 62, 32, 32, s_playermodel.corner_ur_18_18); // UR Corner
|
|
UI_DrawHandlePic( 240, 368, 32, 8, s_playermodel.corner_lr_18_4); // LR Corner
|
|
UI_DrawHandlePic( 96, 81, 4, 290, uis.whiteShader); // Left side
|
|
UI_DrawHandlePic( 242, 87, 18, 18, uis.whiteShader ); //Right Side Up Arrow Button
|
|
if ( s_playermodel.scrollBar.generic.flags & QMF_HIDDEN )
|
|
{
|
|
UI_DrawHandlePic( 242, 108, 18, 236, uis.whiteShader); // Right side
|
|
}
|
|
else
|
|
{
|
|
if ( s_playermodel.scrollBar.generic.y > MAX_SCROLLTOP + 4 )
|
|
UI_DrawHandlePic( 242, 108, 18, s_playermodel.scrollBar.generic.y - 108 - 3, uis.whiteShader);
|
|
if ( s_playermodel.scrollBar.generic.bottom + 3 < 343 )
|
|
UI_DrawHandlePic( 242, s_playermodel.scrollBar.generic.bottom + 3, 18, 343 - 3 - s_playermodel.scrollBar.generic.bottom, uis.whiteShader);
|
|
}
|
|
UI_DrawHandlePic( 242, 347, 18, 18, uis.whiteShader ); //Right Side Down Button
|
|
UI_DrawHandlePic( 100, 62, 141, 18, uis.whiteShader); // Top
|
|
UI_DrawHandlePic( 101, 371, 140, 4, uis.whiteShader); // Bottom
|
|
|
|
//TiM - Frame around the model specific data window
|
|
UI_DrawHandlePic( 265, 50, 8, -32, s_playermodel.corner_ll_4_18); // UL Corner
|
|
UI_DrawHandlePic( 265, 369, 8, 8, s_playermodel.corner_ll_4_4); // LL Corner
|
|
UI_DrawHandlePic( 422, 50, -8, -32, s_playermodel.corner_ll_4_18); // UR Corner
|
|
UI_DrawHandlePic( 422, 369, -8, 8, s_playermodel.corner_ll_4_4); // LR Corner
|
|
UI_DrawHandlePic( 265, 81, 4, 290, uis.whiteShader); // Left side
|
|
UI_DrawHandlePic( 426, 81, 4, 290, uis.whiteShader); // Right side
|
|
UI_DrawHandlePic( 269, 62, 157, 18, uis.whiteShader); // Top
|
|
UI_DrawHandlePic( 269, 371, 157, 4, uis.whiteShader); // Bottom
|
|
|
|
//TiM - Draw the stunningly awesome icon of the character
|
|
UI_DrawHandlePic( 306, 114, 82, 82, uis.whiteShader);
|
|
if ( !s_playermodel.playerIcon ) {
|
|
trap_R_SetColor( colorTable[CT_BLACK] );
|
|
UI_DrawHandlePic( 307, 115, 80, 80, uis.whiteShader );
|
|
UI_DrawProportionalString( 347, 145, "?", UI_BIGFONT|UI_CENTER, colorTable[CT_LTORANGE] );
|
|
}
|
|
else {
|
|
trap_R_SetColor( colorTable[CT_WHITE]);
|
|
UI_DrawHandlePic( 307, 115, 80, 80, s_playermodel.playerIcon );
|
|
}
|
|
|
|
//UI_DrawProportionalString( 220, 362, va("%s %d %s %d",menu_normal_text[MNT_SCREEN],(s_playermodel.modelpage + 1),menu_normal_text[MNT_OF],s_playermodel.numpages),UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
|
|
|
|
UI_DrawProportionalString( 108, 64, menu_normal_text[MNT_CHARS],UI_SMALLFONT,colorTable[CT_BLACK]); // Top
|
|
|
|
UI_DrawProportionalString( 275, 64, menu_normal_text[MNT_CHARDATA], UI_SMALLFONT, colorTable[CT_BLACK] );
|
|
|
|
trap_R_SetColor( colorTable[CT_DKGREY2]);
|
|
UI_DrawHandlePic( 439, 79, 151, 295, uis.whiteShader); // Background
|
|
|
|
// Frame around player model
|
|
trap_R_SetColor( colorTable[CT_LTORANGE]);
|
|
UI_DrawHandlePic( 435, 50, 8, -32, s_playermodel.corner_ll_4_18); // UL Corner
|
|
UI_DrawHandlePic( 435, 369, 8, 8, s_playermodel.corner_ll_4_4); // LL Corner
|
|
UI_DrawHandlePic( 440, 62, 150, 18, uis.whiteShader); // Top
|
|
UI_DrawHandlePic( 435, 79, 4, 295, uis.whiteShader); // Left side
|
|
UI_DrawHandlePic( 440, 371, 150, 4, uis.whiteShader); // Bottom
|
|
|
|
// Left rounded ends for buttons
|
|
trap_R_SetColor( colorTable[s_playermodel.mainmenu.color]);
|
|
UI_DrawHandlePic(s_playermodel.mainmenu.generic.x - 14, s_playermodel.mainmenu.generic.y,
|
|
MENU_BUTTON_MED_HEIGHT, MENU_BUTTON_MED_HEIGHT, uis.graphicButtonLeftEnd);
|
|
|
|
trap_R_SetColor( colorTable[s_playermodel.back.color]);
|
|
UI_DrawHandlePic(s_playermodel.back.generic.x - 14, s_playermodel.back.generic.y,
|
|
MENU_BUTTON_MED_HEIGHT, MENU_BUTTON_MED_HEIGHT, uis.graphicButtonLeftEnd);
|
|
|
|
trap_R_SetColor( colorTable[s_playermodel.data.color]);
|
|
UI_DrawHandlePic(s_playermodel.data.generic.x - 14, s_playermodel.data.generic.y,
|
|
MENU_BUTTON_MED_HEIGHT, MENU_BUTTON_MED_HEIGHT, uis.graphicButtonLeftEnd);
|
|
|
|
trap_R_SetColor( colorTable[s_playermodel.model.color]);
|
|
UI_DrawHandlePic(s_playermodel.model.generic.x - 14, s_playermodel.model.generic.y,
|
|
MENU_BUTTON_MED_HEIGHT, MENU_BUTTON_MED_HEIGHT, uis.graphicButtonLeftEnd);
|
|
|
|
//Model Name along the top
|
|
if ( s_playermodel.modelName[0] )
|
|
{
|
|
char* buf = s_playermodel.modelName;
|
|
|
|
UI_DrawProportionalString( 347, 89, Q_strupr( buf ), UI_SMALLFONT|UI_CENTER,colorTable[CT_DKPURPLE1]);
|
|
}
|
|
|
|
UI_DrawProportionalString( 74, 28, "881",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
|
|
UI_DrawProportionalString( 74, 150, "2445",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
|
|
UI_DrawProportionalString( 74, 206, "600",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
|
|
UI_DrawProportionalString( 74, 395, "3-44",UI_RIGHT|UI_TINYFONT, colorTable[CT_BLACK]);
|
|
|
|
//paint the selected model white
|
|
{
|
|
for ( i = 0; i < MAX_MENULISTITEMS; i++ )
|
|
{
|
|
if ( s_playermodel.charMenu[i].textcolor == CT_WHITE && s_playermodel.charMenu[i].textcolor2 == CT_WHITE )
|
|
{
|
|
s_playermodel.charMenu[i].textcolor = CT_DKGOLD1;
|
|
s_playermodel.charMenu[i].textcolor2 = CT_LTGOLD1;
|
|
}
|
|
|
|
//override between straight list, and filters
|
|
if ( ( s_playermodel.charNames[i + s_playermodel.scrollOffset].index == -1 && i + s_playermodel.scrollOffset == s_playermodel.selectedChar)
|
|
||
|
|
( s_playermodel.charNames[i + s_playermodel.scrollOffset].index >= 0 && s_playermodel.charNames[i + s_playermodel.scrollOffset].index == s_playermodel.selectedChar )
|
|
)
|
|
{
|
|
//Com_Printf( S_COLOR_GREEN "%i %i %i\n", i, s_playermodel.selectedChar, s_playermodel.charNames[i + s_playermodel.scrollOffset].index );
|
|
s_playermodel.charMenu[i].textcolor = CT_WHITE;
|
|
s_playermodel.charMenu[i].textcolor2 = CT_WHITE;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerSettings_MenuDraw
|
|
=================
|
|
*/
|
|
static void PlayerModel_MenuDraw (void)
|
|
{
|
|
PlayerModelMenu_Graphics();
|
|
|
|
Menu_Draw( &s_playermodel.menu );
|
|
}
|
|
/*
|
|
=================
|
|
PlayerModel_MenuInit
|
|
=================
|
|
*/
|
|
static void PlayerModel_MenuInit(int menuFrom)
|
|
{
|
|
int i;
|
|
//int j;
|
|
//int k;
|
|
int x;
|
|
int y;
|
|
static char playername[32];
|
|
//static char modelname[32];
|
|
//static char skinname[32];
|
|
//static char skinnameviewed[32];
|
|
qboolean races=qfalse;
|
|
qboolean genders=qfalse;
|
|
|
|
// zero set all our globals
|
|
memset( &s_playermodel, 0 ,sizeof(playermodel_t) );
|
|
|
|
s_playermodel.prevMenu = menuFrom;
|
|
|
|
//TiM : Model Spin view
|
|
uis.spinView = qfalse;
|
|
uis.lastYaw = 150;
|
|
|
|
PlayerModel_Cache();
|
|
|
|
//Set up some false data to feed our spin controls for the time being
|
|
//Spin controls NEED data passed to them on init, eitherwise they immediately terminate. which sucks lol
|
|
s_playermodel.modelList[0] = "NONE";
|
|
s_playermodel.skinList[0] = "NONE";
|
|
|
|
Q_strncpyz( s_playermodel.genderList[0].filterName , "All", 32 );
|
|
Q_strncpyz( s_playermodel.raceList[0].filterName, "All", 32 );
|
|
|
|
// set initial states
|
|
PlayerModel_BuildList();
|
|
|
|
//sort the race list alphabetically
|
|
//+1 for number to account for the 'All' value
|
|
qsort( (void *)s_playermodel.raceList, s_playermodel.numRaces+1, sizeof( filterData_t ), FilterList_Compare );
|
|
qsort( (void *)s_playermodel.genderList, s_playermodel.numGenders+1, sizeof( filterData_t ), FilterList_Compare );
|
|
|
|
//Populate the spin control pointers
|
|
for ( i = 0; i < 128; i++ ) {
|
|
if ( !s_playermodel.genderList[i].filterName[0] && !s_playermodel.raceList[i].filterName[0] )
|
|
break;
|
|
|
|
if ( s_playermodel.genderList[i].filterName[0] ) {
|
|
s_playermodel.genderNames[i] = s_playermodel.genderList[i].filterName;
|
|
genders = qtrue;
|
|
}
|
|
|
|
if ( s_playermodel.raceList[i].filterName[0] ) {
|
|
s_playermodel.raceNames[i] = s_playermodel.raceList[i].filterName;
|
|
races = qtrue;
|
|
}
|
|
}
|
|
|
|
s_playermodel.menu.key = PlayerModel_MenuKey;
|
|
s_playermodel.menu.wrapAround = qtrue;
|
|
s_playermodel.menu.fullscreen = qtrue;
|
|
s_playermodel.menu.draw = PlayerModel_MenuDraw;
|
|
s_playermodel.menu.descX = MENU_DESC_X;
|
|
s_playermodel.menu.descY = MENU_DESC_Y;
|
|
s_playermodel.menu.titleX = MENU_TITLE_X;
|
|
s_playermodel.menu.titleY = MENU_TITLE_Y;
|
|
s_playermodel.menu.titleI = MNT_CHANGEPLAYER_TITLE;
|
|
s_playermodel.menu.footNoteEnum = MNT_CHANGEPLAYER;
|
|
|
|
s_playermodel.mainmenu.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.mainmenu.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
s_playermodel.mainmenu.generic.x = 110;
|
|
s_playermodel.mainmenu.generic.y = 391;
|
|
s_playermodel.mainmenu.generic.name = BUTTON_GRAPHIC_LONGRIGHT;
|
|
s_playermodel.mainmenu.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.mainmenu.width = MENU_BUTTON_MED_WIDTH;
|
|
s_playermodel.mainmenu.height = MENU_BUTTON_MED_HEIGHT;
|
|
s_playermodel.mainmenu.color = CT_DKPURPLE1;
|
|
s_playermodel.mainmenu.color2 = CT_LTPURPLE1;
|
|
|
|
if (!ingameFlag)
|
|
{
|
|
s_playermodel.mainmenu.textEnum = MBT_MAINMENU;
|
|
s_playermodel.mainmenu.generic.id = ID_MAINMENU;
|
|
}
|
|
else
|
|
{
|
|
s_playermodel.mainmenu.textEnum = MBT_INGAMEMENU;
|
|
s_playermodel.mainmenu.generic.id = ID_INGAMEMENU;
|
|
}
|
|
|
|
s_playermodel.mainmenu.textX = MENU_BUTTON_TEXT_X;
|
|
s_playermodel.mainmenu.textY = MENU_BUTTON_TEXT_Y;
|
|
s_playermodel.mainmenu.textcolor = CT_BLACK;
|
|
s_playermodel.mainmenu.textcolor2 = CT_WHITE;
|
|
|
|
s_playermodel.back.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.back.generic.name = BUTTON_GRAPHIC_LONGRIGHT;
|
|
s_playermodel.back.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
s_playermodel.back.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.back.generic.id = ID_BACK;
|
|
s_playermodel.back.generic.x = 110;
|
|
s_playermodel.back.generic.y = 415;
|
|
s_playermodel.back.width = MENU_BUTTON_MED_WIDTH;
|
|
s_playermodel.back.height = MENU_BUTTON_MED_HEIGHT;
|
|
s_playermodel.back.color = CT_DKPURPLE1;
|
|
s_playermodel.back.color2 = CT_LTPURPLE1;
|
|
s_playermodel.back.textX = MENU_BUTTON_TEXT_X;
|
|
s_playermodel.back.textY = MENU_BUTTON_TEXT_Y;
|
|
s_playermodel.back.textEnum = MBT_BACK;
|
|
s_playermodel.back.generic.id = ID_BACK;
|
|
s_playermodel.back.textcolor = CT_BLACK;
|
|
s_playermodel.back.textcolor2 = CT_WHITE;
|
|
|
|
s_playermodel.data.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.data.generic.name = BUTTON_GRAPHIC_LONGRIGHT;
|
|
s_playermodel.data.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
s_playermodel.data.generic.id = ID_SETTINGS;
|
|
s_playermodel.data.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.data.generic.x = 482;
|
|
s_playermodel.data.generic.y = 391;
|
|
s_playermodel.data.width = MENU_BUTTON_MED_WIDTH;
|
|
s_playermodel.data.height = MENU_BUTTON_MED_HEIGHT;
|
|
s_playermodel.data.color = CT_DKPURPLE1;
|
|
s_playermodel.data.color2 = CT_LTPURPLE1;
|
|
s_playermodel.data.textX = 5;
|
|
s_playermodel.data.textY = 2;
|
|
s_playermodel.data.textEnum = MBT_PLAYERDATA;
|
|
s_playermodel.data.textcolor = CT_BLACK;
|
|
s_playermodel.data.textcolor2 = CT_WHITE;
|
|
|
|
s_playermodel.model.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.model.generic.name = BUTTON_GRAPHIC_LONGRIGHT;
|
|
s_playermodel.model.generic.flags = QMF_GRAYED;
|
|
s_playermodel.model.generic.x = 482;
|
|
s_playermodel.model.generic.y = 415;
|
|
s_playermodel.model.width = MENU_BUTTON_MED_WIDTH;
|
|
s_playermodel.model.height = MENU_BUTTON_MED_HEIGHT;
|
|
s_playermodel.model.color = CT_DKPURPLE1;
|
|
s_playermodel.model.color2 = CT_LTPURPLE1;
|
|
s_playermodel.model.textX = 5;
|
|
s_playermodel.model.textY = 2;
|
|
s_playermodel.model.textEnum = MBT_CHANGEMODEL;
|
|
s_playermodel.model.textcolor = CT_BLACK;
|
|
s_playermodel.model.textcolor2 = CT_WHITE;
|
|
|
|
//y = 88;
|
|
x = 107;
|
|
y = 85;
|
|
|
|
for (i=0; i < MAX_MENULISTITEMS; i++ ) {
|
|
s_playermodel.charMenu[i].generic.type = MTYPE_BITMAP;
|
|
s_playermodel.charMenu[i].generic.flags = QMF_INACTIVE | QMF_HIDDEN;
|
|
s_playermodel.charMenu[i].generic.x = x;
|
|
s_playermodel.charMenu[i].generic.y = y;
|
|
s_playermodel.charMenu[i].generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.charMenu[i].generic.id = ID_MENUCHAR0+i;
|
|
s_playermodel.charMenu[i].width = 129;
|
|
s_playermodel.charMenu[i].height = 16;
|
|
s_playermodel.charMenu[i].color = CT_DKPURPLE1;
|
|
s_playermodel.charMenu[i].color2 = CT_LTPURPLE1;
|
|
s_playermodel.charMenu[i].textPtr = NULL;
|
|
s_playermodel.charMenu[i].textX = 4;
|
|
s_playermodel.charMenu[i].textY = 1;
|
|
s_playermodel.charMenu[i].textcolor = CT_DKGOLD1;
|
|
s_playermodel.charMenu[i].textcolor2 = CT_LTGOLD1;
|
|
s_playermodel.charMenu[i].textStyle = UI_SMALLFONT;
|
|
|
|
y += 24;
|
|
}
|
|
|
|
s_playermodel.playername.generic.type = MTYPE_PTEXT;
|
|
s_playermodel.playername.generic.flags = QMF_INACTIVE;
|
|
s_playermodel.playername.generic.x = 444;
|
|
s_playermodel.playername.generic.y = 63;
|
|
s_playermodel.playername.string = playername;
|
|
s_playermodel.playername.style = UI_SMALLFONT;
|
|
s_playermodel.playername.color = colorTable[CT_BLACK];
|
|
|
|
/*s_playermodel.modelname.generic.type = MTYPE_PTEXT;
|
|
s_playermodel.modelname.generic.flags = QMF_INACTIVE;
|
|
s_playermodel.modelname.generic.x = 121;
|
|
s_playermodel.modelname.generic.y = 338;
|
|
s_playermodel.modelname.string = modelname;
|
|
s_playermodel.modelname.style = UI_LEFT;
|
|
s_playermodel.modelname.color = colorTable[CT_LTBLUE1];*/
|
|
|
|
/*s_playermodel.skinname.generic.type = MTYPE_PTEXT;
|
|
s_playermodel.skinname.generic.flags = QMF_INACTIVE;
|
|
s_playermodel.skinname.generic.x = 323;
|
|
s_playermodel.skinname.generic.y = 338;
|
|
s_playermodel.skinname.string = skinname;
|
|
s_playermodel.skinname.style = UI_RIGHT;
|
|
s_playermodel.skinname.color = colorTable[CT_LTBLUE1];*/
|
|
|
|
s_playermodel.player.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.player.generic.flags = QMF_SILENT;
|
|
s_playermodel.player.generic.ownerdraw = PlayerModel_DrawPlayer;
|
|
s_playermodel.player.generic.callback = PlayerModel_SpinPlayer;
|
|
s_playermodel.player.generic.x = 439; //400
|
|
s_playermodel.player.generic.y = 80; //20
|
|
s_playermodel.player.width = 151; //32*7.3
|
|
s_playermodel.player.height = 291; //56*7.3
|
|
|
|
s_playermodel.upArrow.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.upArrow.generic.name = PIC_ARROW_UP;
|
|
s_playermodel.upArrow.generic.flags = QMF_GRAYED | QMF_INACTIVE;
|
|
s_playermodel.upArrow.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.upArrow.generic.id = ID_UPARROW;
|
|
s_playermodel.upArrow.generic.x = 243;
|
|
s_playermodel.upArrow.generic.y = 89;
|
|
s_playermodel.upArrow.width = 16;
|
|
s_playermodel.upArrow.height = 16;
|
|
s_playermodel.upArrow.color = CT_DKPURPLE1;
|
|
s_playermodel.upArrow.color2 = CT_LTPURPLE1;
|
|
s_playermodel.upArrow.textX = MENU_BUTTON_TEXT_X;
|
|
s_playermodel.upArrow.textY = MENU_BUTTON_TEXT_Y;
|
|
//s_playermodel.upArrow.textEnum = MBT_PREVPAGE;
|
|
s_playermodel.upArrow.textcolor = CT_BLACK;
|
|
s_playermodel.upArrow.textcolor2 = CT_WHITE;
|
|
|
|
s_playermodel.dnArrow.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.dnArrow.generic.name = PIC_ARROW_DOWN;
|
|
s_playermodel.dnArrow.generic.flags = QMF_GRAYED | QMF_INACTIVE;
|
|
s_playermodel.dnArrow.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.dnArrow.generic.id = ID_DNARROW;
|
|
s_playermodel.dnArrow.generic.x = 243;
|
|
s_playermodel.dnArrow.generic.y = 349;
|
|
s_playermodel.dnArrow.width = 16;
|
|
s_playermodel.dnArrow.height = 16;
|
|
s_playermodel.dnArrow.color = CT_DKPURPLE1;
|
|
s_playermodel.dnArrow.color2 = CT_LTPURPLE1;
|
|
s_playermodel.dnArrow.textX = MENU_BUTTON_TEXT_X;
|
|
s_playermodel.dnArrow.textY = MENU_BUTTON_TEXT_Y;
|
|
//s_playermodel.dnArrow.textEnum = MBT_NEXTPAGE;
|
|
s_playermodel.dnArrow.textcolor = CT_BLACK;
|
|
s_playermodel.dnArrow.textcolor2 = CT_WHITE;
|
|
|
|
s_playermodel.charModel.generic.type = MTYPE_SPINCONTROL;
|
|
s_playermodel.charModel.generic.flags = QMF_INACTIVE | QMF_GRAYED; //QMF_HIGHLIGHT_IF_FOCUS
|
|
s_playermodel.charModel.generic.id = ID_MODELSET;
|
|
s_playermodel.charModel.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.charModel.generic.x = 291;//134;
|
|
s_playermodel.charModel.generic.y = 209;//207;
|
|
s_playermodel.charModel.textEnum = MBT_CHARMODEL;
|
|
s_playermodel.charModel.textcolor = CT_BLACK;
|
|
s_playermodel.charModel.textcolor2 = CT_WHITE;
|
|
s_playermodel.charModel.color = CT_DKPURPLE1;
|
|
s_playermodel.charModel.color2 = CT_LTPURPLE1;
|
|
s_playermodel.charModel.width = 92;//80;
|
|
s_playermodel.charModel.textX = 56;
|
|
s_playermodel.charModel.textY = 2;
|
|
s_playermodel.charModel.textFlags = UI_CENTER;
|
|
s_playermodel.charModel.listX = 56;
|
|
s_playermodel.charModel.listY = 24;
|
|
s_playermodel.charModel.listFlags = UI_CENTER;
|
|
s_playermodel.charModel.focusWidth = 110;
|
|
s_playermodel.charModel.focusHeight = 40;
|
|
s_playermodel.charModel.itemnames = (const char **)s_playermodel.modelList;
|
|
|
|
s_playermodel.charSkin.generic.type = MTYPE_SPINCONTROL;
|
|
s_playermodel.charSkin.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
s_playermodel.charSkin.generic.id = ID_SKINSET;
|
|
s_playermodel.charSkin.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.charSkin.generic.x = 291;//134;
|
|
s_playermodel.charSkin.generic.y = 266;//207;
|
|
s_playermodel.charSkin.textEnum = MBT_CHARSKIN;
|
|
s_playermodel.charSkin.textcolor = CT_BLACK;
|
|
s_playermodel.charSkin.textcolor2 = CT_WHITE;
|
|
s_playermodel.charSkin.color = CT_DKPURPLE1;
|
|
s_playermodel.charSkin.color2 = CT_LTPURPLE1;
|
|
s_playermodel.charSkin.width = 90;//80;
|
|
s_playermodel.charSkin.textX = 56;
|
|
s_playermodel.charSkin.textY = 2;
|
|
s_playermodel.charSkin.textFlags = UI_CENTER;
|
|
s_playermodel.charSkin.listX = 56;
|
|
s_playermodel.charSkin.listY = 24;
|
|
s_playermodel.charSkin.listFlags = UI_CENTER;
|
|
s_playermodel.charSkin.focusWidth = 110;
|
|
s_playermodel.charSkin.focusHeight = 40;
|
|
s_playermodel.charSkin.itemnames = (const char**)s_playermodel.skinList;
|
|
|
|
s_playermodel.raceFilter.generic.type = MTYPE_SPINCONTROL;
|
|
if ( !races ) {
|
|
s_playermodel.raceFilter.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
}
|
|
else {
|
|
s_playermodel.raceFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
s_playermodel.raceFilter.generic.id = ID_RACEFILTER;
|
|
s_playermodel.raceFilter.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.raceFilter.generic.x = 270;
|
|
s_playermodel.raceFilter.generic.y = 391;
|
|
s_playermodel.raceFilter.textEnum = MBT_RACEFILTER;
|
|
s_playermodel.raceFilter.textcolor = CT_BLACK;
|
|
s_playermodel.raceFilter.textcolor2 = CT_WHITE;
|
|
s_playermodel.raceFilter.color = CT_DKPURPLE1;
|
|
s_playermodel.raceFilter.color2 = CT_LTPURPLE1;
|
|
s_playermodel.raceFilter.textX = 10;
|
|
s_playermodel.raceFilter.textY = 1;
|
|
s_playermodel.raceFilter.width = 65;
|
|
s_playermodel.raceFilter.itemnames = (const char**)s_playermodel.raceNames;
|
|
|
|
s_playermodel.genderFilter.generic.type = MTYPE_SPINCONTROL;
|
|
if ( !genders ) {
|
|
s_playermodel.genderFilter.generic.flags = QMF_INACTIVE | QMF_GRAYED;
|
|
}
|
|
else {
|
|
s_playermodel.genderFilter.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
s_playermodel.genderFilter.generic.id = ID_GENDERFILTER;
|
|
s_playermodel.genderFilter.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.genderFilter.generic.x = 270;
|
|
s_playermodel.genderFilter.generic.y = 414;
|
|
s_playermodel.genderFilter.textEnum = MBT_GENDERFILTER;
|
|
s_playermodel.genderFilter.textcolor = CT_BLACK;
|
|
s_playermodel.genderFilter.textcolor2 = CT_WHITE;
|
|
s_playermodel.genderFilter.color = CT_DKPURPLE1;
|
|
s_playermodel.genderFilter.color2 = CT_LTPURPLE1;
|
|
s_playermodel.genderFilter.textX = 10;
|
|
s_playermodel.genderFilter.textY = 1;
|
|
s_playermodel.genderFilter.width = 65;
|
|
s_playermodel.genderFilter.itemnames = (const char**)s_playermodel.genderNames;
|
|
|
|
s_playermodel.apply.generic.type = MTYPE_BITMAP;
|
|
s_playermodel.apply.generic.name = GRAPHIC_SQUARE;
|
|
s_playermodel.apply.generic.flags = QMF_GRAYED | QMF_INACTIVE;
|
|
s_playermodel.apply.generic.callback = PlayerModel_MenuEvent;
|
|
s_playermodel.apply.generic.id = ID_APPLY;
|
|
s_playermodel.apply.generic.x = 281;
|
|
s_playermodel.apply.generic.y = 321;
|
|
s_playermodel.apply.width = 132;
|
|
s_playermodel.apply.height = 39;
|
|
s_playermodel.apply.color = CT_DKPURPLE1;
|
|
s_playermodel.apply.color2 = CT_LTPURPLE1;
|
|
s_playermodel.apply.textX = MENU_BUTTON_TEXT_X;
|
|
s_playermodel.apply.textY = MENU_BUTTON_TEXT_Y;
|
|
s_playermodel.apply.textEnum = MBT_VIDEOAPPLYCHANGES;
|
|
s_playermodel.apply.textcolor = CT_BLACK;
|
|
s_playermodel.apply.textcolor2 = CT_WHITE;
|
|
|
|
s_playermodel.scrollBar.generic.type = MTYPE_ACTION;
|
|
s_playermodel.scrollBar.generic.flags = QMF_INACTIVE | QMF_HIDDEN;
|
|
s_playermodel.scrollBar.generic.x = 242;
|
|
s_playermodel.scrollBar.generic.y = 108;
|
|
s_playermodel.scrollBar.generic.id = ID_SCROLLBAR;
|
|
s_playermodel.scrollBar.generic.ownerdraw = PlayerModel_DrawScrollBar;
|
|
s_playermodel.scrollBar.width = 18;
|
|
s_playermodel.scrollBar.height = MIN_SCROLLHEIGHT;
|
|
s_playermodel.scrollBar.color = CT_DKPURPLE1;
|
|
s_playermodel.scrollBar.color2 = CT_LTPURPLE1;
|
|
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.model );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.data );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.player );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.playername );
|
|
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.upArrow );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.scrollBar );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.dnArrow );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.charModel );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.charSkin );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.apply );
|
|
|
|
for (i=0; i < MAX_MENULISTITEMS; i++ ) {
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.charMenu[i] );
|
|
}
|
|
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.raceFilter );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.genderFilter );
|
|
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.back );
|
|
Menu_AddItem( &s_playermodel.menu, &s_playermodel.mainmenu );
|
|
|
|
if ( s_playermodel.numChars >= MAX_MENULISTITEMS ) {
|
|
s_playermodel.upArrow.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
s_playermodel.dnArrow.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
|
|
}
|
|
|
|
PlayerModel_SetMenuItems();
|
|
|
|
PlayerModel_OffsetCharList( &s_playermodel.scrollOffset );
|
|
|
|
PlayerModel_SetupScrollBar( &s_playermodel.scrollBar );
|
|
PlayerModel_UpdateScrollBar( &s_playermodel.scrollBar );
|
|
|
|
// update user interface
|
|
PlayerModel_UpdateModel();
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_Cache
|
|
=================
|
|
*/
|
|
void PlayerModel_Cache( void )
|
|
{
|
|
//int i;
|
|
|
|
s_playermodel.corner_ll_4_18 = trap_R_RegisterShaderNoMip("menu/common/corner_ll_4_18");
|
|
s_playermodel.corner_ll_4_4 = trap_R_RegisterShaderNoMip("menu/common/corner_ll_4_4");
|
|
s_playermodel.corner_lr_4_18 = trap_R_RegisterShaderNoMip("menu/common/corner_lr_4_18");
|
|
s_playermodel.corner_lr_18_4 = trap_R_RegisterShaderNoMip("menu/common/corner_lr_18_4");
|
|
s_playermodel.corner_ur_18_18 = trap_R_RegisterShaderNoMip("menu/common/corner_ur_18_18");
|
|
|
|
trap_R_RegisterShaderNoMip(PIC_ARROW_UP);
|
|
trap_R_RegisterShaderNoMip(PIC_ARROW_DOWN);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_DrawLoading
|
|
=================
|
|
*/
|
|
static void PlayerModel_DrawLoading( void )
|
|
{
|
|
//register the corners now
|
|
qhandle_t cornerPic = trap_R_RegisterShaderNoMip("menu/common/corner_ll_47_18.tga");
|
|
int y = 50;
|
|
|
|
trap_R_SetColor( colorTable[CT_DKPURPLE2]);
|
|
|
|
UI_DrawHandlePic( 132, y+ 42, 128, -64, cornerPic); // Top Left corner
|
|
UI_DrawHandlePic( 132, y+252, 128, 64, cornerPic); // Bottom Left corner
|
|
|
|
UI_DrawHandlePic( 429, y+ 42, -128, -64, cornerPic); // Top Right corner
|
|
UI_DrawHandlePic( 429, y+252, -128, 64, cornerPic); // Bottom Right corner
|
|
|
|
UI_DrawHandlePic(145, y+75, 395, 18, uis.whiteShader); // Top
|
|
UI_DrawHandlePic(132, y+93, 47, 175, uis.whiteShader); // Left side
|
|
UI_DrawHandlePic(510, y+93, 47, 175, uis.whiteShader); // Right side
|
|
UI_DrawHandlePic(147,y+265, 65, 18, uis.whiteShader); // Bottom Left
|
|
UI_DrawHandlePic(477,y+265, 65, 18, uis.whiteShader); // Bottom Right
|
|
UI_DrawHandlePic(214,y+265, 261, 18, uis.whiteShader); // Bottom
|
|
|
|
UI_DrawProportionalString(345,y+159,menu_normal_text[MNT_LOADING],UI_SMALLFONT | UI_CENTER,colorTable[CT_LTGOLD1]);
|
|
}
|
|
|
|
/*
|
|
=================
|
|
PlayerModel_Cache
|
|
=================
|
|
*/
|
|
void UI_PlayerModelMenu(int menuFrom)
|
|
{
|
|
//TiM - Spawn a quick "loading" box
|
|
//Sometimes this gives me the eerie creeps the game froze
|
|
PlayerModel_DrawLoading();
|
|
|
|
PlayerModel_MenuInit(menuFrom);
|
|
|
|
UI_PushMenu( &s_playermodel.menu );
|
|
|
|
//Menu_SetCursorToItem( &s_playermodel.menu, &s_playermodel.pics[s_playermodel.selectedmodel % MAX_MODELSPERPAGE] );
|
|
}
|
|
|
|
|