📄 ui_playermodel.c
字号:
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena 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.
Quake III Arena 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 Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//
#include "ui_local.h"
#define MODEL_BACK0 "menu/art/back_0"
#define MODEL_BACK1 "menu/art/back_1"
#define MODEL_SELECT "menu/art/opponents_select"
#define MODEL_SELECTED "menu/art/opponents_selected"
#define MODEL_FRAMEL "menu/art/frame1_l"
#define MODEL_FRAMER "menu/art/frame1_r"
#define MODEL_PORTS "menu/art/player_models_ports"
#define MODEL_ARROWS "menu/art/gs_arrows_0"
#define MODEL_ARROWSL "menu/art/gs_arrows_l"
#define MODEL_ARROWSR "menu/art/gs_arrows_r"
#define LOW_MEMORY (5 * 1024 * 1024)
static char* playermodel_artlist[] =
{
MODEL_BACK0,
MODEL_BACK1,
MODEL_SELECT,
MODEL_SELECTED,
MODEL_FRAMEL,
MODEL_FRAMER,
MODEL_PORTS,
MODEL_ARROWS,
MODEL_ARROWSL,
MODEL_ARROWSR,
NULL
};
#define PLAYERGRID_COLS 4
#define PLAYERGRID_ROWS 4
#define MAX_MODELSPERPAGE (PLAYERGRID_ROWS*PLAYERGRID_COLS)
#define MAX_PLAYERMODELS 256
#define ID_PLAYERPIC0 0
#define ID_PLAYERPIC1 1
#define ID_PLAYERPIC2 2
#define ID_PLAYERPIC3 3
#define ID_PLAYERPIC4 4
#define ID_PLAYERPIC5 5
#define ID_PLAYERPIC6 6
#define ID_PLAYERPIC7 7
#define ID_PLAYERPIC8 8
#define ID_PLAYERPIC9 9
#define ID_PLAYERPIC10 10
#define ID_PLAYERPIC11 11
#define ID_PLAYERPIC12 12
#define ID_PLAYERPIC13 13
#define ID_PLAYERPIC14 14
#define ID_PLAYERPIC15 15
#define ID_PREVPAGE 100
#define ID_NEXTPAGE 101
#define ID_BACK 102
typedef struct
{
menuframework_s menu;
menubitmap_s pics[MAX_MODELSPERPAGE];
menubitmap_s picbuttons[MAX_MODELSPERPAGE];
menubitmap_s framel;
menubitmap_s framer;
menubitmap_s ports;
menutext_s banner;
menubitmap_s back;
menubitmap_s player;
menubitmap_s arrows;
menubitmap_s left;
menubitmap_s right;
menutext_s modelname;
menutext_s skinname;
menutext_s playername;
playerInfo_t playerinfo;
int nummodels;
char modelnames[MAX_PLAYERMODELS][128];
int modelpage;
int numpages;
char modelskin[64];
int selectedmodel;
} playermodel_t;
static playermodel_t s_playermodel;
/*
=================
PlayerModel_UpdateGrid
=================
*/
static void PlayerModel_UpdateGrid( void )
{
int i;
int j;
j = s_playermodel.modelpage * MAX_MODELSPERPAGE;
for (i=0; i<PLAYERGRID_ROWS*PLAYERGRID_COLS; i++,j++)
{
if (j < s_playermodel.nummodels)
{
// model/skin portrait
s_playermodel.pics[i].generic.name = s_playermodel.modelnames[j];
s_playermodel.picbuttons[i].generic.flags &= ~QMF_INACTIVE;
}
else
{
// dead slot
s_playermodel.pics[i].generic.name = NULL;
s_playermodel.picbuttons[i].generic.flags |= QMF_INACTIVE;
}
s_playermodel.pics[i].generic.flags &= ~QMF_HIGHLIGHT;
s_playermodel.pics[i].shader = 0;
s_playermodel.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS;
}
if (s_playermodel.selectedmodel/MAX_MODELSPERPAGE == s_playermodel.modelpage)
{
// set selected model
i = s_playermodel.selectedmodel % MAX_MODELSPERPAGE;
s_playermodel.pics[i].generic.flags |= QMF_HIGHLIGHT;
s_playermodel.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;
}
if (s_playermodel.numpages > 1)
{
if (s_playermodel.modelpage > 0)
s_playermodel.left.generic.flags &= ~QMF_INACTIVE;
else
s_playermodel.left.generic.flags |= QMF_INACTIVE;
if (s_playermodel.modelpage < s_playermodel.numpages-1)
s_playermodel.right.generic.flags &= ~QMF_INACTIVE;
else
s_playermodel.right.generic.flags |= QMF_INACTIVE;
}
else
{
// hide left/right markers
s_playermodel.left.generic.flags |= QMF_INACTIVE;
s_playermodel.right.generic.flags |= QMF_INACTIVE;
}
}
/*
=================
PlayerModel_UpdateModel
=================
*/
static void PlayerModel_UpdateModel( void )
{
vec3_t viewangles;
vec3_t moveangles;
memset( &s_playermodel.playerinfo, 0, sizeof(playerInfo_t) );
viewangles[YAW] = 180 - 30;
viewangles[PITCH] = 0;
viewangles[ROLL] = 0;
VectorClear( moveangles );
UI_PlayerInfo_SetModel( &s_playermodel.playerinfo, s_playermodel.modelskin );
UI_PlayerInfo_SetInfo( &s_playermodel.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, moveangles, WP_MACHINEGUN, qfalse );
}
/*
=================
PlayerModel_SaveChanges
=================
*/
static void PlayerModel_SaveChanges( void )
{
trap_Cvar_Set( "model", s_playermodel.modelskin );
trap_Cvar_Set( "headmodel", s_playermodel.modelskin );
trap_Cvar_Set( "team_model", s_playermodel.modelskin );
trap_Cvar_Set( "team_headmodel", s_playermodel.modelskin );
}
/*
=================
PlayerModel_MenuEvent
=================
*/
static void PlayerModel_MenuEvent( void* ptr, int event )
{
if (event != QM_ACTIVATED)
return;
switch (((menucommon_s*)ptr)->id)
{
case ID_PREVPAGE:
if (s_playermodel.modelpage > 0)
{
s_playermodel.modelpage--;
PlayerModel_UpdateGrid();
}
break;
case ID_NEXTPAGE:
if (s_playermodel.modelpage < s_playermodel.numpages-1)
{
s_playermodel.modelpage++;
PlayerModel_UpdateGrid();
}
break;
case ID_BACK:
PlayerModel_SaveChanges();
UI_PopMenu();
break;
}
}
/*
=================
PlayerModel_MenuKey
=================
*/
static sfxHandle_t PlayerModel_MenuKey( int key )
{
menucommon_s* m;
int picnum;
switch (key)
{
case K_KP_LEFTARROW:
case K_LEFTARROW:
m = Menu_ItemAtCursor(&s_playermodel.menu);
picnum = m->id - ID_PLAYERPIC0;
if (picnum >= 0 && picnum <= 15)
{
if (picnum > 0)
{
Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-1);
return (menu_move_sound);
}
else if (s_playermodel.modelpage > 0)
{
s_playermodel.modelpage--;
Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+15);
PlayerModel_UpdateGrid();
return (menu_move_sound);
}
else
return (menu_buzz_sound);
}
break;
case K_KP_RIGHTARROW:
case K_RIGHTARROW:
m = Menu_ItemAtCursor(&s_playermodel.menu);
picnum = m->id - ID_PLAYERPIC0;
if (picnum >= 0 && picnum <= 15)
{
if ((picnum < 15) && (s_playermodel.modelpage*MAX_MODELSPERPAGE + picnum+1 < s_playermodel.nummodels))
{
Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor+1);
return (menu_move_sound);
}
else if ((picnum == 15) && (s_playermodel.modelpage < s_playermodel.numpages-1))
{
s_playermodel.modelpage++;
Menu_SetCursor(&s_playermodel.menu,s_playermodel.menu.cursor-15);
PlayerModel_UpdateGrid();
return (menu_move_sound);
}
else
return (menu_buzz_sound);
}
break;
case K_MOUSE2:
case K_ESCAPE:
PlayerModel_SaveChanges();
break;
}
return ( Menu_DefaultKey( &s_playermodel.menu, key ) );
}
/*
=================
PlayerModel_PicEvent
=================
*/
static void PlayerModel_PicEvent( void* ptr, int event )
{
int modelnum;
int maxlen;
char* buffptr;
char* pdest;
int i;
if (event != QM_ACTIVATED)
return;
for (i=0; i<PLAYERGRID_ROWS*PLAYERGRID_COLS; i++)
{
// reset
s_playermodel.pics[i].generic.flags &= ~QMF_HIGHLIGHT;
s_playermodel.picbuttons[i].generic.flags |= QMF_PULSEIFFOCUS;
}
// set selected
i = ((menucommon_s*)ptr)->id - ID_PLAYERPIC0;
s_playermodel.pics[i].generic.flags |= QMF_HIGHLIGHT;
s_playermodel.picbuttons[i].generic.flags &= ~QMF_PULSEIFFOCUS;
// get model and strip icon_
modelnum = s_playermodel.modelpage*MAX_MODELSPERPAGE + i;
buffptr = s_playermodel.modelnames[modelnum] + strlen("models/players/");
pdest = strstr(buffptr,"icon_");
if (pdest)
{
// track the whole model/skin name
Q_strncpyz(s_playermodel.modelskin,buffptr,pdest-buffptr+1);
strcat(s_playermodel.modelskin,pdest + 5);
// seperate the model name
maxlen = pdest-buffptr;
if (maxlen > 16)
maxlen = 16;
Q_strncpyz( s_playermodel.modelname.string, buffptr, maxlen );
Q_strupr( s_playermodel.modelname.string );
// seperate the skin name
maxlen = strlen(pdest+5)+1;
if (maxlen > 16)
maxlen = 16;
Q_strncpyz( s_playermodel.skinname.string, pdest+5, maxlen );
Q_strupr( s_playermodel.skinname.string );
s_playermodel.selectedmodel = modelnum;
if( trap_MemoryRemaining() > LOW_MEMORY ) {
PlayerModel_UpdateModel();
}
}
}
/*
=================
PlayerModel_DrawPlayer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -