/* ======================================================================================================================= Map_SaveFile ======================================================================================================================= */ bool Map_SaveFile(const char *filename, bool use_region, bool autosave) { entity_t *e, *next; idStr temp; int count; brush_t *b; idStr status; int len = strlen(filename); WIN32_FIND_DATA FileData; if (FindFirstFile(filename, &FileData) != INVALID_HANDLE_VALUE) { // the file exists; if (len > 0 && GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY) { g_pParentWnd->MessageBox("File is read only", "Read Only", MB_OK); return false; } } if (filename == NULL || len == 0 || (filename && stricmp(filename, "unnamed.map") == 0)) { CFileDialog dlgSave(FALSE,"map",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"Map Files (*.map)|*.map||",AfxGetMainWnd()); if (dlgSave.DoModal() == IDOK) { filename = dlgSave.m_ofn.lpstrFile; strcpy(currentmap, filename); } else { return false; } } MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatusEx (&statex); if ( statex.dwMemoryLoad > 95 ) { g_pParentWnd->MessageBox("Physical memory is over 95% utilized. Consider saving and restarting", "Memory"); } CWaitDlg dlg; Pointfile_Clear(); temp = filename; temp.BackSlashesToSlashes(); if ( !use_region ) { idStr backup; backup = temp; backup.StripFileExtension(); backup.SetFileExtension( ".bak" ); if ( _unlink(backup) != 0 && errno != 2 ) { // errno 2 means the file doesn't exist, which we don't care about g_pParentWnd->MessageBox( va("Unable to delete %s: %s", backup.c_str(), strerror(errno) ), "File Error" ); } if ( rename(filename, backup) != 0 ) { g_pParentWnd->MessageBox( va("Unable to rename %s to %s: %s", filename, backup.c_str(), strerror(errno) ), "File Error" ); } } common->Printf("Map_SaveFile: %s\n", filename); idStr mapFile; bool localFile = (strstr(filename, ":") != NULL); if (autosave || localFile) { mapFile = filename; } else { mapFile = fileSystem->OSPathToRelativePath( filename ); } if (use_region) { AddRegionBrushes(); } idMapFile map; world_entity->origin.Zero(); idMapEntity *mapentity = EntityToMapEntity(world_entity, use_region, &dlg); dlg.SetText("Saving worldspawn..."); map.AddEntity(mapentity); if ( use_region ) { idStr buf; sprintf( buf, "{\n\"classname\" \"info_player_start\"\n\"origin\"\t \"%i %i %i\"\n\"angle\"\t \"%i\"\n}\n", (int)g_pParentWnd->GetCamera()->Camera().origin[0], (int)g_pParentWnd->GetCamera()->Camera().origin[1], (int)g_pParentWnd->GetCamera()->Camera().origin[2], (int)g_pParentWnd->GetCamera()->Camera().angles[YAW] ); idLexer src( LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); src.LoadMemory( buf, buf.Length(), "regionbuf" ); idMapEntity *playerstart = idMapEntity::Parse( src ); map.AddEntity( playerstart ); } count = -1; for ( e = entities.next; e != &entities; e = next ) { count++; next = e->next; if (e->brushes.onext == &e->brushes) { Entity_Free(e); // no brushes left, so remove it } else { if (use_region) { for (b = e->brushes.onext; b != &e->brushes; b = b->onext) { if (!Map_IsBrushFiltered(b)) { break; // got one } } if (b == &e->brushes) { continue; // nothing visible } } idVec3 origin; if (!GetVectorForKey(e, "origin", origin)) { idStr text; VectorSubtract(e->brushes.onext->mins, e->eclass->mins, origin); sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue(e, "origin", text); } if (use_region && !idStr::Icmp(ValueForKey(e, "classname"), "info_player_start")) { continue; } idStr classname = e->epairs.GetString("classname"); sprintf(status, "Saving entity %i (%s)...", count, classname.c_str()); dlg.SetText(status); map.AddEntity(EntityToMapEntity(e, use_region, &dlg)); count++; } } mapFile.StripFileExtension(); idStr mapExt = (use_region) ? ".reg" : ".map"; sprintf(status, "Writing file %s.%s...", mapFile.c_str(), mapExt.c_str()); dlg.SetText(status); map.Write(mapFile, mapExt, !(autosave || localFile)); mapModified = 0; if (use_region) { RemoveRegionBrushes(); } if (!strstr(temp, "autosave")) { Sys_SetTitle(temp); } Sys_Status("Saved.\n", 0); return true; }
/* ======================================================================================================================= Map_LoadFile ======================================================================================================================= */ void Map_LoadFile(const char *filename) { entity_t *ent; CWaitDlg dlg; idStr fileStr, status; idMapFile mapfile; Sys_BeginWait(); Select_Deselect(); dlg.AllowCancel( true ); idStr( filename ).ExtractFileName( fileStr ); sprintf( status, "Loading %s...", fileStr.c_str() ); dlg.SetWindowText( status ); sprintf( status, "Reading file %s...", fileStr.c_str() ); dlg.SetText( status ); // SetInspectorMode(W_CONSOLE); fileStr = filename; fileStr.BackSlashesToSlashes(); common->Printf( "Map_LoadFile: %s\n", fileStr.c_str() ); Map_Free(); g_qeglobals.d_parsed_brushes = 0; strcpy( currentmap, filename ); if(mapfile.Parse(filename, true, true)) { g_qeglobals.bNeedConvert = false; g_qeglobals.bOldBrushes = false; g_qeglobals.bPrimitBrushes = false; g_qeglobals.mapVersion = 1.0; long lastUpdate = 0; int count = mapfile.GetNumEntities(); for (int i = 0; i < count; i++) { idMapEntity *mapent = mapfile.GetEntity(i); if (mapent) { idStr classname = mapent->epairs.GetString("classname"); // Update 20 times a second if ( (GetTickCount() - lastUpdate) > 50 ) { lastUpdate = GetTickCount(); sprintf(status, "Loading entity %i (%s)...", i, classname.c_str()); dlg.SetText(status); } if ( dlg.CancelPressed() ) { Sys_Status("Map load cancelled.\n"); Map_New(); return; } if (classname == "worldspawn") { world_entity = EntityFromMapEntity(mapent, &dlg); Entity_PostParse(world_entity, &active_brushes); } else { ent = EntityFromMapEntity(mapent, &dlg); Entity_PostParse(ent, &active_brushes); Entity_Name(ent, true); // add the entity to the end of the entity list ent->next = &entities; ent->prev = entities.prev; entities.prev->next = ent; entities.prev = ent; g_qeglobals.d_num_entities++; } } } } if (!world_entity) { Sys_Status("No worldspawn in map.\n"); Map_New(); return; } common->Printf("--- LoadMapFile ---\n"); common->Printf("%s\n", fileStr.c_str()); common->Printf("%5i brushes\n", g_qeglobals.d_parsed_brushes); common->Printf("%5i entities\n", g_qeglobals.d_num_entities); dlg.SetText("Restoring Between"); Map_RestoreBetween(); dlg.SetText("Building Brush Data"); common->Printf("Map_BuildAllDisplayLists\n"); Map_BuildBrushData(); // // reset the "need conversion" flag conversion to the good format done in // Map_BuildBrushData // g_qeglobals.bNeedConvert = false; // move the view to a start position ent = AngledEntity(); g_pParentWnd->GetCamera()->Camera().angles[PITCH] = 0; if (ent) { GetVectorForKey(ent, "origin", g_pParentWnd->GetCamera()->Camera().origin); GetVectorForKey(ent, "origin", g_pParentWnd->GetXYWnd()->GetOrigin()); g_pParentWnd->GetCamera()->Camera().angles[YAW] = FloatForKey(ent, "angle"); } else { g_pParentWnd->GetCamera()->Camera().angles[YAW] = 0; VectorCopy(vec3_origin, g_pParentWnd->GetCamera()->Camera().origin); VectorCopy(vec3_origin, g_pParentWnd->GetXYWnd()->GetOrigin()); } Map_RegionOff(); mapModified = 0; if (GetFileAttributes(filename) & FILE_ATTRIBUTE_READONLY) { fileStr += " (read only) "; } Sys_SetTitle(fileStr); Texture_ShowInuse(); if (g_pParentWnd->GetCamera()->GetRenderMode()) { g_pParentWnd->GetCamera()->BuildRendererState(); } Sys_EndWait(); Sys_UpdateWindows(W_ALL); }