static int json_write_callback(const char *buffer, size_t size, void *data) { CFILE* cfp = (CFILE*)data; if ((size_t)cfwrite(buffer, 1, (int)size, cfp) != size) { return -1; // Error } else { return 0; // Success } }
static void cache_program_binary(GLuint program, const SCP_string& hash) { if (!do_shader_caching()) { return; } GR_DEBUG_SCOPE("Saving shader binary"); GLint size; glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &size); if (size <= 0) { // No binary available (I'm looking at you Mesa...) return; } SCP_vector<uint8_t> binary; binary.resize((size_t) size); GLenum binary_fmt; GLsizei length; glGetProgramBinary(program, (GLsizei) binary.size(), &length, &binary_fmt, binary.data()); if (length == 0) { return; } auto base_filename = SCP_string("ogl_shader-") + hash; auto metadata_name = base_filename + ".json"; auto binary_name = base_filename + ".bin"; auto metadata_fp = cfopen(metadata_name.c_str(), "wb", CFILE_NORMAL, CF_TYPE_CACHE, false, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT); if (!metadata_fp) { mprintf(("Could not open shader cache metadata file!\n")); return; } auto metadata = json_pack("{sI}", "format", (json_int_t)binary_fmt); if (json_dump_callback(metadata, json_write_callback, metadata_fp, 0) != 0) { mprintf(("Failed to write shader cache metadata file!\n")); cfclose(metadata_fp); return; } cfclose(metadata_fp); json_decref(metadata); auto binary_fp = cfopen(binary_name.c_str(), "wb", CFILE_NORMAL, CF_TYPE_CACHE, false, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT); if (!binary_fp) { mprintf(("Could not open shader cache binary file!\n")); return; } cfwrite(binary.data(), 1, (int) binary.size(), binary_fp); cfclose(binary_fp); }
// Overkill (2006-07-20): Saver functions! void Layer::save(FILE *f) { fwrite(layername, 1, 256, f); fwrite(¶llax_x, 1, 8, f); fwrite(¶llax_y, 1, 8, f); fwrite(&width, 1, 2, f); fwrite(&height, 1, 2, f); fwrite(&lucent, 1, 1, f); cfwrite(tiledata, 1, width*height*2, f); }
// Overkill (2006-07-20): Saver functions! void VSP::save(FILE *f) { // Signature int signature = VSP_SIGNATURE; fwrite(&signature, 1, 4, f); // Version int version = VSP_VERSION; fwrite(&version, 1, 4, f); // Tilesize - always 16x16 int tilesize = 16; fwrite(&tilesize, 1, 4, f); // Format??? always 0, I assume. int format = 0; fwrite(&format, 1, 4, f); // Number of tiles. fwrite(&numtiles, 1, 4, f); // Compression - always ZLIB int compression = VSP_ZLIB; fwrite(&compression, 1, 4, f); // Write our tiledata. byte *tiledatabuf = ImageTo24bpp(vspdata); cfwrite(tiledatabuf, 1, 16*16*3*numtiles, f); // Animation! fwrite(&numanims, 1, 4, f); for(int i = 0; i < numanims; i++) { fwrite(anims[i].name, 1, 256, f); fwrite(&anims[i].start, 1, 4, f); fwrite(&anims[i].finish, 1, 4, f); fwrite(&anims[i].delay, 1, 4, f); fwrite(&anims[i].mode, 1, 4, f); } // Obstruction tiles fwrite(&numobs, 1, 4, f); cfwrite(obs, 1, numobs*256, f); }
void dump_fix_as_short( fix value, int nbits, CFILE * SaveFile ) { int int_value = (int)(value>>nbits); short short_value; if( int_value > 0x7fff ) { short_value = 0x7fff; mprintf((1, "Warning: Fix (%8x) won't fit in short. Saturating to %8x.\n", int_value, short_value<<nbits)); } else if( int_value < -0x7fff ) { short_value = -0x7fff; mprintf((1, "Warning: Fix (%8x) won't fit in short. Saturating to %8x.\n", int_value, short_value<<nbits)); } else short_value = (short)int_value; cfwrite( &short_value, sizeof(short_value), 1, SaveFile ); }
//version of dump for unsigned values void dump_fix_as_ushort( fix value, int nbits, CFILE * SaveFile ) { uint int_value; ushort short_value; if (value < 0) { mprintf((1, "Warning: fix (%8x) is signed...setting to zero.\n", value)); Int3(); //hey---show this to Matt value = 0; } else int_value = value >> nbits; if( int_value > 0xffff ) { short_value = 0xffff; mprintf((1, "Warning: Fix (%8x) won't fit in unsigned short. Saturating to %8x.\n", int_value, short_value<<nbits)); } else short_value = int_value; cfwrite( &short_value, sizeof(short_value), 1, SaveFile ); }
int cfwrite_compressed(void *param_buf, int param_elsize, int param_nelem, CFILE *cfile) { char *in = (char *)param_buf; int bytecount = (param_elsize * param_nelem ); int pixcount; // number of pixels in the current packet char *inputpixel=NULL; // current input pixel position char *matchpixel=NULL; // pixel value to match for a run int rlcount; // current count in r.l. string int rlthresh; // minimum valid run length char *copyloc; // location to begin copying at // set the threshold -- the minimum valid run length rlthresh = 2; // Require a 2 pixel span before rle'ing // set the first pixel up inputpixel = in; pixcount = 1; rlcount = 0; copyloc = (char *)0; // loop till data processing complete do { // if we have accumulated a 128-byte packet, process it if ( pixcount == 129 ) { ubyte code = 127; // set the run flag if this is a run if ( rlcount >= rlthresh ) { code |= 0x80; pixcount = 2; } cfwrite( &code, 1, 1, cfile ); // copy the data into place cfwrite( copyloc, 1, pixcount-1, cfile ); pixcount = 1; // set up for next packet continue; } // if zeroth byte, handle as special case if ( pixcount == 1 ) { rlcount = 0; copyloc = inputpixel; /* point to 1st guy in packet */ matchpixel = inputpixel; /* set pointer to pix to match */ pixcount = 2; inputpixel += 1; continue; } // assembling a packet -- look at next pixel // current pixel == match pixel? if ( *inputpixel == *matchpixel ) { // establishing a run of enough length to // save space by doing it // -- write the non-run length packet // -- start run-length packet if ( ++rlcount == rlthresh ) { // close a non-run packet if ( pixcount > (rlcount+1) ) { // write out length and do not set run flag ubyte code = (ubyte)(pixcount - 2 - rlthresh); cfwrite( &code, 1, 1, cfile ); cfwrite( copyloc, 1, (pixcount-1-rlcount), cfile ); copyloc = inputpixel; pixcount = rlcount + 1; } } } else { // no match -- either break a run or continue without one // if a run exists break it: // write the bytes in the string (1+1) // start the next string if ( rlcount >= rlthresh ) { ubyte code = (ubyte)(0x80 | rlcount); cfwrite( &code, 1, 1, cfile ); cfwrite( copyloc, 1, 1, cfile ); pixcount = 1; continue; } else { // not a match and currently not a run // - save the current pixel // - reset the run-length flag rlcount = 0; matchpixel = inputpixel; } } pixcount++; inputpixel += 1; } while ( inputpixel < (in + bytecount)); // quit this buffer without loosing any data if ( --pixcount >= 1 ) { ubyte code = ubyte(pixcount - 1); // set the run flag if this is a run if ( rlcount >= rlthresh ) { code |= 0x80; pixcount = 1; } cfwrite( &code, 1, 1, cfile ); // copy the data into place cfwrite( copyloc, 1, pixcount, cfile ); } return param_nelem; }
// --------------------------------------------------------------------- // reads and updates style.cfg file void Config::initstyle() { QString f=ConfigPath.filePath("style.cfg"); QSettings *s=new QSettings(f,QSettings::IniFormat); QString h,t,w; EditFore.set(s->value("Edit/fore","0 0 0").toString()); EditBack.set(s->value("Edit/back","221 252 222").toString()); EditHigh.set(s->value("Edit/high","240 240 232").toString()); EditSelt.set(s->value("Edit/selt","255 255 255").toString()); EditSelb.set(s->value("Edit/selb","0 162 232").toString()); TermFore.set(s->value("Term/fore","0 0 0").toString()); TermBack.set(s->value("Term/back","252 252 221").toString()); TermHigh.set(s->value("Term/high","240 240 232").toString()); TermSelt.set(s->value("Term/selt","255 255 255").toString()); TermSelb.set(s->value("Term/selb","0 162 232").toString()); adverbStyle.set(s->value("Class/adverb","221 68 68").toString()); commentStyle.set(s->value("Class/comment","136 136 136 italic").toString()); conjunctionStyle.set(s->value("Class/conjunction","221 153 153").toString()); controlStyle.set(s->value("Class/control","255 0 0").toString()); functionStyle.set(s->value("Class/function","0 0 255").toString()); nounStyle.set(s->value("Class/noun","0 0 255 bold").toString()); noundefStyle.set(s->value("Class/noundef","0 0 255").toString()); numberStyle.set(s->value("Class/number","160 32 240").toString()); stringStyle.set(s->value("Class/string","0 0 255").toString()); verbStyle.set(s->value("Class/verb","0 153 102").toString()); if (s->allKeys().contains("Edit/selt")) return; delete s; #ifdef _WIN32 QFile temp(ConfigPath.filePath("style.cfg.0")); #else QTemporaryFile temp; temp.open(); temp.close(); #endif s=new QSettings(temp.fileName(),QSettings::IniFormat); s->setValue("Edit/fore",EditFore.read()); s->setValue("Edit/back",EditBack.read()); s->setValue("Edit/high",EditHigh.read()); s->setValue("Edit/selt",EditSelt.read()); s->setValue("Edit/selb",EditSelb.read()); s->setValue("Term/fore",TermFore.read()); s->setValue("Term/back",TermBack.read()); s->setValue("Term/high",TermHigh.read()); s->setValue("Term/selt",TermSelt.read()); s->setValue("Term/selb",TermSelb.read()); s->setValue("Class/adverb",adverbStyle.read()); s->setValue("Class/comment",commentStyle.read()); s->setValue("Class/conjunction",conjunctionStyle.read()); s->setValue("Class/control",controlStyle.read()); s->setValue("Class/function",functionStyle.read()); s->setValue("Class/noun",nounStyle.read()); s->setValue("Class/noundef",noundefStyle.read()); s->setValue("Class/number",numberStyle.read()); s->setValue("Class/string",stringStyle.read()); s->setValue("Class/verb",verbStyle.read()); s->sync(); #ifdef _WIN32 t=cfread(ConfigPath.filePath("style.cfg.0")); #else t=cfread(temp.fileName()); #endif h="# Qt Styles config\n" "# This file is read and written by the Qt IDE.\n" "# Make changes in the same format as the original.\n" "#\n" "# Each style has rgb color values (0-255), optionally\n" "# followed by bold or italic, e.g.\n" "# verb=0 128 128 bold\n" "#\n" "# Edit/Term definitions are:\n" "# fore = text color\n" "# back = default background color\n" "# high = edit-line background color\n" "# selb = selection background color\n" "# selt = selection text color\n" ; cfwrite(f,h + "\n" + t); }
int main(int argc, char* argv[]) { const char *comment = "Created with Bin2Var v1.10"; FILE *fp; char *buf, str[256], *c; int i, n, ext, n2; unsigned short chk; printf("Bin2Var v1.20 by David Phillips <*****@*****.**>\n\n"); if (argc != 3) die(0); buf = strrchr(argv[2], '.'); if (!buf) die("Output file must have an extension!\n"); if (!stricmp(buf, ".82p")) ext = E_82P; else if (!stricmp(buf, ".83p")) ext = E_83P; else if (!stricmp(buf, ".8xp")) ext = E_8XP; else if (!stricmp(buf, ".85s")) ext = E_85S; else if (!stricmp(buf, ".86p")) ext = E_86P; else if (!stricmp(buf, ".86s")) ext = E_86S; else die("Extension \'%s\' is not supported!\n", buf); genname(argv[2], str); fp = fopen(argv[1], "rb"); if (!fp) die("Failed to open input file: %s\n", argv[1]); n = fsize(fp); buf = (char *)malloc(n); fread(buf, n, 1, fp); if (ferror(fp)) die("Error reading input file: %s\n", argv[1]); fclose(fp); fp = fopen(argv[2], "wb"); if (!fp) die("Failed to open output file: %s\n", argv[2]); chk = 0; if (ext == E_82P) fwrite("**TI82**\x1a\x0a\x00", 11, 1, fp); else if (ext == E_83P) fwrite("**TI83**\x1a\x0a\x00", 11, 1, fp); else if (ext == E_8XP) fwrite("**TI83F*\x1a\x0a\x00", 11, 1, fp); else if (ext == E_85S) fwrite("**TI85**\x1a\x0c\x00", 11, 1, fp); else if ((ext == E_86P) || (ext == E_86S)) fwrite("**TI86**\x1a\x0a\x00", 11, 1, fp); writecomment(fp, comment); if ((ext == E_82P) ) i = n + 17; else if (ext == E_83P) i = (n * 2) + 26; else if (ext == E_8XP) i = (n * 2) + 20; else if (ext == E_85S) i = n + 10 + strlen(str); else i = n + 18; fwrite(&i, 2, 1, fp); if ((ext == E_82P) || (ext == E_83P) || (ext == E_8XP)) cfwrite("\x0b\0x00", 2, fp, &chk); else if (ext == E_85S) { i = 4 + strlen(str); cfwrite(&i, 1, fp, &chk); cfwrite("\0x00", 1, fp, &chk); } else cfwrite("\x0c\0x00", 2, fp, &chk); if(ext == E_8XP) i = (n * 2) + 5; else if(ext == E_83P) i = (n * 2) + 11; else i = n + 2; cfwrite(&i, 2, fp, &chk); if ((ext == E_82P) || (ext == E_83P) || (ext == E_8XP)) cfwrite("\x06", 1, fp, &chk); else if (ext == E_86P) cfwrite("\x12", 1, fp, &chk); else if ((ext == E_85S) || (ext == E_86S)) cfwrite("\x0c", 1, fp, &chk); i = strlen(str); if ((ext == E_85S) || (ext == E_86P) || (ext == E_86S)) cfwrite(&i, 1, fp, &chk); cfwrite(str, i, fp, &chk); memset(str, 0, 8); if (ext != E_85S) cfwrite(str, 8 - i, fp, &chk); if (ext == E_8XP) { i = (n * 2) + 5; n2 = (n * 2) + 3; } else if (ext == E_83P) { i = (n * 2) + 11; n2 = (n * 2) + 9; } else { i = n + 2; n2 = n; } cfwrite(&i, 2, fp, &chk); cfwrite(&n2, 2, fp, &chk); if(ext == E_8XP) { cfwrite("\xBB", 1, fp, &chk); cfwrite("\x6C", 1, fp, &chk); cfwrite("\x3F", 1, fp, &chk); } if((ext == E_83P) || (ext == E_8XP)) datawrite(buf, n, fp, &chk); else cfwrite(buf, n, fp, &chk); if(ext == E_83P) { cfwrite("\x3F", 1, fp, &chk); cfwrite("\xD4", 1, fp, &chk); cfwrite("\x3F", 1, fp, &chk); cfwrite("0000", 4, fp, &chk); cfwrite("\x3F", 1, fp, &chk); cfwrite("\xD4", 1, fp, &chk); } fwrite(&chk, 2, 1, fp); if (ferror(fp)) die("Failed writing output file: %s\n", argv[2]); fclose(fp); free(buf); printf("'%s' successfully converted to '%s'\n", argv[1], argv[2]); return 0; }
// ----------------------------------------------------------------------------- // saves compiled mine data to an already-open file... int save_mine_data_compiled_new(FILE * SaveFile) { short i, segnum, sidenum, temp_short; ubyte version = COMPILED_MINE_VERSION; ubyte bit_mask = 0; med_compress_mine(); warn_if_concave_segments(); if (Highest_segment_index >= MAX_GAME_SEGMENTS) { char message[128]; sprintf(message, "Error: Too many segments (%i > %i) for game (not editor)", Highest_segment_index+1, MAX_GAME_SEGMENTS); MessageBox( -2, -2, 1, message, "Ok" ); } if (Highest_vertex_index >= MAX_GAME_VERTICES) { char message[128]; sprintf(message, "Error: Too many vertices (%i > %i) for game (not editor)", Highest_vertex_index+1, MAX_GAME_VERTICES); MessageBox( -2, -2, 1, message, "Ok" ); } //=============================== Writing part ============================== cfwrite( &version, sizeof(ubyte), 1, SaveFile ); // 1 byte = compiled version temp_short = Num_vertices; cfwrite( &temp_short, sizeof(short), 1, SaveFile ); // 2 bytes = Num_vertices temp_short = Num_segments; cfwrite( &temp_short, sizeof(short), 1, SaveFile ); // 2 bytes = Num_segments cfwrite( Vertices, sizeof(vms_vector), Num_vertices, SaveFile ); for (segnum=0; segnum<Num_segments; segnum++ ) { for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) { if (Segments[segnum].children[sidenum] != -1) bit_mask |= (1 << sidenum); } if ((Segments[segnum].special != 0) || (Segments[segnum].matcen_num != 0) || (Segments[segnum].value != 0)) bit_mask |= (1 << MAX_SIDES_PER_SEGMENT); cfwrite( &bit_mask, sizeof(ubyte), 1, SaveFile ); for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) { if (bit_mask & (1 << sidenum)) cfwrite( &Segments[segnum].children[sidenum], sizeof(short), 1, SaveFile ); } cfwrite( &Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, SaveFile ); if (bit_mask & (1 << MAX_SIDES_PER_SEGMENT)) { cfwrite( &Segments[segnum].special, sizeof(ubyte), 1, SaveFile ); cfwrite( &Segments[segnum].matcen_num, sizeof(ubyte), 1, SaveFile ); cfwrite( &Segments[segnum].value, sizeof(short), 1, SaveFile ); } dump_fix_as_ushort( Segments[segnum].static_light, 4, SaveFile ); // Write the walls as a 6 byte array bit_mask = 0; for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { uint wallnum; if (Segments[segnum].sides[sidenum].wall_num >= 0) { bit_mask |= (1 << sidenum); wallnum = Segments[segnum].sides[sidenum].wall_num; Assert( wallnum < 255 ); // Get John or Mike.. can only store up to 255 walls!!! } } cfwrite( &bit_mask, sizeof(ubyte), 1, SaveFile ); for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { if (bit_mask & (1 << sidenum)) cfwrite( &Segments[segnum].sides[sidenum].wall_num, sizeof(ubyte), 1, SaveFile ); } for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) ) { ushort tmap_num, tmap_num2; tmap_num = Segments[segnum].sides[sidenum].tmap_num; tmap_num2 = Segments[segnum].sides[sidenum].tmap_num2; if (tmap_num2 != 0) tmap_num |= 0x8000; cfwrite( &tmap_num, sizeof(ushort), 1, SaveFile ); if (tmap_num2 != 0) cfwrite( &tmap_num2, sizeof(ushort), 1, SaveFile ); for (i=0; i<4; i++ ) { dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].u, 5, SaveFile ); dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].v, 5, SaveFile ); dump_fix_as_ushort( Segments[segnum].sides[sidenum].uvls[i].l, 1, SaveFile ); } } } } return 0; }
// ----------------------------------------------------------------------------- // saves compiled mine data to an already-open file... int save_mine_data_compiled(FILE * SaveFile) { short i,segnum,sidenum; ubyte version = COMPILED_MINE_VERSION; #ifndef SHAREWARE if (New_file_format_save) return save_mine_data_compiled_new(SaveFile); #endif med_compress_mine(); warn_if_concave_segments(); if (Highest_segment_index >= MAX_GAME_SEGMENTS) { char message[128]; sprintf(message, "Error: Too many segments (%i > %i) for game (not editor)", Highest_segment_index+1, MAX_GAME_SEGMENTS); MessageBox( -2, -2, 1, message, "Ok" ); } if (Highest_vertex_index >= MAX_GAME_VERTICES) { char message[128]; sprintf(message, "Error: Too many vertices (%i > %i) for game (not editor)", Highest_vertex_index+1, MAX_GAME_VERTICES); MessageBox( -2, -2, 1, message, "Ok" ); } //=============================== Writing part ============================== cfwrite( &version, sizeof(ubyte), 1, SaveFile ); // 1 byte = compiled version cfwrite( &Num_vertices, sizeof(int), 1, SaveFile ); // 4 bytes = Num_vertices cfwrite( &Num_segments, sizeof(int), 1, SaveFile ); // 4 bytes = Num_segments cfwrite( Vertices, sizeof(vms_vector), Num_vertices, SaveFile ); for (segnum=0; segnum<Num_segments; segnum++ ) { // Write short Segments[segnum].children[MAX_SIDES_PER_SEGMENT] cfwrite( &Segments[segnum].children, sizeof(short), MAX_SIDES_PER_SEGMENT, SaveFile ); // Write short Segments[segnum].verts[MAX_VERTICES_PER_SEGMENT] cfwrite( &Segments[segnum].verts, sizeof(short), MAX_VERTICES_PER_SEGMENT, SaveFile ); // Write ubyte Segments[segnum].special cfwrite( &Segments[segnum].special, sizeof(ubyte), 1, SaveFile ); // Write byte Segments[segnum].matcen_num cfwrite( &Segments[segnum].matcen_num, sizeof(ubyte), 1, SaveFile ); // Write short Segments[segnum].value cfwrite( &Segments[segnum].value, sizeof(short), 1, SaveFile ); // Write fix Segments[segnum].static_light (shift down 5 bits, write as short) dump_fix_as_ushort( Segments[segnum].static_light, 4, SaveFile ); //cfwrite( &Segments[segnum].static_light , sizeof(fix), 1, SaveFile ); // Write the walls as a 6 byte array for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { uint wallnum; ubyte byte_wallnum; if (Segments[segnum].sides[sidenum].wall_num<0) wallnum = 255; // Use 255 to mark no walls else { wallnum = Segments[segnum].sides[sidenum].wall_num; Assert( wallnum < 255 ); // Get John or Mike.. can only store up to 255 walls!!! } byte_wallnum = (ubyte)wallnum; cfwrite( &byte_wallnum, sizeof(ubyte), 1, SaveFile ); } for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++ ) { if ( (Segments[segnum].children[sidenum]==-1) || (Segments[segnum].sides[sidenum].wall_num!=-1) ) { // Write short Segments[segnum].sides[sidenum].tmap_num; cfwrite( &Segments[segnum].sides[sidenum].tmap_num, sizeof(short), 1, SaveFile ); // Write short Segments[segnum].sides[sidenum].tmap_num2; cfwrite( &Segments[segnum].sides[sidenum].tmap_num2, sizeof(short), 1, SaveFile ); // Write uvl Segments[segnum].sides[sidenum].uvls[4] (u,v>>5, write as short, l>>1 write as short) for (i=0; i<4; i++ ) { dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].u, 5, SaveFile ); dump_fix_as_short( Segments[segnum].sides[sidenum].uvls[i].v, 5, SaveFile ); dump_fix_as_ushort( Segments[segnum].sides[sidenum].uvls[i].l, 1, SaveFile ); //cfwrite( &Segments[segnum].sides[sidenum].uvls[i].l, sizeof(fix), 1, SaveFile ); } } } } return 0; }
// ----------------------------------------------------------------------------- // saves to an already-open file int save_mine_data(CFILE * SaveFile) { int header_offset, editor_offset, vertex_offset, segment_offset, doors_offset, texture_offset, walls_offset, triggers_offset; //, links_offset; int newseg_verts_offset; int newsegment_offset; int i; med_compress_mine(); warn_if_concave_segments(); for (i=0;i<NumTextures;i++) strncpy(current_tmap_list[i], TmapInfo[i].filename, 13); //=================== Calculate offsets into file ================== header_offset = cftell(SaveFile) + sizeof(mine_fileinfo); editor_offset = header_offset + sizeof(mine_header); texture_offset = editor_offset + sizeof(mine_editor); vertex_offset = texture_offset + (13*NumTextures); segment_offset = vertex_offset + (sizeof(vms_vector)*Num_vertices); newsegment_offset = segment_offset + (sizeof(segment)*Num_segments); newseg_verts_offset = newsegment_offset + sizeof(segment); walls_offset = newseg_verts_offset + (sizeof(vms_vector)*8); triggers_offset = walls_offset + (sizeof(wall)*Num_walls); doors_offset = triggers_offset + (sizeof(trigger)*Num_triggers); //===================== SAVE FILE INFO ======================== mine_fileinfo.fileinfo_signature= 0x2884; mine_fileinfo.fileinfo_version = MINE_VERSION; mine_fileinfo.fileinfo_sizeof = sizeof(mine_fileinfo); mine_fileinfo.header_offset = header_offset; mine_fileinfo.header_size = sizeof(mine_header); mine_fileinfo.editor_offset = editor_offset; mine_fileinfo.editor_size = sizeof(mine_editor); mine_fileinfo.vertex_offset = vertex_offset; mine_fileinfo.vertex_howmany = Num_vertices; mine_fileinfo.vertex_sizeof = sizeof(vms_vector); mine_fileinfo.segment_offset = segment_offset; mine_fileinfo.segment_howmany = Num_segments; mine_fileinfo.segment_sizeof = sizeof(segment); mine_fileinfo.newseg_verts_offset = newseg_verts_offset; mine_fileinfo.newseg_verts_howmany = 8; mine_fileinfo.newseg_verts_sizeof = sizeof(vms_vector); mine_fileinfo.texture_offset = texture_offset; mine_fileinfo.texture_howmany = NumTextures; mine_fileinfo.texture_sizeof = 13; // num characters in a name mine_fileinfo.walls_offset = walls_offset; mine_fileinfo.walls_howmany = Num_walls; mine_fileinfo.walls_sizeof = sizeof(wall); mine_fileinfo.triggers_offset = triggers_offset; mine_fileinfo.triggers_howmany = Num_triggers; mine_fileinfo.triggers_sizeof = sizeof(trigger); // Write the fileinfo cfwrite( &mine_fileinfo, sizeof(mine_fileinfo), 1, SaveFile ); //===================== SAVE HEADER INFO ======================== mine_header.num_vertices = Num_vertices; mine_header.num_segments = Num_segments; // Write the editor info if (header_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( &mine_header, sizeof(mine_header), 1, SaveFile ); //===================== SAVE EDITOR INFO ========================== mine_editor.current_seg = Cursegp - Segments; mine_editor.newsegment_offset = newsegment_offset; mine_editor.newsegment_size = sizeof(segment); // Next 3 vars added 10/07 by JAS mine_editor.Curside = Curside; if (Markedsegp) mine_editor.Markedsegp = Markedsegp - Segments; else mine_editor.Markedsegp = -1; mine_editor.Markedside = Markedside; for (i=0;i<10;i++) mine_editor.Groupsegp[i] = Groupsegp[i] - Segments; for (i=0;i<10;i++) mine_editor.Groupside[i] = Groupside[i]; if (editor_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( &mine_editor, sizeof(mine_editor), 1, SaveFile ); //===================== SAVE TEXTURE INFO ========================== if (texture_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( current_tmap_list, 13, NumTextures, SaveFile ); //===================== SAVE VERTEX INFO ========================== if (vertex_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( Vertices, sizeof(vms_vector), Num_vertices, SaveFile ); //===================== SAVE SEGMENT INFO ========================= if (segment_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( Segments, sizeof(segment), Num_segments, SaveFile ); //===================== SAVE NEWSEGMENT INFO ====================== if (newsegment_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( &New_segment, sizeof(segment), 1, SaveFile ); if (newseg_verts_offset != cftell(SaveFile)) Error( "OFFSETS WRONG IN MINE.C!" ); cfwrite( &Vertices[New_segment.verts[0]], sizeof(vms_vector), 8, SaveFile ); //==================== CLOSE THE FILE ============================= return 0; }
// Overkill (2006-07-20): Saver functions! void MAP::save(FILE *f) { int i; char tempfn[16] = "$$v3map.tmp"; FILE *out = fopen(tempfn, "wb"); if (!out) err("Unable to open %s for writing!", tempfn); // Map signature. char signature[8]; strcpy(signature, maptag); fwrite(&signature, 1, 6, f); // Version int version = MAP_VERSION; fwrite(&version, 1, 4, f); // USE OUTPUT BUFFER FROM THIS POINT ON. fwrite(mapname, 1, 256, out); //log("mapname: %s", mapname); // savevspname, not vspname because it's what the vsp file WILL be, // not necessarily what it IS at that moment. // So, you can set it then FileSaveVSP() down the line. fwrite(savevspname, 1, 256, out); //log("savevspname: %s", savevspname); fwrite(musicname, 1, 256, out); //log("musicname: %s", musicname); fwrite(renderstring, 1, 256, out); //log("renderstring: %s", renderstring); fwrite(startupscript, 1, 256, out); //log("startupscript: %s", startupscript); fwrite(&startx, 1, 2, out); fwrite(&starty, 1, 2, out); fwrite(&numlayers, 1, 4, out); for (i = 0; i < numlayers; i++) { layers[i]->save(out); } // Obs. cfwrite(obslayer, 1, mapwidth*mapheight, out); // Zones cfwrite(zonelayer, 1, mapwidth*mapheight*2, out); fwrite(&numzones, 1, 4, out); for (i=0; i<numzones; i++) { fwrite(zones[i]->name, 1, 256, out); fwrite(zones[i]->script, 1, 256, out); fwrite(&zones[i]->percent, 1, 1, out); fwrite(&zones[i]->delay, 1, 1, out); fwrite(&zones[i]->method, 1, 1, out); } // ENTITIES! <3. fwrite(&entities, 1, 4, out); for (i=0; i<entities; i++) { //log("ENT %d of %d", i, entities); // Tile coords. int x = entity[i]->x / 16; int y = entity[i]->y / 16; fwrite(&x, 1, 2, out); fwrite(&y, 1, 2, out); fwrite(&entity[i]->face, 1, 1, out); fwrite(&entity[i]->obstructable, 1, 1, out); fwrite(&entity[i]->obstruction, 1, 1, out); fwrite(&entity[i]->autoface, 1, 1, out); fwrite(&entity[i]->speed, 1, 2, out); //log("HERE?"); // FIXME: ACTIVATION MODE int activationMode = 0; fwrite(&activationMode, 1, 1, out); // Movecode and wandering. fwrite(&entity[i]->movecode, 1, 1, out); fwrite(&entity[i]->wx1, 1, 2, out); fwrite(&entity[i]->wy1, 1, 2, out); fwrite(&entity[i]->wx2, 1, 2, out); fwrite(&entity[i]->wy2, 1, 2, out); fwrite(&entity[i]->wdelay, 1, 2, out); //log("YAR?"); // Expand! whatever, man. int expand = 0; fwrite(&expand, 1, 4, out); // h8 u STD::string. char tempchar[256]; //log("movestr: %s", entity[i]->movestr); fwrite(entity[i]->movestr, 1, 256, out); strcpy(tempchar, entity[i]->chr->name.c_str()); fwrite(tempchar, 1, 256, out); strcpy(tempchar, entity[i]->description.c_str()); fwrite(tempchar, 1, 256, out); // description strcpy(tempchar, entity[i]->script.c_str()); fwrite(tempchar, 1, 256, out); // The actual script position. } // NO LONGER NEED TO USE THE OUTPUT BUFFER fclose(out); // Why vopen instead? I... don't know! // Now that we've finished the buffer though, we can // use this to fill in the unknown map information. VFILE *tmp = vopen(tempfn); if (!tmp) err("Could not open %s for reading!", tempfn); int bufferlength = filesize(tmp); byte* buf = new byte[bufferlength]; vread(buf, bufferlength, tmp); vclose(tmp); // Delete the temporary buffer, we've gotten what we wanted. remove(tempfn); // Alright... finally, all this to get the offset for the VC stuffs. int vcofs = 14 + bufferlength; fwrite(&vcofs, 1, 4, f); // Write the buffer into the map now. fwrite(buf, 1, bufferlength, f); // VC funcs are waaay down here. int vcfuncs = 0; // number compiled should be none. //log("VCOFS: %d CURRENT POS: %d", vcofs, ftell(f)); fwrite(&vcfuncs, 1, 4, f); }