void ETextureThumbnail::Save(int age, LPCSTR path) { if (!Valid()) return; CMemoryWriter F; F.open_chunk (THM_CHUNK_VERSION); F.w_u16 (THM_TEXTURE_VERSION); F.close_chunk (); /* F.w_chunk (THM_CHUNK_DATA | CFS_CompressMark,m_Pixels.begin(),m_Pixels.size()*sizeof(u32)); */ F.open_chunk (THM_CHUNK_TYPE); F.w_u32 (m_Type); F.close_chunk (); m_TexParams.Save(F); string_path fn; if (path) FS.update_path(fn, path, m_Name.c_str()); else FS.update_path(fn, _game_textures_, m_Name.c_str()); if (F.save_to(fn)) { FS.set_file_age (fn,age?age:m_Age); }else{ Log ("!Can't save thumbnail:",fn); } }
bool CPSLibrary::Save(const char* nm) { CMemoryWriter F; F.open_chunk (PS_CHUNK_VERSION); F.w_u16 (PS_VERSION); F.close_chunk (); F.open_chunk (PS_CHUNK_SECONDGEN); u32 chunk_id = 0; for (PS::PEDIt it=m_PEDs.begin(); it!=m_PEDs.end(); ++it,++chunk_id) { F.open_chunk (chunk_id); (*it)->Save (F); F.close_chunk (); } F.close_chunk (); F.open_chunk (PS_CHUNK_THIRDGEN); chunk_id = 0; for (PS::PGDIt g_it=m_PGDs.begin(); g_it!=m_PGDs.end(); ++g_it,++chunk_id) { F.open_chunk (chunk_id); (*g_it)->Save (F); F.close_chunk (); } F.close_chunk (); return F.save_to(nm); }
void CGameGraphBuilder::save_cross_table (const float &start, const float &amount) { Progress (start); Msg ("Saving cross table"); // CTimer timer; // timer.Start (); CMemoryWriter tMemoryStream; CGameLevelCrossTable::CHeader tCrossTableHeader; tCrossTableHeader.dwVersion = XRAI_CURRENT_VERSION; tCrossTableHeader.dwNodeCount = level_graph().header().vertex_count(); tCrossTableHeader.dwGraphPointCount = graph().header().vertex_count(); tCrossTableHeader.m_level_guid = level_graph().header().guid(); tCrossTableHeader.m_game_guid = m_graph_guid; tMemoryStream.open_chunk (CROSS_TABLE_CHUNK_VERSION); tMemoryStream.w (&tCrossTableHeader,sizeof(tCrossTableHeader)); tMemoryStream.close_chunk (); tMemoryStream.open_chunk (CROSS_TABLE_CHUNK_DATA); for (int i=0, n=level_graph().header().vertex_count(); i<n; i++) { CGameLevelCrossTable::CCell tCrossTableCell; tCrossTableCell.tGraphIndex = (GameGraph::_GRAPH_ID)m_results[i]; VERIFY (graph().header().vertex_count() > tCrossTableCell.tGraphIndex); tCrossTableCell.fDistance = float(m_distances[tCrossTableCell.tGraphIndex][i])*level_graph().header().cell_size(); tMemoryStream.w (&tCrossTableCell,sizeof(tCrossTableCell)); } tMemoryStream.close_chunk(); // Msg ("CT:SAVE : %f",timer.GetElapsed_sec()); // Msg ("Flushing cross table"); #ifdef PRIQUEL tMemoryStream.save_to (m_cross_table_name); #else // PRIQUEL string_path file_name; strconcat (sizeof(file_name), file_name,*m_level_name,CROSS_TABLE_NAME_RAW); tMemoryStream.save_to (file_name); #endif // PRIQUEL // Msg ("CT:SAVE : %f",timer.GetElapsed_sec()); // Msg ("Freiing cross table resources"); m_marks.clear (); m_mark_stack.clear (); m_distances.clear (); m_current_fringe.clear (); m_next_fringe.clear (); // Msg ("CT:SAVE : %f",timer.GetElapsed_sec()); Progress (start + amount); }
bool SceneBuilder::BuildSOMModel() { BOOL bResult = TRUE; CMemoryWriter F; F.open_chunk (0); F.w_u32 (0); F.close_chunk (); F.open_chunk (1); ObjectList& lst = Scene->ListObj(OBJCLASS_SCENEOBJECT); for (ObjectIt it=lst.begin(); it!=lst.end(); it++){ CSceneObject* S = (CSceneObject*)(*it); CEditableObject* E = S->GetReference(); R_ASSERT(E); if (E->m_Flags.is(CEditableObject::eoSoundOccluder)){ Fvector v; const Fmatrix& parent = S->_Transform(); for (EditMeshIt m_it=E->FirstMesh(); m_it!=E->LastMesh(); m_it++){ for (SurfFacesPairIt sf_it=(*m_it)->m_SurfFaces.begin(); sf_it!=(*m_it)->m_SurfFaces.end(); sf_it++){ CSurface* surf = sf_it->first; int gm_id = surf->_GameMtl(); if (gm_id==GAMEMTL_NONE_ID){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain invalid game material.",(*m_it)->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } SGameMtl* mtl = GMLib.GetMaterialByID(gm_id); if (0==mtl){ ELog.DlgMsg (mtError,"Object '%s', surface '%s' contain undefined game material.",(*m_it)->Parent()->m_LibName.c_str(),surf->_Name()); bResult = FALSE; break; } BOOL b2Sided = surf->m_Flags.is(CSurface::sf2Sided); IntVec& i_lst = sf_it->second; for (IntIt i_it=i_lst.begin(); i_it!=i_lst.end(); i_it++){ st_Face& face = (*m_it)->m_Faces[*i_it]; for (int k=0; k<3; k++){ parent.transform_tiny(v,(*m_it)->m_Verts[face.pv[k].pindex]); F.w_fvector3(v); } F.w_u32 (b2Sided); F.w_float (mtl->fSndOcclusionFactor); } } } } } BOOL bValid = !!F.chunk_size()&&bResult; F.close_chunk(); if (bValid){ xr_string som_name = MakeLevelPath("level.som"); bValid = F.save_to(som_name.c_str()); } return bValid; }
void COMotion::SaveMotion(const char* buf){ CMemoryWriter F; F.open_chunk (EOBJ_OMOTION); Save (F); F.close_chunk (); if (!F.save_to(buf)) Log ("!Can't save object motion:",buf); }
void ELightAnimLibrary::Save() { CMemoryWriter F; F.open_chunk (CHUNK_VERSION); F.w_u16 (LANIM_VERSION); F.close_chunk (); F.open_chunk (CHUNK_ITEM_LIST); int count = 0; for (LAItemIt it=Items.begin(); it!=Items.end(); it++){ F.open_chunk(count++); (*it)->Save (F); F.close_chunk(); } F.close_chunk (); string_path fn; FS.update_path (fn,_game_data_,"lanims.xr"); if (!F.save_to(fn)) Log ("!Can't save color animations:",fn); }
//---------------------------------------------------- // some types bool SceneBuilder::BuildHOMModel() { CMemoryWriter F; F.open_chunk(0); F.w_u32(0); F.close_chunk(); F.open_chunk(1); ObjectList& lst = Scene->ListObj(OBJCLASS_SCENEOBJECT); for (ObjectIt it=lst.begin(); it!=lst.end(); it++){ CSceneObject* S = (CSceneObject*)(*it); CEditableObject* E = S->GetReference(); R_ASSERT(E); if (E->m_Flags.is(CEditableObject::eoHOM)){ Fvector v; const Fmatrix& parent = S->_Transform(); for (EditMeshIt m_it=E->FirstMesh(); m_it!=E->LastMesh(); m_it++){ for (SurfFacesPairIt sf_it=(*m_it)->m_SurfFaces.begin(); sf_it!=(*m_it)->m_SurfFaces.end(); sf_it++){ BOOL b2Sided = sf_it->first->m_Flags.is(CSurface::sf2Sided); IntVec& i_lst= sf_it->second; for (IntIt i_it=i_lst.begin(); i_it!=i_lst.end(); i_it++){ st_Face& face = (*m_it)->m_Faces[*i_it]; for (int k=0; k<3; k++){ parent.transform_tiny(v,(*m_it)->m_Verts[face.pv[k].pindex]); F.w_fvector3 (v); } F.w_u32(b2Sided); } } } } } BOOL bValid = !!F.chunk_size(); F.close_chunk(); if (bValid){ xr_string hom_name = MakeLevelPath("level.hom"); bValid = F.save_to(hom_name.c_str()); } return bValid; }
void CBuild::SaveTREE (IWriter &fs) { CMemoryWriter MFS; Status ("Geometry buffers..."); xr_vector<u32> remap; remap.reserve (g_tree.size()); for (u32 rid=0; rid<g_tree.size(); rid++) { OGF* o = dynamic_cast<OGF*> (g_tree[rid]); if (o) remap.push_back(rid); } std::stable_sort (remap.begin(),remap.end(),remap_order); clMsg ("remap-size: %d / %d",remap.size(),g_tree.size()); for (u32 sid=0; sid<remap.size(); sid++) { u32 id = remap[sid]; //clMsg ("%3d: subdiv: %d",sid,id); g_tree[id]->PreSave (id); } Status ("Visuals..."); fs.open_chunk (fsL_VISUALS); for (xr_vector<OGF_Base*>::iterator it = g_tree.begin(); it!=g_tree.end(); it++) { u32 idx = u32(it-g_tree.begin()); MFS.open_chunk (idx); (*it)->Save (MFS); MFS.close_chunk (); Progress (float(idx)/float(g_tree.size())); } fs.w (MFS.pointer(),MFS.size()); fs.close_chunk (); clMsg ("Average: %d verts/%d faces, 50(%2.1f), 100(%2.1f), 500(%2.1f), 1000(%2.1f), 5000(%2.1f)", g_batch_verts/g_batch_count, g_batch_faces/g_batch_count, 100.f * float(g_batch_50)/float(g_batch_count), 100.f * float(g_batch_100)/float(g_batch_count), 100.f * float(g_batch_500)/float(g_batch_count), 100.f * float(g_batch_1000)/float(g_batch_count), 100.f * float(g_batch_5000)/float(g_batch_count) ); mem_Compact (); SaveGEOMs ("level.geom", g_VB,g_IB,g_SWI); // Normal SaveGEOMs ("level.geomx", x_VB,x_IB,x_SWI); // Fast-Path Status ("Shader table..."); fs.open_chunk (fsL_SHADERS); fs.w_u32 (g_Shaders.size()); for (xr_vector<LPCSTR>::iterator T=g_Shaders.begin(); T!=g_Shaders.end(); T++) fs.w_stringZ (*T); fs.close_chunk (); //mem_Compact (); }
void CLevel::net_Save (LPCSTR name) // Game Save { if (0==Server) { Msg("KERNEL::Can't save game on pure client"); return; } // 1. Create stream CMemoryWriter fs; // 2. Description fs.open_chunk (fsSLS_Description); fs.w_stringZ (net_SessionName()); fs.close_chunk (); // 3. Server state fs.open_chunk (fsSLS_ServerState); Server->SLS_Save (fs); fs.close_chunk (); // Save it to file fs.save_to (name); }
void CGameSpawnConstructor::save_spawn (LPCSTR name, LPCSTR output) { CMemoryWriter stream; m_spawn_header.m_version = XRAI_CURRENT_VERSION; m_spawn_header.m_guid = generate_guid(); m_spawn_header.m_graph_guid = game_graph().header().guid(); m_spawn_header.m_spawn_count = spawn_graph().vertex_count(); m_spawn_header.m_level_count = (u32)m_level_spawns.size(); stream.open_chunk (0); stream.w_u32 (m_spawn_header.m_version); save_data (m_spawn_header.m_guid,stream); save_data (m_spawn_header.m_graph_guid,stream); stream.w_u32 (m_spawn_header.m_spawn_count); stream.w_u32 (m_spawn_header.m_level_count); stream.close_chunk (); stream.open_chunk (1); save_data (spawn_graph(),stream); stream.close_chunk (); stream.open_chunk (2); save_data (m_level_points,stream); stream.close_chunk (); stream.open_chunk (3); save_data (m_patrol_path_storage,stream); stream.close_chunk (); stream.open_chunk (4); m_game_graph->save (stream); stream.close_chunk (); stream.save_to (*spawn_name(output)); }
void CBuild::SaveSectors(IWriter& fs) { CMemoryWriter MFS; Status("Processing..."); // validate & save for (u32 I=0; I<g_sectors.size(); I++) { MFS.open_chunk(I); g_sectors[I]->Validate(); g_sectors[I]->Save(MFS); MFS.close_chunk(); Progress(float(I)/float(g_sectors.size())); } fs.w_chunk(fsL_SECTORS,MFS.pointer(),MFS.size()); }
bool CGameMtlLibrary::Save() { R_ASSERT (FALSE==UpdateMtlPairs()); // save CMemoryWriter fs; fs.open_chunk (GAMEMTLS_CHUNK_VERSION); fs.w_u16 (GAMEMTL_CURRENT_VERSION); fs.close_chunk (); fs.open_chunk (GAMEMTLS_CHUNK_AUTOINC); fs.w_u32 (material_index); fs.w_u32 (material_pair_index); fs.close_chunk (); fs.open_chunk (GAMEMTLS_CHUNK_MTLS); int count = 0; for(GameMtlIt m_it=materials.begin(); m_it!=materials.end(); m_it++){ fs.open_chunk (count++); (*m_it)->Save (fs); fs.close_chunk (); } fs.close_chunk (); fs.open_chunk (GAMEMTLS_CHUNK_MTLS_PAIR); count = 0; for(GameMtlPairIt p_it=material_pairs.begin(); p_it!=material_pairs.end(); p_it++){ fs.open_chunk (count++); (*p_it)->Save (fs); fs.close_chunk (); } fs.close_chunk (); string_path fn; FS.update_path (fn,_game_data_,GAMEMTL_FILENAME); return fs.save_to (fn); }
bool EDetailManager::Export(LPCSTR path) { AnsiString fn = AnsiString(path)+"build.details"; bool bRes=true; SPBItem* pb = UI->ProgressStart(5,"Making details..."); CMemoryWriter F; pb->Inc ("merge textures"); Fvector2Vec offsets; Fvector2Vec scales; boolVec rotated; RStringSet textures_set; RStringVec textures; U32Vec remap; U8Vec remap_object (objects.size(),u8(-1)); int slot_cnt = dtH.size_x*dtH.size_z; for (int slot_idx=0; slot_idx<slot_cnt; slot_idx++){ DetailSlot* it = &dtSlots[slot_idx]; for (int part=0; part<4; part++){ u8 id = it->r_id(part); if (id!=DetailSlot::ID_Empty) { textures_set.insert(((EDetail*)(objects[id]))->GetTextureName()); remap_object[id] = 1; } } } textures.assign (textures_set.begin(),textures_set.end()); U8It remap_object_it= remap_object.begin(); u32 new_idx = 0; for (DetailIt d_it=objects.begin(); d_it!=objects.end(); d_it++,remap_object_it++) if ((*remap_object_it==1)&&(textures_set.find(((EDetail*)(*d_it))->GetTextureName())!=textures_set.end())) *remap_object_it = (u8)new_idx++; AnsiString do_tex_name = ChangeFileExt(fn,"_details"); int res = ImageLib.CreateMergedTexture(textures,do_tex_name.c_str(),STextureParams::tfADXT1,256,1024,256,1024,offsets,scales,rotated,remap); if (1!=res) bRes=FALSE; pb->Inc ("export geometry"); // objects int object_idx = 0; if (bRes){ do_tex_name = ExtractFileName(do_tex_name); F.open_chunk (DETMGR_CHUNK_OBJECTS); for (DetailIt it=objects.begin(); it!=objects.end(); it++){ if (remap_object[it-objects.begin()]!=u8(-1)){ F.open_chunk (object_idx++); if (!((EDetail*)(*it))->m_pRefs){ ELog.DlgMsg(mtError, "Bad object or object not found '%s'.", ((EDetail*)(*it))->m_sRefs.c_str()); bRes=false; }else{ LPCSTR tex_name = ((EDetail*)(*it))->GetTextureName(); for (u32 t_idx=0; t_idx<textures.size(); t_idx++) if (textures[t_idx]==tex_name) break; VERIFY(t_idx<textures.size()); t_idx = remap[t_idx]; ((EDetail*)(*it))->Export (F,do_tex_name.c_str(),offsets[t_idx],scales[t_idx],rotated[t_idx]); } F.close_chunk (); if (!bRes) break; } } F.close_chunk (); } pb->Inc ("export slots"); // slots if (bRes){ xr_vector<DetailSlot> dt_slots(slot_cnt); dt_slots.assign(dtSlots,dtSlots+slot_cnt); for (slot_idx=0; slot_idx<slot_cnt; slot_idx++){ DetailSlot& it = dt_slots[slot_idx]; // zero colors need lighting it.c_dir = 0; it.c_hemi = 0; it.c_r = 0; it.c_g = 0; it.c_b = 0; for (int part=0; part<4; part++){ u8 id = it.r_id(part); if (id!=DetailSlot::ID_Empty) it.w_id(part,remap_object[id]); } } F.open_chunk (DETMGR_CHUNK_SLOTS); F.w (dt_slots.begin(),dtH.size_x*dtH.size_z*sizeof(DetailSlot)); F.close_chunk (); pb->Inc(); // write header dtH.version = DETAIL_VERSION; dtH.object_count= object_idx; F.w_chunk (DETMGR_CHUNK_HEADER,&dtH,sizeof(DetailHeader)); bRes = F.save_to(fn.c_str()); } pb->Inc(); UI->ProgressEnd(pb); return bRes; }
CCrossTableBuilder::CCrossTableBuilder(LPCSTR caProjectName) { FILE_NAME caFileName; strconcat (sizeof(caFileName),caFileName,caProjectName,GAME_LEVEL_GRAPH); Phase ("Loading level graph"); CGameGraph tGraph(caFileName); Phase ("Loading AI map"); CLevelGraph tMap(caProjectName); Phase ("Building dynamic objects"); FLOAT_VECTOR_VECTOR tDistances; int iVertexCount = tGraph.header().vertex_count(); R_ASSERT2 (iVertexCount > 0,"There are no graph points in the graph!"); int iNodeCount = tMap.header().vertex_count(); xr_vector<bool> tMarks; tMarks.assign (tMap.header().vertex_count(),false); { for (int i=0; i<iVertexCount; i++) vfRecurseMark(tMap,tMarks,tGraph.vertex(i)->level_vertex_id()); tMarks.flip (); } tDistances.resize (iVertexCount); { FLOAT_VECTOR_IT I = tDistances.begin(); FLOAT_VECTOR_IT E = tDistances.end(); for ( ; I != E; I++) { (*I).resize (iNodeCount); FLOAT_IT i = (*I).begin(); FLOAT_IT e = (*I).end(); for ( ; i != e; i++) *i = u32(-1); } } Phase ("Building cross table"); Progress(0.f); for (int i=0; i<iVertexCount; ++i) { if (i) for (int k=0; k<(int)tMap.header().vertex_count(); k++) tDistances[i][k] = tDistances[i - 1][k]; g_tDistances = &tDistances[i]; g_tMap = &tMap; g_tMarks = &tMarks; vfRecurseUpdate(tGraph.vertex(i)->level_vertex_id(),i,iVertexCount); Progress(float(i + 1)/float(iVertexCount)); } Progress (1.f); Phase ("Saving cross table"); CMemoryWriter tMemoryStream; CGameLevelCrossTable::CHeader tCrossTableHeader; tCrossTableHeader.dwVersion = XRAI_CURRENT_VERSION; tCrossTableHeader.dwNodeCount = iNodeCount; tCrossTableHeader.dwGraphPointCount = iVertexCount; tCrossTableHeader.m_level_guid = tMap.header().guid(); tCrossTableHeader.m_game_guid = tGraph.header().guid(); tMemoryStream.open_chunk (CROSS_TABLE_CHUNK_VERSION); tMemoryStream.w (&tCrossTableHeader,sizeof(tCrossTableHeader)); tMemoryStream.close_chunk (); tMemoryStream.open_chunk (CROSS_TABLE_CHUNK_DATA); { for (int i=0; i<iNodeCount; i++) { FLOAT_VECTOR_IT I = tDistances.begin(), B = I; FLOAT_VECTOR_IT E = tDistances.end(); CGameLevelCrossTable::CCell tCrossTableCell; tCrossTableCell.fDistance = flt_max; tCrossTableCell.tGraphIndex = u16(-1); for ( ; I != E; I++) if (float((*I)[i])*tMap.header().cell_size() < tCrossTableCell.fDistance) { tCrossTableCell.fDistance = float((*I)[i])*tMap.header().cell_size(); tCrossTableCell.tGraphIndex = GameGraph::_GRAPH_ID(I - B); } for (int j=0; j<iVertexCount; j++) if ((tGraph.vertex(j)->level_vertex_id() == (u32)i) && (tCrossTableCell.tGraphIndex != j)) { Msg("! Warning : graph points are too close, therefore cross table is automatically validated"); Msg("%d : [%f][%f][%f] %d[%f] -> %d[%f]",i,VPUSH(tGraph.vertex(j)->level_point()),tCrossTableCell.tGraphIndex,tCrossTableCell.fDistance,j,tDistances[j][i]); tCrossTableCell.fDistance = float(tDistances[j][i])*tMap.header().cell_size(); tCrossTableCell.tGraphIndex = (GameGraph::_GRAPH_ID)j; } tMemoryStream.w(&tCrossTableCell,sizeof(tCrossTableCell)); } } tMemoryStream.close_chunk(); strconcat (sizeof(caFileName),caFileName,caProjectName,CROSS_TABLE_NAME_RAW); tMemoryStream.save_to(caFileName); }