models: move Mod_LoadFile to client side

This commit is contained in:
Denis Pauk 2024-05-01 11:00:33 +03:00
parent bbcc0ed222
commit 98cc9c1ea0
13 changed files with 412 additions and 352 deletions

View file

@ -1008,6 +1008,7 @@ CLIENT_OBJS_ := \
src/common/filesystem.o \
src/common/glob.o \
src/common/md4.o \
src/common/models.o \
src/common/movemsg.o \
src/common/frame.o \
src/common/netchan.o \
@ -1296,6 +1297,7 @@ SERVER_OBJS_ := \
src/common/glob.o \
src/common/md4.o \
src/common/frame.o \
src/common/models.o \
src/common/movemsg.o \
src/common/netchan.o \
src/common/pmove.o \

View file

@ -1495,7 +1495,7 @@ Mod_LoadModel_MD3(const char *mod_name, const void *buffer, int modfilelen,
{
const md3_shader_t *md3_shader = (md3_shader_t*)((byte*)buffer + meshofs + LittleLong(md3_mesh->ofs_shaders)) + j;
strncpy(skin, md3_shader->name, MAX_SKINNAME - 1);
strncpy(skin, md3_shader->name, Q_min(sizeof(md3_shader->name), MAX_SKINNAME) - 1);
skin += MAX_SKINNAME;
}
@ -1943,50 +1943,6 @@ Mod_LoadModel_MD2(const char *mod_name, const void *buffer, int modfilelen,
return extradata;
}
static void
Mod_LoadSkinList_MD2(const char *mod_name, const void *buffer, int modfilelen,
char **skins, int *numskins)
{
dmdl_t pinmodel;
int i;
if (modfilelen < sizeof(pinmodel))
{
R_Printf(PRINT_ALL, "%s: %s has incorrect header size (%i should be " YQ2_COM_PRIdS ")\n",
__func__, mod_name, modfilelen, sizeof(pinmodel));
return;
}
for (i = 0; i < sizeof(pinmodel) / sizeof(int); i++)
{
((int *)&pinmodel)[i] = LittleLong(((int *)buffer)[i]);
}
if (pinmodel.version != ALIAS_VERSION)
{
R_Printf(PRINT_ALL, "%s: %s has wrong version number (%i should be %i)\n",
__func__, mod_name, pinmodel.version, ALIAS_VERSION);
}
if (pinmodel.ofs_end < 0 || pinmodel.ofs_end > modfilelen)
{
R_Printf(PRINT_ALL, "%s: model %s file size(%d) too small, should be %d\n",
__func__, mod_name, modfilelen, pinmodel.ofs_end);
}
if (pinmodel.num_skins < 0)
{
R_Printf(PRINT_ALL, "%s: model %s file has incorrect skins count %d\n",
__func__, mod_name, pinmodel.num_skins);
}
*numskins = pinmodel.num_skins;
*skins = malloc(pinmodel.num_skins * MAX_SKINNAME);
memcpy(*skins, (char *)buffer + pinmodel.ofs_skins,
pinmodel.num_skins * MAX_SKINNAME);
}
/*
=============
Mod_LoadModel_Flex
@ -2685,19 +2641,6 @@ Mod_LoadMinMaxUpdate(const char *mod_name, vec3_t mins, vec3_t maxs, void *extra
}
}
static void
Mod_LoadSkinList(const char *mod_name, const void *buffer, int modfilelen,
char **skins, int *numskins)
{
switch (LittleLong(*(unsigned *)buffer))
{
case IDALIASHEADER:
Mod_LoadSkinList_MD2(mod_name, buffer, modfilelen,
skins, numskins);
break;
}
}
/*
=================
Mod_LoadModel
@ -2783,294 +2726,6 @@ Mod_LoadModel(const char *mod_name, const void *buffer, int modfilelen,
return extradata;
}
/* Add md5 to full file name */
static void
Mod_LoadFileInsertMD5(char *newname, const char *oldname, int size)
{
const char *filename;
filename = COM_SkipPath(oldname);
memset(newname, 0, size);
memcpy(newname, oldname, strlen(oldname) - strlen(filename));
Q_strlcat(newname, "md5/", size);
Q_strlcat(newname, filename, size);
}
static int
Mod_LoadFileMD5Merge(const char *namewe, void **buffer)
{
int fullsize, filesize_anim, filesize, filesize_skins;
char *final_buffer = NULL, *skins_list = NULL;
void *anim_buffer = NULL, *skins_buffer = NULL;
qboolean md5path = false;
char newname[256];
/* search mesh file */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".md5mesh", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
/* check overwrite file */
if (filesize <= 0)
{
char md5modelname[256];
Mod_LoadFileInsertMD5(md5modelname, newname, sizeof(md5modelname));
filesize = ri.FS_LoadFile(md5modelname, buffer);
/* no replace file */
if (filesize <= 0)
{
return filesize;
}
md5path = true;
strcpy(newname, md5modelname);
}
/* search animation file */
memcpy(newname + strlen(newname) - strlen("mesh"), "anim", strlen("anim"));
filesize_anim = ri.FS_LoadFile(newname, &anim_buffer);
if (filesize_anim <= 0)
{
ri.FS_FreeFile(*buffer);
return filesize;
}
/* search skins list */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".md2", sizeof(newname));
filesize_skins = ri.FS_LoadFile(newname, &skins_buffer);
if (filesize_skins > 0)
{
char *skins = NULL;
int numskins = 0, i;
Mod_LoadSkinList(newname, skins_buffer, filesize_skins,
&skins, &numskins);
ri.FS_FreeFile(skins_buffer);
/*
* 20 -> numSkins <num> | skin <num> "MAX_SKINNAME" + md5
*/
skins_list = malloc((numskins + 1) * (MAX_SKINNAME + 20));
sprintf(skins_list, "\nnumSkins %d\n", numskins);
for(i = 0; i < numskins; i++)
{
const char *skinname = skins + MAX_SKINNAME * i;
if (!md5path)
{
sprintf(skins_list + strlen(skins_list), "skin %d \"%s\"\n",
i, skinname);
}
else
{
char md5skinname[256];
Mod_LoadFileInsertMD5(md5skinname, skinname, sizeof(md5skinname));
sprintf(skins_list + strlen(skins_list), "skin %d \"%s\"\n",
i, md5skinname);
}
}
}
/* prepare final file */
fullsize = filesize + filesize_anim + 1;
if (skins_list)
{
fullsize += strlen(skins_list);
}
/* allocate new buffer, ERR_FATAL on alloc fail */
final_buffer = ri.FS_AllocFile(fullsize);
/* copy combined information */
memcpy(final_buffer, *buffer, filesize);
if (skins_list)
{
memcpy(final_buffer + filesize, skins_list, strlen(skins_list));
filesize += strlen(skins_list);
free(skins_list);
}
final_buffer[filesize] = 0;
memcpy(final_buffer + filesize + 1, anim_buffer, filesize_anim);
/* Remove old buffers */
ri.FS_FreeFile(anim_buffer);
ri.FS_FreeFile(*buffer);
*buffer = final_buffer;
return fullsize;
}
static int
Mod_LoadFileWithoutExt(const char *namewe, void **buffer, const char* ext)
{
char newname[256];
size_t tlen;
*buffer = NULL;
tlen = strlen(namewe);
if (!strcmp(ext, "fm") ||
!strcmp(ext, "dkm") ||
!strcmp(ext, "md2") ||
!strcmp(ext, "md3") ||
!strcmp(ext, "md5mesh") ||
!strcmp(ext, "mdx") ||
!strcmp(ext, "mdl"))
{
int filesize;
/* Check ReRelease / Doom 3 / Quake 4 model */
filesize = Mod_LoadFileMD5Merge(namewe, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as md5 (Doom 3)\n",
__func__, namewe);
return filesize;
}
/* Check Quake 3 model */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcpy(newname + tlen, ".md3", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as md3 (Quake 3)\n",
__func__, namewe);
return filesize;
}
/* Check Heretic2 model */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".fm", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as fm (Heretic 2)\n",
__func__, namewe);
return filesize;
}
/* Check Quake 2 model */
Q_strlcpy(newname + tlen, ".md2", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as md2 (Quake 2/Anachronox)\n",
__func__, namewe);
return filesize;
}
/* Check Kingpin model */
Q_strlcpy(newname + tlen, ".mdx", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as mdx (Kingpin)\n",
__func__, namewe);
return filesize;
}
/* Check Daikatana model */
Q_strlcpy(newname + tlen, ".dkm", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as dkm (Daikatana)\n",
__func__, namewe);
return filesize;
}
/* Check Quake model */
Q_strlcpy(newname + tlen, ".mdl", sizeof(newname));
filesize = ri.FS_LoadFile(newname, buffer);
if (filesize > 0)
{
R_Printf(PRINT_DEVELOPER, "%s: %s loaded as mdl (Quake 1)\n",
__func__, namewe);
return filesize;
}
}
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".", sizeof(newname));
Q_strlcat(newname, ext, sizeof(newname));
return ri.FS_LoadFile(newname, buffer);
}
/*
=================
Mod_LoadFile
=================
*/
int
Mod_LoadFile(const char *name, void **buffer)
{
char namewe[256];
const char* ext;
int filesize, len;
size_t tlen;
if (!name)
{
return -1;
}
ext = COM_FileExtension(name);
if(!ext[0])
{
/* file has no extension */
return -1;
}
len = strlen(name);
if (len < 5)
{
return -1;
}
/* Remove the extension */
tlen = len - (strlen(ext) + 1);
memset(namewe, 0, 256);
memcpy(namewe, name, tlen);
filesize = Mod_LoadFileWithoutExt(namewe, buffer, ext);
if (filesize > 0)
{
return filesize;
}
/* Replacement of ReRelease models */
if (!strcmp(namewe, "models/monsters/soldierh/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/soldier/tris",
buffer, ext);
}
else if (!strcmp(namewe, "models/monsters/gladb/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/gladiatr/tris",
buffer, ext);
}
else if (!strcmp(namewe, "models/monsters/boss5/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/boss1/tris",
buffer, ext);
}
else if (!strcmp(namewe, "models/monsters/bitch2/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/bitch/tris",
buffer, ext);
}
return filesize;
}
/*
=================
Mod_ReLoad

View file

@ -443,7 +443,7 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
strcpy(mod->name, name);
/* load the file */
modfilelen = Mod_LoadFile(mod->name, &buf);
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
if (!buf)
{

View file

@ -444,7 +444,7 @@ Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash)
strcpy(mod->name, name);
/* load the file */
modfilelen = Mod_LoadFile(mod->name, &buf);
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
if (!buf)
{

View file

@ -444,7 +444,7 @@ Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash)
strcpy(mod->name, name);
/* load the file */
modfilelen = Mod_LoadFile(mod->name, &buf);
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
if (!buf)
{

View file

@ -368,7 +368,6 @@ extern const void *Mod_LoadBSPXFindLump(const bspx_header_t *bspx_header,
extern const bspx_header_t *Mod_LoadBSPX(int filesize, const byte *mod_base,
maptype_t maptype);
extern int Mod_LoadBSPXDecoupledLM(const dlminfo_t* lminfos, int surfnum, msurface_t *out);
extern int Mod_LoadFile(const char *name, void **buffer);
extern int Mod_CalcNonModelLumpHunkSize(const byte *mod_base, const dheader_t *header,
maptype_t maptype);

View file

@ -451,7 +451,7 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
strcpy(mod->name, name);
/* load the file */
modfilelen = Mod_LoadFile(mod->name, &buf);
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
if (!buf)
{

View file

@ -418,7 +418,7 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
strcpy(mod->name, name);
/* load the file */
modfilelen = Mod_LoadFile(mod->name, &buf);
modfilelen = ri.Mod_LoadFile(mod->name, &buf);
if (!buf)
{

View file

@ -258,6 +258,9 @@ typedef struct
qboolean (IMPORT *GLimp_GetDesktopMode)(int *pwidth, int *pheight);
void (IMPORT *Vid_RequestRestart)(ref_restart_t rs);
/* Rerelease: Get file from cache/converted */
int (IMPORT *Mod_LoadFile)(const char *path, void **buffer);
} refimport_t;
// this is the only function actually exported at the linker level

View file

@ -439,6 +439,7 @@ VID_LoadRenderer(void)
ri.FS_Gamedir = FS_Gamedir;
ri.FS_LoadFile = FS_LoadFile;
ri.FS_AllocFile = Z_Malloc;
ri.Mod_LoadFile = Mod_LoadFile;
ri.GLimp_InitGraphics = GLimp_InitGraphics;
ri.GLimp_GetDesktopMode = GLimp_GetDesktopMode;
ri.Sys_Error = Com_Error;

View file

@ -2114,3 +2114,11 @@ CM_ClusterPHS(int cluster)
return phsrow;
}
/*
* Return file content for most case but could cache converted file in future
*/
int
CM_LoadFile(const char *path, void **buffer)
{
return -1;
}

View file

@ -680,6 +680,10 @@ int CM_WriteAreaBits(byte *buffer, int area);
qboolean CM_HeadnodeVisible(int headnode, byte *visbits);
void CM_WritePortalState(FILE *f);
int CM_LoadFile(const char *path, void **buffer);
/* Shared Model load code */
int Mod_LoadFile(const char *path, void **buffer);
/* PLAYER MOVEMENT CODE */

388
src/common/models.c Normal file
View file

@ -0,0 +1,388 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* The collision model. Slaps "boxes" through the world and checks if
* they collide with the world model, entities or other boxes.
*
* =======================================================================
*/
#include "header/common.h"
static void
Mod_LoadSkinList_MD2(const char *mod_name, const void *buffer, int modfilelen,
char **skins, int *numskins)
{
dmdl_t pinmodel;
int i;
if (modfilelen < sizeof(pinmodel))
{
Com_Printf("%s: %s has incorrect header size (%i should be " YQ2_COM_PRIdS ")\n",
__func__, mod_name, modfilelen, sizeof(pinmodel));
return;
}
for (i = 0; i < sizeof(pinmodel) / sizeof(int); i++)
{
((int *)&pinmodel)[i] = LittleLong(((int *)buffer)[i]);
}
if (pinmodel.version != ALIAS_VERSION)
{
Com_Printf("%s: %s has wrong version number (%i should be %i)\n",
__func__, mod_name, pinmodel.version, ALIAS_VERSION);
}
if (pinmodel.ofs_end < 0 || pinmodel.ofs_end > modfilelen)
{
Com_Printf("%s: model %s file size(%d) too small, should be %d\n",
__func__, mod_name, modfilelen, pinmodel.ofs_end);
}
if (pinmodel.num_skins < 0)
{
Com_Printf("%s: model %s file has incorrect skins count %d\n",
__func__, mod_name, pinmodel.num_skins);
}
*numskins = pinmodel.num_skins;
*skins = malloc(pinmodel.num_skins * MAX_SKINNAME);
memcpy(*skins, (char *)buffer + pinmodel.ofs_skins,
pinmodel.num_skins * MAX_SKINNAME);
}
static void
Mod_LoadSkinList(const char *mod_name, const void *buffer, int modfilelen,
char **skins, int *numskins)
{
switch (LittleLong(*(unsigned *)buffer))
{
case IDALIASHEADER:
Mod_LoadSkinList_MD2(mod_name, buffer, modfilelen,
skins, numskins);
break;
}
}
/* Add md5 to full file name */
static void
Mod_LoadFileInsertMD5(char *newname, const char *oldname, int size)
{
const char *filename;
filename = COM_SkipPath(oldname);
memset(newname, 0, size);
memcpy(newname, oldname, strlen(oldname) - strlen(filename));
Q_strlcat(newname, "md5/", size);
Q_strlcat(newname, filename, size);
}
static int
Mod_LoadFileMD5Merge(const char *namewe, void **buffer)
{
int fullsize, filesize_anim, filesize, filesize_skins;
char *final_buffer = NULL, *skins_list = NULL;
void *anim_buffer = NULL, *skins_buffer = NULL;
qboolean md5path = false;
char newname[256];
/* search mesh file */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".md5mesh", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
/* check overwrite file */
if (filesize <= 0)
{
char md5modelname[256];
Mod_LoadFileInsertMD5(md5modelname, newname, sizeof(md5modelname));
filesize = FS_LoadFile(md5modelname, buffer);
/* no replace file */
if (filesize <= 0)
{
return filesize;
}
md5path = true;
strcpy(newname, md5modelname);
}
/* search animation file */
memcpy(newname + strlen(newname) - strlen("mesh"), "anim", strlen("anim"));
filesize_anim = FS_LoadFile(newname, &anim_buffer);
if (filesize_anim <= 0)
{
FS_FreeFile(*buffer);
return filesize;
}
/* search skins list */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".md2", sizeof(newname));
filesize_skins = FS_LoadFile(newname, &skins_buffer);
if (filesize_skins > 0)
{
char *skins = NULL;
int numskins = 0, i;
Mod_LoadSkinList(newname, skins_buffer, filesize_skins,
&skins, &numskins);
FS_FreeFile(skins_buffer);
/*
* 20 -> numSkins <num> | skin <num> "MAX_SKINNAME" + md5
*/
skins_list = malloc((numskins + 1) * (MAX_SKINNAME + 20));
sprintf(skins_list, "\nnumSkins %d\n", numskins);
for(i = 0; i < numskins; i++)
{
const char *skinname = skins + MAX_SKINNAME * i;
if (!md5path)
{
sprintf(skins_list + strlen(skins_list), "skin %d \"%s\"\n",
i, skinname);
}
else
{
char md5skinname[256];
Mod_LoadFileInsertMD5(md5skinname, skinname, sizeof(md5skinname));
sprintf(skins_list + strlen(skins_list), "skin %d \"%s\"\n",
i, md5skinname);
}
}
}
/* prepare final file */
fullsize = filesize + filesize_anim + 1;
if (skins_list)
{
fullsize += strlen(skins_list);
}
/* allocate new buffer, ERR_FATAL on alloc fail */
final_buffer = Z_Malloc(fullsize);
/* copy combined information */
memcpy(final_buffer, *buffer, filesize);
if (skins_list)
{
memcpy(final_buffer + filesize, skins_list, strlen(skins_list));
filesize += strlen(skins_list);
free(skins_list);
}
final_buffer[filesize] = 0;
memcpy(final_buffer + filesize + 1, anim_buffer, filesize_anim);
/* Remove old buffers */
FS_FreeFile(anim_buffer);
FS_FreeFile(*buffer);
*buffer = final_buffer;
return fullsize;
}
static int
Mod_LoadFileWithoutExt(const char *namewe, void **buffer, const char* ext)
{
char newname[256];
size_t tlen;
*buffer = NULL;
tlen = strlen(namewe);
if (!strcmp(ext, "fm") ||
!strcmp(ext, "dkm") ||
!strcmp(ext, "md2") ||
!strcmp(ext, "md3") ||
!strcmp(ext, "md5mesh") ||
!strcmp(ext, "mdx") ||
!strcmp(ext, "mdl"))
{
int filesize;
/* Check ReRelease / Doom 3 / Quake 4 model */
filesize = Mod_LoadFileMD5Merge(namewe, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as md5 (Doom 3)\n",
__func__, namewe);
return filesize;
}
/* Check Quake 3 model */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcpy(newname + tlen, ".md3", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as md3 (Quake 3)\n",
__func__, namewe);
return filesize;
}
/* Check Heretic2 model */
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".fm", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as fm (Heretic 2)\n",
__func__, namewe);
return filesize;
}
/* Check Quake 2 model */
Q_strlcpy(newname + tlen, ".md2", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as md2 (Quake 2/Anachronox)\n",
__func__, namewe);
return filesize;
}
/* Check Kingpin model */
Q_strlcpy(newname + tlen, ".mdx", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as mdx (Kingpin)\n",
__func__, namewe);
return filesize;
}
/* Check Daikatana model */
Q_strlcpy(newname + tlen, ".dkm", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as dkm (Daikatana)\n",
__func__, namewe);
return filesize;
}
/* Check Quake model */
Q_strlcpy(newname + tlen, ".mdl", sizeof(newname));
filesize = FS_LoadFile(newname, buffer);
if (filesize > 0)
{
Com_DPrintf("%s: %s loaded as mdl (Quake 1)\n",
__func__, namewe);
return filesize;
}
}
if (!strcmp(ext, "bsp"))
{
int filesize;
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".", sizeof(newname));
Q_strlcat(newname, ext, sizeof(newname));
filesize = CM_LoadFile(newname, buffer);
if (filesize > 0)
{
return filesize;
}
}
Q_strlcpy(newname, namewe, sizeof(newname));
Q_strlcat(newname, ".", sizeof(newname));
Q_strlcat(newname, ext, sizeof(newname));
return FS_LoadFile(newname, buffer);
}
/*
=================
Mod_LoadFile
=================
*/
int
Mod_LoadFile(const char *name, void **buffer)
{
char namewe[256];
const char* ext;
int filesize, len;
size_t tlen;
if (!name)
{
return -1;
}
ext = COM_FileExtension(name);
if(!ext[0])
{
/* file has no extension */
return -1;
}
len = strlen(name);
if (len < 5)
{
return -1;
}
/* Remove the extension */
tlen = len - (strlen(ext) + 1);
memset(namewe, 0, 256);
memcpy(namewe, name, tlen);
filesize = Mod_LoadFileWithoutExt(namewe, buffer, ext);
if (filesize > 0)
{
return filesize;
}
/* Replacement of ReRelease models */
if (!strcmp(namewe, "models/monsters/soldierh/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/soldier/tris",
buffer, ext);
}
else if (!strcmp(namewe, "models/monsters/gladb/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/gladiatr/tris",
buffer, ext);
}
else if (!strcmp(namewe, "models/monsters/boss5/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/boss1/tris",
buffer, ext);
}
else if (!strcmp(namewe, "models/monsters/bitch2/tris"))
{
filesize = Mod_LoadFileWithoutExt("models/monsters/bitch/tris",
buffer, ext);
}
return filesize;
}