forked from valve/halflife-sdk
248 lines
No EOL
5.3 KiB
C
248 lines
No EOL
5.3 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.
|
|
*
|
|
***/
|
|
//
|
|
// Read a .smd reference file
|
|
//
|
|
#include <ctype.h>
|
|
#include <malloc.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#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);
|
|
} |