Merge pull request #1111 from 0lvin/backport

Show weapon in player model preview
This commit is contained in:
Yamagi 2024-06-16 09:53:24 +02:00 committed by GitHub
commit 71ff8bcdfc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 146 additions and 104 deletions

View file

@ -726,7 +726,7 @@ InitMainMenu(void)
static void static void
M_Main_Draw(void) M_Main_Draw(void)
{ {
menucommon_s * item = 0; menucommon_s * item = NULL;
int x = 0; int x = 0;
int y = 0; int y = 0;
@ -752,7 +752,7 @@ M_Main_Key(int key)
void void
M_Menu_Main_f(void) M_Menu_Main_f(void)
{ {
menucommon_s * item = 0; menucommon_s * item = NULL;
InitMainMenu(); InitMainMenu();
@ -2988,7 +2988,7 @@ M_Credits_MenuDraw(void)
} }
} }
const char * static const char *
M_Credits_Key(int key) M_Credits_Key(int key)
{ {
key = Key_GetMenuKey(key); key = Key_GetMenuKey(key);
@ -5253,7 +5253,6 @@ static menuseparator_s s_player_hand_title;
static menuseparator_s s_player_rate_title; static menuseparator_s s_player_rate_title;
static menuaction_s s_player_download_action; static menuaction_s s_player_download_action;
#define MAX_DISPLAYNAME 16
#define MAX_PLAYERMODELS 1024 #define MAX_PLAYERMODELS 1024
typedef struct _stringlist typedef struct _stringlist
@ -5321,7 +5320,8 @@ static qboolean IconOfSkinExists(char* skin, char** pcxfiles, int npcxfiles)
} }
// strip file extension // strip file extension
void StripExtension(char* path) static void
StripExtension(char* path)
{ {
int length; int length;
@ -5370,7 +5370,8 @@ ContainsFile(char* path, char* file)
} }
// replace characters in string // replace characters in string
void ReplaceCharacters(char* s, char r, char c) static void
ReplaceCharacters(char* s, char r, char c)
{ {
char* p = s; char* p = s;
@ -5423,7 +5424,7 @@ dircmp_func(const void* _a, const void* _b)
static void static void
PlayerModelFree() PlayerModelFree()
{ {
char* s = 0; char* s = NULL;
// there should be no valid skin names if there is no valid model // there should be no valid skin names if there is no valid model
if (s_modelname.num != 0) if (s_modelname.num != 0)
@ -5501,17 +5502,18 @@ static qboolean
PlayerDirectoryList(void) PlayerDirectoryList(void)
{ {
char* findname = "players/*"; char* findname = "players/*";
char** list = 0; char** list = NULL;
int num = 0; int num = 0;
// get a list of "players" subdirectories // get a list of "players" subdirectories
if ((list = FS_ListFiles2(findname, &num, 0, 0)) == 0) if ((list = FS_ListFiles2(findname, &num, 0, 0)) == NULL)
{ {
return false; return false;
} }
if (num > MAX_PLAYERMODELS) if (num > MAX_PLAYERMODELS)
{ {
Com_Printf("Too many player models (%d)!\n", num);
num = MAX_PLAYERMODELS - 1; num = MAX_PLAYERMODELS - 1;
} }
@ -5557,10 +5559,8 @@ static qboolean
PlayerModelList(void) PlayerModelList(void)
{ {
char findname[MAX_QPATH]; char findname[MAX_QPATH];
char** list = 0; char** list = NULL;
char** data = 0; char** data = NULL;
char* s = 0;
char* t = 0;
int num = 0; int num = 0;
int mdl = 0; int mdl = 0;
qboolean result = true; qboolean result = true;
@ -5575,6 +5575,10 @@ PlayerModelList(void)
// verify the existence of at least one pcx skin // verify the existence of at least one pcx skin
for (int i = 0; i < s_directory.num; ++i) for (int i = 0; i < s_directory.num; ++i)
{ {
char* s = NULL;
char* t = NULL;
int l;
if (s_directory.data[i] == 0) if (s_directory.data[i] == 0)
{ {
continue; continue;
@ -5584,7 +5588,7 @@ PlayerModelList(void)
strcat(findname, "/*.pcx"); strcat(findname, "/*.pcx");
// get a list of pcx files // get a list of pcx files
if ((list = FS_ListFiles2(findname, &num, 0, 0)) == 0) if ((list = FS_ListFiles2(findname, &num, 0, 0)) == NULL)
{ {
continue; continue;
} }
@ -5647,13 +5651,14 @@ PlayerModelList(void)
{ {
ReplaceCharacters(list[k], '\\', '/'); ReplaceCharacters(list[k], '\\', '/');
s = (char*)malloc(MAX_DISPLAYNAME);
t = strrchr(list[k], '/'); t = strrchr(list[k], '/');
YQ2_COM_CHECK_OOM(s, "malloc()", MAX_DISPLAYNAME * sizeof(char)) l = strlen(t) + 1;
s = (char*)malloc(l);
YQ2_COM_CHECK_OOM(s, "malloc()", l * sizeof(char))
StripExtension(t); StripExtension(t);
Q_strlcpy(s, t + 1, MAX_DISPLAYNAME); Q_strlcpy(s, t + 1, l);
data[s_skinnames[mdl].num++] = s; data[s_skinnames[mdl].num++] = s;
} }
@ -5664,12 +5669,13 @@ PlayerModelList(void)
qsort(s_skinnames[mdl].data, s_skinnames[mdl].num, sizeof(char**), Q_sort_stricmp); qsort(s_skinnames[mdl].data, s_skinnames[mdl].num, sizeof(char**), Q_sort_stricmp);
// at this point we have a valid player model // at this point we have a valid player model
s = (char*)malloc(MAX_DISPLAYNAME);
t = strrchr(s_directory.data[i], '/'); t = strrchr(s_directory.data[i], '/');
l = strlen(t) + 1;
s = (char*)malloc(l);
YQ2_COM_CHECK_OOM(s, "malloc()", MAX_DISPLAYNAME * sizeof(char)) YQ2_COM_CHECK_OOM(s, "malloc()", l * sizeof(char))
Q_strlcpy(s, t + 1, MAX_DISPLAYNAME); Q_strlcpy(s, t + 1, l);
s_modelname.data[s_modelname.num++] = s; s_modelname.data[s_modelname.num++] = s;
mdl = s_modelname.num; mdl = s_modelname.num;
@ -5733,8 +5739,8 @@ PlayerConfig_MenuInit(void)
extern cvar_t *skin; extern cvar_t *skin;
cvar_t *hand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE ); cvar_t *hand = Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
static const char *handedness[] = { "right", "left", "center", 0 }; static const char *handedness[] = { "right", "left", "center", 0 };
char mdlname[MAX_DISPLAYNAME * 2]; char mdlname[MAX_QPATH];
char imgname[MAX_DISPLAYNAME]; char imgname[MAX_QPATH];
int mdlindex = 0; int mdlindex = 0;
int imgindex = 0; int imgindex = 0;
int i = 0; int i = 0;
@ -5745,12 +5751,12 @@ PlayerConfig_MenuInit(void)
return false; return false;
} }
Q_strlcpy(mdlname, skin->string, MAX_DISPLAYNAME * 2); Q_strlcpy(mdlname, skin->string, sizeof(mdlname));
ReplaceCharacters(mdlname, '\\', '/' ); ReplaceCharacters(mdlname, '\\', '/' );
if (strchr(mdlname, '/')) if (strchr(mdlname, '/'))
{ {
Q_strlcpy(imgname, strchr(mdlname, '/') + 1, MAX_DISPLAYNAME); Q_strlcpy(imgname, strchr(mdlname, '/') + 1, sizeof(imgname));
*strchr(mdlname, '/') = 0; *strchr(mdlname, '/') = 0;
} }
else else
@ -5902,9 +5908,9 @@ extern float CalcFov(float fov_x, float w, float h);
* Model animation * Model animation
*/ */
static void static void
PlayerConfig_AnimateModel(entity_t *entity, int curTime) PlayerConfig_AnimateModel(entity_t *entity, int count, int curTime)
{ {
cvar_t *cl_start_frame, *cl_end_frame; const cvar_t *cl_start_frame, *cl_end_frame;
int startFrame, endFrame; int startFrame, endFrame;
cl_start_frame = Cvar_Get("cl_model_preview_start", "84", CVAR_ARCHIVE); cl_start_frame = Cvar_Get("cl_model_preview_start", "84", CVAR_ARCHIVE);
@ -5913,9 +5919,14 @@ PlayerConfig_AnimateModel(entity_t *entity, int curTime)
endFrame = cl_end_frame->value; endFrame = cl_end_frame->value;
if (startFrame >= 0 && endFrame > startFrame) if (startFrame >= 0 && endFrame > startFrame)
{
int i;
for (i = 0; i < count; i ++)
{ {
/* salute male 84..94 frame */ /* salute male 84..94 frame */
entity->frame = (curTime / 100) % (endFrame - startFrame) + startFrame; entity[i].frame = (curTime / 100) % (endFrame - startFrame) + startFrame;
}
} }
} }
@ -5940,36 +5951,67 @@ PlayerConfig_MenuDraw(void)
&& (s_player_skin_box.curvalue >= 0 && (s_player_skin_box.curvalue >= 0
&& s_player_skin_box.curvalue < s_skinnames[s_player_model_box.curvalue].num)) && s_player_skin_box.curvalue < s_skinnames[s_player_model_box.curvalue].num))
{ {
entity_t entity; entity_t entities[2];
char scratch[MAX_QPATH]; char scratch[MAX_QPATH];
char* mdlname = s_modelname.data[s_player_model_box.curvalue]; char* mdlname = s_modelname.data[s_player_model_box.curvalue];
char* imgname = s_skinnames[s_player_model_box.curvalue].data[s_player_skin_box.curvalue]; char* imgname = s_skinnames[s_player_model_box.curvalue].data[s_player_skin_box.curvalue];
int i, curTime;
memset(&entity, 0, sizeof(entity)); memset(&entities, 0, sizeof(entities));
Com_sprintf(scratch, sizeof(scratch), "players/%s/tris.md2", mdlname); Com_sprintf(scratch, sizeof(scratch), "players/%s/tris.md2", mdlname);
entity.model = R_RegisterModel(scratch); entities[0].model = R_RegisterModel(scratch);
Com_sprintf(scratch, sizeof(scratch), "players/%s/%s.pcx", mdlname, Com_sprintf(scratch, sizeof(scratch), "players/%s/%s.pcx", mdlname,
imgname); imgname);
entity.skin = R_RegisterSkin(scratch); entities[0].skin = R_RegisterSkin(scratch);
entity.flags = RF_FULLBRIGHT;
entity.origin[0] = 80; curTime = Sys_Milliseconds();
entity.origin[1] = 0;
entity.origin[2] = 0; /* multiplayer weapons loaded */
VectorCopy(entity.origin, entity.oldorigin); if (num_cl_weaponmodels)
entity.frame = 0; {
entity.oldframe = 0; int weapon_id;
entity.backlerp = 0.0;
/* change weapon every 3 rounds */
weapon_id = curTime / 9000;
weapon_id = weapon_id % num_cl_weaponmodels;
/* show weapon also */
Com_sprintf(scratch, sizeof(scratch),
"players/%s/%s", mdlname, cl_weaponmodels[weapon_id]);
entities[1].model = R_RegisterModel(scratch);
}
/* no such weapon model */
if (!entities[1].model)
{
/* show weapon also */
Com_sprintf(scratch, sizeof(scratch),
"players/%s/weapon.md2", mdlname);
entities[1].model = R_RegisterModel(scratch);
}
int curTime = Sys_Milliseconds();
PlayerConfig_AnimateModel(&entity, curTime);
// one full turn is 3s = 3000ms => 3000/360 deg per millisecond
curTime = curTime % 3000; curTime = curTime % 3000;
entity.angles[1] = (float)curTime/(3000.0f/360.0f); for (i = 0; i < 2; i++)
{
entities[i].flags = RF_FULLBRIGHT;
entities[i].origin[0] = 80;
entities[i].origin[1] = 0;
entities[i].origin[2] = 0;
VectorCopy(entities[i].origin, entities[i].oldorigin);
entities[i].frame = 0;
entities[i].oldframe = 0;
entities[i].backlerp = 0.0;
// one full turn is 3s = 3000ms => 3000/360 deg per millisecond
entities[i].angles[1] = (float)curTime/(3000.0f/360.0f);
}
PlayerConfig_AnimateModel(entities, 2, curTime);
refdef.areabits = 0; refdef.areabits = 0;
refdef.num_entities = 1; refdef.num_entities = (entities[1].model) ? 2 : 1;
refdef.entities = &entity; refdef.entities = entities;
refdef.lightstyles = 0; refdef.lightstyles = 0;
refdef.rdflags = RDF_NOWORLDMODEL; refdef.rdflags = RDF_NOWORLDMODEL;
@ -5997,9 +6039,9 @@ PlayerConfig_MenuKey(int key)
if (key == K_ESCAPE) if (key == K_ESCAPE)
{ {
char skin[MAX_QPATH]; char skin[MAX_QPATH];
char* name = 0; char* name = NULL;
char* mdl = 0; char* mdl = NULL;
char* img = 0; char* img = NULL;
name = s_player_name_field.buffer; name = s_player_name_field.buffer;
mdl = s_modelname.data[s_player_model_box.curvalue]; mdl = s_modelname.data[s_player_model_box.curvalue];

View file

@ -912,7 +912,7 @@ Cmd_CompleteMapCommand(char *partial)
char *pmatch[1024]; char *pmatch[1024];
qboolean partialFillContinue = true; qboolean partialFillContinue = true;
if ((mapNames = FS_ListFiles2("maps/*.bsp", &nMaps, 0, 0)) != 0) if ((mapNames = FS_ListFiles2("maps/*.bsp", &nMaps, 0, 0)) != NULL)
{ {
len = strlen(partial); len = strlen(partial);
nbMatches = 0; nbMatches = 0;

View file

@ -321,7 +321,7 @@ void SV_ListMaps_f(void)
Com_Printf("\n"); Com_Printf("\n");
if ((userMapNames = FS_ListFiles2("maps/*.bsp", &nUserMaps, 0, 0)) != 0) if ((userMapNames = FS_ListFiles2("maps/*.bsp", &nUserMaps, 0, 0)) != NULL)
{ {
for (i = 0; i < nUserMaps - 1; i++) for (i = 0; i < nUserMaps - 1; i++)
{ {