mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-25 22:10:59 +00:00
models: move Mod_LoadFile to client side
This commit is contained in:
parent
bbcc0ed222
commit
98cc9c1ea0
13 changed files with 412 additions and 352 deletions
2
Makefile
2
Makefile
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
388
src/common/models.c
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue