int replay_write(Replay *rpy, FILE *file) { int i, j; // header replay_write_int(file, REPLAY_MAGICNUMBER); replay_write_string(file, tconfig.strval[PLAYERNAME]); replay_write_string(file, "Get out of here, you nasty cheater!"); replay_write_int(file, rpy->stgcount); for(j = 0; j < rpy->stgcount; ++j) { ReplayStage *stg = &(rpy->stages[j]); // initial game settings replay_write_int(file, stg->stage); replay_write_int(file, stg->seed); replay_write_int(file, stg->diff); replay_write_int(file, stg->points); // initial player settings replay_write_int(file, stg->plr_char); replay_write_int(file, stg->plr_shot); replay_write_complex(file, stg->plr_pos); replay_write_int(file, stg->plr_focus); replay_write_int(file, stg->plr_fire); replay_write_double(file, stg->plr_power); replay_write_int(file, stg->plr_lifes); replay_write_int(file, stg->plr_bombs); replay_write_int(file, stg->plr_mflags); // events replay_write_int(file, stg->ecount); for(i = 0; i < stg->ecount; ++i) { ReplayEvent *e = &(stg->events[i]); replay_write_int(file, e->frame); replay_write_int(file, e->type); replay_write_int(file, e->key); } } return True; }
bool replay_write(Replay *rpy, SDL_RWops *file, uint16_t version) { uint16_t base_version = (version & ~REPLAY_VERSION_COMPRESSION_BIT); bool compression = (version & REPLAY_VERSION_COMPRESSION_BIT); int i, j; SDL_RWwrite(file, replay_magic_header, sizeof(replay_magic_header), 1); SDL_WriteLE16(file, version); if(base_version >= REPLAY_STRUCT_VERSION_TS102000_REV0) { TaiseiVersion v; TAISEI_VERSION_GET_CURRENT(&v); if(taisei_version_write(file, &v) != TAISEI_VERSION_SIZE) { log_warn("Failed to write game version: %s", SDL_GetError()); return false; } } void *buf; SDL_RWops *abuf = NULL; SDL_RWops *vfile = file; if(compression) { abuf = SDL_RWAutoBuffer(&buf, 64); vfile = SDL_RWWrapZWriter(abuf, REPLAY_COMPRESSION_CHUNK_SIZE, false); } replay_write_string(vfile, config_get_str(CONFIG_PLAYERNAME), base_version); fix_flags(rpy); if(base_version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { SDL_WriteLE32(vfile, rpy->flags); } SDL_WriteLE16(vfile, rpy->numstages); for(i = 0; i < rpy->numstages; ++i) { if(!replay_write_stage(rpy->stages + i, vfile, base_version)) { if(compression) { SDL_RWclose(vfile); SDL_RWclose(abuf); } return false; } } if(compression) { SDL_RWclose(vfile); SDL_WriteLE32(file, SDL_RWtell(file) + SDL_RWtell(abuf) + 4); SDL_RWwrite(file, buf, SDL_RWtell(abuf), 1); SDL_RWclose(abuf); vfile = SDL_RWWrapZWriter(file, REPLAY_COMPRESSION_CHUNK_SIZE, false); } for(i = 0; i < rpy->numstages; ++i) { ReplayStage *stg = rpy->stages + i; for(j = 0; j < stg->numevents; ++j) { if(!replay_write_stage_event(stg->events + j, vfile)) { if(compression) { SDL_RWclose(vfile); } return false; } } } if(compression) { SDL_RWclose(vfile); } // useless byte to simplify the premature EOF check, can be anything SDL_WriteU8(file, REPLAY_USELESS_BYTE); return true; }