00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00022
00023 #include "crogue.h"
00024
00025 void compress_tiles(void);
00026
00027 static const uchar save_file_extension[6] = { 0,'S','A','V',0,0xf8 };
00028
00029 #ifdef IS_CALCULATOR
00030
00031 static void archive_file(const char *filename, int filesize)
00032 {
00033 ulong space_free, block_free;
00034
00035 filesize += 16;
00036
00037 EM_survey(NULL, &space_free, &block_free, NULL, NULL, NULL);
00038 space_free += block_free;
00039
00040 if(space_free < filesize) {
00041 message(gettext("WARNING: Not enough archive free. Using main memory."));
00042 read_char();
00043 return;
00044 } else if(block_free < filesize) {
00045 if(prompt(gettext("Garbage collect archive memory?")))
00046 {
00047 message(gettext("Garbage collecting archive memory."));
00048 EM_GC(FALSE);
00049 EM_survey(NULL, &space_free, &block_free, NULL, NULL, NULL);
00050 if(space_free < filesize)
00051 {
00052 message(gettext("Still not enough archive free. Using main memory."));
00053 return;
00054 }
00055 } else {
00056 message(gettext("Not enough archive free. Using main memory."));
00057 read_char();
00058 return;
00059 }
00060 }
00061 EM_moveSymToExtMem(SYMSTR(filename), HS_NULL);
00062 }
00063
00064 #endif
00065
00066
00067 void link_data_file(void)
00068 {
00069 w->tiledescs = (struct tiledesc* )deref_file_ptr(w->desc.tileoffset);
00070 w->itemdescs = (struct filelink* )deref_file_ptr(w->desc.itemoffset);
00071 w->spelldescs = (struct spelldesc*)deref_file_ptr(w->desc.spelllist);
00072 w->shopdescs = (struct shopdesc* )deref_file_ptr(w->desc.shopdescs);
00073 w->playerclasses = (struct classdesc*)deref_file_ptr(w->desc.playerclasses);
00074 w->shuffledata = (struct filelink* )deref_file_ptr(w->desc.stdata);
00075 #ifdef IS_CALCULATOR
00076 w->dll_functions = _DLL_call(const void**,(const import_functions *f),0)(&body_functions);
00077 w->dll_interface = (const export_functions*)w->dll_functions;
00078 #else
00079 w->dll_functions = dll_load(&body_functions);
00080 w->dll_interface = (const export_functions*)w->dll_functions;
00081 #endif
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 void save_game(void)
00093 {
00094 FILE *sg;
00095 const char *filename;
00096 # ifdef EXTERNAL_COMPRESSOR
00097 char cmd[512];
00098 # endif
00099
00100 # ifdef IS_CALCULATOR
00101 int filesize;
00102 # endif
00103
00104
00105 # ifdef IS_CALCULATOR
00106 EM_moveSymFromExtMem(SYMSTR(SAVEFILENAME), HS_NULL);
00107 SymDel(SYMSTR(SAVEFILENAME));
00108 # endif
00109
00110 # ifdef SHARED_SCORES
00111 filename = retprintf("%s%s_%s", file_prefix, getlogin(), SAVEFILENAME);
00112 # else
00113 filename = SAVEFILENAME;
00114 # endif
00115
00116 sg = fopen(filename, "wb");
00117
00118 if(sg)
00119 {
00120 frleinit_write(sg, &fhuffmanputc);
00121 fhuffmaninit_write();
00122 frlewrite(w, sizeof(world), sizeof(monster), sg);
00123 frlewrite(&w->t[0][0], sizeof(tile)*w->mapsize_x*w->mapsize_y, sizeof(tile), sg);
00124 frlewrite(w->shuffletranslation, sizeof(uint)*w->desc.shuffletabsize, sizeof(uint), sg);
00125 frlewrite(w->itemids, (w->desc.itementries/32 + 1) * 4, 1, sg);
00126 frlewrite(w->plr.spellknowledge, sizeof(slong)*w->desc.numspells, sizeof(slong), sg);
00127 frlewrite(w->items.items, sizeof(item)*w->items.alloced, sizeof(item), sg);
00128 if(w->wandering_monsters_num)
00129 frlewrite(w->wandering_monsters, sizeof(monster)*w->wandering_monsters_num, sizeof(monster), sg);
00130 frleflush(sg);
00131 fhuffmanflush(sg);
00132 # ifdef IS_CALCULATOR
00133 fwrite(save_file_extension, 6, 1, sg);
00134 filesize = peek_w(sg->base);
00135 # endif
00136 frlefinalize(sg);
00137 fclose(sg);
00138 # ifdef IS_CALCULATOR
00139 if(w->options[OPTION_AUTOARCHIVE] == OPTION_ARCHIVE_YES)
00140 archive_file(SAVEFILENAME, filesize);
00141 # endif
00142 # ifdef EXTERNAL_COMPRESSOR
00143 sprintf(cmd, EXTERNAL_COMPRESSOR " -f -q %s", filename);
00144 system(cmd);
00145 # endif
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154 int restore_game(void)
00155 {
00156 FILE *fin;
00157
00158 #ifdef SHARED_SCORES
00159 char filename[512];
00160 sprintf(filename, "%s%s_%s", file_prefix, getlogin(), SAVEFILENAME);
00161 #else
00162 const char *filename = SAVEFILENAME;
00163 #endif
00164
00165 #ifdef EXTERNAL_COMPRESSOR
00166 system( retprintf(EXTERNAL_COMPRESSOR " -f -q -d %s.gz", filename) );
00167 #endif
00168
00169 fin = fopen( filename, "rb");
00170 if( fin )
00171 {
00172 if(!frleverify(fin))
00173 {
00174 message(gettext("There's a corrupted save file here..."));
00175 fclose(fin);
00176 read_char();
00177 return 0;
00178 }
00179 frleinit_read(fin);
00180 fhuffmaninit_read();
00181
00182 frleread(w, sizeof(world), sizeof(monster), fin);
00183 w->t = NULL;
00184 resize_map_store(w->mapsize_x, w->mapsize_y);
00185 frleread(&w->t[0][0], sizeof(tile)*w->mapsize_x*w->mapsize_y, sizeof(tile), fin);
00186 sys_init_data_file();
00187
00188 w->shuffletranslation = (uint*)debug_malloc( sizeof(uint) * w->desc.shuffletabsize );
00189 init_discoveries();
00190 w->items.items = (item*)debug_malloc(w->items.alloced*sizeof(item));
00191 init_spells();
00192
00193 frleread(w->shuffletranslation, sizeof(uint)*w->desc.shuffletabsize, sizeof(uint), fin);
00194 frleread(w->itemids, (w->desc.itementries/32 + 1) * 4, 1, fin);
00195 frleread(w->plr.spellknowledge, sizeof(slong)*w->desc.numspells, sizeof(slong), fin);
00196 frleread(w->items.items, sizeof(item)*w->items.alloced, sizeof(item), fin);
00197 if(w->wandering_monsters_num)
00198 {
00199 w->wandering_monsters = debug_malloc(sizeof(monster)*w->wandering_monsters_num);
00200 frleread(w->wandering_monsters, sizeof(monster)*w->wandering_monsters_num, sizeof(monster), fin);
00201 }
00202
00203 w->current_map = deref_file_ptr(w->current_map_link);
00204
00205 fclose(fin);
00206 #ifdef EXTERNAL_COMPRESSOR
00207
00208 system( retprintf(EXTERNAL_COMPRESSOR " -f -q %s", filename) );
00209 #endif
00210 return 1;
00211 } else {
00212 return 0;
00213 }
00214 }
00215
00216
00217 const uchar level_file_extension[6] = { 0,'L','E','V',0,0xf8 };
00218
00219
00220 const char *levelfile_name(int levelnum)
00221 {
00222 #ifdef IS_CALCULATOR
00223 return retprintf("ROGLVL%i", levelnum);
00224 #endif
00225 #ifdef REALCOMPUTER
00226 #ifdef SHARED_SCORES
00227 return retprintf("%s%s_roglvl%i.sav", file_prefix, getlogin(), levelnum);
00228 #else
00229 return retprintf("roglvl%i.sav", levelnum);
00230 #endif
00231 #endif
00232 #ifdef PALMOS
00233 return retprintf("roglvl%i", levelnum);
00234 #endif
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 void save_level(void)
00250 {
00251 FILE *save;
00252 const char *name;
00253 ushort map_size[2];
00254 # ifdef EXTERNAL_COMPRESSOR
00255 char cmd[512];
00256 # endif
00257 # ifdef IS_CALCULATOR
00258 int filesize;
00259 # endif
00260
00261 name = levelfile_name(w->level);
00262
00263 #ifdef IS_CALCULATOR
00264
00265 EM_moveSymFromExtMem(SYMSTR(name), HS_NULL);
00266 SymDel(SYMSTR(name));
00267 #endif
00268
00269
00270 compress_items();
00271 compress_monsters();
00272
00273 save = fopen(name, "wb");
00274
00275 frleinit_write(save, &fhuffmanputc);
00276 fhuffmaninit_write();
00277
00278 frlewrite( (char*)(&w->m[0]), sizeof(monster)*MONSTERS_MAX, sizeof(monster), save );
00279 map_size[0] = w->mapsize_x; map_size[1] = w->mapsize_y;
00280 frlewrite( (char*)(map_size), sizeof(ushort)*2, sizeof(ushort), save );
00281 frlewrite( (char*)(&w->t[0][0]), sizeof(tile)*MAPSIZE_X*MAPSIZE_Y, sizeof(tile), save );
00282
00283
00284 frlewrite(&w->items, sizeof(itemsinfo), 1, save);
00285 frlewrite(w->items.items, sizeof(item)*w->items.alloced, sizeof(item), save);
00286
00287 frleflush(save);
00288 fhuffmanflush(save);
00289
00290 # ifdef IS_CALCULATOR
00291 fwrite(level_file_extension, 6, 1, save);
00292 filesize = peek_w(save->base);
00293 # endif
00294 frlefinalize(save);
00295 fclose(save);
00296
00297 # ifdef EXTERNAL_COMPRESSOR
00298 sprintf(cmd, EXTERNAL_COMPRESSOR " -f -q %s", name);
00299 system(cmd);
00300 # endif
00301 # ifdef IS_CALCULATOR
00302 if(w->options[OPTION_AUTOARCHIVE] == OPTION_ARCHIVE_YES)
00303 archive_file(name, filesize);
00304 # endif
00305 }
00306
00307
00308
00309
00310
00311
00312 int load_level(int source, coord pos)
00313 {
00314 FILE *save;
00315 const char *name;
00316 ushort map_size[2];
00317 #ifdef EXTERNAL_COMPRESSOR
00318 char cmd[512];
00319 #endif
00320
00321 name = levelfile_name(w->level);
00322
00323 #ifdef EXTERNAL_COMPRESSOR
00324
00325 sprintf(cmd, "%s.gz", name);
00326 if(access(cmd, R_OK) != 0)
00327 return 0;
00328
00329
00330 sprintf(cmd, EXTERNAL_COMPRESSOR " -f -q -d %s.gz", name);
00331 system(cmd);
00332 #endif
00333
00334 save = fopen(name, "rb");
00335
00336 if( !save )
00337 return 0;
00338
00339 if(!frleverify(save))
00340 {
00341 message(gettext("This level is corrupt... I'll build a new one."));
00342 fclose(save);
00343 return 0;
00344 }
00345 frleinit_read(save);
00346 fhuffmaninit_read();
00347
00348 frleread( (char*)(&w->m[0]), sizeof(monster)*MONSTERS_MAX, sizeof(monster), save );
00349 frleread( (char*)(map_size), sizeof(ushort)*2, sizeof(ushort), save );
00350 resize_map_store(map_size[0], map_size[1]);
00351 frleread( (char*)(&w->t[0][0]), sizeof(tile)*MAPSIZE_X*MAPSIZE_Y, sizeof(tile), save );
00352
00353 place_player_on_map(source, pos);
00354
00355
00356 cleanup_items();
00357 frleread(&w->items, sizeof(itemsinfo), 1, save);
00358 w->items.items = (item*)debug_malloc(w->items.alloced*sizeof(item));
00359 frleread(w->items.items, sizeof(item)*w->items.alloced, sizeof(item), save);
00360
00361 fclose(save);
00362
00363 #ifdef EXTERNAL_COMPRESSOR
00364
00365 sprintf(cmd, EXTERNAL_COMPRESSOR " -f -q %s", name);
00366 system(cmd);
00367 #endif
00368
00369 full_redraw();
00370
00371 return 1;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380 void cleanup_save(void)
00381 {
00382 #ifdef IS_CALCULATOR
00383 int i;
00384 const char *name;
00385
00386 EM_moveSymFromExtMem(SYMSTR(SAVEFILENAME), HS_NULL);
00387 SymDel(SYMSTR(SAVEFILENAME));
00388
00389 for(i=1; i<=w->maxlevel; i++)
00390 {
00391 name = levelfile_name(i);
00392 EM_moveSymFromExtMem(SYMSTR(name), HS_NULL);
00393 SymDel(SYMSTR(name));
00394 }
00395 #else
00396 int i;
00397 const char *name;
00398 #ifdef SHARED_SCORES
00399 #ifdef EXTERNAL_COMPRESSOR
00400 name = retprintf("%s%s_%s.gz", file_prefix, getlogin(), SAVEFILENAME);
00401 #else
00402 name = retprintf("%s%s_%s", file_prefix, getlogin(), SAVEFILENAME);
00403 #endif
00404 #else
00405 name = SAVEFILENAME;
00406 #endif
00407
00408 remove(name);
00409
00410 for(i=1; i<=w->maxlevel+1; i++)
00411 {
00412 name = levelfile_name(i);
00413 remove(name);
00414 }
00415 #endif
00416 }
00417
00418
00419
00420 void compress_tiles(void)
00421 {
00422 int i, j;
00423
00424 for(i=0; i<MAPSIZE_Y; i++)
00425 for(j=0; j<MAPSIZE_X; j++)
00426 {
00427 w->t[i][j].flags &= ~TFLAG_LIT;
00428 }
00429 }
00430
00431