mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-29 05:41:02 +00:00
Common model format, with MD2/MD3 loading
This commit is contained in:
parent
9d5622c0bc
commit
295ca25171
19 changed files with 2319 additions and 516 deletions
|
@ -58,8 +58,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
|
||||||
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
|
||||||
|
|
||||||
//Hurdler: added for new development
|
//Hurdler: added for new development
|
||||||
EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale);
|
EXPORT void HWRAPI(DrawModel) (model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
|
||||||
EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
|
|
||||||
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
|
||||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||||
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
|
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
|
||||||
|
@ -96,8 +95,7 @@ struct hwdriver_s
|
||||||
GClipRect pfnGClipRect;
|
GClipRect pfnGClipRect;
|
||||||
ClearMipMapCache pfnClearMipMapCache;
|
ClearMipMapCache pfnClearMipMapCache;
|
||||||
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
|
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
|
||||||
DrawMD2 pfnDrawMD2;
|
DrawModel pfnDrawModel;
|
||||||
DrawMD2i pfnDrawMD2i;
|
|
||||||
SetTransform pfnSetTransform;
|
SetTransform pfnSetTransform;
|
||||||
GetTextureUsed pfnGetTextureUsed;
|
GetTextureUsed pfnGetTextureUsed;
|
||||||
GetRenderVersion pfnGetRenderVersion;
|
GetRenderVersion pfnGetRenderVersion;
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "../r_draw.h"
|
#include "../r_draw.h"
|
||||||
#include "../p_tick.h"
|
#include "../p_tick.h"
|
||||||
#include "../k_kart.h" // colortranslations
|
#include "../k_kart.h" // colortranslations
|
||||||
|
#include "hw_model.h"
|
||||||
|
|
||||||
#include "hw_main.h"
|
#include "hw_main.h"
|
||||||
#include "../v_video.h"
|
#include "../v_video.h"
|
||||||
|
@ -75,172 +76,6 @@
|
||||||
#include "errno.h"
|
#include "errno.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define NUMVERTEXNORMALS 162
|
|
||||||
float avertexnormals[NUMVERTEXNORMALS][3] = {
|
|
||||||
{-0.525731f, 0.000000f, 0.850651f},
|
|
||||||
{-0.442863f, 0.238856f, 0.864188f},
|
|
||||||
{-0.295242f, 0.000000f, 0.955423f},
|
|
||||||
{-0.309017f, 0.500000f, 0.809017f},
|
|
||||||
{-0.162460f, 0.262866f, 0.951056f},
|
|
||||||
{0.000000f, 0.000000f, 1.000000f},
|
|
||||||
{0.000000f, 0.850651f, 0.525731f},
|
|
||||||
{-0.147621f, 0.716567f, 0.681718f},
|
|
||||||
{0.147621f, 0.716567f, 0.681718f},
|
|
||||||
{0.000000f, 0.525731f, 0.850651f},
|
|
||||||
{0.309017f, 0.500000f, 0.809017f},
|
|
||||||
{0.525731f, 0.000000f, 0.850651f},
|
|
||||||
{0.295242f, 0.000000f, 0.955423f},
|
|
||||||
{0.442863f, 0.238856f, 0.864188f},
|
|
||||||
{0.162460f, 0.262866f, 0.951056f},
|
|
||||||
{-0.681718f, 0.147621f, 0.716567f},
|
|
||||||
{-0.809017f, 0.309017f, 0.500000f},
|
|
||||||
{-0.587785f, 0.425325f, 0.688191f},
|
|
||||||
{-0.850651f, 0.525731f, 0.000000f},
|
|
||||||
{-0.864188f, 0.442863f, 0.238856f},
|
|
||||||
{-0.716567f, 0.681718f, 0.147621f},
|
|
||||||
{-0.688191f, 0.587785f, 0.425325f},
|
|
||||||
{-0.500000f, 0.809017f, 0.309017f},
|
|
||||||
{-0.238856f, 0.864188f, 0.442863f},
|
|
||||||
{-0.425325f, 0.688191f, 0.587785f},
|
|
||||||
{-0.716567f, 0.681718f, -0.147621f},
|
|
||||||
{-0.500000f, 0.809017f, -0.309017f},
|
|
||||||
{-0.525731f, 0.850651f, 0.000000f},
|
|
||||||
{0.000000f, 0.850651f, -0.525731f},
|
|
||||||
{-0.238856f, 0.864188f, -0.442863f},
|
|
||||||
{0.000000f, 0.955423f, -0.295242f},
|
|
||||||
{-0.262866f, 0.951056f, -0.162460f},
|
|
||||||
{0.000000f, 1.000000f, 0.000000f},
|
|
||||||
{0.000000f, 0.955423f, 0.295242f},
|
|
||||||
{-0.262866f, 0.951056f, 0.162460f},
|
|
||||||
{0.238856f, 0.864188f, 0.442863f},
|
|
||||||
{0.262866f, 0.951056f, 0.162460f},
|
|
||||||
{0.500000f, 0.809017f, 0.309017f},
|
|
||||||
{0.238856f, 0.864188f, -0.442863f},
|
|
||||||
{0.262866f, 0.951056f, -0.162460f},
|
|
||||||
{0.500000f, 0.809017f, -0.309017f},
|
|
||||||
{0.850651f, 0.525731f, 0.000000f},
|
|
||||||
{0.716567f, 0.681718f, 0.147621f},
|
|
||||||
{0.716567f, 0.681718f, -0.147621f},
|
|
||||||
{0.525731f, 0.850651f, 0.000000f},
|
|
||||||
{0.425325f, 0.688191f, 0.587785f},
|
|
||||||
{0.864188f, 0.442863f, 0.238856f},
|
|
||||||
{0.688191f, 0.587785f, 0.425325f},
|
|
||||||
{0.809017f, 0.309017f, 0.500000f},
|
|
||||||
{0.681718f, 0.147621f, 0.716567f},
|
|
||||||
{0.587785f, 0.425325f, 0.688191f},
|
|
||||||
{0.955423f, 0.295242f, 0.000000f},
|
|
||||||
{1.000000f, 0.000000f, 0.000000f},
|
|
||||||
{0.951056f, 0.162460f, 0.262866f},
|
|
||||||
{0.850651f, -0.525731f, 0.000000f},
|
|
||||||
{0.955423f, -0.295242f, 0.000000f},
|
|
||||||
{0.864188f, -0.442863f, 0.238856f},
|
|
||||||
{0.951056f, -0.162460f, 0.262866f},
|
|
||||||
{0.809017f, -0.309017f, 0.500000f},
|
|
||||||
{0.681718f, -0.147621f, 0.716567f},
|
|
||||||
{0.850651f, 0.000000f, 0.525731f},
|
|
||||||
{0.864188f, 0.442863f, -0.238856f},
|
|
||||||
{0.809017f, 0.309017f, -0.500000f},
|
|
||||||
{0.951056f, 0.162460f, -0.262866f},
|
|
||||||
{0.525731f, 0.000000f, -0.850651f},
|
|
||||||
{0.681718f, 0.147621f, -0.716567f},
|
|
||||||
{0.681718f, -0.147621f, -0.716567f},
|
|
||||||
{0.850651f, 0.000000f, -0.525731f},
|
|
||||||
{0.809017f, -0.309017f, -0.500000f},
|
|
||||||
{0.864188f, -0.442863f, -0.238856f},
|
|
||||||
{0.951056f, -0.162460f, -0.262866f},
|
|
||||||
{0.147621f, 0.716567f, -0.681718f},
|
|
||||||
{0.309017f, 0.500000f, -0.809017f},
|
|
||||||
{0.425325f, 0.688191f, -0.587785f},
|
|
||||||
{0.442863f, 0.238856f, -0.864188f},
|
|
||||||
{0.587785f, 0.425325f, -0.688191f},
|
|
||||||
{0.688191f, 0.587785f, -0.425325f},
|
|
||||||
{-0.147621f, 0.716567f, -0.681718f},
|
|
||||||
{-0.309017f, 0.500000f, -0.809017f},
|
|
||||||
{0.000000f, 0.525731f, -0.850651f},
|
|
||||||
{-0.525731f, 0.000000f, -0.850651f},
|
|
||||||
{-0.442863f, 0.238856f, -0.864188f},
|
|
||||||
{-0.295242f, 0.000000f, -0.955423f},
|
|
||||||
{-0.162460f, 0.262866f, -0.951056f},
|
|
||||||
{0.000000f, 0.000000f, -1.000000f},
|
|
||||||
{0.295242f, 0.000000f, -0.955423f},
|
|
||||||
{0.162460f, 0.262866f, -0.951056f},
|
|
||||||
{-0.442863f, -0.238856f, -0.864188f},
|
|
||||||
{-0.309017f, -0.500000f, -0.809017f},
|
|
||||||
{-0.162460f, -0.262866f, -0.951056f},
|
|
||||||
{0.000000f, -0.850651f, -0.525731f},
|
|
||||||
{-0.147621f, -0.716567f, -0.681718f},
|
|
||||||
{0.147621f, -0.716567f, -0.681718f},
|
|
||||||
{0.000000f, -0.525731f, -0.850651f},
|
|
||||||
{0.309017f, -0.500000f, -0.809017f},
|
|
||||||
{0.442863f, -0.238856f, -0.864188f},
|
|
||||||
{0.162460f, -0.262866f, -0.951056f},
|
|
||||||
{0.238856f, -0.864188f, -0.442863f},
|
|
||||||
{0.500000f, -0.809017f, -0.309017f},
|
|
||||||
{0.425325f, -0.688191f, -0.587785f},
|
|
||||||
{0.716567f, -0.681718f, -0.147621f},
|
|
||||||
{0.688191f, -0.587785f, -0.425325f},
|
|
||||||
{0.587785f, -0.425325f, -0.688191f},
|
|
||||||
{0.000000f, -0.955423f, -0.295242f},
|
|
||||||
{0.000000f, -1.000000f, 0.000000f},
|
|
||||||
{0.262866f, -0.951056f, -0.162460f},
|
|
||||||
{0.000000f, -0.850651f, 0.525731f},
|
|
||||||
{0.000000f, -0.955423f, 0.295242f},
|
|
||||||
{0.238856f, -0.864188f, 0.442863f},
|
|
||||||
{0.262866f, -0.951056f, 0.162460f},
|
|
||||||
{0.500000f, -0.809017f, 0.309017f},
|
|
||||||
{0.716567f, -0.681718f, 0.147621f},
|
|
||||||
{0.525731f, -0.850651f, 0.000000f},
|
|
||||||
{-0.238856f, -0.864188f, -0.442863f},
|
|
||||||
{-0.500000f, -0.809017f, -0.309017f},
|
|
||||||
{-0.262866f, -0.951056f, -0.162460f},
|
|
||||||
{-0.850651f, -0.525731f, 0.000000f},
|
|
||||||
{-0.716567f, -0.681718f, -0.147621f},
|
|
||||||
{-0.716567f, -0.681718f, 0.147621f},
|
|
||||||
{-0.525731f, -0.850651f, 0.000000f},
|
|
||||||
{-0.500000f, -0.809017f, 0.309017f},
|
|
||||||
{-0.238856f, -0.864188f, 0.442863f},
|
|
||||||
{-0.262866f, -0.951056f, 0.162460f},
|
|
||||||
{-0.864188f, -0.442863f, 0.238856f},
|
|
||||||
{-0.809017f, -0.309017f, 0.500000f},
|
|
||||||
{-0.688191f, -0.587785f, 0.425325f},
|
|
||||||
{-0.681718f, -0.147621f, 0.716567f},
|
|
||||||
{-0.442863f, -0.238856f, 0.864188f},
|
|
||||||
{-0.587785f, -0.425325f, 0.688191f},
|
|
||||||
{-0.309017f, -0.500000f, 0.809017f},
|
|
||||||
{-0.147621f, -0.716567f, 0.681718f},
|
|
||||||
{-0.425325f, -0.688191f, 0.587785f},
|
|
||||||
{-0.162460f, -0.262866f, 0.951056f},
|
|
||||||
{0.442863f, -0.238856f, 0.864188f},
|
|
||||||
{0.162460f, -0.262866f, 0.951056f},
|
|
||||||
{0.309017f, -0.500000f, 0.809017f},
|
|
||||||
{0.147621f, -0.716567f, 0.681718f},
|
|
||||||
{0.000000f, -0.525731f, 0.850651f},
|
|
||||||
{0.425325f, -0.688191f, 0.587785f},
|
|
||||||
{0.587785f, -0.425325f, 0.688191f},
|
|
||||||
{0.688191f, -0.587785f, 0.425325f},
|
|
||||||
{-0.955423f, 0.295242f, 0.000000f},
|
|
||||||
{-0.951056f, 0.162460f, 0.262866f},
|
|
||||||
{-1.000000f, 0.000000f, 0.000000f},
|
|
||||||
{-0.850651f, 0.000000f, 0.525731f},
|
|
||||||
{-0.955423f, -0.295242f, 0.000000f},
|
|
||||||
{-0.951056f, -0.162460f, 0.262866f},
|
|
||||||
{-0.864188f, 0.442863f, -0.238856f},
|
|
||||||
{-0.951056f, 0.162460f, -0.262866f},
|
|
||||||
{-0.809017f, 0.309017f, -0.500000f},
|
|
||||||
{-0.864188f, -0.442863f, -0.238856f},
|
|
||||||
{-0.951056f, -0.162460f, -0.262866f},
|
|
||||||
{-0.809017f, -0.309017f, -0.500000f},
|
|
||||||
{-0.681718f, 0.147621f, -0.716567f},
|
|
||||||
{-0.681718f, -0.147621f, -0.716567f},
|
|
||||||
{-0.850651f, 0.000000f, -0.525731f},
|
|
||||||
{-0.688191f, 0.587785f, -0.425325f},
|
|
||||||
{-0.587785f, 0.425325f, -0.688191f},
|
|
||||||
{-0.425325f, 0.688191f, -0.587785f},
|
|
||||||
{-0.425325f, -0.688191f, -0.587785f},
|
|
||||||
{-0.587785f, -0.425325f, -0.688191f},
|
|
||||||
{-0.688191f, -0.587785f, -0.425325f},
|
|
||||||
};
|
|
||||||
|
|
||||||
md2_t md2_models[NUMSPRITES];
|
md2_t md2_models[NUMSPRITES];
|
||||||
md2_t md2_playermodels[MAXSKINS];
|
md2_t md2_playermodels[MAXSKINS];
|
||||||
|
|
||||||
|
@ -248,36 +83,9 @@ md2_t md2_playermodels[MAXSKINS];
|
||||||
/*
|
/*
|
||||||
* free model
|
* free model
|
||||||
*/
|
*/
|
||||||
static void md2_freeModel (md2_model_t *model)
|
static void md2_freeModel (model_t *model)
|
||||||
{
|
{
|
||||||
if (model)
|
UnloadModel(model);
|
||||||
{
|
|
||||||
if (model->skins)
|
|
||||||
free(model->skins);
|
|
||||||
|
|
||||||
if (model->texCoords)
|
|
||||||
free(model->texCoords);
|
|
||||||
|
|
||||||
if (model->triangles)
|
|
||||||
free(model->triangles);
|
|
||||||
|
|
||||||
if (model->frames)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < model->header.numFrames; i++)
|
|
||||||
{
|
|
||||||
if (model->frames[i].vertices)
|
|
||||||
free(model->frames[i].vertices);
|
|
||||||
}
|
|
||||||
free(model->frames);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (model->glCommandBuffer)
|
|
||||||
free(model->glCommandBuffer);
|
|
||||||
|
|
||||||
free(model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -285,157 +93,13 @@ static void md2_freeModel (md2_model_t *model)
|
||||||
// load model
|
// load model
|
||||||
//
|
//
|
||||||
// Hurdler: the current path is the Legacy.exe path
|
// Hurdler: the current path is the Legacy.exe path
|
||||||
static md2_model_t *md2_readModel(const char *filename)
|
static model_t *md2_readModel(const char *filename)
|
||||||
{
|
{
|
||||||
FILE *file;
|
|
||||||
md2_model_t *model;
|
|
||||||
UINT8 buffer[MD2_MAX_FRAMESIZE];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
model = calloc(1, sizeof (*model));
|
|
||||||
if (model == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
//Filename checking fixed ~Monster Iestyn and Golden
|
//Filename checking fixed ~Monster Iestyn and Golden
|
||||||
file = fopen(va("%s"PATHSEP"%s", srb2home, filename), "rb");
|
return LoadModel(va("%s"PATHSEP"%s", srb2home, filename), PU_STATIC);
|
||||||
if (!file)
|
|
||||||
{
|
|
||||||
free(model);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize model and read header
|
|
||||||
|
|
||||||
if (fread(&model->header, sizeof (model->header), 1, file) != 1
|
|
||||||
|| model->header.magic != MD2_IDENT
|
|
||||||
|| model->header.version != MD2_VERSION)
|
|
||||||
{
|
|
||||||
fclose(file);
|
|
||||||
free(model);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
model->header.numSkins = 1;
|
|
||||||
|
|
||||||
#define MD2LIMITCHECK(field, max, msgname) \
|
|
||||||
if (field > max) \
|
|
||||||
{ \
|
|
||||||
CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \
|
|
||||||
md2_freeModel (model); \
|
|
||||||
fclose(file); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncomment if these are actually needed
|
|
||||||
// MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins")
|
|
||||||
// MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates")
|
|
||||||
MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles")
|
|
||||||
MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames")
|
|
||||||
MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices")
|
|
||||||
|
|
||||||
#undef MD2LIMITCHECK
|
|
||||||
|
|
||||||
// read skins
|
|
||||||
fseek(file, model->header.offsetSkins, SEEK_SET);
|
|
||||||
if (model->header.numSkins > 0)
|
|
||||||
{
|
|
||||||
model->skins = calloc(sizeof (md2_skin_t), model->header.numSkins);
|
|
||||||
if (!model->skins || model->header.numSkins !=
|
|
||||||
fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file))
|
|
||||||
{
|
|
||||||
md2_freeModel (model);
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read texture coordinates
|
|
||||||
fseek(file, model->header.offsetTexCoords, SEEK_SET);
|
|
||||||
if (model->header.numTexCoords > 0)
|
|
||||||
{
|
|
||||||
model->texCoords = calloc(sizeof (md2_textureCoordinate_t), model->header.numTexCoords);
|
|
||||||
if (!model->texCoords || model->header.numTexCoords !=
|
|
||||||
fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file))
|
|
||||||
{
|
|
||||||
md2_freeModel (model);
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read triangles
|
|
||||||
fseek(file, model->header.offsetTriangles, SEEK_SET);
|
|
||||||
if (model->header.numTriangles > 0)
|
|
||||||
{
|
|
||||||
model->triangles = calloc(sizeof (md2_triangle_t), model->header.numTriangles);
|
|
||||||
if (!model->triangles || model->header.numTriangles !=
|
|
||||||
fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file))
|
|
||||||
{
|
|
||||||
md2_freeModel (model);
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read alias frames
|
|
||||||
fseek(file, model->header.offsetFrames, SEEK_SET);
|
|
||||||
if (model->header.numFrames > 0)
|
|
||||||
{
|
|
||||||
model->frames = calloc(sizeof (md2_frame_t), model->header.numFrames);
|
|
||||||
if (!model->frames)
|
|
||||||
{
|
|
||||||
md2_freeModel (model);
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < model->header.numFrames; i++)
|
|
||||||
{
|
|
||||||
md2_alias_frame_t *frame = (md2_alias_frame_t *)(void *)buffer;
|
|
||||||
size_t j;
|
|
||||||
|
|
||||||
model->frames[i].vertices = calloc(sizeof (md2_triangleVertex_t), model->header.numVertices);
|
|
||||||
if (!model->frames[i].vertices || model->header.frameSize !=
|
|
||||||
fread(frame, 1, model->header.frameSize, file))
|
|
||||||
{
|
|
||||||
md2_freeModel (model);
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(model->frames[i].name, frame->name);
|
|
||||||
for (j = 0; j < model->header.numVertices; j++)
|
|
||||||
{
|
|
||||||
model->frames[i].vertices[j].vertex[0] = (float) ((INT32) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0];
|
|
||||||
model->frames[i].vertices[j].vertex[2] = -1* ((float) ((INT32) frame->alias_vertices[j].vertex[1]) * frame->scale[1] + frame->translate[1]);
|
|
||||||
model->frames[i].vertices[j].vertex[1] = (float) ((INT32) frame->alias_vertices[j].vertex[2]) * frame->scale[2] + frame->translate[2];
|
|
||||||
model->frames[i].vertices[j].normal[0] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][0];
|
|
||||||
model->frames[i].vertices[j].normal[1] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][1];
|
|
||||||
model->frames[i].vertices[j].normal[2] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read gl commands
|
|
||||||
fseek(file, model->header.offsetGlCommands, SEEK_SET);
|
|
||||||
if (model->header.numGlCommands)
|
|
||||||
{
|
|
||||||
model->glCommandBuffer = calloc(sizeof (INT32), model->header.numGlCommands);
|
|
||||||
if (!model->glCommandBuffer || model->header.numGlCommands !=
|
|
||||||
fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file))
|
|
||||||
{
|
|
||||||
md2_freeModel (model);
|
|
||||||
fclose(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void md2_printModelInfo (md2_model_t *model)
|
static inline void md2_printModelInfo (model_t *model)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
@ -936,7 +600,7 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for any MD2s that match the names of player skins!
|
// Check for any MD2s that match the names of sprite names!
|
||||||
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
|
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
|
||||||
{
|
{
|
||||||
if (stricmp(name, sprnames[spritenum]) == 0)
|
if (stricmp(name, sprnames[spritenum]) == 0)
|
||||||
|
@ -1216,10 +880,9 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
// Look at HWR_ProjectSprite for more
|
// Look at HWR_ProjectSprite for more
|
||||||
{
|
{
|
||||||
GLPatch_t *gpatch;
|
GLPatch_t *gpatch;
|
||||||
INT32 *buff;
|
|
||||||
INT32 durs = spr->mobj->state->tics;
|
INT32 durs = spr->mobj->state->tics;
|
||||||
INT32 tics = spr->mobj->tics;
|
INT32 tics = spr->mobj->tics;
|
||||||
md2_frame_t *curr, *next = NULL;
|
mdlframe_t *curr, *next = NULL;
|
||||||
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
|
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
|
||||||
spritedef_t *sprdef;
|
spritedef_t *sprdef;
|
||||||
spriteframe_t *sprframe;
|
spriteframe_t *sprframe;
|
||||||
|
@ -1332,9 +995,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: this is not yet correct
|
//FIXME: this is not yet correct
|
||||||
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
|
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames;
|
||||||
buff = md2->model->glCommandBuffer;
|
curr = &md2->model->meshes[0].frames[frame];
|
||||||
curr = &md2->model->frames[frame];
|
|
||||||
#if 0
|
#if 0
|
||||||
if (cv_grmd2.value == 1 && tics <= durs)
|
if (cv_grmd2.value == 1 && tics <= durs)
|
||||||
{
|
{
|
||||||
|
@ -1401,7 +1063,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
p.anglex = FIXED_TO_FLOAT(tempangle);
|
p.anglex = FIXED_TO_FLOAT(tempangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
color[0] = Surf.FlatColor.s.red;
|
color[0] = Surf.FlatColor.s.red;
|
||||||
color[1] = Surf.FlatColor.s.green;
|
color[1] = Surf.FlatColor.s.green;
|
||||||
color[2] = Surf.FlatColor.s.blue;
|
color[2] = Surf.FlatColor.s.blue;
|
||||||
|
@ -1413,7 +1074,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
p.flip = atransform.flip;
|
p.flip = atransform.flip;
|
||||||
p.mirror = atransform.mirror;
|
p.mirror = atransform.mirror;
|
||||||
|
|
||||||
HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color);
|
HWD.pfnDrawModel(md2->model, curr, durs, tics, next, &p, finalscale, flip, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,97 +22,7 @@
|
||||||
#define _HW_MD2_H_
|
#define _HW_MD2_H_
|
||||||
|
|
||||||
#include "hw_glob.h"
|
#include "hw_glob.h"
|
||||||
|
#include "hw_model.h"
|
||||||
// magic number "IDP2" or 844121161
|
|
||||||
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
|
|
||||||
// model version
|
|
||||||
#define MD2_VERSION 8
|
|
||||||
|
|
||||||
#define MD2_MAX_TRIANGLES 16384
|
|
||||||
#define MD2_MAX_VERTICES 4096
|
|
||||||
#define MD2_MAX_TEXCOORDS 4096
|
|
||||||
#define MD2_MAX_FRAMES 512
|
|
||||||
#define MD2_MAX_SKINS 32
|
|
||||||
#define MD2_MAX_FRAMESIZE (MD2_MAX_VERTICES * 4 + 128)
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT32 magic;
|
|
||||||
UINT32 version;
|
|
||||||
UINT32 skinWidth;
|
|
||||||
UINT32 skinHeight;
|
|
||||||
UINT32 frameSize;
|
|
||||||
UINT32 numSkins;
|
|
||||||
UINT32 numVertices;
|
|
||||||
UINT32 numTexCoords;
|
|
||||||
UINT32 numTriangles;
|
|
||||||
UINT32 numGlCommands;
|
|
||||||
UINT32 numFrames;
|
|
||||||
UINT32 offsetSkins;
|
|
||||||
UINT32 offsetTexCoords;
|
|
||||||
UINT32 offsetTriangles;
|
|
||||||
UINT32 offsetFrames;
|
|
||||||
UINT32 offsetGlCommands;
|
|
||||||
UINT32 offsetEnd;
|
|
||||||
} ATTRPACK md2_header_t; //NOTE: each of md2_header's members are 4 unsigned bytes
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
UINT8 vertex[3];
|
|
||||||
UINT8 lightNormalIndex;
|
|
||||||
} ATTRPACK md2_alias_triangleVertex_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
float vertex[3];
|
|
||||||
float normal[3];
|
|
||||||
} ATTRPACK md2_triangleVertex_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
INT16 vertexIndices[3];
|
|
||||||
INT16 textureIndices[3];
|
|
||||||
} ATTRPACK md2_triangle_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
INT16 s, t;
|
|
||||||
} ATTRPACK md2_textureCoordinate_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
float scale[3];
|
|
||||||
float translate[3];
|
|
||||||
char name[16];
|
|
||||||
md2_alias_triangleVertex_t alias_vertices[1];
|
|
||||||
} ATTRPACK md2_alias_frame_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char name[16];
|
|
||||||
md2_triangleVertex_t *vertices;
|
|
||||||
} ATTRPACK md2_frame_t;
|
|
||||||
|
|
||||||
typedef char md2_skin_t[64];
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
float s, t;
|
|
||||||
INT32 vertexIndex;
|
|
||||||
} ATTRPACK md2_glCommandVertex_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
md2_header_t header;
|
|
||||||
md2_skin_t *skins;
|
|
||||||
md2_textureCoordinate_t *texCoords;
|
|
||||||
md2_triangle_t *triangles;
|
|
||||||
md2_frame_t *frames;
|
|
||||||
INT32 *glCommandBuffer;
|
|
||||||
} ATTRPACK md2_model_t;
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
@ -123,7 +33,7 @@ typedef struct
|
||||||
char filename[32];
|
char filename[32];
|
||||||
float scale;
|
float scale;
|
||||||
float offset;
|
float offset;
|
||||||
md2_model_t *model;
|
model_t *model;
|
||||||
void *grpatch;
|
void *grpatch;
|
||||||
void *blendgrpatch;
|
void *blendgrpatch;
|
||||||
boolean notfound;
|
boolean notfound;
|
||||||
|
|
520
src/hardware/hw_md2load.c
Normal file
520
src/hardware/hw_md2load.c
Normal file
|
@ -0,0 +1,520 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "hw_md2load.h"
|
||||||
|
#include "hw_model.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
|
||||||
|
#define NUMVERTEXNORMALS 162
|
||||||
|
|
||||||
|
// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and
|
||||||
|
// you'll have your normals.
|
||||||
|
float avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||||
|
{-0.525731f, 0.000000f, 0.850651f},
|
||||||
|
{-0.442863f, 0.238856f, 0.864188f},
|
||||||
|
{-0.295242f, 0.000000f, 0.955423f},
|
||||||
|
{-0.309017f, 0.500000f, 0.809017f},
|
||||||
|
{-0.162460f, 0.262866f, 0.951056f},
|
||||||
|
{0.000000f, 0.000000f, 1.000000f},
|
||||||
|
{0.000000f, 0.850651f, 0.525731f},
|
||||||
|
{-0.147621f, 0.716567f, 0.681718f},
|
||||||
|
{0.147621f, 0.716567f, 0.681718f},
|
||||||
|
{0.000000f, 0.525731f, 0.850651f},
|
||||||
|
{0.309017f, 0.500000f, 0.809017f},
|
||||||
|
{0.525731f, 0.000000f, 0.850651f},
|
||||||
|
{0.295242f, 0.000000f, 0.955423f},
|
||||||
|
{0.442863f, 0.238856f, 0.864188f},
|
||||||
|
{0.162460f, 0.262866f, 0.951056f},
|
||||||
|
{-0.681718f, 0.147621f, 0.716567f},
|
||||||
|
{-0.809017f, 0.309017f, 0.500000f},
|
||||||
|
{-0.587785f, 0.425325f, 0.688191f},
|
||||||
|
{-0.850651f, 0.525731f, 0.000000f},
|
||||||
|
{-0.864188f, 0.442863f, 0.238856f},
|
||||||
|
{-0.716567f, 0.681718f, 0.147621f},
|
||||||
|
{-0.688191f, 0.587785f, 0.425325f},
|
||||||
|
{-0.500000f, 0.809017f, 0.309017f},
|
||||||
|
{-0.238856f, 0.864188f, 0.442863f},
|
||||||
|
{-0.425325f, 0.688191f, 0.587785f},
|
||||||
|
{-0.716567f, 0.681718f, -0.147621f},
|
||||||
|
{-0.500000f, 0.809017f, -0.309017f},
|
||||||
|
{-0.525731f, 0.850651f, 0.000000f},
|
||||||
|
{0.000000f, 0.850651f, -0.525731f},
|
||||||
|
{-0.238856f, 0.864188f, -0.442863f},
|
||||||
|
{0.000000f, 0.955423f, -0.295242f},
|
||||||
|
{-0.262866f, 0.951056f, -0.162460f},
|
||||||
|
{0.000000f, 1.000000f, 0.000000f},
|
||||||
|
{0.000000f, 0.955423f, 0.295242f},
|
||||||
|
{-0.262866f, 0.951056f, 0.162460f},
|
||||||
|
{0.238856f, 0.864188f, 0.442863f},
|
||||||
|
{0.262866f, 0.951056f, 0.162460f},
|
||||||
|
{0.500000f, 0.809017f, 0.309017f},
|
||||||
|
{0.238856f, 0.864188f, -0.442863f},
|
||||||
|
{0.262866f, 0.951056f, -0.162460f},
|
||||||
|
{0.500000f, 0.809017f, -0.309017f},
|
||||||
|
{0.850651f, 0.525731f, 0.000000f},
|
||||||
|
{0.716567f, 0.681718f, 0.147621f},
|
||||||
|
{0.716567f, 0.681718f, -0.147621f},
|
||||||
|
{0.525731f, 0.850651f, 0.000000f},
|
||||||
|
{0.425325f, 0.688191f, 0.587785f},
|
||||||
|
{0.864188f, 0.442863f, 0.238856f},
|
||||||
|
{0.688191f, 0.587785f, 0.425325f},
|
||||||
|
{0.809017f, 0.309017f, 0.500000f},
|
||||||
|
{0.681718f, 0.147621f, 0.716567f},
|
||||||
|
{0.587785f, 0.425325f, 0.688191f},
|
||||||
|
{0.955423f, 0.295242f, 0.000000f},
|
||||||
|
{1.000000f, 0.000000f, 0.000000f},
|
||||||
|
{0.951056f, 0.162460f, 0.262866f},
|
||||||
|
{0.850651f, -0.525731f, 0.000000f},
|
||||||
|
{0.955423f, -0.295242f, 0.000000f},
|
||||||
|
{0.864188f, -0.442863f, 0.238856f},
|
||||||
|
{0.951056f, -0.162460f, 0.262866f},
|
||||||
|
{0.809017f, -0.309017f, 0.500000f},
|
||||||
|
{0.681718f, -0.147621f, 0.716567f},
|
||||||
|
{0.850651f, 0.000000f, 0.525731f},
|
||||||
|
{0.864188f, 0.442863f, -0.238856f},
|
||||||
|
{0.809017f, 0.309017f, -0.500000f},
|
||||||
|
{0.951056f, 0.162460f, -0.262866f},
|
||||||
|
{0.525731f, 0.000000f, -0.850651f},
|
||||||
|
{0.681718f, 0.147621f, -0.716567f},
|
||||||
|
{0.681718f, -0.147621f, -0.716567f},
|
||||||
|
{0.850651f, 0.000000f, -0.525731f},
|
||||||
|
{0.809017f, -0.309017f, -0.500000f},
|
||||||
|
{0.864188f, -0.442863f, -0.238856f},
|
||||||
|
{0.951056f, -0.162460f, -0.262866f},
|
||||||
|
{0.147621f, 0.716567f, -0.681718f},
|
||||||
|
{0.309017f, 0.500000f, -0.809017f},
|
||||||
|
{0.425325f, 0.688191f, -0.587785f},
|
||||||
|
{0.442863f, 0.238856f, -0.864188f},
|
||||||
|
{0.587785f, 0.425325f, -0.688191f},
|
||||||
|
{0.688191f, 0.587785f, -0.425325f},
|
||||||
|
{-0.147621f, 0.716567f, -0.681718f},
|
||||||
|
{-0.309017f, 0.500000f, -0.809017f},
|
||||||
|
{0.000000f, 0.525731f, -0.850651f},
|
||||||
|
{-0.525731f, 0.000000f, -0.850651f},
|
||||||
|
{-0.442863f, 0.238856f, -0.864188f},
|
||||||
|
{-0.295242f, 0.000000f, -0.955423f},
|
||||||
|
{-0.162460f, 0.262866f, -0.951056f},
|
||||||
|
{0.000000f, 0.000000f, -1.000000f},
|
||||||
|
{0.295242f, 0.000000f, -0.955423f},
|
||||||
|
{0.162460f, 0.262866f, -0.951056f},
|
||||||
|
{-0.442863f, -0.238856f, -0.864188f},
|
||||||
|
{-0.309017f, -0.500000f, -0.809017f},
|
||||||
|
{-0.162460f, -0.262866f, -0.951056f},
|
||||||
|
{0.000000f, -0.850651f, -0.525731f},
|
||||||
|
{-0.147621f, -0.716567f, -0.681718f},
|
||||||
|
{0.147621f, -0.716567f, -0.681718f},
|
||||||
|
{0.000000f, -0.525731f, -0.850651f},
|
||||||
|
{0.309017f, -0.500000f, -0.809017f},
|
||||||
|
{0.442863f, -0.238856f, -0.864188f},
|
||||||
|
{0.162460f, -0.262866f, -0.951056f},
|
||||||
|
{0.238856f, -0.864188f, -0.442863f},
|
||||||
|
{0.500000f, -0.809017f, -0.309017f},
|
||||||
|
{0.425325f, -0.688191f, -0.587785f},
|
||||||
|
{0.716567f, -0.681718f, -0.147621f},
|
||||||
|
{0.688191f, -0.587785f, -0.425325f},
|
||||||
|
{0.587785f, -0.425325f, -0.688191f},
|
||||||
|
{0.000000f, -0.955423f, -0.295242f},
|
||||||
|
{0.000000f, -1.000000f, 0.000000f},
|
||||||
|
{0.262866f, -0.951056f, -0.162460f},
|
||||||
|
{0.000000f, -0.850651f, 0.525731f},
|
||||||
|
{0.000000f, -0.955423f, 0.295242f},
|
||||||
|
{0.238856f, -0.864188f, 0.442863f},
|
||||||
|
{0.262866f, -0.951056f, 0.162460f},
|
||||||
|
{0.500000f, -0.809017f, 0.309017f},
|
||||||
|
{0.716567f, -0.681718f, 0.147621f},
|
||||||
|
{0.525731f, -0.850651f, 0.000000f},
|
||||||
|
{-0.238856f, -0.864188f, -0.442863f},
|
||||||
|
{-0.500000f, -0.809017f, -0.309017f},
|
||||||
|
{-0.262866f, -0.951056f, -0.162460f},
|
||||||
|
{-0.850651f, -0.525731f, 0.000000f},
|
||||||
|
{-0.716567f, -0.681718f, -0.147621f},
|
||||||
|
{-0.716567f, -0.681718f, 0.147621f},
|
||||||
|
{-0.525731f, -0.850651f, 0.000000f},
|
||||||
|
{-0.500000f, -0.809017f, 0.309017f},
|
||||||
|
{-0.238856f, -0.864188f, 0.442863f},
|
||||||
|
{-0.262866f, -0.951056f, 0.162460f},
|
||||||
|
{-0.864188f, -0.442863f, 0.238856f},
|
||||||
|
{-0.809017f, -0.309017f, 0.500000f},
|
||||||
|
{-0.688191f, -0.587785f, 0.425325f},
|
||||||
|
{-0.681718f, -0.147621f, 0.716567f},
|
||||||
|
{-0.442863f, -0.238856f, 0.864188f},
|
||||||
|
{-0.587785f, -0.425325f, 0.688191f},
|
||||||
|
{-0.309017f, -0.500000f, 0.809017f},
|
||||||
|
{-0.147621f, -0.716567f, 0.681718f},
|
||||||
|
{-0.425325f, -0.688191f, 0.587785f},
|
||||||
|
{-0.162460f, -0.262866f, 0.951056f},
|
||||||
|
{0.442863f, -0.238856f, 0.864188f},
|
||||||
|
{0.162460f, -0.262866f, 0.951056f},
|
||||||
|
{0.309017f, -0.500000f, 0.809017f},
|
||||||
|
{0.147621f, -0.716567f, 0.681718f},
|
||||||
|
{0.000000f, -0.525731f, 0.850651f},
|
||||||
|
{0.425325f, -0.688191f, 0.587785f},
|
||||||
|
{0.587785f, -0.425325f, 0.688191f},
|
||||||
|
{0.688191f, -0.587785f, 0.425325f},
|
||||||
|
{-0.955423f, 0.295242f, 0.000000f},
|
||||||
|
{-0.951056f, 0.162460f, 0.262866f},
|
||||||
|
{-1.000000f, 0.000000f, 0.000000f},
|
||||||
|
{-0.850651f, 0.000000f, 0.525731f},
|
||||||
|
{-0.955423f, -0.295242f, 0.000000f},
|
||||||
|
{-0.951056f, -0.162460f, 0.262866f},
|
||||||
|
{-0.864188f, 0.442863f, -0.238856f},
|
||||||
|
{-0.951056f, 0.162460f, -0.262866f},
|
||||||
|
{-0.809017f, 0.309017f, -0.500000f},
|
||||||
|
{-0.864188f, -0.442863f, -0.238856f},
|
||||||
|
{-0.951056f, -0.162460f, -0.262866f},
|
||||||
|
{-0.809017f, -0.309017f, -0.500000f},
|
||||||
|
{-0.681718f, 0.147621f, -0.716567f},
|
||||||
|
{-0.681718f, -0.147621f, -0.716567f},
|
||||||
|
{-0.850651f, 0.000000f, -0.525731f},
|
||||||
|
{-0.688191f, 0.587785f, -0.425325f},
|
||||||
|
{-0.587785f, 0.425325f, -0.688191f},
|
||||||
|
{-0.425325f, 0.688191f, -0.587785f},
|
||||||
|
{-0.425325f, -0.688191f, -0.587785f},
|
||||||
|
{-0.587785f, -0.425325f, -0.688191f},
|
||||||
|
{-0.688191f, -0.587785f, -0.425325f},
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int ident; // A "magic number" that's used to identify the .md2 file
|
||||||
|
int version; // The version of the file, always 8
|
||||||
|
int skinwidth; // Width of the skin(s) in pixels
|
||||||
|
int skinheight; // Height of the skin(s) in pixels
|
||||||
|
int framesize; // Size of each frame in bytes
|
||||||
|
int numSkins; // Number of skins with the model
|
||||||
|
int numXYZ; // Number of vertices in each frame
|
||||||
|
int numST; // Number of texture coordinates in each frame.
|
||||||
|
int numTris; // Number of triangles in each frame
|
||||||
|
int numGLcmds; // Number of dwords (4 bytes) in the gl command list.
|
||||||
|
int numFrames; // Number of frames
|
||||||
|
int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names.
|
||||||
|
int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates
|
||||||
|
int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles
|
||||||
|
int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames
|
||||||
|
int offsetGLcmds; // Offset, in bytes from the start of the file, to the list of gl commands
|
||||||
|
int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize)
|
||||||
|
} md2header_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned short meshIndex[3]; // indices into the array of vertices in each frames
|
||||||
|
unsigned short stIndex[3]; // indices into the array of texture coordinates
|
||||||
|
} md2triangle_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short s;
|
||||||
|
short t;
|
||||||
|
} md2texcoord_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned char v[3]; // Scaled vertices. You'll need to multiply them with scale[x] to make them normal.
|
||||||
|
unsigned char lightNormalIndex; // Index to the array of normals
|
||||||
|
} md2vertex_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float scale[3]; // Used by the v member in the md2framePoint structure
|
||||||
|
float translate[3]; // Used by the v member in the md2framePoint structure
|
||||||
|
char name[16]; // Name of the frame
|
||||||
|
} md2frame_t;
|
||||||
|
|
||||||
|
// Load the model
|
||||||
|
model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||||
|
{
|
||||||
|
useFloat = true; // Right now we always useFloat = true, because the GL subsystem needs some work for the other option to work.
|
||||||
|
|
||||||
|
model_t *retModel = NULL;
|
||||||
|
md2header_t *header;
|
||||||
|
|
||||||
|
FILE *f = fopen(fileName, "rb");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0);
|
||||||
|
|
||||||
|
size_t fileLen;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
size_t namelen;
|
||||||
|
char *texturefilename;
|
||||||
|
const char *texPos = strchr(fileName, '/');
|
||||||
|
|
||||||
|
if (texPos)
|
||||||
|
{
|
||||||
|
texPos++;
|
||||||
|
namelen = strlen(texPos) + 1;
|
||||||
|
texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0);
|
||||||
|
strcpy(texturefilename, texPos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
namelen = strlen(fileName) + 1;
|
||||||
|
texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0);
|
||||||
|
strcpy(texturefilename, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
texturefilename[namelen-2] = 'z';
|
||||||
|
texturefilename[namelen-3] = 'u';
|
||||||
|
texturefilename[namelen-4] = 'b';
|
||||||
|
|
||||||
|
// find length of file
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
fileLen = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// read in file
|
||||||
|
char *buffer = malloc(fileLen);
|
||||||
|
fread(buffer, fileLen, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
// get pointer to file header
|
||||||
|
header = (md2header_t*)buffer;
|
||||||
|
|
||||||
|
retModel->numMeshes = 1; // MD2 only has one mesh
|
||||||
|
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0);
|
||||||
|
retModel->meshes[0].numFrames = header->numFrames;
|
||||||
|
const float WUNITS = 1.0f;
|
||||||
|
float dataScale = WUNITS;
|
||||||
|
|
||||||
|
// Tris and ST are simple structures that can be straight-copied
|
||||||
|
md2triangle_t *tris = (md2triangle_t*)&buffer[header->offsetTris];
|
||||||
|
md2texcoord_t *texcoords = (md2texcoord_t*)&buffer[header->offsetST];
|
||||||
|
md2frame_t *frames = (md2frame_t*)&buffer[header->offsetFrames];
|
||||||
|
|
||||||
|
// Read in textures
|
||||||
|
retModel->numMaterials = header->numSkins;
|
||||||
|
|
||||||
|
if (retModel->numMaterials <= 0) // Always at least one skin, duh
|
||||||
|
retModel->numMaterials = 1;
|
||||||
|
|
||||||
|
retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0);
|
||||||
|
|
||||||
|
int t;
|
||||||
|
for (t = 0; t < retModel->numMaterials; t++)
|
||||||
|
{
|
||||||
|
retModel->materials[t].ambient[0] = 0.8f;
|
||||||
|
retModel->materials[t].ambient[1] = 0.8f;
|
||||||
|
retModel->materials[t].ambient[2] = 0.8f;
|
||||||
|
retModel->materials[t].ambient[3] = 1.0f;
|
||||||
|
retModel->materials[t].diffuse[0] = 0.8f;
|
||||||
|
retModel->materials[t].diffuse[1] = 0.8f;
|
||||||
|
retModel->materials[t].diffuse[2] = 0.8f;
|
||||||
|
retModel->materials[t].diffuse[3] = 1.0f;
|
||||||
|
retModel->materials[t].emissive[0] = 0.0f;
|
||||||
|
retModel->materials[t].emissive[1] = 0.0f;
|
||||||
|
retModel->materials[t].emissive[2] = 0.0f;
|
||||||
|
retModel->materials[t].emissive[3] = 1.0f;
|
||||||
|
retModel->materials[t].specular[0] = 0.0f;
|
||||||
|
retModel->materials[t].specular[1] = 0.0f;
|
||||||
|
retModel->materials[t].specular[2] = 0.0f;
|
||||||
|
retModel->materials[t].specular[3] = 1.0f;
|
||||||
|
retModel->materials[t].shininess = 0.0f;
|
||||||
|
retModel->materials[t].spheremap = false;
|
||||||
|
|
||||||
|
/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE);
|
||||||
|
|
||||||
|
if (!systemSucks)
|
||||||
|
{
|
||||||
|
// Check for a normal map...??
|
||||||
|
char openfilename[1024];
|
||||||
|
char normalMapName[1024];
|
||||||
|
strcpy(normalMapName, texturefilename);
|
||||||
|
size_t len = strlen(normalMapName);
|
||||||
|
char *ptr = &normalMapName[len];
|
||||||
|
ptr--; // z
|
||||||
|
ptr--; // u
|
||||||
|
ptr--; // b
|
||||||
|
ptr--; // .
|
||||||
|
*ptr++ = '_';
|
||||||
|
*ptr++ = 'n';
|
||||||
|
*ptr++ = '.';
|
||||||
|
*ptr++ = 'b';
|
||||||
|
*ptr++ = 'u';
|
||||||
|
*ptr++ = 'z';
|
||||||
|
*ptr++ = '\0';
|
||||||
|
|
||||||
|
sprintf(openfilename, "%s/%s", "textures", normalMapName);
|
||||||
|
// Convert backslashes to forward slashes
|
||||||
|
for (int k = 0; k < 1024; k++)
|
||||||
|
{
|
||||||
|
if (openfilename[k] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (openfilename[k] == '\\')
|
||||||
|
openfilename[k] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource::resource_t *res = Resource::Open(openfilename);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
Resource::Close(res);
|
||||||
|
retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
retModel->meshes[0].numTriangles = header->numTris;
|
||||||
|
|
||||||
|
if (!useFloat) // Decompress to MD3 'tinyframe' space
|
||||||
|
{
|
||||||
|
dataScale = 0.015624f; // 1 / 64.0f
|
||||||
|
retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0);
|
||||||
|
retModel->meshes[0].numVertices = header->numXYZ;
|
||||||
|
retModel->meshes[0].uvs = (float*)Z_Malloc (sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0);
|
||||||
|
|
||||||
|
byte *ptr = (byte*)frames;
|
||||||
|
for (i = 0; i < header->numFrames; i++, ptr += header->framesize)
|
||||||
|
{
|
||||||
|
md2frame_t *framePtr = (md2frame_t*)ptr;
|
||||||
|
retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short)*3*header->numXYZ, ztag, 0);
|
||||||
|
retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char)*3*header->numXYZ, ztag, 0);
|
||||||
|
|
||||||
|
// if (retModel->materials[0].lightmap)
|
||||||
|
// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag);
|
||||||
|
retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0);
|
||||||
|
|
||||||
|
short *vertptr = retModel->meshes[0].tinyframes[i].vertices;
|
||||||
|
char *normptr = retModel->meshes[0].tinyframes[i].normals;
|
||||||
|
|
||||||
|
// char *tanptr = retModel->meshes[0].tinyframes[i].tangents;
|
||||||
|
retModel->meshes[0].tinyframes[i].material = &retModel->materials[0];
|
||||||
|
|
||||||
|
framePtr++; // Advance to vertex list
|
||||||
|
md2vertex_t *vertex = (md2vertex_t*)framePtr;
|
||||||
|
framePtr--;
|
||||||
|
for (j = 0; j < header->numXYZ; j++, vertex++)
|
||||||
|
{
|
||||||
|
*vertptr = (short)(((vertex->v[1] * framePtr->scale[1]) + framePtr->translate[1]) / dataScale);
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = (short)(((vertex->v[2] * framePtr->scale[2]) + framePtr->translate[2]) / dataScale);
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = (short)(((vertex->v[0] * framePtr->scale[0]) + framePtr->translate[0]) / dataScale);
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
// Normal
|
||||||
|
*normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][1] * 127);
|
||||||
|
*normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][2] * 127);
|
||||||
|
*normptr++ = (byte)(avertexnormals[vertex->lightNormalIndex][0] * 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This doesn't need to be done every frame!
|
||||||
|
md2triangle_t *trisPtr = tris;
|
||||||
|
unsigned short *indexptr = retModel->meshes[0].indices;
|
||||||
|
float *uvptr = (float*)retModel->meshes[0].uvs;
|
||||||
|
for (j = 0; j < header->numTris; j++, trisPtr++)
|
||||||
|
{
|
||||||
|
*indexptr = trisPtr->meshIndex[0];
|
||||||
|
indexptr++;
|
||||||
|
*indexptr = trisPtr->meshIndex[2];
|
||||||
|
indexptr++;
|
||||||
|
*indexptr = trisPtr->meshIndex[1];
|
||||||
|
indexptr++;
|
||||||
|
|
||||||
|
uvptr[trisPtr->meshIndex[1] * 2] = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth;
|
||||||
|
uvptr[trisPtr->meshIndex[1] * 2 + 1] = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight);
|
||||||
|
uvptr[trisPtr->meshIndex[2] * 2] = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth;
|
||||||
|
uvptr[trisPtr->meshIndex[2] * 2 + 1] = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight);
|
||||||
|
uvptr[trisPtr->meshIndex[0] * 2] = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth;
|
||||||
|
uvptr[trisPtr->meshIndex[0] * 2 + 1] = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Full float loading method
|
||||||
|
{
|
||||||
|
retModel->meshes[0].numVertices = header->numTris*3;
|
||||||
|
retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0);
|
||||||
|
retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float)*2*retModel->meshes[0].numVertices, ztag, 0);
|
||||||
|
|
||||||
|
md2triangle_t *trisPtr = tris;
|
||||||
|
float *uvptr = retModel->meshes[0].uvs;
|
||||||
|
for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++)
|
||||||
|
{
|
||||||
|
*uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth;
|
||||||
|
*uvptr++ = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight);
|
||||||
|
*uvptr++ = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth;
|
||||||
|
*uvptr++ = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight);
|
||||||
|
*uvptr++ = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth;
|
||||||
|
*uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte *ptr = (byte*)frames;
|
||||||
|
for (i = 0; i < header->numFrames; i++, ptr += header->framesize)
|
||||||
|
{
|
||||||
|
md2frame_t *framePtr = (md2frame_t*)ptr;
|
||||||
|
retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0);
|
||||||
|
retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag, 0);
|
||||||
|
// if (retModel->materials[0].lightmap)
|
||||||
|
// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag);
|
||||||
|
float *vertptr, *normptr;
|
||||||
|
normptr = (float*)retModel->meshes[0].frames[i].normals;
|
||||||
|
vertptr = (float*)retModel->meshes[0].frames[i].vertices;
|
||||||
|
trisPtr = tris;
|
||||||
|
|
||||||
|
retModel->meshes[0].frames[i].material = &retModel->materials[0];
|
||||||
|
|
||||||
|
framePtr++; // Advance to vertex list
|
||||||
|
md2vertex_t *vertex = (md2vertex_t*)framePtr;
|
||||||
|
framePtr--;
|
||||||
|
for (j = 0; j < header->numTris; j++, trisPtr++)
|
||||||
|
{
|
||||||
|
*vertptr = ((vertex[trisPtr->meshIndex[0]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = ((vertex[trisPtr->meshIndex[0]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[0]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
*vertptr = ((vertex[trisPtr->meshIndex[1]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = ((vertex[trisPtr->meshIndex[1]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[1]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
*vertptr = ((vertex[trisPtr->meshIndex[2]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = ((vertex[trisPtr->meshIndex[2]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[2]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][0];
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][1];
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][2];
|
||||||
|
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][0];
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][1];
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][2];
|
||||||
|
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][0];
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][1];
|
||||||
|
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][2];
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Rotate MD2 by 90 degrees in code BLAAHH
|
||||||
|
vector_t *normVecptr = (vector_t*)retModel->meshes[0].frames[i].normals;
|
||||||
|
vector_t *vertVecptr = (vector_t*)retModel->meshes[0].frames[i].vertices;
|
||||||
|
for (j = 0; j < header->numTris * 3; j++, normVecptr++, vertVecptr++)
|
||||||
|
{
|
||||||
|
VectorRotate(normVecptr, &vectorYaxis, -90.0f);
|
||||||
|
VectorRotate(vertVecptr, &vectorYaxis, -90.0f);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
return retModel;
|
||||||
|
}
|
19
src/hardware/hw_md2load.h
Normal file
19
src/hardware/hw_md2load.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HW_MD2LOAD_H_
|
||||||
|
#define _HW_MD2LOAD_H_
|
||||||
|
|
||||||
|
#include "hw_model.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
// Load the Model
|
||||||
|
model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat);
|
||||||
|
|
||||||
|
#endif
|
489
src/hardware/hw_md3load.c
Normal file
489
src/hardware/hw_md3load.c
Normal file
|
@ -0,0 +1,489 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "hw_md3load.h"
|
||||||
|
#include "hw_model.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int ident; // A "magic number" that's used to identify the .md3 file
|
||||||
|
int version; // The version of the file, always 15
|
||||||
|
char name[64];
|
||||||
|
int flags;
|
||||||
|
int numFrames; // Number of frames
|
||||||
|
int numTags;
|
||||||
|
int numSurfaces;
|
||||||
|
int numSkins; // Number of skins with the model
|
||||||
|
int offsetFrames;
|
||||||
|
int offsetTags;
|
||||||
|
int offsetSurfaces;
|
||||||
|
int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize)
|
||||||
|
} md3modelHeader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float minBounds[3]; // First corner of the bounding box
|
||||||
|
float maxBounds[3]; // Second corner of the bounding box
|
||||||
|
float localOrigin[3]; // Local origin, usually (0, 0, 0)
|
||||||
|
float radius; // Radius of bounding sphere
|
||||||
|
char name[16]; // Name of frame
|
||||||
|
} md3Frame;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[64]; // Name of tag
|
||||||
|
float origin[3]; // Coordinates of tag
|
||||||
|
float axis[9]; // Orientation of tag object
|
||||||
|
} md3Tag;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int ident;
|
||||||
|
char name[64]; // Name of this surface
|
||||||
|
int flags;
|
||||||
|
int numFrames; // # of keyframes
|
||||||
|
int numShaders; // # of shaders
|
||||||
|
int numVerts; // # of vertices
|
||||||
|
int numTriangles; // # of triangles
|
||||||
|
int offsetTriangles; // Relative offset from start of this struct to where the list of Triangles start
|
||||||
|
int offsetShaders; // Relative offset from start of this struct to where the list of Shaders start
|
||||||
|
int offsetST; // Relative offset from start of this struct to where the list of tex coords start
|
||||||
|
int offsetXYZNormal; // Relative offset from start of this struct to where the list of vertices start
|
||||||
|
int offsetEnd; // Relative offset from start of this struct to where this surface ends
|
||||||
|
} md3Surface;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char name[64]; // Name of this shader
|
||||||
|
int shaderIndex; // Shader index number
|
||||||
|
} md3Shader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int index[3]; // List of offset values into the list of Vertex objects that constitute the corners of the Triangle object.
|
||||||
|
} md3Triangle;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float st[2];
|
||||||
|
} md3TexCoord;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
short x, y, z, n;
|
||||||
|
} md3Vertex;
|
||||||
|
|
||||||
|
static float latlnglookup[256][256][3];
|
||||||
|
|
||||||
|
static void GetNormalFromLatLong(short latlng, float *out)
|
||||||
|
{
|
||||||
|
float *lookup = latlnglookup[(unsigned char)(latlng >> 8)][(unsigned char)(latlng & 255)];
|
||||||
|
|
||||||
|
out[0] = *lookup++;
|
||||||
|
out[1] = *lookup++;
|
||||||
|
out[2] = *lookup++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void NormalToLatLng(float *n, short *out)
|
||||||
|
{
|
||||||
|
// Special cases
|
||||||
|
if (0.0f == n[0] && 0.0f == n[1])
|
||||||
|
{
|
||||||
|
if (n[2] > 0.0f)
|
||||||
|
*out = 0;
|
||||||
|
else
|
||||||
|
*out = 128;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char x, y;
|
||||||
|
|
||||||
|
x = (char)(57.2957795f * (atan2(n[1], n[0])) * (255.0f / 360.0f));
|
||||||
|
y = (char)(57.2957795f * (acos(n[2])) * (255.0f / 360.0f));
|
||||||
|
|
||||||
|
*out = (x << 8) + y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void LatLngToNormal(short n, float *out)
|
||||||
|
{
|
||||||
|
const float PI = (3.1415926535897932384626433832795f);
|
||||||
|
float lat = (float)(n >> 8);
|
||||||
|
float lng = (float)(n & 255);
|
||||||
|
|
||||||
|
lat *= PI / 128.0f;
|
||||||
|
lng *= PI / 128.0f;
|
||||||
|
|
||||||
|
out[0] = cosf(lat) * sinf(lng);
|
||||||
|
out[1] = sinf(lat) * sinf(lng);
|
||||||
|
out[2] = cosf(lng);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LatLngInit(void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < 256; j++)
|
||||||
|
LatLngToNormal((short)((i << 8) + j), latlnglookup[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool latlnginit = false;
|
||||||
|
|
||||||
|
model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
|
||||||
|
{
|
||||||
|
useFloat = true; // Right now we always useFloat = true, because the GL subsystem needs some work for the other option to work.
|
||||||
|
|
||||||
|
if (!latlnginit)
|
||||||
|
{
|
||||||
|
LatLngInit();
|
||||||
|
latlnginit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float WUNITS = 1.0f;
|
||||||
|
model_t *retModel = NULL;
|
||||||
|
|
||||||
|
FILE *f = fopen(fileName, "rb");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0);
|
||||||
|
|
||||||
|
md3modelHeader *mdh;
|
||||||
|
|
||||||
|
// find length of file
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fileLen = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
// read in file
|
||||||
|
char *buffer = malloc(fileLen);
|
||||||
|
fread(buffer, fileLen, 1, f);
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
// get pointer to file header
|
||||||
|
mdh = (md3modelHeader*)buffer;
|
||||||
|
|
||||||
|
retModel->numMeshes = mdh->numSurfaces;
|
||||||
|
|
||||||
|
retModel->numMaterials = 0;
|
||||||
|
int surfEnd = 0;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < mdh->numSurfaces; i++)
|
||||||
|
{
|
||||||
|
md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces];
|
||||||
|
surfEnd += mdS->offsetEnd;
|
||||||
|
|
||||||
|
retModel->numMaterials += mdS->numShaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize materials
|
||||||
|
if (retModel->numMaterials <= 0) // Always at least one skin, duh
|
||||||
|
retModel->numMaterials = 1;
|
||||||
|
|
||||||
|
retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0);
|
||||||
|
|
||||||
|
int t;
|
||||||
|
for (t = 0; t < retModel->numMaterials; t++)
|
||||||
|
{
|
||||||
|
retModel->materials[t].ambient[0] = 0.3686f;
|
||||||
|
retModel->materials[t].ambient[1] = 0.3684f;
|
||||||
|
retModel->materials[t].ambient[2] = 0.3684f;
|
||||||
|
retModel->materials[t].ambient[3] = 1.0f;
|
||||||
|
retModel->materials[t].diffuse[0] = 0.8863f;
|
||||||
|
retModel->materials[t].diffuse[1] = 0.8850f;
|
||||||
|
retModel->materials[t].diffuse[2] = 0.8850f;
|
||||||
|
retModel->materials[t].diffuse[3] = 1.0f;
|
||||||
|
retModel->materials[t].emissive[0] = 0.0f;
|
||||||
|
retModel->materials[t].emissive[1] = 0.0f;
|
||||||
|
retModel->materials[t].emissive[2] = 0.0f;
|
||||||
|
retModel->materials[t].emissive[3] = 1.0f;
|
||||||
|
retModel->materials[t].specular[0] = 0.4902f;
|
||||||
|
retModel->materials[t].specular[1] = 0.4887f;
|
||||||
|
retModel->materials[t].specular[2] = 0.4887f;
|
||||||
|
retModel->materials[t].specular[3] = 1.0f;
|
||||||
|
retModel->materials[t].shininess = 25.0f;
|
||||||
|
retModel->materials[t].spheremap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0);
|
||||||
|
|
||||||
|
int matCount = 0;
|
||||||
|
for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++)
|
||||||
|
{
|
||||||
|
md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces + surfEnd];
|
||||||
|
surfEnd += mdS->offsetEnd;
|
||||||
|
|
||||||
|
md3Shader *mdShader = (md3Shader*)((char*)mdS + mdS->offsetShaders);
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mdS->numShaders; j++, matCount++)
|
||||||
|
{
|
||||||
|
size_t len = strlen(mdShader[j].name);
|
||||||
|
mdShader[j].name[len-1] = 'z';
|
||||||
|
mdShader[j].name[len-2] = 'u';
|
||||||
|
mdShader[j].name[len-3] = 'b';
|
||||||
|
|
||||||
|
// Load material
|
||||||
|
/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE);
|
||||||
|
|
||||||
|
if (!systemSucks)
|
||||||
|
{
|
||||||
|
// Check for a normal map...??
|
||||||
|
char openfilename[1024];
|
||||||
|
char normalMapName[1024];
|
||||||
|
strcpy(normalMapName, mdShader[j].name);
|
||||||
|
len = strlen(normalMapName);
|
||||||
|
char *ptr = &normalMapName[len];
|
||||||
|
ptr--; // z
|
||||||
|
ptr--; // u
|
||||||
|
ptr--; // b
|
||||||
|
ptr--; // .
|
||||||
|
*ptr++ = '_';
|
||||||
|
*ptr++ = 'n';
|
||||||
|
*ptr++ = '.';
|
||||||
|
*ptr++ = 'b';
|
||||||
|
*ptr++ = 'u';
|
||||||
|
*ptr++ = 'z';
|
||||||
|
*ptr++ = '\0';
|
||||||
|
|
||||||
|
sprintf(openfilename, "%s/%s", "textures", normalMapName);
|
||||||
|
// Convert backslashes to forward slashes
|
||||||
|
for (int k = 0; k < 1024; k++)
|
||||||
|
{
|
||||||
|
if (openfilename[k] == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (openfilename[k] == '\\')
|
||||||
|
openfilename[k] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource::resource_t *res = Resource::Open(openfilename);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
Resource::Close(res);
|
||||||
|
retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
retModel->meshes[i].numFrames = mdS->numFrames;
|
||||||
|
retModel->meshes[i].numTriangles = mdS->numTriangles;
|
||||||
|
|
||||||
|
if (!useFloat) // 'tinyframe' mode with indices
|
||||||
|
{
|
||||||
|
float tempNormal[3];
|
||||||
|
retModel->meshes[i].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*mdS->numFrames, ztag, 0);
|
||||||
|
retModel->meshes[i].numVertices = mdS->numVerts;
|
||||||
|
retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numVerts, ztag, 0);
|
||||||
|
for (j = 0; j < mdS->numFrames; j++)
|
||||||
|
{
|
||||||
|
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
|
||||||
|
retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, 0);
|
||||||
|
retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, 0);
|
||||||
|
|
||||||
|
// if (retModel->materials[0].lightmap)
|
||||||
|
// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag);
|
||||||
|
retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, 0);
|
||||||
|
short *vertptr = retModel->meshes[i].tinyframes[j].vertices;
|
||||||
|
char *normptr = retModel->meshes[i].tinyframes[j].normals;
|
||||||
|
|
||||||
|
// char *tanptr = retModel->meshes[i].tinyframes[j].tangents;
|
||||||
|
retModel->meshes[i].tinyframes[j].material = &retModel->materials[i];
|
||||||
|
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < mdS->numVerts; k++)
|
||||||
|
{
|
||||||
|
// Vertex
|
||||||
|
*vertptr = mdV[k].y;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[k].z;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[k].x;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
// Normal
|
||||||
|
GetNormalFromLatLong(mdV[k].n, tempNormal);
|
||||||
|
*normptr = (byte)(tempNormal[1] * 127);
|
||||||
|
normptr++;
|
||||||
|
*normptr = (byte)(tempNormal[2] * 127);
|
||||||
|
normptr++;
|
||||||
|
*normptr = (byte)(tempNormal[0] * 127);
|
||||||
|
normptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float *uvptr = (float*)retModel->meshes[i].uvs;
|
||||||
|
md3TexCoord *mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST);
|
||||||
|
for (j = 0; j < mdS->numVerts; j++)
|
||||||
|
{
|
||||||
|
*uvptr = mdST[j].st[0];
|
||||||
|
uvptr++;
|
||||||
|
*uvptr = 1.0f - mdST[j].st[1];
|
||||||
|
uvptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short *indexptr = retModel->meshes[i].indices;
|
||||||
|
md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
|
||||||
|
for (j = 0; j < mdS->numTriangles; j++, mdT++)
|
||||||
|
{
|
||||||
|
// Indices
|
||||||
|
*indexptr = (unsigned short)mdT->index[0];
|
||||||
|
indexptr++;
|
||||||
|
*indexptr = (unsigned short)mdT->index[2];
|
||||||
|
indexptr++;
|
||||||
|
*indexptr = (unsigned short)mdT->index[1];
|
||||||
|
indexptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Traditional full-float loading method
|
||||||
|
{
|
||||||
|
retModel->meshes[i].numVertices = mdS->numTriangles * 3;//mdS->numVerts;
|
||||||
|
float dataScale = 0.015624f * WUNITS;
|
||||||
|
float tempNormal[3];
|
||||||
|
retModel->meshes[i].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*mdS->numFrames, ztag, 0);
|
||||||
|
retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numTriangles*3, ztag, 0);
|
||||||
|
|
||||||
|
for (j = 0; j < mdS->numFrames; j++)
|
||||||
|
{
|
||||||
|
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
|
||||||
|
retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0);
|
||||||
|
retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0);
|
||||||
|
// if (retModel->materials[i].lightmap)
|
||||||
|
// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag);
|
||||||
|
float *vertptr = retModel->meshes[i].frames[j].vertices;
|
||||||
|
float *normptr = retModel->meshes[i].frames[j].normals;
|
||||||
|
retModel->meshes[i].frames[j].material = &retModel->materials[i];
|
||||||
|
|
||||||
|
int k;
|
||||||
|
md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
|
||||||
|
|
||||||
|
for (k = 0; k < mdS->numTriangles; k++)
|
||||||
|
{
|
||||||
|
// Vertex 1
|
||||||
|
*vertptr = mdV[mdT->index[0]].x * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[mdT->index[0]].z * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[mdT->index[0]].y * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
GetNormalFromLatLong(mdV[mdT->index[0]].n, tempNormal);
|
||||||
|
*normptr = tempNormal[1];
|
||||||
|
normptr++;
|
||||||
|
*normptr = tempNormal[2];
|
||||||
|
normptr++;
|
||||||
|
*normptr = tempNormal[0];
|
||||||
|
normptr++;
|
||||||
|
|
||||||
|
// Vertex 2
|
||||||
|
*vertptr = mdV[mdT->index[2]].x * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[mdT->index[2]].z * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[mdT->index[2]].y * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
GetNormalFromLatLong(mdV[mdT->index[2]].n, tempNormal);
|
||||||
|
*normptr = tempNormal[1];
|
||||||
|
normptr++;
|
||||||
|
*normptr = tempNormal[2];
|
||||||
|
normptr++;
|
||||||
|
*normptr = tempNormal[0];
|
||||||
|
normptr++;
|
||||||
|
|
||||||
|
// Vertex 3
|
||||||
|
*vertptr = mdV[mdT->index[1]].x * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[mdT->index[1]].z * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
*vertptr = mdV[mdT->index[1]].y * dataScale;
|
||||||
|
vertptr++;
|
||||||
|
|
||||||
|
GetNormalFromLatLong(mdV[mdT->index[1]].n, tempNormal);
|
||||||
|
*normptr = tempNormal[1];
|
||||||
|
normptr++;
|
||||||
|
*normptr = tempNormal[2];
|
||||||
|
normptr++;
|
||||||
|
*normptr = tempNormal[0];
|
||||||
|
normptr++;
|
||||||
|
|
||||||
|
mdT++; // Advance to next triangle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
md3TexCoord *mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST);
|
||||||
|
float *uvptr = (float*)retModel->meshes[i].uvs;
|
||||||
|
int k;
|
||||||
|
md3Triangle *mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
|
||||||
|
|
||||||
|
for (k = 0; k < mdS->numTriangles; k++)
|
||||||
|
{
|
||||||
|
*uvptr = mdST[mdT->index[0]].st[0];
|
||||||
|
uvptr++;
|
||||||
|
*uvptr = mdST[mdT->index[0]].st[1];
|
||||||
|
uvptr++;
|
||||||
|
|
||||||
|
*uvptr = mdST[mdT->index[2]].st[0];
|
||||||
|
uvptr++;
|
||||||
|
*uvptr = mdST[mdT->index[2]].st[1];
|
||||||
|
uvptr++;
|
||||||
|
|
||||||
|
*uvptr = mdST[mdT->index[1]].st[0];
|
||||||
|
uvptr++;
|
||||||
|
*uvptr = mdST[mdT->index[1]].st[1];
|
||||||
|
uvptr++;
|
||||||
|
|
||||||
|
mdT++; // Advance to next triangle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Tags?
|
||||||
|
retModel->numTags = mdh->numTags;
|
||||||
|
retModel->maxNumFrames = mdh->numFrames;
|
||||||
|
retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag);
|
||||||
|
md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags];
|
||||||
|
tag_t *curTag = retModel->tags;
|
||||||
|
for (i = 0; i < mdh->numFrames; i++)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < retModel->numTags; j++, mdTag++)
|
||||||
|
{
|
||||||
|
strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char));
|
||||||
|
curTag->transform.m[0][0] = mdTag->axis[0];
|
||||||
|
curTag->transform.m[0][1] = mdTag->axis[1];
|
||||||
|
curTag->transform.m[0][2] = mdTag->axis[2];
|
||||||
|
curTag->transform.m[1][0] = mdTag->axis[3];
|
||||||
|
curTag->transform.m[1][1] = mdTag->axis[4];
|
||||||
|
curTag->transform.m[1][2] = mdTag->axis[5];
|
||||||
|
curTag->transform.m[2][0] = mdTag->axis[6];
|
||||||
|
curTag->transform.m[2][1] = mdTag->axis[7];
|
||||||
|
curTag->transform.m[2][2] = mdTag->axis[8];
|
||||||
|
curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS;
|
||||||
|
curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS;
|
||||||
|
curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS;
|
||||||
|
curTag->transform.m[3][3] = 1.0f;
|
||||||
|
|
||||||
|
Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis);
|
||||||
|
curTag++;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
|
||||||
|
return retModel;
|
||||||
|
}
|
19
src/hardware/hw_md3load.h
Normal file
19
src/hardware/hw_md3load.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HW_MD3LOAD_H_
|
||||||
|
#define _HW_MD3LOAD_H_
|
||||||
|
|
||||||
|
#include "hw_model.h"
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
// Load the Model
|
||||||
|
model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat);
|
||||||
|
|
||||||
|
#endif
|
706
src/hardware/hw_model.c
Normal file
706
src/hardware/hw_model.c
Normal file
|
@ -0,0 +1,706 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../z_zone.h"
|
||||||
|
#include "../doomdef.h"
|
||||||
|
#include "hw_model.h"
|
||||||
|
#include "hw_md2load.h"
|
||||||
|
#include "hw_md3load.h"
|
||||||
|
#include "u_list.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static float PI = (3.1415926535897932384626433832795f);
|
||||||
|
float U_Deg2Rad(float deg)
|
||||||
|
{
|
||||||
|
return deg * ((float)PI / 180.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector_t vectorXaxis = { 1.0f, 0.0f, 0.0f };
|
||||||
|
vector_t vectorYaxis = { 0.0f, 1.0f, 0.0f };
|
||||||
|
vector_t vectorZaxis = { 0.0f, 0.0f, 1.0f };
|
||||||
|
|
||||||
|
void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle)
|
||||||
|
{
|
||||||
|
angle = U_Deg2Rad(angle);
|
||||||
|
|
||||||
|
// Rotate the point (x,y,z) around the vector (u,v,w)
|
||||||
|
float ux = axisVec->x * rotVec->x;
|
||||||
|
float uy = axisVec->x * rotVec->y;
|
||||||
|
float uz = axisVec->x * rotVec->z;
|
||||||
|
float vx = axisVec->y * rotVec->x;
|
||||||
|
float vy = axisVec->y * rotVec->y;
|
||||||
|
float vz = axisVec->y * rotVec->z;
|
||||||
|
float wx = axisVec->z * rotVec->x;
|
||||||
|
float wy = axisVec->z * rotVec->y;
|
||||||
|
float wz = axisVec->z * rotVec->z;
|
||||||
|
float sa = sinf(angle);
|
||||||
|
float ca = cosf(angle);
|
||||||
|
|
||||||
|
rotVec->x = axisVec->x*(ux + vy + wz) + (rotVec->x*(axisVec->y*axisVec->y + axisVec->z*axisVec->z) - axisVec->x*(vy + wz))*ca + (-wy + vz)*sa;
|
||||||
|
rotVec->y = axisVec->y*(ux + vy + wz) + (rotVec->y*(axisVec->x*axisVec->x + axisVec->z*axisVec->z) - axisVec->y*(ux + wz))*ca + (wx - uz)*sa;
|
||||||
|
rotVec->z = axisVec->z*(ux + vy + wz) + (rotVec->z*(axisVec->x*axisVec->x + axisVec->y*axisVec->y) - axisVec->z*(ux + vy))*ca + (-vx + uy)*sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
/* int bufferSize = sizeof(VBO::vbotiny_t)*mesh->numTriangles*3;
|
||||||
|
VBO::vbotiny_t *buffer = (VBO::vbotiny_t*)Z_Malloc(bufferSize, PU_STATIC, 0);
|
||||||
|
VBO::vbotiny_t *bufPtr = buffer;
|
||||||
|
|
||||||
|
short *vertPtr = frame->vertices;
|
||||||
|
char *normPtr = frame->normals;
|
||||||
|
float *uvPtr = mesh->uvs;
|
||||||
|
char *tanPtr = frame->tangents;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < mesh->numTriangles*3; i++)
|
||||||
|
{
|
||||||
|
bufPtr->x = *vertPtr++;
|
||||||
|
bufPtr->y = *vertPtr++;
|
||||||
|
bufPtr->z = *vertPtr++;
|
||||||
|
|
||||||
|
bufPtr->nx = (*normPtr++) * 127;
|
||||||
|
bufPtr->ny = (*normPtr++) * 127;
|
||||||
|
bufPtr->nz = (*normPtr++) * 127;
|
||||||
|
|
||||||
|
bufPtr->s0 = *uvPtr++;
|
||||||
|
bufPtr->t0 = *uvPtr++;
|
||||||
|
|
||||||
|
if (tanPtr)
|
||||||
|
{
|
||||||
|
bufPtr->tanx = *tanPtr++;
|
||||||
|
bufPtr->tany = *tanPtr++;
|
||||||
|
bufPtr->tanz = *tanPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bglGenBuffers(1, &frame->vboID);
|
||||||
|
bglBindBuffer(BGL_ARRAY_BUFFER, frame->vboID);
|
||||||
|
bglBufferData(BGL_ARRAY_BUFFER, bufferSize, buffer, BGL_STATIC_DRAW);
|
||||||
|
Z_Free(buffer);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateVBO(mesh_t *mesh, mdlframe_t *frame)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
/* int bufferSize = sizeof(VBO::vbo64_t)*mesh->numTriangles*3;
|
||||||
|
VBO::vbo64_t *buffer = (VBO::vbo64_t*)Z_Malloc(bufferSize, PU_STATIC, 0);
|
||||||
|
VBO::vbo64_t *bufPtr = buffer;
|
||||||
|
|
||||||
|
float *vertPtr = frame->vertices;
|
||||||
|
float *normPtr = frame->normals;
|
||||||
|
float *tanPtr = frame->tangents;
|
||||||
|
float *uvPtr = mesh->uvs;
|
||||||
|
float *lightPtr = mesh->lightuvs;
|
||||||
|
byte *colorPtr = frame->colors;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < mesh->numTriangles*3; i++)
|
||||||
|
{
|
||||||
|
bufPtr->x = *vertPtr++;
|
||||||
|
bufPtr->y = *vertPtr++;
|
||||||
|
bufPtr->z = *vertPtr++;
|
||||||
|
|
||||||
|
bufPtr->nx = *normPtr++;
|
||||||
|
bufPtr->ny = *normPtr++;
|
||||||
|
bufPtr->nz = *normPtr++;
|
||||||
|
|
||||||
|
bufPtr->s0 = *uvPtr++;
|
||||||
|
bufPtr->t0 = *uvPtr++;
|
||||||
|
|
||||||
|
if (tanPtr != NULL)
|
||||||
|
{
|
||||||
|
bufPtr->tan0 = *tanPtr++;
|
||||||
|
bufPtr->tan1 = *tanPtr++;
|
||||||
|
bufPtr->tan2 = *tanPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lightPtr != NULL)
|
||||||
|
{
|
||||||
|
bufPtr->s1 = *lightPtr++;
|
||||||
|
bufPtr->t1 = *lightPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorPtr)
|
||||||
|
{
|
||||||
|
bufPtr->r = *colorPtr++;
|
||||||
|
bufPtr->g = *colorPtr++;
|
||||||
|
bufPtr->b = *colorPtr++;
|
||||||
|
bufPtr->a = *colorPtr++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufPtr->r = 255;
|
||||||
|
bufPtr->g = 255;
|
||||||
|
bufPtr->b = 255;
|
||||||
|
bufPtr->a = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufPtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bglGenBuffers(1, &frame->vboID);
|
||||||
|
bglBindBuffer(BGL_ARRAY_BUFFER, frame->vboID);
|
||||||
|
bglBufferData(BGL_ARRAY_BUFFER, bufferSize, buffer, BGL_STATIC_DRAW);
|
||||||
|
Z_Free(buffer);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadModel(model_t *model)
|
||||||
|
{
|
||||||
|
// Wouldn't it be great if C just had destructors?
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < model->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *mesh = &model->meshes[i];
|
||||||
|
|
||||||
|
if (mesh->frames)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mesh->numFrames; j++)
|
||||||
|
{
|
||||||
|
if (mesh->frames[j].normals)
|
||||||
|
Z_Free(mesh->frames[j].normals);
|
||||||
|
|
||||||
|
if (mesh->frames[j].tangents)
|
||||||
|
Z_Free(mesh->frames[j].tangents);
|
||||||
|
|
||||||
|
if (mesh->frames[j].vertices)
|
||||||
|
Z_Free(mesh->frames[j].vertices);
|
||||||
|
|
||||||
|
if (mesh->frames[j].colors)
|
||||||
|
Z_Free(mesh->frames[j].colors);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(mesh->frames);
|
||||||
|
}
|
||||||
|
else if (mesh->tinyframes)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mesh->numFrames; j++)
|
||||||
|
{
|
||||||
|
if (mesh->tinyframes[j].normals)
|
||||||
|
Z_Free(mesh->tinyframes[j].normals);
|
||||||
|
|
||||||
|
if (mesh->tinyframes[j].tangents)
|
||||||
|
Z_Free(mesh->tinyframes[j].tangents);
|
||||||
|
|
||||||
|
if (mesh->tinyframes[j].vertices)
|
||||||
|
Z_Free(mesh->tinyframes[j].vertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->indices)
|
||||||
|
Z_Free(mesh->indices);
|
||||||
|
|
||||||
|
Z_Free(mesh->tinyframes);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh->uvs)
|
||||||
|
Z_Free(mesh->uvs);
|
||||||
|
|
||||||
|
if (mesh->lightuvs)
|
||||||
|
Z_Free(mesh->lightuvs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model->meshes)
|
||||||
|
Z_Free(model->meshes);
|
||||||
|
|
||||||
|
if (model->tags)
|
||||||
|
Z_Free(model->tags);
|
||||||
|
|
||||||
|
if (model->materials)
|
||||||
|
Z_Free(model->materials);
|
||||||
|
|
||||||
|
DeleteVBOs(model);
|
||||||
|
Z_Free(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_t *GetTagByName(model_t *model, char *name, int frame)
|
||||||
|
{
|
||||||
|
if (frame < model->maxNumFrames)
|
||||||
|
{
|
||||||
|
tag_t *iterator = &model->tags[frame * model->numTags];
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < model->numTags; i++)
|
||||||
|
{
|
||||||
|
if (!stricmp(iterator[i].name, name))
|
||||||
|
return &iterator[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// LoadModel
|
||||||
|
//
|
||||||
|
// Load a model and
|
||||||
|
// convert it to the
|
||||||
|
// internal format.
|
||||||
|
//
|
||||||
|
model_t *LoadModel(const char *filename, int ztag)
|
||||||
|
{
|
||||||
|
model_t *model;
|
||||||
|
|
||||||
|
// What type of file?
|
||||||
|
const char *extension = NULL;
|
||||||
|
int i;
|
||||||
|
for (i = (int)strlen(filename)-1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (filename[i] != '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
extension = &filename[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extension)
|
||||||
|
{
|
||||||
|
CONS_Printf("Model %s is lacking a file extension, unable to determine type!\n", filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(extension, ".md3"))
|
||||||
|
{
|
||||||
|
if (!(model = MD3_LoadModel(filename, ztag, false)))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (!strcmp(extension, ".md3s")) // MD3 that will be converted in memory to use full floats
|
||||||
|
{
|
||||||
|
if (!(model = MD3_LoadModel(filename, ztag, true)))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (!strcmp(extension, ".md2"))
|
||||||
|
{
|
||||||
|
if (!(model = MD2_LoadModel(filename, ztag, false)))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (!strcmp(extension, ".md2s"))
|
||||||
|
{
|
||||||
|
if (!(model = MD2_LoadModel(filename, ztag, true)))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CONS_Printf("Unknown model format: %s\n", extension);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
model->mdlFilename = (char*)Z_Malloc(strlen(filename)+1, ztag, 0);
|
||||||
|
strcpy(model->mdlFilename, filename);
|
||||||
|
|
||||||
|
Optimize(model);
|
||||||
|
GeneratePolygonNormals(model, ztag);
|
||||||
|
|
||||||
|
// Default material properties
|
||||||
|
for (i = 0 ; i < model->numMaterials; i++)
|
||||||
|
{
|
||||||
|
material_t *material = &model->materials[i];
|
||||||
|
material->ambient[0] = 0.7686f;
|
||||||
|
material->ambient[1] = 0.7686f;
|
||||||
|
material->ambient[2] = 0.7686f;
|
||||||
|
material->ambient[3] = 1.0f;
|
||||||
|
material->diffuse[0] = 0.5863f;
|
||||||
|
material->diffuse[1] = 0.5863f;
|
||||||
|
material->diffuse[2] = 0.5863f;
|
||||||
|
material->diffuse[3] = 1.0f;
|
||||||
|
material->specular[0] = 0.4902f;
|
||||||
|
material->specular[1] = 0.4902f;
|
||||||
|
material->specular[2] = 0.4902f;
|
||||||
|
material->specular[3] = 1.0f;
|
||||||
|
material->shininess = 25.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONS_Printf("Generating VBOs for %s\n", filename);
|
||||||
|
for (i = 0; i < model->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *mesh = &model->meshes[i];
|
||||||
|
|
||||||
|
if (mesh->frames)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < model->meshes[i].numFrames; j++)
|
||||||
|
{
|
||||||
|
mdlframe_t *frame = &mesh->frames[j];
|
||||||
|
frame->vboID = 0;
|
||||||
|
CreateVBO(mesh, frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mesh->tinyframes)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < model->meshes[i].numFrames; j++)
|
||||||
|
{
|
||||||
|
tinyframe_t *frame = &mesh->tinyframes[j];
|
||||||
|
frame->vboID = 0;
|
||||||
|
CreateVBOTiny(mesh, frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// GenerateVertexNormals
|
||||||
|
//
|
||||||
|
// Creates a new normal for a vertex using the average of all of the polygons it belongs to.
|
||||||
|
//
|
||||||
|
void GenerateVertexNormals(model_t *model)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < model->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *mesh = &model->meshes[i];
|
||||||
|
|
||||||
|
if (!mesh->frames)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mesh->numFrames; j++)
|
||||||
|
{
|
||||||
|
mdlframe_t *frame = &mesh->frames[j];
|
||||||
|
int memTag = PU_STATIC;
|
||||||
|
float *newNormals = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag, 0);
|
||||||
|
M_Memcpy(newNormals, frame->normals, sizeof(float)*3*mesh->numTriangles*3);
|
||||||
|
|
||||||
|
/* if (!systemSucks)
|
||||||
|
{
|
||||||
|
memTag = Z_GetTag(frame->tangents);
|
||||||
|
float *newTangents = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag);
|
||||||
|
M_Memcpy(newTangents, frame->tangents, sizeof(float)*3*mesh->numTriangles*3);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int k;
|
||||||
|
float *vertPtr = frame->vertices;
|
||||||
|
for (k = 0; k < mesh->numVertices; k++)
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
x = *vertPtr++;
|
||||||
|
y = *vertPtr++;
|
||||||
|
z = *vertPtr++;
|
||||||
|
|
||||||
|
int vCount = 0;
|
||||||
|
vector_t normal;
|
||||||
|
normal.x = normal.y = normal.z = 0;
|
||||||
|
int l;
|
||||||
|
float *testPtr = frame->vertices;
|
||||||
|
for (l = 0; l < mesh->numVertices; l++)
|
||||||
|
{
|
||||||
|
float testX, testY, testZ;
|
||||||
|
testX = *testPtr++;
|
||||||
|
testY = *testPtr++;
|
||||||
|
testZ = *testPtr++;
|
||||||
|
|
||||||
|
if (x != testX || y != testY || z != testZ)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Found a vertex match! Add it...
|
||||||
|
normal.x += frame->normals[3 * l + 0];
|
||||||
|
normal.y += frame->normals[3 * l + 1];
|
||||||
|
normal.z += frame->normals[3 * l + 2];
|
||||||
|
vCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vCount > 1)
|
||||||
|
{
|
||||||
|
// Vector::Normalize(&normal);
|
||||||
|
newNormals[3 * k + 0] = (float)normal.x;
|
||||||
|
newNormals[3 * k + 1] = (float)normal.y;
|
||||||
|
newNormals[3 * k + 2] = (float)normal.z;
|
||||||
|
|
||||||
|
/* if (!systemSucks)
|
||||||
|
{
|
||||||
|
Vector::vector_t tangent;
|
||||||
|
Vector::Tangent(&normal, &tangent);
|
||||||
|
newTangents[3 * k + 0] = tangent.x;
|
||||||
|
newTangents[3 * k + 1] = tangent.y;
|
||||||
|
newTangents[3 * k + 2] = tangent.z;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float *oldNormals = frame->normals;
|
||||||
|
frame->normals = newNormals;
|
||||||
|
Z_Free(oldNormals);
|
||||||
|
|
||||||
|
/* if (!systemSucks)
|
||||||
|
{
|
||||||
|
float *oldTangents = frame->tangents;
|
||||||
|
frame->tangents = newTangents;
|
||||||
|
Z_Free(oldTangents);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct materiallist_s
|
||||||
|
{
|
||||||
|
struct materiallist_s *next;
|
||||||
|
struct materiallist_s *prev;
|
||||||
|
material_t *material;
|
||||||
|
} materiallist_t;
|
||||||
|
|
||||||
|
static bool AddMaterialToList(materiallist_t **head, material_t *material)
|
||||||
|
{
|
||||||
|
materiallist_t *node;
|
||||||
|
for (node = *head; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (node->material == material)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Didn't find it, so add to the list
|
||||||
|
materiallist_t *newMatNode = (materiallist_t*)Z_Malloc(sizeof(materiallist_t), PU_CACHE, 0);
|
||||||
|
newMatNode->material = material;
|
||||||
|
ListAdd(newMatNode, (listitem_t**)head);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Optimize
|
||||||
|
//
|
||||||
|
// Groups triangles from meshes in the model
|
||||||
|
// Only works for models with 1 frame
|
||||||
|
//
|
||||||
|
void Optimize(model_t *model)
|
||||||
|
{
|
||||||
|
if (model->numMeshes <= 1)
|
||||||
|
return; // No need
|
||||||
|
|
||||||
|
int numMeshes = 0;
|
||||||
|
int i;
|
||||||
|
materiallist_t *matListHead = NULL;
|
||||||
|
for (i = 0; i < model->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *curMesh = &model->meshes[i];
|
||||||
|
|
||||||
|
if (curMesh->numFrames > 1)
|
||||||
|
return; // Can't optimize models with > 1 frame
|
||||||
|
|
||||||
|
if (!curMesh->frames)
|
||||||
|
return; // Don't optimize tinyframe models (no need)
|
||||||
|
|
||||||
|
// We are condensing to 1 mesh per material, so
|
||||||
|
// the # of materials we use will be the new
|
||||||
|
// # of meshes
|
||||||
|
if (AddMaterialToList(&matListHead, curMesh->frames[0].material))
|
||||||
|
numMeshes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int memTag = PU_STATIC;
|
||||||
|
mesh_t *newMeshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * numMeshes, memTag, 0);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
materiallist_t *node;
|
||||||
|
for (node = matListHead; node; node = node->next)
|
||||||
|
{
|
||||||
|
material_t *curMat = node->material;
|
||||||
|
mesh_t *newMesh = &newMeshes[i];
|
||||||
|
|
||||||
|
// Find all triangles with this material and count them
|
||||||
|
int numTriangles = 0;
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < model->numMeshes; j++)
|
||||||
|
{
|
||||||
|
mesh_t *curMesh = &model->meshes[j];
|
||||||
|
|
||||||
|
if (curMesh->frames[0].material == curMat)
|
||||||
|
numTriangles += curMesh->numTriangles;
|
||||||
|
}
|
||||||
|
|
||||||
|
newMesh->numFrames = 1;
|
||||||
|
newMesh->numTriangles = numTriangles;
|
||||||
|
newMesh->numVertices = numTriangles * 3;
|
||||||
|
newMesh->uvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
|
||||||
|
// if (node->material->lightmap)
|
||||||
|
// newMesh->lightuvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
|
||||||
|
newMesh->frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t), memTag, 0);
|
||||||
|
mdlframe_t *curFrame = &newMesh->frames[0];
|
||||||
|
|
||||||
|
curFrame->material = curMat;
|
||||||
|
curFrame->normals = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
|
||||||
|
// if (!systemSucks)
|
||||||
|
// curFrame->tangents = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
|
||||||
|
curFrame->vertices = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
|
||||||
|
curFrame->colors = (byte*)Z_Malloc(sizeof(byte)*4*numTriangles*3, memTag, 0);
|
||||||
|
|
||||||
|
// Now traverse the meshes of the model, adding in
|
||||||
|
// vertices/normals/uvs that match the current material
|
||||||
|
int uvCount = 0;
|
||||||
|
int vertCount = 0;
|
||||||
|
int colorCount = 0;
|
||||||
|
for (j = 0; j < model->numMeshes; j++)
|
||||||
|
{
|
||||||
|
mesh_t *curMesh = &model->meshes[j];
|
||||||
|
|
||||||
|
if (curMesh->frames[0].material == curMat)
|
||||||
|
{
|
||||||
|
float *dest;
|
||||||
|
float *src;
|
||||||
|
|
||||||
|
M_Memcpy(&newMesh->uvs[uvCount],
|
||||||
|
curMesh->uvs,
|
||||||
|
sizeof(float)*2*curMesh->numTriangles*3);
|
||||||
|
|
||||||
|
/* if (node->material->lightmap)
|
||||||
|
{
|
||||||
|
M_Memcpy(&newMesh->lightuvs[uvCount],
|
||||||
|
curMesh->lightuvs,
|
||||||
|
sizeof(float)*2*curMesh->numTriangles*3);
|
||||||
|
}*/
|
||||||
|
uvCount += 2*curMesh->numTriangles*3;
|
||||||
|
|
||||||
|
dest = (float*)newMesh->frames[0].vertices;
|
||||||
|
src = (float*)curMesh->frames[0].vertices;
|
||||||
|
M_Memcpy(&dest[vertCount],
|
||||||
|
src,
|
||||||
|
sizeof(float)*3*curMesh->numTriangles*3);
|
||||||
|
|
||||||
|
dest = (float*)newMesh->frames[0].normals;
|
||||||
|
src = (float*)curMesh->frames[0].normals;
|
||||||
|
M_Memcpy(&dest[vertCount],
|
||||||
|
src,
|
||||||
|
sizeof(float)*3*curMesh->numTriangles*3);
|
||||||
|
|
||||||
|
/* if (!systemSucks)
|
||||||
|
{
|
||||||
|
dest = (float*)newMesh->frames[0].tangents;
|
||||||
|
src = (float*)curMesh->frames[0].tangents;
|
||||||
|
M_Memcpy(&dest[vertCount],
|
||||||
|
src,
|
||||||
|
sizeof(float)*3*curMesh->numTriangles*3);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
vertCount += 3 * curMesh->numTriangles * 3;
|
||||||
|
|
||||||
|
byte *destByte;
|
||||||
|
byte *srcByte;
|
||||||
|
destByte = (byte*)newMesh->frames[0].colors;
|
||||||
|
srcByte = (byte*)curMesh->frames[0].colors;
|
||||||
|
|
||||||
|
if (srcByte)
|
||||||
|
{
|
||||||
|
M_Memcpy(&destByte[colorCount],
|
||||||
|
srcByte,
|
||||||
|
sizeof(byte)*4*curMesh->numTriangles*3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(&destByte[colorCount],
|
||||||
|
255,
|
||||||
|
sizeof(byte)*4*curMesh->numTriangles*3);
|
||||||
|
}
|
||||||
|
|
||||||
|
colorCount += 4 * curMesh->numTriangles * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONS_Printf("Model::Optimize(): Model reduced from %d to %d meshes.\n", model->numMeshes, numMeshes);
|
||||||
|
model->meshes = newMeshes;
|
||||||
|
model->numMeshes = numMeshes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GeneratePolygonNormals(model_t *model, int ztag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < model->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *mesh = &model->meshes[i];
|
||||||
|
|
||||||
|
if (!mesh->frames)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mesh->numFrames; j++)
|
||||||
|
{
|
||||||
|
mdlframe_t *frame = &mesh->frames[j];
|
||||||
|
|
||||||
|
frame->polyNormals = (vector_t*)Z_Malloc(sizeof(vector_t) * mesh->numTriangles, ztag, 0);
|
||||||
|
|
||||||
|
const float *vertices = frame->vertices;
|
||||||
|
vector_t *polyNormals = frame->polyNormals;
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < mesh->numTriangles; k++)
|
||||||
|
{
|
||||||
|
// Vector::Normal(vertices, polyNormals);
|
||||||
|
vertices += 3 * 3;
|
||||||
|
polyNormals++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reload
|
||||||
|
//
|
||||||
|
// Reload VBOs
|
||||||
|
//
|
||||||
|
void Reload(void)
|
||||||
|
{
|
||||||
|
/* model_t *node;
|
||||||
|
for (node = modelHead; node; node = node->next)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < node->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *mesh = &node->meshes[i];
|
||||||
|
|
||||||
|
if (mesh->frames)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mesh->numFrames; j++)
|
||||||
|
CreateVBO(mesh, &mesh->frames[j]);
|
||||||
|
}
|
||||||
|
else if (mesh->tinyframes)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < mesh->numFrames; j++)
|
||||||
|
CreateVBO(mesh, &mesh->tinyframes[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteVBOs(model_t *model)
|
||||||
|
{
|
||||||
|
/* for (int i = 0; i < model->numMeshes; i++)
|
||||||
|
{
|
||||||
|
mesh_t *mesh = &model->meshes[i];
|
||||||
|
|
||||||
|
if (mesh->frames)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < mesh->numFrames; j++)
|
||||||
|
{
|
||||||
|
mdlframe_t *frame = &mesh->frames[j];
|
||||||
|
if (!frame->vboID)
|
||||||
|
continue;
|
||||||
|
bglDeleteBuffers(1, &frame->vboID);
|
||||||
|
frame->vboID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mesh->tinyframes)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < mesh->numFrames; j++)
|
||||||
|
{
|
||||||
|
tinyframe_t *frame = &mesh->tinyframes[j];
|
||||||
|
if (!frame->vboID)
|
||||||
|
continue;
|
||||||
|
bglDeleteBuffers(1, &frame->vboID);
|
||||||
|
frame->vboID = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
104
src/hardware/hw_model.h
Normal file
104
src/hardware/hw_model.h
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _HW_MODEL_H_
|
||||||
|
#define _HW_MODEL_H_
|
||||||
|
|
||||||
|
#include "../doomtype.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
} vector_t;
|
||||||
|
|
||||||
|
extern vector_t vectorXaxis;
|
||||||
|
extern vector_t vectorYaxis;
|
||||||
|
extern vector_t vectorZaxis;
|
||||||
|
|
||||||
|
void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float ambient[4], diffuse[4], specular[4], emissive[4];
|
||||||
|
float shininess;
|
||||||
|
bool spheremap;
|
||||||
|
// Texture::texture_t *texture;
|
||||||
|
// Texture::texture_t *lightmap;
|
||||||
|
} material_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
material_t *material; // Pointer to the allocated 'materials' list in model_t
|
||||||
|
float *vertices;
|
||||||
|
float *normals;
|
||||||
|
float *tangents;
|
||||||
|
byte *colors;
|
||||||
|
unsigned int vboID;
|
||||||
|
vector_t *polyNormals;
|
||||||
|
} mdlframe_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
material_t *material;
|
||||||
|
short *vertices;
|
||||||
|
char *normals;
|
||||||
|
char *tangents;
|
||||||
|
unsigned int vboID;
|
||||||
|
} tinyframe_t;
|
||||||
|
|
||||||
|
// Equivalent to MD3's many 'surfaces'
|
||||||
|
typedef struct mesh_s
|
||||||
|
{
|
||||||
|
int numVertices;
|
||||||
|
int numTriangles;
|
||||||
|
|
||||||
|
float *uvs;
|
||||||
|
float *lightuvs;
|
||||||
|
|
||||||
|
int numFrames;
|
||||||
|
mdlframe_t *frames;
|
||||||
|
tinyframe_t *tinyframes;
|
||||||
|
unsigned short *indices;
|
||||||
|
} mesh_t;
|
||||||
|
|
||||||
|
typedef struct tag_s
|
||||||
|
{
|
||||||
|
char name[64];
|
||||||
|
// matrix_t transform;
|
||||||
|
} tag_t;
|
||||||
|
|
||||||
|
typedef struct model_s
|
||||||
|
{
|
||||||
|
int maxNumFrames;
|
||||||
|
|
||||||
|
int numMaterials;
|
||||||
|
material_t *materials;
|
||||||
|
int numMeshes;
|
||||||
|
mesh_t *meshes;
|
||||||
|
int numTags;
|
||||||
|
tag_t *tags;
|
||||||
|
|
||||||
|
char *mdlFilename;
|
||||||
|
boolean unloaded;
|
||||||
|
} model_t;
|
||||||
|
|
||||||
|
extern int numModels;
|
||||||
|
extern model_t *modelHead;
|
||||||
|
|
||||||
|
tag_t *GetTagByName(model_t *model, char *name, int frame);
|
||||||
|
model_t *LoadModel(const char *filename, int ztag);
|
||||||
|
void UnloadModel(model_t *model);
|
||||||
|
void Optimize(model_t *model);
|
||||||
|
void GenerateVertexNormals(model_t *model);
|
||||||
|
void GeneratePolygonNormals(model_t *model, int ztag);
|
||||||
|
void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame);
|
||||||
|
void CreateVBO(mesh_t *mesh, mdlframe_t *frame);
|
||||||
|
void DeleteVBOs(model_t *model);
|
||||||
|
|
||||||
|
#endif
|
|
@ -245,6 +245,12 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
||||||
#define pglColor4f glColor4f
|
#define pglColor4f glColor4f
|
||||||
#define pglColor4fv glColor4fv
|
#define pglColor4fv glColor4fv
|
||||||
#define pglTexCoord2f glTexCoord2f
|
#define pglTexCoord2f glTexCoord2f
|
||||||
|
#define pglVertexPointer glVertexPointer
|
||||||
|
#define pglNormalPointer glNormalPointer
|
||||||
|
#define pglTexCoordPointer glTexCoordPointer
|
||||||
|
#define pglDrawArrays glDrawArrays
|
||||||
|
#define pglEnableClientState glEnableClientState
|
||||||
|
#define pglDisableClientState pglDisableClientState
|
||||||
|
|
||||||
/* Lighting */
|
/* Lighting */
|
||||||
#define pglShadeModel glShadeModel
|
#define pglShadeModel glShadeModel
|
||||||
|
@ -357,6 +363,18 @@ typedef void (APIENTRY * PFNglColor4fv) (const GLfloat *v);
|
||||||
static PFNglColor4fv pglColor4fv;
|
static PFNglColor4fv pglColor4fv;
|
||||||
typedef void (APIENTRY * PFNglTexCoord2f) (GLfloat s, GLfloat t);
|
typedef void (APIENTRY * PFNglTexCoord2f) (GLfloat s, GLfloat t);
|
||||||
static PFNglTexCoord2f pglTexCoord2f;
|
static PFNglTexCoord2f pglTexCoord2f;
|
||||||
|
typedef void (APIENTRY * PFNglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||||
|
static PFNglVertexPointer pglVertexPointer;
|
||||||
|
typedef void (APIENTRY * PFNglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||||
|
static PFNglNormalPointer pglNormalPointer;
|
||||||
|
typedef void (APIENTRY * PFNglTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||||
|
static PFNglTexCoordPointer pglTexCoordPointer;
|
||||||
|
typedef void (APIENTRY * PFNglDrawArrays) (GLenum mode, GLint first, GLsizei count);
|
||||||
|
static PFNglDrawArrays pglDrawArrays;
|
||||||
|
typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap);
|
||||||
|
static PFNglEnableClientState pglEnableClientState;
|
||||||
|
typedef void (APIENTRY * PFNglDisableClientState) (GLenum cap);
|
||||||
|
static PFNglDisableClientState pglDisableClientState;
|
||||||
|
|
||||||
/* Lighting */
|
/* Lighting */
|
||||||
typedef void (APIENTRY * PFNglShadeModel) (GLenum mode);
|
typedef void (APIENTRY * PFNglShadeModel) (GLenum mode);
|
||||||
|
@ -495,6 +513,12 @@ boolean SetupGLfunc(void)
|
||||||
GETOPENGLFUNC(pglColor4f , glColor4f)
|
GETOPENGLFUNC(pglColor4f , glColor4f)
|
||||||
GETOPENGLFUNC(pglColor4fv , glColor4fv)
|
GETOPENGLFUNC(pglColor4fv , glColor4fv)
|
||||||
GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f)
|
GETOPENGLFUNC(pglTexCoord2f , glTexCoord2f)
|
||||||
|
GETOPENGLFUNC(pglVertexPointer, glVertexPointer)
|
||||||
|
GETOPENGLFUNC(pglNormalPointer, glNormalPointer)
|
||||||
|
GETOPENGLFUNC(pglTexCoordPointer, glTexCoordPointer)
|
||||||
|
GETOPENGLFUNC(pglDrawArrays, glDrawArrays)
|
||||||
|
GETOPENGLFUNC(pglEnableClientState, glEnableClientState)
|
||||||
|
GETOPENGLFUNC(pglDisableClientState, glDisableClientState)
|
||||||
|
|
||||||
GETOPENGLFUNC(pglShadeModel , glShadeModel)
|
GETOPENGLFUNC(pglShadeModel , glShadeModel)
|
||||||
GETOPENGLFUNC(pglLightfv, glLightfv)
|
GETOPENGLFUNC(pglLightfv, glLightfv)
|
||||||
|
@ -1878,7 +1902,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
|
static void DrawModelEx(model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
|
||||||
{
|
{
|
||||||
INT32 val, count, pindex;
|
INT32 val, count, pindex;
|
||||||
GLfloat s, t;
|
GLfloat s, t;
|
||||||
|
@ -1886,6 +1910,7 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
|
||||||
GLfloat diffuse[4];
|
GLfloat diffuse[4];
|
||||||
|
|
||||||
float pol = 0.0f;
|
float pol = 0.0f;
|
||||||
|
scale *= 0.5f;
|
||||||
float scalex = scale, scaley = scale, scalez = scale;
|
float scalex = scale, scaley = scale, scalez = scale;
|
||||||
|
|
||||||
// Because Otherwise, scaling the screen negatively vertically breaks the lighting
|
// Because Otherwise, scaling the screen negatively vertically breaks the lighting
|
||||||
|
@ -1966,68 +1991,107 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
|
||||||
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
|
pglRotatef(pos->anglex, -1.0f, 0.0f, 0.0f);
|
||||||
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f);
|
||||||
|
|
||||||
val = *gl_cmd_buffer++;
|
pglScalef(scalex, scaley, scalez);
|
||||||
|
|
||||||
while (val != 0)
|
mesh_t *mesh = &model->meshes[0];
|
||||||
|
|
||||||
|
if (!nextframe || pol == 0.0f)
|
||||||
{
|
{
|
||||||
if (val < 0)
|
// Zoom! Take advantage of just shoving the entire arrays to the GPU.
|
||||||
|
pglEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
pglEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
pglVertexPointer(3, GL_FLOAT, 0, frame->vertices);
|
||||||
|
pglNormalPointer(GL_FLOAT, 0, frame->normals);
|
||||||
|
pglTexCoordPointer(2, GL_FLOAT, 0, mesh->uvs);
|
||||||
|
pglDrawArrays(GL_TRIANGLES, 0, mesh->numTriangles * 3);
|
||||||
|
pglDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
pglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
pglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
/*
|
||||||
|
pglBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
float *uvPtr = mesh->uvs;
|
||||||
|
float *frameVert = frame->vertices;
|
||||||
|
float *frameNormal = frame->normals;
|
||||||
|
for (i = 0; i < mesh->numTriangles; i++)
|
||||||
{
|
{
|
||||||
pglBegin(GL_TRIANGLE_FAN);
|
float uvx = *uvPtr++;
|
||||||
count = -val;
|
float uvy = *uvPtr++;
|
||||||
}
|
|
||||||
else
|
// Interpolate
|
||||||
{
|
float px1 = *frameVert++;
|
||||||
pglBegin(GL_TRIANGLE_STRIP);
|
float py1 = *frameVert++;
|
||||||
count = val;
|
float pz1 = *frameVert++;
|
||||||
|
float nx1 = *frameNormal++;
|
||||||
|
float ny1 = *frameNormal++;
|
||||||
|
float nz1 = *frameNormal++;
|
||||||
|
|
||||||
|
pglTexCoord2f(uvx, uvy);
|
||||||
|
pglNormal3f(nx1, ny1, nz1);
|
||||||
|
pglVertex3f(px1, py1, pz1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (count--)
|
pglEnd();*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Dangit, I soooo want to do this in a GLSL shader...
|
||||||
|
pglBegin(GL_TRIANGLES);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
float *uvPtr = mesh->uvs;
|
||||||
|
float *frameVert = frame->vertices;
|
||||||
|
float *frameNormal = frame->normals;
|
||||||
|
float *nextFrameVert = nextframe->vertices;
|
||||||
|
float *nextFrameNormal = frame->normals;
|
||||||
|
for (i = 0; i < mesh->numTriangles; i++)
|
||||||
{
|
{
|
||||||
s = *(float *) gl_cmd_buffer++;
|
float uvx = *uvPtr++;
|
||||||
t = *(float *) gl_cmd_buffer++;
|
float uvy = *uvPtr++;
|
||||||
pindex = *gl_cmd_buffer++;
|
|
||||||
|
|
||||||
pglTexCoord2f(s, t);
|
// Interpolate
|
||||||
|
float px1 = *frameVert++;
|
||||||
|
float px2 = *nextFrameVert++;
|
||||||
|
float py1 = *frameVert++;
|
||||||
|
float py2 = *nextFrameVert++;
|
||||||
|
float pz1 = *frameVert++;
|
||||||
|
float pz2 = *nextFrameVert++;
|
||||||
|
float nx1 = *frameNormal++;
|
||||||
|
float nx2 = *nextFrameNormal++;
|
||||||
|
float ny1 = *frameNormal++;
|
||||||
|
float ny2 = *nextFrameNormal++;
|
||||||
|
float nz1 = *frameNormal++;
|
||||||
|
float nz2 = *nextFrameNormal++;
|
||||||
|
|
||||||
if (!nextframe || pol == 0.0f)
|
pglTexCoord2f(uvx, uvy);
|
||||||
{
|
pglNormal3f((nx1 + pol * (nx2 - nx1)),
|
||||||
pglNormal3f(frame->vertices[pindex].normal[0],
|
(ny1 + pol * (ny2 - ny1)),
|
||||||
frame->vertices[pindex].normal[1],
|
(nz1 + pol * (nz2 - nz1)));
|
||||||
frame->vertices[pindex].normal[2]);
|
pglVertex3f((px1 + pol * (px2 - px1)),
|
||||||
|
(py1 + pol * (py2 - py1)),
|
||||||
pglVertex3f(frame->vertices[pindex].vertex[0]*scalex/2.0f,
|
(pz1 + pol * (pz2 - pz1)));
|
||||||
frame->vertices[pindex].vertex[1]*scaley/2.0f,
|
|
||||||
frame->vertices[pindex].vertex[2]*scalez/2.0f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Interpolate
|
|
||||||
float px1 = frame->vertices[pindex].vertex[0]*scalex/2.0f;
|
|
||||||
float px2 = nextframe->vertices[pindex].vertex[0]*scalex/2.0f;
|
|
||||||
float py1 = frame->vertices[pindex].vertex[1]*scaley/2.0f;
|
|
||||||
float py2 = nextframe->vertices[pindex].vertex[1]*scaley/2.0f;
|
|
||||||
float pz1 = frame->vertices[pindex].vertex[2]*scalez/2.0f;
|
|
||||||
float pz2 = nextframe->vertices[pindex].vertex[2]*scalez/2.0f;
|
|
||||||
float nx1 = frame->vertices[pindex].normal[0];
|
|
||||||
float nx2 = nextframe->vertices[pindex].normal[0];
|
|
||||||
float ny1 = frame->vertices[pindex].normal[1];
|
|
||||||
float ny2 = nextframe->vertices[pindex].normal[1];
|
|
||||||
float nz1 = frame->vertices[pindex].normal[2];
|
|
||||||
float nz2 = nextframe->vertices[pindex].normal[2];
|
|
||||||
|
|
||||||
pglNormal3f((nx1 + pol * (nx2 - nx1)),
|
|
||||||
(ny1 + pol * (ny2 - ny1)),
|
|
||||||
(nz1 + pol * (nz2 - nz1)));
|
|
||||||
pglVertex3f((px1 + pol * (px2 - px1)),
|
|
||||||
(py1 + pol * (py2 - py1)),
|
|
||||||
(pz1 + pol * (pz2 - pz1)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pglEnd();
|
pglEnd();
|
||||||
|
|
||||||
val = *gl_cmd_buffer++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if (lightType != LIGHT_NONE)
|
||||||
|
{
|
||||||
|
glVertexAttribPointer(program->slots[Shaders::A_NORMAL_SLOT], 3, BGL_FLOAT, BGL_FALSE, 0, frame->normals);
|
||||||
|
// if (normalmapped)
|
||||||
|
// bglVertexAttribPointer(program->slots[Shaders::A_TANGENT_SLOT], 3, BGL_FLOAT, BGL_FALSE, 0, frame->tangents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame->colors)
|
||||||
|
glVertexAttribPointer(program->slots[Shaders::A_COLOR_SLOT], 4, GL_UNSIGNED_BYTE, BGL_TRUE, 0, frame->colors);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetGlobalWhiteColorArray(mesh->numTriangles * 3);
|
||||||
|
glVertexAttribPointer(program->slots[Shaders::A_COLOR_SLOT], 3, BGL_UNSIGNED_BYTE, BGL_TRUE, 0, globalWhiteColorArray);
|
||||||
|
}
|
||||||
|
*/
|
||||||
pglPopMatrix(); // should be the same as glLoadIdentity
|
pglPopMatrix(); // should be the same as glLoadIdentity
|
||||||
if (color)
|
if (color)
|
||||||
pglDisable(GL_LIGHTING);
|
pglDisable(GL_LIGHTING);
|
||||||
|
@ -2038,17 +2102,11 @@ static void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration,
|
||||||
// -----------------+
|
// -----------------+
|
||||||
// HWRAPI DrawMD2 : Draw an MD2 model with glcommands
|
// HWRAPI DrawMD2 : Draw an MD2 model with glcommands
|
||||||
// -----------------+
|
// -----------------+
|
||||||
EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
|
EXPORT void HWRAPI(DrawModel) (model_t *model, mdlframe_t *frame, INT32 duration, INT32 tics, mdlframe_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
|
||||||
{
|
{
|
||||||
DrawMD2Ex(gl_cmd_buffer, frame, duration, tics, nextframe, pos, scale, flipped, color);
|
DrawModelEx(model, frame, duration, tics, nextframe, pos, scale, flipped, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale)
|
|
||||||
{
|
|
||||||
DrawMD2Ex(gl_cmd_buffer, frame, 0, 0, NULL, pos, scale, false, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------+
|
// -----------------+
|
||||||
// SetTransform :
|
// SetTransform :
|
||||||
// -----------------+
|
// -----------------+
|
||||||
|
|
230
src/hardware/u_list.c
Normal file
230
src/hardware/u_list.c
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "u_list.h"
|
||||||
|
#include "../z_zone.h"
|
||||||
|
|
||||||
|
// Utility for managing
|
||||||
|
// structures in a linked
|
||||||
|
// list.
|
||||||
|
//
|
||||||
|
// Struct must have "next" and "prev" pointers
|
||||||
|
// as its first two variables.
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListAdd
|
||||||
|
//
|
||||||
|
// Adds an item to the list
|
||||||
|
//
|
||||||
|
void ListAdd(void *pItem, listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)pItem;
|
||||||
|
|
||||||
|
if (*itemHead == NULL)
|
||||||
|
{
|
||||||
|
*itemHead = item;
|
||||||
|
(*itemHead)->prev = (*itemHead)->next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
listitem_t *tail;
|
||||||
|
tail = *itemHead;
|
||||||
|
|
||||||
|
while (tail->next != NULL)
|
||||||
|
tail = tail->next;
|
||||||
|
|
||||||
|
tail->next = item;
|
||||||
|
|
||||||
|
tail->next->prev = tail;
|
||||||
|
|
||||||
|
item->next = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListAddFront
|
||||||
|
//
|
||||||
|
// Adds an item to the front of the list
|
||||||
|
// (This is much faster)
|
||||||
|
//
|
||||||
|
void ListAddFront(void *pItem, listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)pItem;
|
||||||
|
|
||||||
|
if (*itemHead == NULL)
|
||||||
|
{
|
||||||
|
*itemHead = item;
|
||||||
|
(*itemHead)->prev = (*itemHead)->next = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*itemHead)->prev = item;
|
||||||
|
item->next = (*itemHead);
|
||||||
|
item->prev = NULL;
|
||||||
|
*itemHead = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListAddBefore
|
||||||
|
//
|
||||||
|
// Adds an item before the item specified in the list
|
||||||
|
//
|
||||||
|
void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)pItem;
|
||||||
|
listitem_t *spot = (listitem_t*)pSpot;
|
||||||
|
|
||||||
|
listitem_t *prev = spot->prev;
|
||||||
|
|
||||||
|
if (!prev)
|
||||||
|
ListAddFront(pItem, itemHead);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->next = spot;
|
||||||
|
spot->prev = item;
|
||||||
|
item->prev = prev;
|
||||||
|
prev->next = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListAddAfter
|
||||||
|
//
|
||||||
|
// Adds an item after the item specified in the list
|
||||||
|
//
|
||||||
|
void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)pItem;
|
||||||
|
listitem_t *spot = (listitem_t*)pSpot;
|
||||||
|
|
||||||
|
listitem_t *next = spot->next;
|
||||||
|
|
||||||
|
if (!next)
|
||||||
|
ListAdd(pItem, itemHead);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->prev = spot;
|
||||||
|
spot->next = item;
|
||||||
|
item->next = next;
|
||||||
|
next->prev = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListRemove
|
||||||
|
//
|
||||||
|
// Take an item out of the list and free its memory.
|
||||||
|
//
|
||||||
|
void ListRemove(void *pItem, listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)pItem;
|
||||||
|
|
||||||
|
if (item == *itemHead) // Start of list
|
||||||
|
{
|
||||||
|
*itemHead = item->next;
|
||||||
|
|
||||||
|
if (*itemHead)
|
||||||
|
(*itemHead)->prev = NULL;
|
||||||
|
}
|
||||||
|
else if (item->next == NULL) // end of list
|
||||||
|
{
|
||||||
|
item->prev->next = NULL;
|
||||||
|
}
|
||||||
|
else // Somewhere in between
|
||||||
|
{
|
||||||
|
item->prev->next = item->next;
|
||||||
|
item->next->prev = item->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free (item);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListRemoveAll
|
||||||
|
//
|
||||||
|
// Removes all items from the list, freeing their memory.
|
||||||
|
//
|
||||||
|
void ListRemoveAll(listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item;
|
||||||
|
listitem_t *next;
|
||||||
|
for (item = *itemHead; item; item = next)
|
||||||
|
{
|
||||||
|
next = item->next;
|
||||||
|
ListRemove(item, itemHead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListRemoveNoFree
|
||||||
|
//
|
||||||
|
// Take an item out of the list, but don't free its memory.
|
||||||
|
//
|
||||||
|
void ListRemoveNoFree(void *pItem, listitem_t **itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)pItem;
|
||||||
|
|
||||||
|
if (item == *itemHead) // Start of list
|
||||||
|
{
|
||||||
|
*itemHead = item->next;
|
||||||
|
|
||||||
|
if (*itemHead)
|
||||||
|
(*itemHead)->prev = NULL;
|
||||||
|
}
|
||||||
|
else if (item->next == NULL) // end of list
|
||||||
|
{
|
||||||
|
item->prev->next = NULL;
|
||||||
|
}
|
||||||
|
else // Somewhere in between
|
||||||
|
{
|
||||||
|
item->prev->next = item->next;
|
||||||
|
item->next->prev = item->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListGetCount
|
||||||
|
//
|
||||||
|
// Counts the # of items in a list
|
||||||
|
// Should not be used in performance-minded code
|
||||||
|
//
|
||||||
|
unsigned int ListGetCount(void *itemHead)
|
||||||
|
{
|
||||||
|
listitem_t *item = (listitem_t*)itemHead;
|
||||||
|
|
||||||
|
unsigned int count = 0;
|
||||||
|
for (; item; item = item->next)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// ListGetByIndex
|
||||||
|
//
|
||||||
|
// Gets an item in the list by its index
|
||||||
|
// Should not be used in performance-minded code
|
||||||
|
//
|
||||||
|
listitem_t *ListGetByIndex(void *itemHead, unsigned int index)
|
||||||
|
{
|
||||||
|
listitem_t *head = (listitem_t*)itemHead;
|
||||||
|
unsigned int count = 0;
|
||||||
|
listitem_t *node;
|
||||||
|
for (node = head; node; node = node->next)
|
||||||
|
{
|
||||||
|
if (count == index)
|
||||||
|
return node;
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
29
src/hardware/u_list.h
Normal file
29
src/hardware/u_list.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
|
||||||
|
An experimental work-in-progress.
|
||||||
|
|
||||||
|
Donated to Sonic Team Junior and adapted to work with
|
||||||
|
Sonic Robo Blast 2. The license of this code matches whatever
|
||||||
|
the licensing is for Sonic Robo Blast 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _U_LIST_H_
|
||||||
|
#define _U_LIST_H_
|
||||||
|
|
||||||
|
typedef struct listitem_s
|
||||||
|
{
|
||||||
|
struct listitem_s *next;
|
||||||
|
struct listitem_s *prev;
|
||||||
|
} listitem_t;
|
||||||
|
|
||||||
|
void ListAdd(void *pItem, listitem_t **itemHead);
|
||||||
|
void ListAddFront(void *pItem, listitem_t **itemHead);
|
||||||
|
void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead);
|
||||||
|
void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead);
|
||||||
|
void ListRemove(void *pItem, listitem_t **itemHead);
|
||||||
|
void ListRemoveAll(listitem_t **itemHead);
|
||||||
|
void ListRemoveNoFree(void *pItem, listitem_t **itemHead);
|
||||||
|
unsigned int ListGetCount(void *itemHead);
|
||||||
|
listitem_t *ListGetByIndex(void *itemHead, unsigned int index);
|
||||||
|
|
||||||
|
#endif
|
|
@ -156,6 +156,10 @@
|
||||||
<ClInclude Include="..\hardware\hw_light.h" />
|
<ClInclude Include="..\hardware\hw_light.h" />
|
||||||
<ClInclude Include="..\hardware\hw_main.h" />
|
<ClInclude Include="..\hardware\hw_main.h" />
|
||||||
<ClInclude Include="..\hardware\hw_md2.h" />
|
<ClInclude Include="..\hardware\hw_md2.h" />
|
||||||
|
<ClInclude Include="..\hardware\hw_md2load.h" />
|
||||||
|
<ClInclude Include="..\hardware\hw_md3load.h" />
|
||||||
|
<ClInclude Include="..\hardware\hw_model.h" />
|
||||||
|
<ClInclude Include="..\hardware\u_list.h" />
|
||||||
<ClInclude Include="..\hu_stuff.h" />
|
<ClInclude Include="..\hu_stuff.h" />
|
||||||
<ClInclude Include="..\info.h" />
|
<ClInclude Include="..\info.h" />
|
||||||
<ClInclude Include="..\i_addrinfo.h" />
|
<ClInclude Include="..\i_addrinfo.h" />
|
||||||
|
@ -294,8 +298,12 @@
|
||||||
<ClCompile Include="..\hardware\hw_light.c" />
|
<ClCompile Include="..\hardware\hw_light.c" />
|
||||||
<ClCompile Include="..\hardware\hw_main.c" />
|
<ClCompile Include="..\hardware\hw_main.c" />
|
||||||
<ClCompile Include="..\hardware\hw_md2.c" />
|
<ClCompile Include="..\hardware\hw_md2.c" />
|
||||||
|
<ClCompile Include="..\hardware\hw_md2load.c" />
|
||||||
|
<ClCompile Include="..\hardware\hw_md3load.c" />
|
||||||
|
<ClCompile Include="..\hardware\hw_model.c" />
|
||||||
<ClCompile Include="..\hardware\hw_trick.c" />
|
<ClCompile Include="..\hardware\hw_trick.c" />
|
||||||
<ClCompile Include="..\hardware\r_opengl\r_opengl.c" />
|
<ClCompile Include="..\hardware\r_opengl\r_opengl.c" />
|
||||||
|
<ClCompile Include="..\hardware\u_list.c" />
|
||||||
<ClCompile Include="..\hu_stuff.c" />
|
<ClCompile Include="..\hu_stuff.c" />
|
||||||
<ClCompile Include="..\info.c" />
|
<ClCompile Include="..\info.c" />
|
||||||
<ClCompile Include="..\i_addrinfo.c">
|
<ClCompile Include="..\i_addrinfo.c">
|
||||||
|
@ -304,7 +312,7 @@
|
||||||
<ClCompile Include="..\i_tcp.c" />
|
<ClCompile Include="..\i_tcp.c" />
|
||||||
<ClCompile Include="..\k_kart.c" />
|
<ClCompile Include="..\k_kart.c" />
|
||||||
<ClCompile Include="..\lua_baselib.c" />
|
<ClCompile Include="..\lua_baselib.c" />
|
||||||
<ClCompile Include="..\lua_blockmaplib.c" />
|
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||||
<ClCompile Include="..\lua_consolelib.c" />
|
<ClCompile Include="..\lua_consolelib.c" />
|
||||||
<ClCompile Include="..\lua_hooklib.c" />
|
<ClCompile Include="..\lua_hooklib.c" />
|
||||||
<ClCompile Include="..\lua_hudlib.c" />
|
<ClCompile Include="..\lua_hudlib.c" />
|
||||||
|
|
|
@ -246,6 +246,18 @@
|
||||||
<ClInclude Include="..\hardware\hw_md2.h">
|
<ClInclude Include="..\hardware\hw_md2.h">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_md2load.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_md3load.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_model.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\u_list.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\byteptr.h">
|
<ClInclude Include="..\byteptr.h">
|
||||||
<Filter>I_Interface</Filter>
|
<Filter>I_Interface</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -624,9 +636,21 @@
|
||||||
<ClCompile Include="..\hardware\hw_md2.c">
|
<ClCompile Include="..\hardware\hw_md2.c">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\hardware\hw_md2load.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\hardware\hw_md3load.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\hardware\hw_model.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\hardware\hw_trick.c">
|
<ClCompile Include="..\hardware\hw_trick.c">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\hardware\u_list.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\filesrch.c">
|
<ClCompile Include="..\filesrch.c">
|
||||||
<Filter>I_Interface</Filter>
|
<Filter>I_Interface</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -87,8 +87,7 @@ void *hwSym(const char *funcName,void *handle)
|
||||||
GETFUNC(ClearMipMapCache);
|
GETFUNC(ClearMipMapCache);
|
||||||
GETFUNC(SetSpecialState);
|
GETFUNC(SetSpecialState);
|
||||||
GETFUNC(GetTextureUsed);
|
GETFUNC(GetTextureUsed);
|
||||||
GETFUNC(DrawMD2);
|
GETFUNC(DrawModel);
|
||||||
GETFUNC(DrawMD2i);
|
|
||||||
GETFUNC(SetTransform);
|
GETFUNC(SetTransform);
|
||||||
GETFUNC(GetRenderVersion);
|
GETFUNC(GetRenderVersion);
|
||||||
#ifdef SHUFFLE
|
#ifdef SHUFFLE
|
||||||
|
|
|
@ -1546,8 +1546,7 @@ void I_StartupGraphics(void)
|
||||||
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
|
||||||
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
|
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
|
||||||
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
|
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
|
||||||
HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL);
|
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
|
||||||
HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL);
|
|
||||||
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
|
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
|
||||||
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
|
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
|
||||||
#ifdef SHUFFLE
|
#ifdef SHUFFLE
|
||||||
|
|
|
@ -124,7 +124,11 @@
|
||||||
<ClCompile Include="..\hardware\hw_light.c" />
|
<ClCompile Include="..\hardware\hw_light.c" />
|
||||||
<ClCompile Include="..\hardware\hw_main.c" />
|
<ClCompile Include="..\hardware\hw_main.c" />
|
||||||
<ClCompile Include="..\hardware\hw_md2.c" />
|
<ClCompile Include="..\hardware\hw_md2.c" />
|
||||||
|
<ClCompile Include="..\hardware\hw_md2load.c" />
|
||||||
|
<ClCompile Include="..\hardware\hw_md3load.c" />
|
||||||
|
<ClCompile Include="..\hardware\hw_model.c" />
|
||||||
<ClCompile Include="..\hardware\hw_trick.c" />
|
<ClCompile Include="..\hardware\hw_trick.c" />
|
||||||
|
<ClCompile Include="..\hardware\u_list.c" />
|
||||||
<ClCompile Include="..\hu_stuff.c" />
|
<ClCompile Include="..\hu_stuff.c" />
|
||||||
<ClCompile Include="..\info.c" />
|
<ClCompile Include="..\info.c" />
|
||||||
<ClCompile Include="..\i_addrinfo.c">
|
<ClCompile Include="..\i_addrinfo.c">
|
||||||
|
@ -132,7 +136,7 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\i_tcp.c" />
|
<ClCompile Include="..\i_tcp.c" />
|
||||||
<ClCompile Include="..\lua_baselib.c" />
|
<ClCompile Include="..\lua_baselib.c" />
|
||||||
<ClCompile Include="..\lua_blockmaplib.c" />
|
<ClCompile Include="..\lua_blockmaplib.c" />
|
||||||
<ClCompile Include="..\lua_consolelib.c" />
|
<ClCompile Include="..\lua_consolelib.c" />
|
||||||
<ClCompile Include="..\lua_hooklib.c" />
|
<ClCompile Include="..\lua_hooklib.c" />
|
||||||
<ClCompile Include="..\lua_hudlib.c" />
|
<ClCompile Include="..\lua_hudlib.c" />
|
||||||
|
@ -287,6 +291,10 @@
|
||||||
<ClInclude Include="..\hardware\hw_light.h" />
|
<ClInclude Include="..\hardware\hw_light.h" />
|
||||||
<ClInclude Include="..\hardware\hw_main.h" />
|
<ClInclude Include="..\hardware\hw_main.h" />
|
||||||
<ClInclude Include="..\hardware\hw_md2.h" />
|
<ClInclude Include="..\hardware\hw_md2.h" />
|
||||||
|
<ClInclude Include="..\hardware\hw_md2load.h" />
|
||||||
|
<ClInclude Include="..\hardware\hw_md3load.h" />
|
||||||
|
<ClInclude Include="..\hardware\hw_model.h" />
|
||||||
|
<ClInclude Include="..\hardware\u_list.h" />
|
||||||
<ClInclude Include="..\hu_stuff.h" />
|
<ClInclude Include="..\hu_stuff.h" />
|
||||||
<ClInclude Include="..\info.h" />
|
<ClInclude Include="..\info.h" />
|
||||||
<ClInclude Include="..\i_addrinfo.h" />
|
<ClInclude Include="..\i_addrinfo.h" />
|
||||||
|
|
|
@ -108,9 +108,21 @@
|
||||||
<ClCompile Include="..\hardware\hw_md2.c">
|
<ClCompile Include="..\hardware\hw_md2.c">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClInclude Include="..\hardware\hw_md2load.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_md3load.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_model.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\hardware\hw_trick.c">
|
<ClCompile Include="..\hardware\hw_trick.c">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClInclude Include="..\hardware\u_list.c">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClCompile Include="..\hardware\hw3sound.c">
|
<ClCompile Include="..\hardware\hw3sound.c">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -506,6 +518,15 @@
|
||||||
<ClInclude Include="..\hardware\hw_md2.h">
|
<ClInclude Include="..\hardware\hw_md2.h">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_md2load.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_md3load.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\hw_model.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\hardware\hw3dsdrv.h">
|
<ClInclude Include="..\hardware\hw3dsdrv.h">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -515,6 +536,9 @@
|
||||||
<ClInclude Include="..\hardware\hws_data.h">
|
<ClInclude Include="..\hardware\hws_data.h">
|
||||||
<Filter>Hw_Hardware</Filter>
|
<Filter>Hw_Hardware</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\hardware\u_list.h">
|
||||||
|
<Filter>Hw_Hardware</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\blua\lapi.h">
|
<ClInclude Include="..\blua\lapi.h">
|
||||||
<Filter>BLUA</Filter>
|
<Filter>BLUA</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -109,8 +109,7 @@ static loadfunc_t hwdFuncTable[] = {
|
||||||
{"GClipRect@20", &hwdriver.pfnGClipRect},
|
{"GClipRect@20", &hwdriver.pfnGClipRect},
|
||||||
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
|
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
|
||||||
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
|
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
|
||||||
{"DrawMD2@16", &hwdriver.pfnDrawMD2},
|
{"DrawModel@16", &hwdriver.pfnDrawModel},
|
||||||
{"DrawMD2i@36", &hwdriver.pfnDrawMD2i},
|
|
||||||
{"SetTransform@4", &hwdriver.pfnSetTransform},
|
{"SetTransform@4", &hwdriver.pfnSetTransform},
|
||||||
{"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed},
|
{"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed},
|
||||||
{"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion},
|
{"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion},
|
||||||
|
@ -140,8 +139,7 @@ static loadfunc_t hwdFuncTable[] = {
|
||||||
{"GClipRect", &hwdriver.pfnGClipRect},
|
{"GClipRect", &hwdriver.pfnGClipRect},
|
||||||
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
|
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
|
||||||
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
|
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
|
||||||
{"DrawMD2", &hwdriver.pfnDrawMD2},
|
{"DrawModel", &hwdriver.pfnDrawModel},
|
||||||
{"DrawMD2i", &hwdriver.pfnDrawMD2i},
|
|
||||||
{"SetTransform", &hwdriver.pfnSetTransform},
|
{"SetTransform", &hwdriver.pfnSetTransform},
|
||||||
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
|
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
|
||||||
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},
|
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},
|
||||||
|
|
Loading…
Reference in a new issue