/*** * * 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. * ***/ // // Read a .smd reference file // #include #include #include #include #include #include "../../common/mathlib.h" #include "../../common/const.h" #include "../../common/twm.h" #include "studiotwm.h" /* ============================== SMD_Error Print an error message and return an error code ============================== */ int SMD_Error(int errid,char *pszStream,...) { va_list argptr; char szString[MAX_STRLEN]; va_start(argptr,pszStream); vsprintf(szString,pszStream,argptr); va_end(argptr); fprintf(stderr,szString); return errid; } /* ============================== SMD_AddTriangle Add triangle to current ref set ============================== */ void SMD_AddTriangle(smdref_t *smdref,smdvertex_t *verts,char *texturename) { int index = smdref->num_triangles; smdref->num_triangles++; // copy memory smdref->triangles = (smdtriangle_t*)realloc(smdref->triangles,sizeof(smdtriangle_t)*smdref->num_triangles); memcpy(smdref->triangles[index].verts,verts,sizeof(smdvertex_t)*3); strcpy(smdref->triangles[index].texturename,texturename); } /* ============================== SMD_ParseTriangles Read a triangle data block Largely read from studiomdl.c Grab_Triangles ============================== */ void SMD_ParseTriangles(FILE *pFile,char *pszLine,smdref_t *smdref) { int i,j; while(fgets(pszLine,sizeof(char)*MAX_STRLEN,pFile) != NULL) { smdvertex_t p[3]; char texturename[64]; int itrash; float fltrash[3]; char *c; // TODO: Remove when neccesary fltrash[0] = 1 * 4; // check for end if(strcmp("end\n",pszLine) == 0) return; // strip off trailing smag strcpy(texturename,pszLine); for(i = strlen(texturename) - 1;i >= 0 && !isgraph(texturename[i]); i--) texturename[i + 1] = '\0'; // strip off newline c = strchr(texturename,'\n'); if(c != NULL) c[0] = '\0'; // Skip blank triangles if(texturename[0] == '\0') { fgets(pszLine,sizeof(char)*MAX_STRLEN,pFile); fgets(pszLine,sizeof(char)*MAX_STRLEN,pFile); fgets(pszLine,sizeof(char)*MAX_STRLEN,pFile); continue; } // Read the triangle data for(j = 0;j < 3;j++) { //TODO: Flip vertex order? if(fgets(pszLine,sizeof(char)*MAX_STRLEN,pFile) != NULL) { // Alot of this crap .TWM doesnt use, so // just throw it into trash vars if(!(sscanf(pszLine, "%d %f %f %f %f %f %f %f %f", &itrash, &p[j].origin[0],&p[j].origin[1],&p[j].origin[2], &fltrash[0],&fltrash[1],&fltrash[2], &p[j].u,&p[j].v) == 9)) { SMD_Error(-1,"ERROR: Invalid triangle format\n"); return; } else { // if needed rescale the verts if(g_flScale != 1.0f) { p[j].origin[0] *= g_flScale; p[j].origin[1] *= g_flScale; p[j].origin[2] *= g_flScale; } } } } // Plug values into smdref SMD_AddTriangle(smdref,p,texturename); } } /* ============================== SMD_ParseSMD Read a SMD file and return a new one returns 0 if parse was not successful ============================== */ int SMD_ParseSMD(char *filename,smdref_t *smdref) { char szLine[MAX_STRLEN]; char szToken[MAX_STRLEN]; int iOption; FILE *pFile = fopen(filename,"r"); if(pFile == NULL) return SMD_Error(0,"ERROR: Invalid file %s\n",filename); // Start parsing while(fgets(szLine,sizeof(szLine),pFile) != NULL) { sscanf(szLine,"%s %d",szToken,&iOption); if(strcmp("version",szToken) == 0) { if(iOption != 1) { // Bad version fprintf(stderr,"ERROR: Invalid version %i\n",iOption); goto parsesmd_error; } } else if(strcmp("triangles",szToken) == 0) { SMD_ParseTriangles(pFile,szLine,smdref); } } fclose(pFile); return 1; parsesmd_error: fclose(pFile); return 0; } /* ============================== SMD_Initialize Reset a smdref ============================== */ void SMD_Initialize(smdref_t *smdref) { // Triangles smdref->num_triangles = 0; smdref->triangles = NULL; } /* ============================== SMD_Destroy Destroy a smdref ============================== */ void SMD_Destroy(smdref_t *smdref) { if(smdref->num_triangles) free(smdref->triangles); } /* ============================== SMD_ConvertToTWM Parse an SMD then create a TWM from it ============================== */ void SMD_ConvertToTWM(char *filein,char *fileout) { int err_count = 0; smdref_t smdref; printf("Parsing [%s]...",filein); SMD_Initialize(&smdref); if(SMD_ParseSMD(filein,&smdref)) { printf("Building [%s]...",fileout); if(TWM_BuildFromSMD(fileout,&smdref)) printf("Done\n",fileout); } SMD_Destroy(&smdref); }