From 10402a5f1c91d44e973f5e9bb3433cb9c80c028c Mon Sep 17 00:00:00 2001 From: Shpoike Date: Fri, 25 Aug 2023 07:17:56 +0100 Subject: [PATCH] Support for Q2E's variation of md5s. --- engine/client/cl_demo.c | 3 +++ engine/common/com_mesh.c | 41 ++++++++++++++++++++++++++++++++++++++++ engine/common/fs.c | 3 ++- engine/gl/gl_model.c | 16 ++++++++++++++-- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index be4106051..8c191a75c 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -2135,6 +2135,9 @@ void CL_DemoList_c(int argn, const char *partial, struct xcommandargcompletioncb COM_EnumerateFiles(va("%s*.mvd", partial), CompleteDemoList, ctx); COM_EnumerateFiles(va("%s*.mvd.gz", partial), CompleteDemoList, ctx); + COM_EnumerateFiles(va("%s*.dm2", partial), CompleteDemoList, ctx); + COM_EnumerateFiles(va("%s*.dm2.gz", partial), CompleteDemoList, ctx); + //fixme: show files in both .zip and .dz // COM_EnumerateFiles(va("%s*.dz", partial), CompleteDemoList, ctx); } diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 9442a9b81..50cf69c2e 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -9405,6 +9405,47 @@ static galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *mod } } } +#ifdef MD2MODELS + if (!numskins && strcmp(mod->publicname, mod->name)) + { //try grabbing the names from an original md2 file. + size_t sz; + md2_t *md2 = FS_LoadMallocFile(mod->publicname, &sz); + if (md2) + { + if (!memcmp(md2, MD2IDALIASHEADER) && md2->version == LittleLong(MD2ALIAS_VERSION)) + { + char *p; + const char *str = (const char*)md2 + LittleLong(md2->ofs_skins); + numskins = LittleLong(md2->num_skins); + if (str + numskins*MD2MAX_SKINNAME>(char*)md2+sz) + numskins = 0; + + skin = ZG_Malloc(&mod->memgroup, sizeof(*skin)*numskins); + inf->numskins = numskins; + inf->ofsskins = skin; + for (num = 0; num < numskins; num++, skin++, str += MD2MAX_SKINNAME) + { + skin->skinspeed = 5; //match bsp anim speed. + skin->numframes = 1; + + frames = ZG_Malloc(&mod->memgroup, sizeof(*frames)*skin->numframes); + skin->frame = frames; + + p = COM_SkipPath(mod->publicname); + if (!strncmp(str, mod->publicname, p-mod->publicname)) + { + Q_snprintfz(frames[0].shadername, sizeof(frames[0].shadername), "%s", mod->name); + *COM_SkipPath(frames[0].shadername) = 0; + Q_strncatz(frames[0].shadername, str+(p-mod->publicname), sizeof(frames[0].shadername)); + } + else + Q_snprintfz(frames[0].shadername, sizeof(frames[0].shadername), "%s", str); + } + } + FS_FreeFile(md2); + } + } +#endif if (!numskins) //FIXME: we probably want to support multiple skins some time Q_strncpyz(frames[0].shadername, token, sizeof(frames[0].shadername)); diff --git a/engine/common/fs.c b/engine/common/fs.c index d772ae13c..f49519975 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -58,7 +58,8 @@ /*set some stuff so our regular qw client appears more like hexen2. sv_mintic must be 0.015 to 'fix' the ravenstaff so that its projectiles don't impact upon each other, or even 0.05 to exactly match the hardcoded assumptions in obj_push. There's maps that depend on a low framerate via waterjump framerate-dependance too.*/ #define HEX2CFG "//schemes hexen2\n" "set v_gammainverted 1\nset com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset cl_forwardspeed 200\nset cl_backspeed 200\ncl_sidespeed 225\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavaalpha 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.05\nset r_meshpitch -1\nset r_meshroll -1\nr_sprite_backfacing 1\nset mod_warnmodels 0\nset cl_model_bobbing 1\nsv_sound_watersplash \"misc/hith2o.wav\"\nsv_sound_land \"fx/thngland.wav\"\nset sv_walkpitch 0\n" /*yay q2!*/ -#define Q2CFG "//schemes quake2\n" "set v_gammainverted 1\nset com_parseutf8 0\ncom_gamedirnativecode 1\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)"\ncl_defaultport "STRINGIFY(PORT_Q2SERVER)"\n" +#define Q2CFG "//schemes quake2\n" "set v_gammainverted 1\nset com_parseutf8 0\ncom_gamedirnativecode 1\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)"\ncl_defaultport "STRINGIFY(PORT_Q2SERVER)"\n" \ + "set r_replacemodels " IFMINIMAL("","md3 md5/md5mesh")"\n" /*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/ #define Q3CFG "//schemes quake3\n" "set v_gammainverted 0\nset snd_ignorecueloops 1\nsetfl g_gametype 0 s\nset gl_clear 1\nset r_clearcolour 0 0 0\nset com_parseutf8 0\ngl_overbright "FORWEB("0","2")"\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_gamedirnativecode 1\nsv_port "STRINGIFY(PORT_Q3SERVER)"\ncl_defaultport "STRINGIFY(PORT_Q3SERVER)"\ncom_protocolversion 68\n" //#define RMQCFG "sv_bigcoords 1\n" diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 16937ed7c..cd2a6782d 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1205,8 +1205,20 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b) if (replstr) { - char altname[MAX_QPATH]; - Q_snprintfz(altname, sizeof(altname), "%s.%s", mdlbase, token); + char altname[MAX_QPATH], *sl; + sl = strchr(token, '/'); + if (sl) + { //models/name.mdl -> path/preslash/name.postslash + char *p = COM_SkipPath(mdlbase); + size_t ofs = (p-mdlbase) + (sl+1-token); + memcpy(altname, mdlbase, p-mdlbase); + memcpy(altname+(p-mdlbase), token, sl+1-token); + if (ofs + strlen(p)+strlen(sl+1)+2 > sizeof(altname)) + continue; //erk + Q_snprintfz(altname + ofs, sizeof(altname)-ofs, "%s.%s", p, sl+1); + } + else + Q_snprintfz(altname, sizeof(altname), "%s.%s", mdlbase, token); if (COM_FDepthFile(altname, true) > basedepth) continue;