halflife-thewastes-sdk/game_shared/twm.cpp

223 lines
5.9 KiB
C++

/***
*
* Copyright (C) 2002 The Wastes Project, All Rights Reserved.
*
* This product contains software technology from Valve Software, LLC,
* Copyright © 1996-2001, Valve LLC, All rights reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* The Wastes Project. All other use, distribution, or modification is prohibited
* without written permission from The Wastes Project.
*
***/
//
// twm.cpp -> .TWM loading code
//
#include "hud.h"
#include "cl_util.h"
#include "const.h"
#include "entity_state.h"
#include "cl_entity.h"
#include "triangleapi.h"
#include "ref_params.h"
#include "event_api.h"
#include "r_efx.h"
#include "twm.h"
#include "twmmanager.h"
CTwmManager g_TwmManager;
/*
CTwmModel methods
*/
CTwmModel::CTwmModel()
{
twminfo.num_vertices = 0;
twminfo.vertex_lump = NULL;
twminfo.num_tris = 0;
twminfo.triangle_lump = NULL;
twminfo.num_materialgroups = 0;
twminfo.materialgroup_lump = NULL;
}
CTwmModel::~CTwmModel()
{
// free all our data used
if(twminfo.num_vertices)
delete[] twminfo.vertex_lump;
if(twminfo.num_tris)
delete[] twminfo.triangle_lump;
if(twminfo.num_materialgroups)
{
for(int i = 0;i < twminfo.num_materialgroups;i++)
delete[] twminfo.materialgroup_lump[i].tris_indices;
delete[] twminfo.materialgroup_lump;
}
}
/*
CTwmManager methods
*/
CTwmManager::CTwmManager()
{
}
CTwmManager::~CTwmManager()
{
// Remove all precached models
for(int i = 0;i < vecModels.size();i++)
delete vecModels[i];
vecModels.clear();
}
void CTwmManager::ParseVertexLump(FILE *pFile,CTwmModel *pTwmModel)
{
// Vertex count
fread((char*)&pTwmModel->twminfo.num_vertices,sizeof(short),1,pFile);
// Allocate and store verts
pTwmModel->twminfo.vertex_lump = new twm_vert_t[pTwmModel->twminfo.num_vertices];
fread((char*)pTwmModel->twminfo.vertex_lump,sizeof(twm_vert_t)*pTwmModel->twminfo.num_vertices,1,pFile);
}
void CTwmManager::ParseTriangleLump(FILE *pFile,CTwmModel *pTwmModel)
{
// Triangle count
fread((char*)&pTwmModel->twminfo.num_tris,sizeof(short),1,pFile);
// allocate and store triangle info
pTwmModel->twminfo.triangle_lump = new twm_triangle_t[pTwmModel->twminfo.num_tris];
for(int i = 0;i < pTwmModel->twminfo.num_tris;i++)
{
twm_triangle_t *cur_tri = &pTwmModel->twminfo.triangle_lump[i];
fread((char*)cur_tri->vert_indices,sizeof(short)*3,1,pFile);
fread((char*)cur_tri->u,sizeof(float)*3,1,pFile);
fread((char*)cur_tri->v,sizeof(float)*3,1,pFile);
}
}
void CTwmManager::ParseMaterialLump(FILE *pFile,CTwmModel *pTwmModel)
{
// Material count
fread((char*)&pTwmModel->twminfo.num_materialgroups,sizeof(short),1,pFile);
// allocate and store material info
pTwmModel->twminfo.materialgroup_lump = new twm_materialgroup_t[pTwmModel->twminfo.num_materialgroups];
for(int i = 0;i < pTwmModel->twminfo.num_materialgroups;i++)
{
twm_materialgroup_t *cur_mat = &pTwmModel->twminfo.materialgroup_lump[i];
fread(cur_mat->texturename,sizeof(char)*64,1,pFile);
// allocate triangle list
fread((char*)&cur_mat->num_triangles,sizeof(short),1,pFile);
cur_mat->tris_indices = new short[cur_mat->num_triangles];
fread((char*)cur_mat->tris_indices,sizeof(short)*cur_mat->num_triangles,1,pFile);
}
}
// just use C style i/o
int CTwmManager::PrecacheModel(string filename)
{
char path[256];
CTwmModel *TwmModel = new CTwmModel;
FILE *pFile;
// store full path
sprintf(path,"%s/%s",gEngfuncs.pfnGetGameDirectory(),filename.c_str());
gEngfuncs.Con_DPrintf("TWM: Loading Model %s\n",filename.c_str());
pFile = fopen(path,"rb");
if(pFile == NULL)
{
gEngfuncs.Con_DPrintf("TWM ERROR: Invalid file %s\n",filename.c_str());
return 0;
}
// Put basic information into twm model
TwmModel->filename = filename;
fread((char*)&TwmModel->twminfo.header_id,sizeof(int),1,pFile);
fread((char*)&TwmModel->twminfo.major_version,sizeof(short),1,pFile);
fread((char*)&TwmModel->twminfo.minor_version,sizeof(short),1,pFile);
if(TwmModel->twminfo.header_id == TWM_ID)
{
if(TwmModel->twminfo.major_version == TWM_MAJOR_VERSION)
{
// Only warning if minor versions differ
if(TwmModel->twminfo.minor_version != TWM_MINOR_VERSION)
gEngfuncs.Con_DPrintf("TWM WARNING: Different minor version for %s, expected %i got %i\n",filename.c_str(),TWM_MINOR_VERSION,TwmModel->twminfo.minor_version);
// Start parsing!
ParseVertexLump(pFile,TwmModel);
ParseTriangleLump(pFile,TwmModel);
ParseMaterialLump(pFile,TwmModel);
// push onto vector for storage
vecModels.push_back(TwmModel);
goto precache_noerror;
}
else
gEngfuncs.Con_DPrintf("TWM ERROR: Invalid version for %s, expected %i got %i\n",filename.c_str(),TWM_MAJOR_VERSION,TwmModel->twminfo.major_version);
}
else
gEngfuncs.Con_DPrintf("TWM ERROR: Invalid header for %s\n",filename.c_str());
fclose(pFile);
return 0;
precache_noerror:
fclose(pFile);
return 1;
}
void CTwmManager::BeginPrecache()
{
// Remove all precached models
for(int i = 0;i < vecModels.size();i++)
delete vecModels[i];
vecModels.clear();
// Start precaching!
GetModelByName("models/muz_test.twm");
}
CTwmModel *CTwmManager::GetModelByName(string filename)
{
for(int i = 0;i < vecModels.size();i++)
if(vecModels[i]->filename == filename)
return vecModels[i];
// Oops! we couldnt find the model, precache and return that
if(PrecacheModel(filename))
return vecModels[vecModels.size()-1];
return NULL;
}
// Update a specific twm object
void CTwmManager::TwmUpdate(twm_clientinfo_t *clientinfo, double frametime)
{
bool bDie = false;
// fade out model
clientinfo->color[3] -= clientinfo->fadetime * frametime;
if(clientinfo->color[3] <= 0.0f)
bDie = true;
// set dead var
clientinfo->dead = bDie;
}