void Preferences::WriteSettings () { /* Serialize contents of "prefs" to a file on disk */ RemoveName ("presetVerifyCode"); AddFloat ("presetVerifyCode", PresetVerifyCode); BFile file (prefsPath.Path(), B_CREATE_FILE | B_WRITE_ONLY); Flatten (&file); }
//*********************************************************************************************** // Saves an FTL File // Must pass the original name of the theo file //----------------------------------------------------------------------------------------------- // VERIFIED (Cyril 2001/10/15) //*********************************************************************************************** bool ARX_FTL_Save(const char * file, EERIE_3DOBJ * obj) { // Need an object to be saved ! if (obj == NULL) return false; // Generate File name/path and create it char path[256]; char gamefic[256]; sprintf(gamefic, "Game\\%s", file); SetExt(gamefic, ".FTL"); strcpy(path, gamefic); RemoveName(path); if (!CreateFullPath(path)) return NULL; // create some usefull vars ARX_FTL_PRIMARY_HEADER * afph; ARX_FTL_SECONDARY_HEADER * afsh; ARX_FTL_CLOTHES_DATA_HEADER * afcdh; ARX_FTL_3D_DATA_HEADER * af3Ddh; ARX_FTL_COLLISION_SPHERES_DATA_HEADER * afcsdh; unsigned char * dat = NULL; long pos = 0; long allocsize = 8000000; // need to compute it more precisely // Compute allocsize... allocsize = sizeof(ARX_FTL_PRIMARY_HEADER) + 512 //checksum + sizeof(ARX_FTL_SECONDARY_HEADER) + sizeof(ARX_FTL_3D_DATA_HEADER) + sizeof(EERIE_OLD_VERTEX) * obj->nbvertex + sizeof(EERIE_FACE_FTL) * obj->nbfaces + obj->nbmaps * 256 // texturecontainernames + sizeof(EERIE_ACTIONLIST) * obj->nbaction + 128000; // just in case... if (obj->nbgroups > 0) { allocsize += sizeof(EERIE_GROUPLIST) * obj->nbgroups; for (long i = 0; i < obj->nbgroups; i++) { if (obj->grouplist[i].nb_index > 0) { allocsize += sizeof(long) * obj->grouplist[i].nb_index; } } } if (obj->nbselections > 0) { allocsize += sizeof(EERIE_SELECTIONS) * obj->nbselections; for (long i = 0; i < obj->nbselections; i++) { allocsize += sizeof(long) * obj->selections[i].nb_selected; } } if (obj->sdata && obj->sdata->nb_spheres) // Collision Spheres Data { allocsize += sizeof(ARX_FTL_COLLISION_SPHERES_DATA_HEADER); allocsize += sizeof(COLLISION_SPHERE) * obj->sdata->nb_spheres; } if (obj->cdata) // Clothes DATA { allocsize += sizeof(ARX_FTL_CLOTHES_DATA_HEADER); allocsize += sizeof(CLOTHESVERTEX) * obj->cdata->nb_cvert; allocsize += sizeof(EERIE_SPRINGS) * obj->cdata->nb_springs; } // Finished computing allocsize Now allocate it... dat = (unsigned char *)malloc(allocsize); if (!dat) HERMES_Memory_Emergency_Out(); memset(dat, 0, allocsize); // Primary Header afph = (ARX_FTL_PRIMARY_HEADER *)dat; pos += sizeof(ARX_FTL_PRIMARY_HEADER); if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); afph->ident[0] = 'F'; afph->ident[1] = 'T'; afph->ident[2] = 'L'; afph->version = CURRENT_FTL_VERSION; // Identification char check[512]; HERMES_CreateFileCheck(file, check, 512, CURRENT_FTL_VERSION); memcpy(dat + pos, check, 512); pos += 512; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); // Secondary Header afsh = (ARX_FTL_SECONDARY_HEADER *)(dat + pos); pos += sizeof(ARX_FTL_SECONDARY_HEADER); if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); // 3D Data afsh->offset_3Ddata = pos; //-1; af3Ddh = (ARX_FTL_3D_DATA_HEADER *)(dat + afsh->offset_3Ddata); pos += sizeof(ARX_FTL_3D_DATA_HEADER); if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); af3Ddh->nb_vertex = obj->nbvertex; af3Ddh->nb_faces = obj->nbfaces; af3Ddh->nb_maps = obj->nbmaps; af3Ddh->nb_groups = obj->nbgroups; af3Ddh->nb_action = obj->nbaction; af3Ddh->nb_selections = obj->nbselections; af3Ddh->origin = obj->origin; // vertexes if (af3Ddh->nb_vertex > 0) { for (long ii = 0; ii < af3Ddh->nb_vertex; ii++) { memcpy(dat + pos, &obj->vertexlist[ii], sizeof(EERIE_OLD_VERTEX)); pos += sizeof(EERIE_OLD_VERTEX); } if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } // faces if (af3Ddh->nb_faces > 0) { for (long ii = 0; ii < af3Ddh->nb_faces; ii++) { EERIE_FACE_FTL * eff = (EERIE_FACE_FTL *)(dat + pos); eff->facetype = obj->facelist[ii].facetype; eff->texid = obj->facelist[ii].texid; eff->transval = obj->facelist[ii].transval; eff->temp = obj->facelist[ii].temp; memcpy(&eff->norm, &obj->facelist[ii].norm, sizeof(EERIE_3D)); for (long kk = 0; kk < IOPOLYVERT; kk++) { memcpy(&eff->nrmls[kk], &obj->facelist[ii].nrmls[kk], sizeof(EERIE_3D)); eff->vid[kk] = obj->facelist[ii].vid[kk]; eff->u[kk] = obj->facelist[ii].u[kk]; eff->v[kk] = obj->facelist[ii].v[kk]; eff->ou[kk] = obj->facelist[ii].ou[kk]; eff->ov[kk] = obj->facelist[ii].ov[kk]; eff->rgb[kk] = 0; } pos += sizeof(EERIE_FACE_FTL); if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } } // textures for (long i = 0; i < af3Ddh->nb_maps; i++) { char ficc[256]; memset(ficc, 0, 256); if (obj->texturecontainer[i]) strcpy(ficc, obj->texturecontainer[i]->m_texName); memcpy(dat + pos, ficc, 256); pos += 256; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } // groups if (af3Ddh->nb_groups > 0) { memcpy(dat + pos, obj->grouplist, sizeof(EERIE_GROUPLIST)*af3Ddh->nb_groups); pos += sizeof(EERIE_GROUPLIST) * af3Ddh->nb_groups; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); for (int i = 0; i < af3Ddh->nb_groups; i++) { if (obj->grouplist[i].nb_index > 0) { memcpy(dat + pos, obj->grouplist[i].indexes, sizeof(long)*obj->grouplist[i].nb_index); pos += sizeof(long) * obj->grouplist[i].nb_index; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } } } // actionpoints if (af3Ddh->nb_action > 0) { memcpy(dat + pos, obj->actionlist, sizeof(EERIE_ACTIONLIST)*af3Ddh->nb_action); pos += sizeof(EERIE_ACTIONLIST) * af3Ddh->nb_action; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } // selections if (af3Ddh->nb_selections > 0) { memcpy(dat + pos, obj->selections, sizeof(EERIE_SELECTIONS)*af3Ddh->nb_selections); pos += sizeof(EERIE_SELECTIONS) * af3Ddh->nb_selections; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); for (int i = 0; i < af3Ddh->nb_selections; i++) { memcpy(dat + pos, obj->selections[i].selected, sizeof(long)*obj->selections[i].nb_selected); pos += sizeof(long) * obj->selections[i].nb_selected; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } strcpy(af3Ddh->name, obj->file); } // Progressive DATA afsh->offset_progressive_data = -1; // Collision Spheres Data if (obj->sdata && obj->sdata->nb_spheres) { afsh->offset_collision_spheres = pos; //-1; afcsdh = (ARX_FTL_COLLISION_SPHERES_DATA_HEADER *)(dat + afsh->offset_collision_spheres); pos += sizeof(ARX_FTL_COLLISION_SPHERES_DATA_HEADER); if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); afcsdh->nb_spheres = obj->sdata->nb_spheres; memcpy(dat + pos, obj->sdata->spheres, sizeof(COLLISION_SPHERE)*obj->sdata->nb_spheres); pos += sizeof(COLLISION_SPHERE) * obj->sdata->nb_spheres; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } else afsh->offset_collision_spheres = -1; // Clothes DATA if (obj->cdata == NULL) { afsh->offset_clothes_data = -1; } else { afsh->offset_clothes_data = pos; afcdh = (ARX_FTL_CLOTHES_DATA_HEADER *)(dat + afsh->offset_clothes_data); afcdh->nb_cvert = obj->cdata->nb_cvert; afcdh->nb_springs = obj->cdata->nb_springs; pos += sizeof(ARX_FTL_CLOTHES_DATA_HEADER); if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); // now save cvert memcpy(dat + pos, obj->cdata->cvert, sizeof(CLOTHESVERTEX)*obj->cdata->nb_cvert); pos += sizeof(CLOTHESVERTEX) * obj->cdata->nb_cvert; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); // now saves springs memcpy(dat + pos, obj->cdata->springs, sizeof(EERIE_SPRINGS)*obj->cdata->nb_springs); pos += sizeof(EERIE_SPRINGS) * obj->cdata->nb_springs; if (pos > allocsize) ShowPopup("Invalid Allocsize in ARX_FTL_Save"); } afsh->offset_physics_box = -1; afsh->offset_cylinder = -1; // Now we can flush our cool FTL file to the hard drive FileHandle handle; char _error[512]; if (pos > allocsize) { sprintf(_error, "Badly Allocated SaveBuffer...%s", gamefic); goto error; } char * compressed; compressed = NULL; long cpr_pos; cpr_pos = 0; LogError <<"IMPLODE NOT IMPLEMENTED"; // TODO fix //compressed = STD_Implode((char *)dat, pos, &cpr_pos); // Now Saving Whole Buffer if (!(handle = FileOpenWrite(gamefic))) { sprintf(_error, "Unable to Open %s for Write...", gamefic); goto error; } if (FileWrite(handle, compressed, cpr_pos) != cpr_pos) { sprintf(_error, "Unable to Write to %s", gamefic); goto error; } FileCloseWrite(handle); free(compressed); free(dat); return true; error: ; ShowPopup(_error); free(dat); return false; }