/*** * * 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; }