mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-22 20:51:31 +00:00
models: add mdx / Kingpin models support
Without meshes support. Based on documentation from https://kingpin.info/?p=mdx Author: tical@kingpin.com
This commit is contained in:
parent
ffeabf4007
commit
b30dd7dd2d
2 changed files with 151 additions and 20 deletions
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
* Copyright (c) 2005-2015 David HENRY
|
||||
* Copyright (c) 2011 Sajt (https://icculus.org/qshed/qwalk/)
|
||||
*
|
||||
* 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
|
||||
|
@ -1674,11 +1675,11 @@ Mod_LoadModel_MD2(const char *mod_name, const void *buffer, int modfilelen,
|
|||
int ofs_meshes, ofs_skins, ofs_st, ofs_tris, ofs_glcmds, ofs_frames, ofs_end;
|
||||
vec3_t translate = {0, 0, 0};
|
||||
const dtriangle_t *pintri;
|
||||
dmdxmesh_t *mesh_nodes;
|
||||
const dstvert_t *pinst;
|
||||
const int *pincmd;
|
||||
dmdl_t pinmodel;
|
||||
dmdx_t *pheader;
|
||||
dmdxmesh_t *mesh_nodes;
|
||||
void *extradata;
|
||||
int i, framesize;
|
||||
|
||||
|
@ -2230,13 +2231,6 @@ Mod_LoadModel_DKM(const char *mod_name, const void *buffer, int modfilelen,
|
|||
for (i=0 ; i<sizeof(dkm_header_t)/sizeof(int) ; i++)
|
||||
((int *)&header)[i] = LittleLong(((int *)buffer)[i]);
|
||||
|
||||
if (header.ident != DKMHEADER)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: %s has wrong ident (%i should be %i)",
|
||||
__func__, mod_name, header.ident, DKMHEADER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.version != DKM1_VERSION && header.version != DKM2_VERSION)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: %s has wrong version number (%i should be %i)",
|
||||
|
@ -2332,6 +2326,103 @@ Mod_LoadModel_DKM(const char *mod_name, const void *buffer, int modfilelen,
|
|||
return extradata;
|
||||
}
|
||||
|
||||
static void *
|
||||
Mod_LoadModel_MDX(const char *mod_name, const void *buffer, int modfilelen,
|
||||
struct image_s ***skins, int *numskins, modtype_t *type)
|
||||
{
|
||||
dmdx_t dmdxheader, *pheader = NULL;
|
||||
vec3_t translate = {0, 0, 0};
|
||||
mdx_header_t header = {0};
|
||||
dmdxmesh_t *mesh_nodes;
|
||||
void *extradata = NULL;
|
||||
int i;
|
||||
|
||||
if (sizeof(mdx_header_t) > modfilelen)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: model %s file size(%d) too small",
|
||||
__func__, mod_name, modfilelen);
|
||||
}
|
||||
|
||||
/* byte swap the header fields and sanity check */
|
||||
for (i=0 ; i<sizeof(mdx_header_t)/sizeof(int) ; i++)
|
||||
((int *)&header)[i] = LittleLong(((int *)buffer)[i]);
|
||||
|
||||
if (header.version != MDX_VERSION)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: %s has wrong version number (%i should be %i)",
|
||||
__func__, mod_name, header.version, MDX_VERSION);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (header.ofs_end < 0 || header.ofs_end > modfilelen)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: model %s file size(%d) too small, should be %d",
|
||||
__func__, mod_name, modfilelen, header.ofs_end);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy back all values */
|
||||
memset(&dmdxheader, 0, sizeof(dmdxheader));
|
||||
dmdxheader.skinwidth = header.skinwidth;
|
||||
dmdxheader.skinheight = header.skinwidth;
|
||||
/* has same frame structure */
|
||||
if (header.framesize < (
|
||||
sizeof(daliasframe_t) + (header.num_xyz - 1) * sizeof(dtrivertx_t)))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s: model %s has incorrect framesize",
|
||||
__func__, mod_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dmdxheader.framesize = sizeof(daliasxframe_t) - sizeof(dxtrivertx_t);
|
||||
dmdxheader.framesize += header.num_xyz * sizeof(dxtrivertx_t);
|
||||
|
||||
dmdxheader.num_meshes = 1;
|
||||
dmdxheader.num_skins = header.num_skins;
|
||||
dmdxheader.num_xyz = header.num_xyz;
|
||||
dmdxheader.num_st = header.num_xyz;
|
||||
dmdxheader.num_tris = header.num_tris;
|
||||
dmdxheader.num_frames = header.num_frames;
|
||||
/* (count vert + 3 vert * (2 float + 1 int)) + final zero; */
|
||||
dmdxheader.num_glcmds = (10 * dmdxheader.num_tris) + 1 * dmdxheader.num_meshes;
|
||||
|
||||
/* just skip header */
|
||||
dmdxheader.ofs_meshes = sizeof(dmdxheader);
|
||||
dmdxheader.ofs_skins = dmdxheader.ofs_meshes + dmdxheader.num_meshes * sizeof(dmdxmesh_t);
|
||||
dmdxheader.ofs_st = dmdxheader.ofs_skins + dmdxheader.num_skins * MAX_SKINNAME;
|
||||
dmdxheader.ofs_tris = dmdxheader.ofs_st + dmdxheader.num_st * sizeof(dstvert_t);
|
||||
dmdxheader.ofs_frames = dmdxheader.ofs_tris + dmdxheader.num_tris * sizeof(dtriangle_t);
|
||||
dmdxheader.ofs_glcmds = dmdxheader.ofs_frames + dmdxheader.num_frames * dmdxheader.framesize;
|
||||
dmdxheader.ofs_end = dmdxheader.ofs_glcmds + dmdxheader.num_glcmds * sizeof(int);
|
||||
|
||||
*numskins = dmdxheader.num_skins;
|
||||
extradata = Hunk_Begin(dmdxheader.ofs_end + Q_max(*numskins, MAX_MD2SKINS) * sizeof(struct image_s *));
|
||||
pheader = Hunk_Alloc(dmdxheader.ofs_end);
|
||||
*skins = Hunk_Alloc((*numskins) * sizeof(struct image_s *));
|
||||
|
||||
memcpy(pheader, &dmdxheader, sizeof(dmdxheader));
|
||||
|
||||
/* create single mesh */
|
||||
mesh_nodes = (dmdxmesh_t *)((char *)pheader + pheader->ofs_meshes);
|
||||
mesh_nodes[0].ofs_tris = 0;
|
||||
mesh_nodes[0].num_tris = pheader->num_tris;
|
||||
|
||||
memcpy((byte*)pheader + pheader->ofs_skins, (byte *)buffer + header.ofs_skins,
|
||||
pheader->num_skins * MAX_SKINNAME);
|
||||
Mod_LoadSTvertList(pheader,
|
||||
(dstvert_t *)((byte *)buffer + header.ofs_st));
|
||||
Mod_LoadFrames_MD2(pheader, (byte *)buffer + header.ofs_frames,
|
||||
header.framesize, translate);
|
||||
Mod_LoadMD2TriangleList(pheader,
|
||||
(dtriangle_t *)((byte *)buffer + header.ofs_tris));
|
||||
Mod_LoadCmdGenerate(pheader);
|
||||
Mod_LoadFixImages(mod_name, pheader, false);
|
||||
|
||||
*type = mod_alias;
|
||||
|
||||
return extradata;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadSprite_SP2
|
||||
|
@ -2527,6 +2618,11 @@ Mod_LoadModel(const char *mod_name, const void *buffer, int modfilelen,
|
|||
|
||||
switch (LittleLong(*(unsigned *)buffer))
|
||||
{
|
||||
case MDXHEADER:
|
||||
extradata = Mod_LoadModel_MDX(mod_name, buffer, modfilelen,
|
||||
skins, numskins, type);
|
||||
break;
|
||||
|
||||
case DKMHEADER:
|
||||
extradata = Mod_LoadModel_DKM(mod_name, buffer, modfilelen,
|
||||
skins, numskins, type);
|
||||
|
|
|
@ -230,17 +230,17 @@ typedef struct
|
|||
|
||||
typedef struct fmheader_s
|
||||
{
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
int framesize; // byte size of each frame
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
int framesize; // byte size of each frame
|
||||
|
||||
int num_skins;
|
||||
int num_xyz;
|
||||
int num_st; // greater than num_xyz for seams
|
||||
int num_tris;
|
||||
int num_glcmds; // dwords in strip/fan command list
|
||||
int num_frames;
|
||||
int num_mesh_nodes;
|
||||
int num_skins;
|
||||
int num_xyz;
|
||||
int num_st; // greater than num_xyz for seams
|
||||
int num_tris;
|
||||
int num_glcmds; // dwords in strip/fan command list
|
||||
int num_frames;
|
||||
int num_mesh_nodes;
|
||||
} fmheader_t;
|
||||
|
||||
/* Daikatana dkm format */
|
||||
|
@ -270,7 +270,7 @@ typedef struct dkm_header_s
|
|||
int num_tris;
|
||||
int num_glcmds; /* dwords in strip/fan command list */
|
||||
int num_frames;
|
||||
int num_surf; /* no idea */
|
||||
int num_surf; /* num meshes */
|
||||
|
||||
int ofs_skins; /* each skin is a MAX_SKINNAME string */
|
||||
int ofs_st; /* byte offset from start for stverts */
|
||||
|
@ -278,10 +278,45 @@ typedef struct dkm_header_s
|
|||
int ofs_frames; /* offset for first frame */
|
||||
int ofs_glcmds;
|
||||
/* has 52 * num_surf and additional 24 * x structures */
|
||||
int ofs_surf; /* no idea */
|
||||
int ofs_surf; /* meshes */
|
||||
int ofs_end; /* end of file */
|
||||
} dkm_header_t;
|
||||
|
||||
/* Kingpin mdx format */
|
||||
#define MDXHEADER (('X' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||
#define MDX_VERSION 4
|
||||
|
||||
typedef struct mdx_header_s
|
||||
{
|
||||
int ident; /* magic number: "DKMD" */
|
||||
int version; /* version: 1 or 2 */
|
||||
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
|
||||
int framesize; /* byte size of each frame */
|
||||
|
||||
int num_skins;
|
||||
int num_xyz;
|
||||
int num_tris;
|
||||
int num_glcmds; /* dwords in strip/fan command list */
|
||||
int num_frames;
|
||||
int num_sfxdef;
|
||||
int num_sfxent;
|
||||
int num_subobj;
|
||||
|
||||
int ofs_skins; /* each skin is a MAX_SKINNAME string */
|
||||
int ofs_tris; /* offset for dtriangles */
|
||||
int ofs_frames; /* offset for first frame */
|
||||
int ofs_glcmds;
|
||||
int ofs_st;
|
||||
int ofs_sfxdef;
|
||||
int ofs_sfxent;
|
||||
int ofs_bbox;
|
||||
int ofs_dummyend;
|
||||
int ofs_end;
|
||||
} mdx_header_t;
|
||||
|
||||
/* .MD3 mesh/anim files */
|
||||
#define ID3HEADER (('3' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
||||
#define ID3_VERSION 15
|
||||
|
|
Loading…
Reference in a new issue