|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "stdafx.h"
#include <io.h>
#include "hammer.h"
#include "GlobalFunctions.h"
#include "MapErrorsDlg.h"
#include "Options.h"
#include "MapDoc.h"
#include "MapEntity.h"
#include "MapFace.h"
#include "MapGroup.h"
#include "MapSolid.h"
#include "MapStudioModel.h"
#include "MapWorld.h"
#include "progdlg.h"
#include "TextureSystem.h"
#include "MapDisp.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
#pragma optimize("g", off)
#pragma warning(disable: 4748) // buffer overrung with optimizations off - remove if we turn "g" back on
#define TEXTURE_NAME_LEN 128
// All files are opened in binary, and we want to save CR/LF
#define ENDLINE "\r\n"
enum { fileOsError = -1, // big error!
fileError = -2, // problem
fileOk = -3, // loaded ok
fileDone = -4 // got not-my-kind of line
};
BOOL bSaveVisiblesOnly;
static BOOL bErrors; static int nInvalidSolids; static CProgressDlg *pProgDlg;
static MAPFORMAT MapFormat;
static BOOL bStuffed; static char szStuffed[255];
static UINT uMapVersion = 0;
//-----------------------------------------------------------------------------
// Purpose:
// Input : buf -
//-----------------------------------------------------------------------------
static void StuffLine(char * buf) { Assert(!bStuffed); strcpy(szStuffed, buf); bStuffed = TRUE; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// buf -
//-----------------------------------------------------------------------------
static void GetLine(std::fstream& file, char *buf) { if(bStuffed) { if(buf) strcpy(buf, szStuffed); bStuffed = FALSE; return; }
char szBuf[1024];
while(1) { file >> std::ws; file.getline(szBuf, 512); if(file.eof()) return; if(!strncmp(szBuf, "//", 2)) continue; file >> std::ws; if(buf) { // char *p = strchr(szBuf, '\n');
// if(p) p[0] = 0;
// p = strchr(szBuf, '\r');
// if(p) p[0] = 0;
strcpy(buf, szBuf); } return; } }
//-----------------------------------------------------------------------------
// Purpose:
// Input : pObject -
// file -
// pIntersecting -
// Output : int
//-----------------------------------------------------------------------------
static int SaveSolidChildrenOf(CMapClass *pObject, std::fstream& file, BoundBox *pIntersecting = NULL) { CMapWorld *pWorld = (CMapWorld*) CMapClass::GetWorldObject(pObject);
//
// If we are only saving visible objects and this object isn't visible, don't save it.
//
if (bSaveVisiblesOnly && (pObject != pWorld) && !pObject->IsVisible()) { return fileOk; // not an error - return ok
} //
// If we are only saving objects within a particular bounding box and this object isn't, don't save it.
//
if (pIntersecting && !pObject->IsIntersectingBox(pIntersecting->bmins, pIntersecting->bmaxs)) { return fileOk; }
const CMapObjectList *pChildren = pObject->GetChildren(); FOR_EACH_OBJ( *pChildren, pos ) { int iRvl = -1; CMapClass *pChild = (CUtlReference< CMapClass >)pChildren->Element(pos);
if (!pIntersecting || pChild->IsIntersectingBox(pIntersecting->bmins, pIntersecting->bmaxs)) { if (pChild->IsMapClass(MAPCLASS_TYPE(CMapSolid))) { if (!bSaveVisiblesOnly || pChild->IsVisible()) { iRvl = pChild->SerializeMAP(file, TRUE); } } else if (pChild->IsMapClass(MAPCLASS_TYPE(CMapGroup))) { iRvl = SaveSolidChildrenOf(pChild, file, pIntersecting); }
// return error if there is an error
if (iRvl != -1 && iRvl != fileOk) { return iRvl; } } }
return fileOk; // ok.
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : pObject -
// file -
// pIntersecting -
// Output : int
//-----------------------------------------------------------------------------
static int SaveEntityChildrenOf(CMapClass *pObject, std::fstream& file, BoundBox *pIntersecting) { CMapWorld *pWorld = (CMapWorld *)CMapClass::GetWorldObject(pObject);
if (bSaveVisiblesOnly && pObject != pWorld && !pObject->IsVisible()) { return fileOk; // no error
}
if (pIntersecting && !pObject->IsIntersectingBox(pIntersecting->bmins, pIntersecting->bmaxs)) { return fileOk; } const CMapObjectList *pChildren = pObject->GetChildren(); FOR_EACH_OBJ( *pChildren, pos ) { int iRvl = -1;
CMapClass *pChild = (CUtlReference< CMapClass >)pChildren->Element(pos);
if (!pIntersecting || pChild->IsIntersectingBox(pIntersecting->bmins, pIntersecting->bmaxs)) { if (pChild->IsMapClass(MAPCLASS_TYPE(CMapEntity))) { if (!bSaveVisiblesOnly || pChild->IsVisible()) { iRvl = pChild->SerializeMAP(file, TRUE); } } else if (pChild->IsMapClass(MAPCLASS_TYPE(CMapGroup))) { iRvl = SaveEntityChildrenOf(pChild, file, pIntersecting); }
// return error if there is an error
if (iRvl != -1 && iRvl != fileOk) { return iRvl; } } }
return fileOk; // ok.
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pObject -
// file -
// Output : int
//-----------------------------------------------------------------------------
static int ReadSolids(CMapClass *pObject, std::fstream& file) { int nSolids = 0; char szBuf[128];
while(1) { GetLine(file, szBuf); if(szBuf[0] != '{') { StuffLine(szBuf); break; }
CMapSolid *pSolid = new CMapSolid; int iRvl = pSolid->SerializeMAP(file, FALSE); if(iRvl == fileError) { // delete the solid
delete pSolid; ++nInvalidSolids; } else if(iRvl == fileOsError) { // big problem
delete pSolid; return fileOsError; } else pObject->AddChild(pSolid);
++nSolids; }
return nSolids; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// Output : int
//-----------------------------------------------------------------------------
static int PeekChar(std::fstream& file) { if(bStuffed) // stuffed.. return first char
return szStuffed[0]; char szBuf[1024]; szBuf[0] = 0; // get next line
GetLine(file, szBuf);
// still blank? return eof
if(szBuf[0] == 0) return EOF;
// to get it next call to getline
StuffLine(szBuf);
return szBuf[0]; }
//-----------------------------------------------------------------------------
// Purpose: Sets the MAP format for saving.
// Input : mf - MAP format to use when saving.
//-----------------------------------------------------------------------------
void SetMapFormat(MAPFORMAT mf) { Assert((mf == mfHalfLife) || (mf == mfHalfLife2)); MapFormat = mf; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// Output : int
//-----------------------------------------------------------------------------
int CMapClass::SerializeMAP(std::fstream& file, BOOL fIsStoring) { // no info stored in MAPs ..
return fileOk; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// Output : int
//-----------------------------------------------------------------------------
int CMapFace::SerializeMAP(std::fstream& file, BOOL fIsStoring) { char szBuf[512];
if (fIsStoring) { char *pszTexture; char szTexture[sizeof(texture.texture)+1]; szTexture[sizeof(texture.texture)] = 0; memcpy(szTexture, texture.texture, sizeof texture.texture); strlwr(szTexture);
if (MapFormat == mfQuake2) { pszTexture = strstr(szTexture, "."); if (pszTexture) { *pszTexture = 0; } pszTexture = strstr(szTexture, "textures\\"); if (pszTexture == NULL) { pszTexture = szTexture; } else { pszTexture += strlen("textures\\"); } } else { pszTexture = szTexture; }
strupr(szTexture);
//
// Reverse the slashes -- thank you id.
//
for (int i = strlen(pszTexture) - 1; i >= 0; i--) { if (pszTexture[i] == '\\') pszTexture[i] = '/'; }
//
// Convert the plane points to integers.
//
for (int nPlane = 0; nPlane < 3; nPlane++) { plane.planepts[nPlane][0] = rint(plane.planepts[nPlane][0]); plane.planepts[nPlane][1] = rint(plane.planepts[nPlane][1]); plane.planepts[nPlane][2] = rint(plane.planepts[nPlane][2]); }
//
// Check for duplicate plane points. All three plane points must be unique
// or it isn't a valid plane. Try to fix it if it isn't valid.
//
if (!CheckFace()) { Fix(); }
sprintf(szBuf, "( %.0f %.0f %.0f ) ( %.0f %.0f %.0f ) ( %.0f %.0f %.0f ) " "%s " "[ %g %g %g %g ] " "[ %g %g %g %g ] " "%g %g %g ",
plane.planepts[0][0], plane.planepts[0][1], plane.planepts[0][2], plane.planepts[1][0], plane.planepts[1][1], plane.planepts[1][2], plane.planepts[2][0], plane.planepts[2][1], plane.planepts[2][2], pszTexture,
(double)texture.UAxis[0], (double)texture.UAxis[1], (double)texture.UAxis[2], (double)texture.UAxis[3], (double)texture.VAxis[0], (double)texture.VAxis[1], (double)texture.VAxis[2], (double)texture.VAxis[3],
(double)texture.rotate, (double)texture.scale[0], (double)texture.scale[1]);
file << szBuf << ENDLINE;
return fileOk; } else { // load the plane
GetLine(file, szBuf);
if(szBuf[0] != '(') { StuffLine(szBuf); return fileDone; }
char szTexName[TEXTURE_NAME_LEN]; DWORD q2contents; DWORD q2surface; int nLightmapScale; int nDummy; int nRead;
if( uMapVersion >= 340 ) { nRead = sscanf(szBuf, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) " "%s " "[ %f %f %f %f ] " "[ %f %f %f %f ] " "%f %f %f " "%u %u %u",
&plane.planepts[0][0], &plane.planepts[0][1], &plane.planepts[0][2], &plane.planepts[1][0], &plane.planepts[1][1], &plane.planepts[1][2], &plane.planepts[2][0], &plane.planepts[2][1], &plane.planepts[2][2], &szTexName,
&texture.UAxis[0], &texture.UAxis[1], &texture.UAxis[2], &texture.UAxis[3], &texture.VAxis[0], &texture.VAxis[1], &texture.VAxis[2], &texture.VAxis[3],
&texture.rotate, &texture.scale[0], &texture.scale[1], &q2contents, &q2surface, &nLightmapScale);
if (nRead < 21) { bErrors = TRUE; } else if (nRead == 24) { // got q2 values - set them here
texture.q2contents = q2contents; texture.q2surface = q2surface; texture.nLightmapScale = nLightmapScale; if (texture.nLightmapScale == 0) { texture.nLightmapScale = g_pGameConfig->GetDefaultLightmapScale(); } }
//
// very cheesy HACK!!! -- this will be better when we have chunks
//
if( uMapVersion <= 350 ) { if( ( file.peek() != '(' ) && ( file.peek() != '}' ) ) { EditDispHandle_t handle = EditDispMgr()->Create(); SetDisp( handle );
CMapDisp *pDisp = EditDispMgr()->GetDisp( handle ); pDisp->SerializedLoadMAP( file, this, uMapVersion ); } } } else if (uMapVersion >= 220 ) { nRead = sscanf(szBuf, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) " "%s " "[ %f %f %f %f ] " "[ %f %f %f %f ] " "%f %f %f " "%u %u %u",
&plane.planepts[0][0], &plane.planepts[0][1], &plane.planepts[0][2], &plane.planepts[1][0], &plane.planepts[1][1], &plane.planepts[1][2], &plane.planepts[2][0], &plane.planepts[2][1], &plane.planepts[2][2], &szTexName,
&texture.UAxis[0], &texture.UAxis[1], &texture.UAxis[2], &texture.UAxis[3], &texture.VAxis[0], &texture.VAxis[1], &texture.VAxis[2], &texture.VAxis[3],
&texture.rotate, &texture.scale[0], &texture.scale[1], &q2contents, &q2surface, &nDummy); // Pre-340 didn't have lightmap scale.
if (nRead < 21) { bErrors = TRUE; } else if (nRead == 24) { // got q2 values - set them here
texture.q2contents = q2contents; texture.q2surface = q2surface; } } else { nRead = sscanf(szBuf, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) " "%s " "%f %f %f " "%f %f %u %u %u",
&plane.planepts[0][0], &plane.planepts[0][1], &plane.planepts[0][2], &plane.planepts[1][0], &plane.planepts[1][1], &plane.planepts[1][2], &plane.planepts[2][0], &plane.planepts[2][1], &plane.planepts[2][2], &szTexName,
&texture.UAxis[3], &texture.VAxis[3], &texture.rotate, &texture.scale[0], &texture.scale[1], &q2contents, &q2surface, &nDummy); // Pre-340 didn't have lightmap scale.
if (nRead < 15) { bErrors = TRUE; } else if (nRead == 18) { // got q2 values - set them here
texture.q2contents = q2contents; texture.q2surface = q2surface; } }
if (g_pGameConfig->GetTextureFormat() != tfVMT) { // reverse the slashes -- thank you id
for (int i = strlen(szTexName) - 1; i >= 0; i--) { if (szTexName[i] == '/') szTexName[i] = '\\'; } }
SetTexture(szTexName); }
if (file.fail()) { return fileOsError; } return fileOk; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// Output : int
//-----------------------------------------------------------------------------
int MDkeyvalue::SerializeMAP(std::fstream& file, BOOL fIsStoring) { // load/save a keyvalue
char szBuf[1024];
if(fIsStoring) { // save a keyvalue
sprintf( szBuf, "\"%s\" \"%s\"",
Key(), Value() );
file << szBuf << ENDLINE; } else { GetLine(file, szBuf); if(szBuf[0] != '\"') { StuffLine(szBuf); return fileDone; } char *p = strchr(szBuf, '\"'); p = strchr(p+1, '\"'); if(!p) return fileError; p[0] = 0; strcpy(szKey, szBuf+1);
// advance to start of value string
p = strchr(p+1, '\"'); if(!p) return fileError; // ocpy in value
strcpy(szValue, p+1); // kill trailing "
p = strchr(szValue, '\"'); if(!p) return fileError; p[0] = 0; }
return file.fail() ? fileOsError : fileOk; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// Output : int
//-----------------------------------------------------------------------------
int CMapSolid::SerializeMAP(std::fstream& file, BOOL fIsStoring) { CMapClass::SerializeMAP(file, fIsStoring);
// load/save a brush
if (fIsStoring) { // save the brush
file << "{" << ENDLINE;
// serialize the Faces
int nFaces = Faces.GetCount(); for(int i = 0; i < nFaces; i++) { if(!Faces[i].Points) continue; if(Faces[i].SerializeMAP(file, fIsStoring) == fileError) return fileError; }
// terminator
file << "}" << ENDLINE; } else { // caller skipped delimiter
Faces.SetCount(0);
// read Faces
for(int i = 0; ; i++) { // extract plane
if (Faces[i].SerializeMAP(file, fIsStoring) == fileDone) { // when fileDone is returned, no face was loaded
break; }
Faces[i].CalcPlane(); }
GetLine(file, NULL); // ignore line
if (!file.fail()) { //
// Create the solid using the planes that were read from the MAP file.
//
if (CreateFromPlanes() == FALSE) { bErrors = TRUE; return(fileError); }
//
// If we are reading from an old map file, the texture axes will need to be set up.
// Leave the rotation and shifts alone; they were read from the MAP file.
//
if (uMapVersion < 220) { InitializeTextureAxes(TEXTURE_ALIGN_QUAKE, INIT_TEXTURE_AXES | INIT_TEXTURE_FORCE); } } else { return(fileOsError); }
CalcBounds();
//
// Set solid type based on texture name.
//
m_eSolidType = HL1SolidTypeFromTextureName(Faces[0].texture.texture); }
return(file.fail() ? fileOsError : fileOk); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// Output : int
//-----------------------------------------------------------------------------
int CMapEntity::SerializeMAP(std::fstream &file, BOOL fIsStoring) { CMapClass::SerializeMAP(file, fIsStoring);
// load/save an object
if (fIsStoring) { //
// If it's a solidentity but it doesn't have any solids,
// don't save it.
//
if (!IsPlaceholder() && !m_Children.Count()) { return(fileOk); }
//
// Save it.
//
file << "{" << ENDLINE;
//
// Save keyvalues & other data.
//
CEditGameClass::SerializeMAP(file, fIsStoring);
//
// If this is a placeholder and either has no class or is not a solid class,
// save our origin.
//
if (IsPlaceholder() && (!IsClass() || !IsSolidClass())) { MDkeyvalue tmpkv; strcpy(tmpkv.szKey, "origin");
Vector Origin; GetOrigin(Origin); sprintf(tmpkv.szValue, "%.0f %.0f %.0f", Origin[0], Origin[1], Origin[2]); tmpkv.SerializeMAP(file, fIsStoring); }
if (!(IsPlaceholder())) { SaveSolidChildrenOf(this, file); }
file << "}" << ENDLINE; } else { // load keyvalues
CEditGameClass::SerializeMAP(file, fIsStoring);
// solids
if (!ReadSolids(this, file)) { flags |= flagPlaceholder; }
// skip delimiter
GetLine(file, NULL); }
return file.fail() ? fileOsError : fileOk; }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// Output : int
//-----------------------------------------------------------------------------
int CEditGameClass::SerializeMAP(std::fstream& file, BOOL fIsStoring) { int iRvl;
if (!fIsStoring) { // loading
if (PeekChar(file) == '\"') { // read kv pairs
MDkeyvalue newkv; while (1) { if (newkv.SerializeMAP(file, fIsStoring) != fileOk) { // fileDone means the keyvalue was not loaded
break; } if (!strcmp(newkv.szKey, "classname")) { m_KeyValues.SetValue(newkv.szKey, newkv.szValue); } else if (!strcmp(newkv.szKey, "angle")) { ImportAngle(atoi(newkv.szValue)); } else if (strcmp(newkv.szKey, "wad")) { //
// All other keys are simply added to the keyvalue list.
//
m_KeyValues.SetValue(newkv.szKey, newkv.szValue); } } } } else { // save keyvalues
MDkeyvalue tmpkv;
if (GetKeyValue("classname") == NULL) { tmpkv.Set("classname", m_szClass); tmpkv.SerializeMAP(file, fIsStoring); }
//
// Determine whether we have a game data class. This will help us decide which keys
// to write.
//
GDclass *pGameDataClass = NULL; if (pGD != NULL) { pGameDataClass = pGD->ClassForName(m_szClass); }
//
// Consider all the keyvalues in this object for serialization.
//
for ( int z=m_KeyValues.GetFirst(); z != m_KeyValues.GetInvalidIndex(); z=m_KeyValues.GetNext( z ) ) { MDkeyvalue &KeyValue = m_KeyValues.GetKeyValue(z);
iRvl = KeyValue.SerializeMAP(file, fIsStoring); if (iRvl != fileOk) { return(iRvl); } }
//
// If we have a base class, for each keyvalue in the class definition, write out all keys
// that are not present in the object and whose defaults are nonzero in the class definition.
//
if (pGameDataClass != NULL) { //
// For each variable from the base class...
//
int nVariableCount = pGameDataClass->GetVariableCount(); for (int i = 0; i < nVariableCount; i++) { GDinputvariable *pVar = pGameDataClass->GetVariableAt(i); Assert(pVar != NULL);
if (pVar != NULL) { int iIndex; MDkeyvalue *pKey; LPCTSTR p = m_KeyValues.GetValue(pVar->GetName(), &iIndex);
//
// If the variable is not present in this object, write out the default value.
//
if (p == NULL) { pKey = &tmpkv; pVar->ResetDefaults(); pVar->ToKeyValue(pKey);
//
// Only write the key value if it is non-zero.
//
if ((pKey->szKey[0] != 0) && (pKey->szValue[0] != 0) && (stricmp(pKey->szValue, "0"))) { iRvl = pKey->SerializeMAP(file, fIsStoring); if (iRvl != fileOk) { return(iRvl); } } } } } } }
return(file.fail() ? fileOsError : fileOk); }
//-----------------------------------------------------------------------------
// Purpose:
// Input : file -
// fIsStoring -
// pIntersecting -
// Output : int
//-----------------------------------------------------------------------------
int CMapWorld::SerializeMAP(std::fstream &file, BOOL fIsStoring, BoundBox *pIntersecting) { int iRvl;
bStuffed = FALSE; bErrors = FALSE; nInvalidSolids = 0;
// load/save a world
if (fIsStoring) { file << "{" << ENDLINE;
// save worldobject
CEditGameClass::SerializeMAP(file, fIsStoring);
if (MapFormat != mfQuake2) { MDkeyvalue tmpkv;
strcpy(tmpkv.szKey, "mapversion"); strcpy(tmpkv.szValue, "360"); tmpkv.SerializeMAP(file, fIsStoring);
// Save wad file line
strcpy(tmpkv.szKey, "wad");
// copy all texfiles into value
tmpkv.szValue[0] = 0; BOOL bFirst = TRUE; int nGraphicsFiles = g_Textures.FilesGetCount(); for (int i = 0; i < nGraphicsFiles; i++) { char szFile[MAX_PATH]; GRAPHICSFILESTRUCT gf;
g_Textures.FilesGetInfo(&gf, i);
//
// Don't save WAL files - they're never used.
//
if (gf.format != tfWAL) { //
// Also make sure this is the right kind of WAD file
// based on the game we're using.
//
if (gf.format == g_pGameConfig->GetTextureFormat()) { //
// Append this WAD file to the WAD list.
//
strcpy(szFile, gf.filename);
// dvs: Strip off the path. This crashes VIS and QRAD!!
/*
char *pszSlash = strrchr(szFile, '\\'); if (pszSlash == NULL) { pszSlash = strrchr(szFile, '/'); }
if (pszSlash != NULL) { pszSlash++; } else { pszSlash = szFile; } */
char *pszSlash = szFile;
// Strip off any drive letter.
if (pszSlash[1] == ':') { pszSlash += 2; }
// WAD names are semicolon delimited.
if (!bFirst) { strcat(tmpkv.szValue, ";"); }
strcat(tmpkv.szValue, pszSlash); bFirst = FALSE; } } }
if ( tmpkv.szValue[0] != '\0' ) { tmpkv.SerializeMAP(file, fIsStoring); } }
//
// Save the brushes.
//
if (SaveSolidChildrenOf(this, file, pIntersecting) == fileOsError) { goto FatalError; }
file << "}" << ENDLINE;
//
// Save the entities.
//
if (SaveEntityChildrenOf(this, file, pIntersecting) == fileOsError) { goto FatalError; }
//
// Save paths (if paths are visible).
//
FOR_EACH_OBJ( m_Paths, pos ) { CMapPath *pPath = m_Paths.Element(pos); pPath->SerializeMAP(file, TRUE, pIntersecting); } } else { pProgDlg = new CProgressDlg; pProgDlg->Create(); pProgDlg->SetStep(1); CString caption; caption.LoadString(IDS_LOADINGFILE); pProgDlg->SetWindowText(caption);
m_Render2DBox.ResetBounds();
// load world
GetLine(file, NULL); // ignore delimiter
CEditGameClass::SerializeMAP(file, fIsStoring);
const char* pszMapVersion;
pszMapVersion = m_KeyValues.GetValue("mapversion"); if (pszMapVersion != NULL) { uMapVersion = atoi(pszMapVersion); } else { uMapVersion = 0; }
// read solids
if (ReadSolids(this, file) == fileOsError) { goto FatalError; }
// skip end-of-entity marker
GetLine(file, NULL);
char szBuf[128];
// read entities
while (1) { GetLine(file, szBuf); if (szBuf[0] != '{') { StuffLine(szBuf); break; }
if (PeekChar(file) == EOF) { break; }
CMapEntity *pEntity;
pEntity = new CMapEntity; iRvl = pEntity->SerializeMAP(file, fIsStoring); AddChild(pEntity); if (iRvl == fileError) { bErrors = TRUE; } else if (iRvl == fileOsError) { goto FatalError; } }
if (bErrors) { if (nInvalidSolids) { CString str; str.Format("For your information, %d solids were not loaded\n" "due to errors in the file.", nInvalidSolids); AfxMessageBox(str); } else if (AfxMessageBox("There was a problem loading the MAP file. Do you\n" "want to view the error report?", MB_YESNO) == IDYES) { CMapErrorsDlg dlg; dlg.DoModal(); } }
PostloadWorld();
if (g_pGameConfig->GetTextureFormat() == tfVMT) { // do batch search and replace of textures from trans.txt if it exists.
char translationFilename[MAX_PATH]; Q_snprintf( translationFilename, sizeof( translationFilename ), "materials/trans.txt" ); if( CMapDoc::GetActiveMapDoc() ) { FileHandle_t searchReplaceFP = g_pFileSystem->Open( translationFilename, "r" ); if( searchReplaceFP ) { CMapDoc::GetActiveMapDoc()->BatchReplaceTextures( searchReplaceFP ); g_pFileSystem->Close( searchReplaceFP ); } } } }
if (pProgDlg) { pProgDlg->DestroyWindow(); delete pProgDlg; pProgDlg = NULL; }
return (bErrors && fIsStoring) ? -1 : 0;
FatalError:
// OS error.
CString str; str.Format("The OS reported an error %s the file: %s", fIsStoring ? "saving" : "loading", strerror(errno)); AfxMessageBox(str);
if (pProgDlg != NULL) { pProgDlg->DestroyWindow(); delete pProgDlg; pProgDlg = NULL; }
return -1; }
|