[PATCH 1/9] qbsp: Replace File class with basic stdio functions

Replace the "File" class with basic stdio C functions. The LoadFile is kept
basically intact. All instances of File objects are replaced with FILE*. Calls
to member functions are replaced with inline C code. There is some redundancy
with the error checking, but this can probably be cleaned up a little bit by
using some of the SafeOpen, etc. functions from common/cmdlib.c.

Signed-off-by: Tyrann <tyrann@disenchant.net>
This commit is contained in:
Tyrann 2006-09-10 17:38:30 +09:30
parent 25f6148fc3
commit 8bded2dfaf
12 changed files with 164 additions and 283 deletions

View File

@ -18,6 +18,10 @@
See file, 'COPYING', for details.
*/
#include <stddef.h>
#include "file.h"
#include "qbsp.h"
dheader_t *header;
@ -32,12 +36,11 @@ LoadBSPFile(void)
{
int i;
int cFileSize, cLumpSize, iLumpOff;
File BSPFile;
// Load the file header
StripExtension(options.szBSPName);
strcat(options.szBSPName, ".bsp");
cFileSize = BSPFile.LoadFile(options.szBSPName, (void **)&header);
cFileSize = LoadFile(options.szBSPName, (void **)&header, true);
if (header->version != BSPVERSION)
Message(msgError, errBadVersion, options.szBSPName, header->version,
@ -66,33 +69,42 @@ LoadBSPFile(void)
// To be used for all dynamic mem data
void
AddLump(File *pBSPFile, int Type)
AddLump(FILE *f, int Type)
{
lump_t *lump;
int cLen = 0, templen;
int iEntity;
size_t ret;
lump = &header->lumps[Type];
lump->fileofs = pBSPFile->Position();
lump->fileofs = ftell(f);
for (iEntity = 0; iEntity < map.cEntities; iEntity++) {
if (map.rgEntities[iEntity].pData[Type] != NULL) {
templen = map.rgEntities[iEntity].cData[Type] * rgcMemSize[Type];
pBSPFile->Write(map.rgEntities[iEntity].pData[Type], templen);
ret = fwrite(map.rgEntities[iEntity].pData[Type], 1, templen, f);
if (ret != templen)
Message(msgError, errWriteFailure);
cLen += templen;
}
}
// Add null terminating char for text
if (Type == BSPENT) {
pBSPFile->Write("", 1);
ret = fwrite("", 1, 1, f);
if (ret != 1)
Message(msgError, errWriteFailure);
cLen++;
}
lump->filelen = cLen;
// Pad to 4-byte boundary
if (cLen % 4 != 0)
pBSPFile->Write(" ", 4 - (cLen % 4));
if (cLen % 4 != 0) {
size_t pad = 4 - (cLen % 4);
ret = fwrite(" ", 1, pad, f);
if (ret != pad)
Message(msgError, errWriteFailure);
}
}
/*
@ -103,7 +115,8 @@ WriteBSPFile
void
WriteBSPFile(void)
{
File BSPFile;
FILE *f;
size_t ret;
header = (dheader_t *)AllocMem(OTHER, sizeof(dheader_t));
header->version = BSPVERSION;
@ -111,30 +124,38 @@ WriteBSPFile(void)
StripExtension(options.szBSPName);
strcat(options.szBSPName, ".bsp");
BSPFile.fOpen(options.szBSPName, "wb");
BSPFile.Write(header, sizeof(dheader_t)); // overwritten later
f = fopen(options.szBSPName, "wb");
if (f == NULL)
Message(msgError, errOpenFailed, options.szBSPName, strerror(errno));
AddLump(&BSPFile, BSPPLANE);
AddLump(&BSPFile, BSPLEAF);
AddLump(&BSPFile, BSPVERTEX);
AddLump(&BSPFile, BSPNODE);
AddLump(&BSPFile, BSPTEXINFO);
AddLump(&BSPFile, BSPFACE);
AddLump(&BSPFile, BSPCLIPNODE);
AddLump(&BSPFile, BSPMARKSURF);
AddLump(&BSPFile, BSPSURFEDGE);
AddLump(&BSPFile, BSPEDGE);
AddLump(&BSPFile, BSPMODEL);
/* write placeholder, header is overwritten later */
ret = fwrite(header, sizeof(dheader_t), 1, f);
if (ret != 1)
Message(msgError, errWriteFailure);
AddLump(&BSPFile, BSPLIGHT);
AddLump(&BSPFile, BSPVIS);
AddLump(&BSPFile, BSPENT);
AddLump(&BSPFile, BSPTEX);
AddLump(f, BSPPLANE);
AddLump(f, BSPLEAF);
AddLump(f, BSPVERTEX);
AddLump(f, BSPNODE);
AddLump(f, BSPTEXINFO);
AddLump(f, BSPFACE);
AddLump(f, BSPCLIPNODE);
AddLump(f, BSPMARKSURF);
AddLump(f, BSPSURFEDGE);
AddLump(f, BSPEDGE);
AddLump(f, BSPMODEL);
BSPFile.Seek(0, SEEK_SET);
BSPFile.Write(header, sizeof(dheader_t));
BSPFile.Close();
AddLump(f, BSPLIGHT);
AddLump(f, BSPVIS);
AddLump(f, BSPENT);
AddLump(f, BSPTEX);
fseek(f, 0, SEEK_SET);
ret = fwrite(header, sizeof(dheader_t), 1, f);
if (ret != 1)
Message(msgError, errWriteFailure);
fclose(f);
FreeMem(header, OTHER, sizeof(dheader_t));
}

View File

@ -18,179 +18,42 @@
See file, 'COPYING', for details.
*/
/*
File source file
*/
#include <stdarg.h>
#include <stdio.h>
#include "qbsp.h"
#include "file.h"
/*
==================
File
==================
*/
File::File (void) {
fp = NULL;
}
/*
==================
~File
==================
*/
File::~File (void) {
if (fp)
fclose(fp);
}
/*
============
fOpen
============
*/
bool File::fOpen(char *szFilename, char *szMode, bool fNoFail)
{
fp = fopen(szFilename, szMode);
if (!fp)
if (fNoFail)
Message(msgError, errOpenFailed, szFilename, strerror(errno));
else
return false;
return true;
}
/*
=============
Close
=============
*/
void File::Close(void)
{
if (fp)
fclose(fp);
fp = NULL;
}
/*
==============
LoadFile
==============
*/
int File::LoadFile(char *szFile, void **ppBuffer, bool fNoFail)
size_t
LoadFile(char *filename, void **buf, bool nofail)
{
int cLen;
size_t len;
FILE *f;
if (!fOpen(szFile, "rb", fNoFail))
f = fopen(filename, "rb");
if (f == NULL) {
if (nofail)
Message(msgError, errOpenFailed, filename, strerror(errno));
return 0;
}
cLen = Length();
*ppBuffer = (char *)AllocMem(OTHER, cLen + 1, false);
((char *)*ppBuffer)[cLen] = 0;
Read(*ppBuffer, cLen);
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
Close();
*buf = AllocMem(OTHER, len + 1, false);
((char *)*buf)[len] = 0;
return cLen;
}
/*
==================
Printf
==================
*/
void File::Printf(char *szFormat, ...)
{
char szBuffer[512];
va_list argptr;
if (!fp)
return;
va_start(argptr, szFormat);
vsprintf(szBuffer, szFormat, argptr);
if (fprintf(fp, "%s", szBuffer) < 0)
Message(msgError, errWriteFailure);
va_end(argptr);
}
/*
========
Read
========
*/
void File::Read(void *pBuffer, int cLen)
{
// Fails silently if fp == NULL
if (fp && fread(pBuffer, 1, cLen, fp) != (size_t) cLen)
if (fread(*buf, 1, len, f) != len)
Message(msgError, errReadFailure);
}
/*
========
Write
========
*/
void File::Write(const void *pBuffer, int cLen)
{
// Fails silently if fp == NULL
if (fp && fwrite(pBuffer, 1, cLen, fp) != (size_t) cLen)
Message(msgError, errWriteFailure);
}
/*
=========
Seek
=========
*/
int File::Seek(int Offset, int origin)
{
return fseek(fp, Offset, origin);
}
/*
=========
Position
=========
*/
int File::Position(void)
{
return ftell(fp);
}
/*
==========
Length
==========
*/
int File::Length(void)
{
int cCur;
int cEnd;
cCur = ftell(fp);
fseek(fp, 0, SEEK_END);
cEnd = ftell(fp);
fseek(fp, cCur, SEEK_SET);
return cEnd;
fclose(f);
return len;
}

View File

@ -18,35 +18,12 @@
See file, 'COPYING', for details.
*/
/*
File header file
*/
#ifndef FILE_H
#define FILE_H
#include <stdio.h>
#include <stdbool.h>
class File {
public:
File (void);
~File (void);
bool fOpen(char *szFile, char *szMode, bool fNoFail = true);
void Close(void);
int LoadFile(char *szFile, void **pBuffer, bool fNoFail = true);
void Printf(char *szFormat, ...);
void Read(void *pBuffer, int cLen);
void Write(const void *pBuffer, int cLen);
int Seek(int Offset, int origin);
int Position(void);
private:
FILE *fp;
int Length(void);
};
size_t LoadFile(char *filename, void **buf, bool nofail);
#endif

View File

@ -54,7 +54,7 @@ int cPlanes;
vec3_t vec3_origin = { 0, 0, 0 };
// util.c
File LogFile;
FILE *logfile;
char *rgszWarnings[cWarnings] = {
"No wad or _wad key exists in the worldmodel",

View File

@ -470,17 +470,16 @@ void
LoadMapFile(void)
{
Parser *pParser;
File MapFile;
char *pBuf;
char *buf;
int i, j, length;
void *pTemp;
Message(msgProgress, "LoadMapFile");
length = MapFile.LoadFile(options.szMapName, (void **)&pBuf);
PreParseFile(pBuf);
length = LoadFile(options.szMapName, (void **)&buf, true);
PreParseFile(buf);
pParser = new Parser (pBuf);
pParser = new Parser (buf);
// Faces are loaded in reverse order, to be compatible with origqbsp.
// Brushes too.
@ -491,7 +490,7 @@ LoadMapFile(void)
while (ParseEntity(pParser));
FreeMem(pBuf, OTHER, length + 1);
FreeMem(buf, OTHER, length + 1);
delete pParser;
// Print out warnings for entities

View File

@ -27,8 +27,8 @@ int hit_occupied;
int backdraw;
int numports;
bool firstone = true;
File LeakFile;
File PorFile;
FILE *LeakFile;
FILE *PorFile;
node_t *leakNode = NULL;
int numleaks;
@ -96,19 +96,19 @@ WriteLeakNode(node_t *n)
}
if (options.fBspleak)
PorFile.Printf("%i\n", count);
fprintf(PorFile, "%i\n", count);
for (p = n->portals; p;) {
s = (p->nodes[0] == n);
if ((p->nodes[s]->contents != CONTENTS_SOLID) &&
(p->nodes[s]->contents != CONTENTS_SKY)) {
if (options.fBspleak) {
PorFile.Printf("%i ", p->winding->numpoints);
fprintf(PorFile, "%i ", p->winding->numpoints);
for (i = 0; i < p->winding->numpoints; i++)
PorFile.Printf("%f %f %f ", p->winding->points[i][0],
p->winding->points[i][1],
p->winding->points[i][2]);
PorFile.Printf("\n");
fprintf(PorFile, "%f %f %f ", p->winding->points[i][0],
p->winding->points[i][1],
p->winding->points[i][2]);
fprintf(PorFile, "\n");
}
}
p = p->next[!s];
@ -145,24 +145,24 @@ MarkLeakTrail(portal_t *n2)
if (firstone) {
firstone = false;
v = map.rgEntities[hit_occupied].origin;
PorFile.Printf("%f %f %f\n", v[0], v[1], v[2]);
fprintf(PorFile, "%f %f %f\n", v[0], v[1], v[2]);
WriteLeakNode(leakNode);
}
numports++;
// write the center...
PorFile.Printf("%f %f %f ", p1[0], p1[1], p2[1]);
PorFile.Printf("%i ", n2->winding->numpoints);
fprintf(PorFile, "%f %f %f ", p1[0], p1[1], p2[1]);
fprintf(PorFile, "%i ", n2->winding->numpoints);
j = n2->winding->numpoints - 1;
for (i = 0; i < n2->winding->numpoints; i++) {
PorFile.Printf("%f %f %f ", n2->winding->points[i][0],
n2->winding->points[i][1],
n2->winding->points[i][2]);
fprintf(PorFile, "%f %f %f ", n2->winding->points[i][0],
n2->winding->points[i][1],
n2->winding->points[i][2]);
}
PorFile.Printf("\n");
fprintf(PorFile, "\n");
}
if (numleaks < 2 || !options.fOldleak)
@ -176,7 +176,7 @@ MarkLeakTrail(portal_t *n2)
VectorNormalize(dir);
while (len > options.dxLeakDist) {
LeakFile.Printf("%f %f %f\n", p1[0], p1[1], p1[2]);
fprintf(LeakFile, "%f %f %f\n", p1[0], p1[1], p1[2]);
for (i = 0; i < 3; i++)
p1[i] += dir[i] * options.dxLeakDist;
len -= options.dxLeakDist;
@ -310,7 +310,7 @@ SimplifyLeakline(node_t *headnode)
VectorNormalize(dir);
while (len > options.dxLeakDist) {
LeakFile.Printf("%f %f %f\n", v1[0], v1[1], v1[2]);
fprintf(LeakFile, "%f %f %f\n", v1[0], v1[1], v1[2]);
for (k = 0; k < 3; k++)
v1[k] += dir[k] * options.dxLeakDist;
len -= options.dxLeakDist;
@ -447,13 +447,23 @@ FillOutside(node_t *node)
(portal_t **)AllocMem(OTHER, sizeof(portal_t *) * num_visportals);
StripExtension(options.szBSPName);
strcat(options.szBSPName, ".pts");
LeakFile.fOpen(options.szBSPName, "wt");
LeakFile = fopen(options.szBSPName, "wt");
if (LeakFile == NULL)
Message(msgError, errOpenFailed, options.szBSPName,
strerror(errno));
if (options.fBspleak) {
StripExtension(options.szBSPName);
strcat(options.szBSPName, ".por");
PorFile.fOpen(options.szBSPName, "wt");
PorFile.Printf("PLACEHOLDER\r\n"); // ??? "make room for the count"
PorFile = fopen(options.szBSPName, "wt");
if (PorFile == NULL)
Message(msgError, errOpenFailed, options.szBSPName,
strerror(errno));
/* ??? "make room for the count" */
fprintf(PorFile, "PLACEHOLDER\r\n");
}
}
@ -468,7 +478,7 @@ FillOutside(node_t *node)
StripExtension(options.szBSPName);
Message(msgLiteral, "Leak file written to %s.pts\n",
options.szBSPName);
LeakFile.Close();
fclose(LeakFile);
// Get rid of .prt file if .pts file is generated
strcat(options.szBSPName, ".prt");
@ -477,9 +487,9 @@ FillOutside(node_t *node)
if (options.fBspleak) {
Message(msgLiteral, "BSP portal file written to %s.por\n",
options.szBSPName);
PorFile.Seek(0, SEEK_SET);
PorFile.Printf("%11i", numports);
PorFile.Close();
fseek(PorFile, 0, SEEK_SET);
fprintf(PorFile, "%11i", numports);
fclose(PorFile);
}
}
return false;
@ -487,7 +497,7 @@ FillOutside(node_t *node)
if (hullnum == 2) {
FreeMem(pLeaks, OTHER, sizeof(portal_t *) * num_visportals);
LeakFile.Close();
fclose(LeakFile);
// Get rid of 0-byte .pts file
StripExtension(options.szBSPName);
@ -495,9 +505,9 @@ FillOutside(node_t *node)
remove(options.szBSPName);
if (options.fBspleak) {
PorFile.Seek(0, SEEK_SET);
PorFile.Printf("%11i", numports);
PorFile.Close();
fseek(PorFile, 0, SEEK_SET);
fprintf(PorFile, "%11i", numports);
fclose(PorFile);
}
}
// now go back and fill things in

View File

@ -24,7 +24,7 @@
int iNodesDone;
node_t outside_node; // portals outside the world face this
File PortalFile;
FILE *PortalFile;
/*
==============================================================================
@ -43,9 +43,9 @@ void
WriteFloat(vec_t v)
{
if (fabs(v - Q_rint(v)) < 0.001)
PortalFile.Printf("%i ", (int)Q_rint(v));
fprintf(PortalFile, "%i ", (int)Q_rint(v));
else
PortalFile.Printf("%f ", v);
fprintf(PortalFile, "%f ", v);
}
void
@ -94,21 +94,19 @@ WritePortalFile_r(node_t *node)
pl = &pPlanes[p->planenum];
PlaneFromWinding(w, &plane2);
if (DotProduct(pl->normal, plane2.normal) < 0.99) { // backwards...
PortalFile.Printf("%i %i %i ", w->numpoints,
p->nodes[1]->visleafnum,
p->nodes[0]->visleafnum);
fprintf(PortalFile, "%i %i %i ", w->numpoints,
p->nodes[1]->visleafnum, p->nodes[0]->visleafnum);
} else
PortalFile.Printf("%i %i %i ", w->numpoints,
p->nodes[0]->visleafnum,
p->nodes[1]->visleafnum);
fprintf(PortalFile, "%i %i %i ", w->numpoints,
p->nodes[0]->visleafnum, p->nodes[1]->visleafnum);
for (i = 0; i < w->numpoints; i++) {
PortalFile.Printf("(");
fprintf(PortalFile, "(");
WriteFloat(w->points[i][0]);
WriteFloat(w->points[i][1]);
WriteFloat(w->points[i][2]);
PortalFile.Printf(") ");
fprintf(PortalFile, ") ");
}
PortalFile.Printf("\n");
fprintf(PortalFile, "\n");
}
NextPortal:
@ -187,15 +185,17 @@ WritePortalfile(node_t *headnode)
StripExtension(options.szBSPName);
strcat(options.szBSPName, ".prt");
PortalFile.fOpen(options.szBSPName, "wt", true);
PortalFile = fopen(options.szBSPName, "wt");
if (PortalFile == NULL)
Message(msgError, errOpenFailed, options.szBSPName, strerror(errno));
PortalFile.Printf("PRT1\n");
PortalFile.Printf("%i\n", num_visleafs);
PortalFile.Printf("%i\n", num_visportals);
fprintf(PortalFile, "PRT1\n");
fprintf(PortalFile, "%i\n", num_visleafs);
fprintf(PortalFile, "%i\n", num_visportals);
WritePortalFile_r(headnode);
PortalFile.Close();
fclose(PortalFile);
}

View File

@ -445,10 +445,10 @@ InitQBSP(int argc, char **argv)
char szArgs[512];
char *szBuf;
int length;
File IniFile;
// Start logging to qbsp.log
if (!LogFile.fOpen("qbsp.log", "wt", false))
logfile = fopen("qbsp.log", "wt");
if (!logfile)
Message(msgWarning, warnNoLogFile);
else
// Kinda dumb, but hey...
@ -460,7 +460,7 @@ InitQBSP(int argc, char **argv)
options.fVerbose = true;
options.szMapName[0] = options.szBSPName[0] = 0;
length = IniFile.LoadFile("qbsp.ini", (void **)&szBuf, false);
length = LoadFile("qbsp.ini", (void **)&szBuf, false);
if (length) {
Message(msgLiteral, "Loading options from qbsp.ini\n");
ParseOptions(szBuf);
@ -541,7 +541,7 @@ main(int argc, char **argv)
// FreeAllMem();
// PrintMem();
LogFile.Close();
fclose(logfile);
return 0;
}

View File

@ -686,6 +686,6 @@ extern void PrintMem(void);
extern void Message(int MsgType, ...);
extern File LogFile;
extern FILE *logfile;
#endif

View File

@ -30,6 +30,8 @@
#endif
#include <stdarg.h>
//#include <malloc.h>
#include "qbsp.h"
extern char *rgszWarnings[cWarnings];
@ -249,8 +251,8 @@ Message(int msgType, ...)
sprintf(szBuffer, "*** ERROR %02d: ", ErrType);
vsprintf(szBuffer + strlen(szBuffer), rgszErrors[ErrType], argptr);
puts(szBuffer);
LogFile.Printf("%s\n", szBuffer);
LogFile.Close();
fprintf(logfile, "%s\n", szBuffer);
fclose(logfile);
exit(1);
break;
@ -303,7 +305,7 @@ Message(int msgType, ...)
if (msgType != msgFile)
printf("%s", szBuffer);
if (msgType != msgScreen)
LogFile.Printf("%s", szBuffer);
fprintf(logfile, "%s", szBuffer);
va_end(argptr);
}

View File

@ -45,7 +45,7 @@ WAD::WAD (void) {
WAD::~WAD (void) {
if (wadlist) {
for (iWad = 0; iWad < cWads; iWad++) {
wadlist[iWad].Wad.Close();
fclose(wadlist[iWad].Wad);
FreeMem(wadlist[iWad].lumps, OTHER,
sizeof(lumpinfo_t) * wadlist[iWad].header.numlumps);
}
@ -62,7 +62,7 @@ bool WAD::InitWADList(char *szWadList)
{
int i, len;
void *pTemp;
File *fileT;
FILE *fileT;
if (!szWadList)
return false;
@ -91,22 +91,27 @@ bool WAD::InitWADList(char *szWadList)
szWadList[i] = 0;
i++;
fileT = &wadlist[iWad].Wad;
if (fileT->fOpen(szWadName, "rb", false)) {
fileT->Read(&wadlist[iWad].header, sizeof(wadinfo_t));
fileT = fopen(szWadName, "rb");
if (fileT) {
wadlist[iWad].Wad = fileT;
len = fread(&wadlist[iWad].header, 1, sizeof(wadinfo_t), fileT);
if (len != sizeof(wadinfo_t))
Message(msgError, errReadFailure);
if (strncmp(wadlist[iWad].header.identification, "WAD2", 4)) {
Message(msgWarning, warnNotWad, szWadName);
fileT->Close();
fclose(fileT);
} else {
// strcpy(wadlist[iWad].szName, szWadName);
fileT->Seek(wadlist[iWad].header.infotableofs, SEEK_SET);
fseek(fileT, wadlist[iWad].header.infotableofs, SEEK_SET);
wadlist[iWad].lumps =
(lumpinfo_t *) AllocMem(OTHER,
sizeof(lumpinfo_t) *
wadlist[iWad].header.numlumps);
fileT->Read(wadlist[iWad].lumps,
len = fread(wadlist[iWad].lumps, 1,
wadlist[iWad].header.numlumps *
sizeof(lumpinfo_t));
sizeof(lumpinfo_t), fileT);
if (len != wadlist[iWad].header.numlumps * sizeof(lumpinfo_t))
Message(msgError, errReadFailure);
iWad++;
// Note that the file is NOT closed here!
// Also iWad is only incremented for valid files
@ -211,11 +216,15 @@ LoadLump
int WAD::LoadLump(char *szName, byte *pDest)
{
int i;
int len;
for (i = 0; i < wadlist[iWad].header.numlumps; i++) {
if (!stricmp(szName, wadlist[iWad].lumps[i].name)) {
wadlist[iWad].Wad.Seek(wadlist[iWad].lumps[i].filepos, SEEK_SET);
wadlist[iWad].Wad.Read(pDest, wadlist[iWad].lumps[i].disksize);
fseek(wadlist[iWad].Wad, wadlist[iWad].lumps[i].filepos, SEEK_SET);
len = fread(pDest, 1, wadlist[iWad].lumps[i].disksize,
wadlist[iWad].Wad);
if (len != wadlist[iWad].lumps[i].disksize)
Message(msgError, errReadFailure);
return wadlist[iWad].lumps[i].disksize;
}
}

View File

@ -43,7 +43,7 @@ typedef struct {
typedef struct {
wadinfo_t header;
lumpinfo_t *lumps;
File Wad;
FILE *Wad;
// char szName[512];
} wadlist_t;