replay: introduce REPLAY_STRUCT_VERSION_TS104000_REV1
* Use zstd instead of zlib compression * Remove plr_focus field * Add skip_frames field for demos
This commit is contained in:
parent
e74c3f60ea
commit
eede63333a
8 changed files with 143 additions and 54 deletions
|
@ -12,7 +12,6 @@
|
|||
#include "rw_common.h"
|
||||
|
||||
#include "player.h"
|
||||
#include "rwops/rwops_zlib.h"
|
||||
#include "rwops/rwops_segment.h"
|
||||
|
||||
#ifdef REPLAY_LOAD_DEBUG
|
||||
|
@ -78,6 +77,7 @@ static bool replay_read_header(Replay *rpy, SDL_RWops *file, int64_t filesize, s
|
|||
case REPLAY_STRUCT_VERSION_TS103000_REV2:
|
||||
case REPLAY_STRUCT_VERSION_TS103000_REV3:
|
||||
case REPLAY_STRUCT_VERSION_TS104000_REV0:
|
||||
case REPLAY_STRUCT_VERSION_TS104000_REV1:
|
||||
{
|
||||
if(taisei_version_read(file, &rpy->game_version) != TAISEI_VERSION_SIZE) {
|
||||
log_error("%s: Failed to read game version", source);
|
||||
|
@ -149,21 +149,35 @@ static bool replay_read_meta(Replay *rpy, SDL_RWops *file, int64_t filesize, con
|
|||
|
||||
CHECKPROP(stg->diff = SDL_ReadU8(file), u);
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
CHECKPROP(stg->skip_frames = SDL_ReadLE16(file), u);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS103000_REV0) {
|
||||
CHECKPROP(stg->plr_points = SDL_ReadLE64(file), zu);
|
||||
} else {
|
||||
CHECKPROP(stg->plr_points = SDL_ReadLE32(file), zu);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
CHECKPROP(stg->plr_total_lives_used = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_total_bombs_used = SDL_ReadU8(file), u);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) {
|
||||
CHECKPROP(stg->plr_continues_used = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_total_continues_used = SDL_ReadU8(file), u);
|
||||
}
|
||||
|
||||
CHECKPROP(stg->plr_char = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_shot = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_pos_x = SDL_ReadLE16(file), u);
|
||||
CHECKPROP(stg->plr_pos_y = SDL_ReadLE16(file), u);
|
||||
CHECKPROP(stg->plr_focus = SDL_ReadU8(file), u); // FIXME remove and bump version
|
||||
|
||||
if(version <= REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
// NOTE: old plr_focus field, ignored
|
||||
SDL_ReadU8(file);
|
||||
}
|
||||
|
||||
CHECKPROP(stg->plr_power = SDL_ReadLE16(file), u);
|
||||
CHECKPROP(stg->plr_lives = SDL_ReadU8(file), u);
|
||||
|
||||
|
@ -195,12 +209,16 @@ static bool replay_read_meta(Replay *rpy, SDL_RWops *file, int64_t filesize, con
|
|||
CHECKPROP(stg->plr_points_final = SDL_ReadLE64(file), zu);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
CHECKPROP(stg->plr_stats_total_lives_used = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_stats_stage_lives_used = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_stats_total_bombs_used = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_stats_stage_bombs_used = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_stats_stage_continues_used = SDL_ReadU8(file), u);
|
||||
if(version == REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
// NOTE: These fields were always bugged, so we ignore them
|
||||
uint8_t junk[5];
|
||||
SDL_RWread(file, junk, sizeof(junk), 1);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
CHECKPROP(stg->plr_stage_lives_used_final = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_stage_bombs_used_final = SDL_ReadU8(file), u);
|
||||
CHECKPROP(stg->plr_stage_continues_used_final = SDL_ReadU8(file), u);
|
||||
}
|
||||
|
||||
CHECKPROP(stg->num_events = SDL_ReadLE16(file), u);
|
||||
|
@ -283,9 +301,9 @@ bool replay_read(Replay *rpy, SDL_RWops *file, ReplayReadMode mode, const char *
|
|||
return false;
|
||||
}
|
||||
|
||||
vfile = SDL_RWWrapZlibReader(
|
||||
vfile = replay_wrap_stream_decompress(
|
||||
rpy->version,
|
||||
SDL_RWWrapSegment(file, ofs, rpy->fileoffset, false),
|
||||
REPLAY_COMPRESSION_CHUNK_SIZE,
|
||||
true
|
||||
);
|
||||
|
||||
|
@ -332,7 +350,7 @@ bool replay_read(Replay *rpy, SDL_RWops *file, ReplayReadMode mode, const char *
|
|||
bool compression = false;
|
||||
|
||||
if(rpy->version & REPLAY_VERSION_COMPRESSION_BIT) {
|
||||
vfile = SDL_RWWrapZlibReader(file, REPLAY_COMPRESSION_CHUNK_SIZE, false);
|
||||
vfile = replay_wrap_stream_decompress(rpy->version, file, false);
|
||||
filesize = -1;
|
||||
compression = true;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "taisei.h"
|
||||
|
||||
#include "rw_common.h"
|
||||
#include "rwops/rwops_zlib.h"
|
||||
#include "rwops/rwops_zstd.h"
|
||||
|
||||
uint8_t replay_magic_header[REPLAY_MAGIC_HEADER_SIZE] = REPLAY_MAGIC_HEADER;
|
||||
|
||||
|
@ -18,12 +20,16 @@ uint32_t replay_struct_stage_metadata_checksum(ReplayStage *stg, uint16_t versio
|
|||
cs += stg->stage;
|
||||
cs += stg->rng_seed;
|
||||
cs += stg->diff;
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
cs += stg->skip_frames;
|
||||
}
|
||||
|
||||
cs += stg->plr_points;
|
||||
cs += stg->plr_char;
|
||||
cs += stg->plr_shot;
|
||||
cs += stg->plr_pos_x;
|
||||
cs += stg->plr_pos_y;
|
||||
cs += stg->plr_focus; // FIXME remove and bump version
|
||||
cs += stg->plr_power;
|
||||
cs += stg->plr_lives;
|
||||
cs += stg->plr_life_fragments;
|
||||
|
@ -37,8 +43,13 @@ uint32_t replay_struct_stage_metadata_checksum(ReplayStage *stg, uint16_t versio
|
|||
cs += stg->num_events;
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
cs += stg->plr_total_lives_used;
|
||||
cs += stg->plr_total_continues_used;
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) {
|
||||
cs += stg->plr_continues_used;
|
||||
cs += stg->plr_total_continues_used;
|
||||
cs += stg->flags;
|
||||
}
|
||||
|
||||
|
@ -54,14 +65,23 @@ uint32_t replay_struct_stage_metadata_checksum(ReplayStage *stg, uint16_t versio
|
|||
cs += stg->plr_points_final;
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
cs += stg->plr_stats_total_lives_used;
|
||||
cs += stg->plr_stats_stage_lives_used;
|
||||
cs += stg->plr_stats_total_bombs_used;
|
||||
cs += stg->plr_stats_stage_bombs_used;
|
||||
cs += stg->plr_stats_stage_continues_used;
|
||||
}
|
||||
|
||||
log_debug("%08x", cs);
|
||||
return cs;
|
||||
}
|
||||
|
||||
SDL_RWops *replay_wrap_stream_compress(uint16_t version, SDL_RWops *rw, bool autoclose) {
|
||||
if((version & ~REPLAY_VERSION_COMPRESSION_BIT) >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
return SDL_RWWrapZstdWriter(rw, 22, autoclose);
|
||||
} else {
|
||||
return SDL_RWWrapZlibWriter(
|
||||
rw, RW_DEFLATE_LEVEL_DEFAULT, REPLAY_COMPRESSION_CHUNK_SIZE, autoclose);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RWops *replay_wrap_stream_decompress(uint16_t version, SDL_RWops *rw, bool autoclose) {
|
||||
if((version & ~REPLAY_VERSION_COMPRESSION_BIT) >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
return SDL_RWWrapZstdReader(rw, autoclose);
|
||||
} else {
|
||||
return SDL_RWWrapZlibReader(rw, REPLAY_COMPRESSION_CHUNK_SIZE, autoclose);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,4 +13,7 @@
|
|||
|
||||
uint32_t replay_struct_stage_metadata_checksum(ReplayStage *stg, uint16_t version);
|
||||
|
||||
SDL_RWops *replay_wrap_stream_compress(uint16_t version, SDL_RWops *rw, bool autoclose);
|
||||
SDL_RWops *replay_wrap_stream_decompress(uint16_t version, SDL_RWops *rw, bool autoclose);
|
||||
|
||||
extern uint8_t replay_magic_header[REPLAY_MAGIC_HEADER_SIZE];
|
||||
|
|
|
@ -29,8 +29,9 @@ ReplayStage *replay_stage_new(Replay *rpy, StageInfo *stage, uint64_t start_time
|
|||
s->plr_pos_y = floor(cimag(plr->pos));
|
||||
|
||||
s->plr_points = plr->points;
|
||||
s->plr_continues_used = plr->stats.total.continues_used;
|
||||
// s->plr_focus = plr->focus; FIXME remove and bump version
|
||||
s->plr_total_lives_used = plr->stats.total.lives_used;
|
||||
s->plr_total_bombs_used = plr->stats.total.bombs_used;
|
||||
s->plr_total_continues_used = plr->stats.total.continues_used;
|
||||
s->plr_char = plr->mode->character->id;
|
||||
s->plr_shot = plr->mode->shot_mode;
|
||||
s->plr_lives = plr->lives;
|
||||
|
@ -48,10 +49,11 @@ ReplayStage *replay_stage_new(Replay *rpy, StageInfo *stage, uint64_t start_time
|
|||
|
||||
void replay_stage_sync_player_state(ReplayStage *stg, Player *plr) {
|
||||
plr->points = stg->plr_points;
|
||||
plr->stats.total.continues_used = stg->plr_continues_used;
|
||||
plr->stats.total.lives_used = stg->plr_total_lives_used;
|
||||
plr->stats.total.bombs_used = stg->plr_total_bombs_used;
|
||||
plr->stats.total.continues_used = stg->plr_total_continues_used;
|
||||
plr->mode = plrmode_find(stg->plr_char, stg->plr_shot);
|
||||
plr->pos = stg->plr_pos_x + I * stg->plr_pos_y;
|
||||
// plr->focus = stg->plr_focus; FIXME remove and bump version
|
||||
plr->lives = stg->plr_lives;
|
||||
plr->life_fragments = stg->plr_life_fragments;
|
||||
plr->bombs = stg->plr_bombs;
|
||||
|
@ -60,12 +62,12 @@ void replay_stage_sync_player_state(ReplayStage *stg, Player *plr) {
|
|||
plr->graze = stg->plr_graze;
|
||||
plr->point_item_value = stg->plr_point_item_value;
|
||||
plr->inputflags = stg->plr_inputflags;
|
||||
}
|
||||
|
||||
plr->stats.total.lives_used = stg->plr_stats_total_lives_used;
|
||||
plr->stats.stage.lives_used = stg->plr_stats_stage_lives_used;
|
||||
plr->stats.total.bombs_used = stg->plr_stats_total_bombs_used;
|
||||
plr->stats.stage.bombs_used = stg->plr_stats_stage_bombs_used;
|
||||
plr->stats.stage.continues_used = stg->plr_stats_stage_continues_used;
|
||||
void replay_stage_update_final_stats(ReplayStage *stg, const Stats *stats) {
|
||||
stg->plr_stage_lives_used_final = stats->stage.lives_used;
|
||||
stg->plr_stage_bombs_used_final = stats->stage.bombs_used;
|
||||
stg->plr_stage_continues_used_final = stats->stage.continues_used;
|
||||
}
|
||||
|
||||
void replay_stage_event(ReplayStage *stg, uint32_t frame, uint8_t type, uint16_t value) {
|
||||
|
|
|
@ -29,5 +29,8 @@ void replay_stage_event(ReplayStage *stg, uint32_t frame, uint8_t type, uint16_t
|
|||
void replay_stage_sync_player_state(ReplayStage *stg, Player *plr)
|
||||
attr_nonnull_all;
|
||||
|
||||
void replay_stage_update_final_stats(ReplayStage *stg, const Stats *stats)
|
||||
attr_nonnull_all;
|
||||
|
||||
void replay_stage_destroy_events(ReplayStage *stg)
|
||||
attr_nonnull_all;
|
||||
|
|
|
@ -52,13 +52,17 @@
|
|||
|
||||
// Taisei v1.4 revision 0: add statistics for player
|
||||
#define REPLAY_STRUCT_VERSION_TS104000_REV0 13
|
||||
|
||||
// Taisei v1.4 revision 1: switch to zstd compression, remove plr_focus, add skip_frames (for demos), rework/fix player resource usage stats
|
||||
#define REPLAY_STRUCT_VERSION_TS104000_REV1 14
|
||||
/* END supported struct versions */
|
||||
|
||||
#define REPLAY_VERSION_COMPRESSION_BIT 0x8000
|
||||
#define REPLAY_COMPRESSION_CHUNK_SIZE 4096
|
||||
|
||||
// What struct version to use when saving recorded replays
|
||||
#define REPLAY_STRUCT_VERSION_WRITE (REPLAY_STRUCT_VERSION_TS104000_REV0 | REPLAY_VERSION_COMPRESSION_BIT)
|
||||
#define REPLAY_STRUCT_VERSION_WRITE \
|
||||
(REPLAY_STRUCT_VERSION_TS104000_REV1 | REPLAY_VERSION_COMPRESSION_BIT)
|
||||
|
||||
#define REPLAY_ALLOC_INITIAL 256
|
||||
|
||||
|
@ -95,17 +99,27 @@ typedef struct ReplayStage {
|
|||
/* END REPLAY_STRUCT_VERSION_TS103000_REV2 and above */
|
||||
uint64_t rng_seed; // NOTE: before REPLAY_STRUCT_VERSION_TS103000_REV2: uint32_t, also specifies start_time
|
||||
uint8_t diff;
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS104000_REV1 and above */
|
||||
uint16_t skip_frames;
|
||||
/* END REPLAY_STRUCT_VERSION_TS104000_REV1 and above */
|
||||
|
||||
// initial player settings
|
||||
uint64_t plr_points; // NOTE: before REPLAY_STRUCT_VERSION_TS103000_REV0: uint32_t
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS104000_REV1 and above */
|
||||
uint8_t plr_total_lives_used;
|
||||
uint8_t plr_total_bombs_used;
|
||||
/* END REPLAY_STRUCT_VERSION_TS104000_REV1 and above */
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS102000_REV1 and above */
|
||||
uint8_t plr_continues_used;
|
||||
uint8_t plr_total_continues_used;
|
||||
/* END REPLAY_STRUCT_VERSION_TS102000_REV1 and above */
|
||||
uint8_t plr_char;
|
||||
uint8_t plr_shot;
|
||||
uint16_t plr_pos_x;
|
||||
uint16_t plr_pos_y;
|
||||
uint8_t plr_focus;
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS104000_REV0 and below */
|
||||
// NOTE: Not used anymore
|
||||
// uint8_t plr_focus;
|
||||
/* END REPLAY_STRUCT_VERSION_TS104000_REV0 and below */
|
||||
uint16_t plr_power;
|
||||
uint8_t plr_lives;
|
||||
uint16_t plr_life_fragments; // NOTE: before REPLAY_STRUCT_VERSION_TS103000_REV1: uint8_t
|
||||
|
@ -124,13 +138,21 @@ typedef struct ReplayStage {
|
|||
uint64_t plr_points_final;
|
||||
/* END REPLAY_STRUCT_VERSION_TS102000_REV3 and above */
|
||||
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS104000_REV0 and above */
|
||||
uint8_t plr_stats_total_lives_used;
|
||||
uint8_t plr_stats_stage_lives_used;
|
||||
uint8_t plr_stats_total_bombs_used;
|
||||
uint8_t plr_stats_stage_bombs_used;
|
||||
uint8_t plr_stats_stage_continues_used;
|
||||
/* END REPLAY_STRUCT_VERSION_TS104000_REV0 and above */
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS104000_REV0 only */
|
||||
// NOTE: These never worked correctly and were always 0
|
||||
// uint8_t plr_stats_total_lives_used;
|
||||
// uint8_t plr_stats_stage_lives_used;
|
||||
// uint8_t plr_stats_total_bombs_used;
|
||||
// uint8_t plr_stats_stage_bombs_used;
|
||||
// uint8_t plr_stats_stage_continues_used;
|
||||
/* END REPLAY_STRUCT_VERSION_TS104000_REV0 only */
|
||||
|
||||
/* BEGIN REPLAY_STRUCT_VERSION_TS104000_REV1 and above */
|
||||
// Resources used in this stage by the end of it
|
||||
uint8_t plr_stage_lives_used_final;
|
||||
uint8_t plr_stage_bombs_used_final;
|
||||
uint8_t plr_stage_continues_used_final;
|
||||
/* END REPLAY_STRUCT_VERSION_TS104000_REV1 and above */
|
||||
|
||||
// player input
|
||||
// NOTE: only used to read the number of events from file.
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "rw_common.h"
|
||||
|
||||
#include "rwops/rwops_autobuf.h"
|
||||
#include "rwops/rwops_zlib.h"
|
||||
|
||||
attr_nonnull_all
|
||||
static void replay_write_string(SDL_RWops *file, char *str, uint16_t version) {
|
||||
|
@ -44,13 +43,29 @@ static bool replay_write_stage(ReplayStage *stg, SDL_RWops *file, uint16_t versi
|
|||
SDL_WriteLE64(file, stg->start_time);
|
||||
SDL_WriteLE64(file, stg->rng_seed);
|
||||
SDL_WriteU8(file, stg->diff);
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
SDL_WriteLE16(file, stg->skip_frames);
|
||||
}
|
||||
|
||||
SDL_WriteLE64(file, stg->plr_points);
|
||||
SDL_WriteU8(file, stg->plr_continues_used);
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
SDL_WriteU8(file, stg->plr_total_lives_used);
|
||||
SDL_WriteU8(file, stg->plr_total_bombs_used);
|
||||
}
|
||||
|
||||
SDL_WriteU8(file, stg->plr_total_continues_used);
|
||||
SDL_WriteU8(file, stg->plr_char);
|
||||
SDL_WriteU8(file, stg->plr_shot);
|
||||
SDL_WriteLE16(file, stg->plr_pos_x);
|
||||
SDL_WriteLE16(file, stg->plr_pos_y);
|
||||
SDL_WriteU8(file, stg->plr_focus); // FIXME remove and bump version
|
||||
|
||||
if(version <= REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
// NOTE: old plr_focus field
|
||||
SDL_WriteU8(file, 0);
|
||||
}
|
||||
|
||||
SDL_WriteLE16(file, stg->plr_power);
|
||||
SDL_WriteU8(file, stg->plr_lives);
|
||||
SDL_WriteLE16(file, stg->plr_life_fragments);
|
||||
|
@ -64,12 +79,16 @@ static bool replay_write_stage(ReplayStage *stg, SDL_RWops *file, uint16_t versi
|
|||
SDL_WriteLE64(file, stg->plr_points_final);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
SDL_WriteU8(file, stg->plr_stats_total_lives_used);
|
||||
SDL_WriteU8(file, stg->plr_stats_stage_lives_used);
|
||||
SDL_WriteU8(file, stg->plr_stats_total_bombs_used);
|
||||
SDL_WriteU8(file, stg->plr_stats_stage_bombs_used);
|
||||
SDL_WriteU8(file, stg->plr_stats_stage_continues_used);
|
||||
if(version == REPLAY_STRUCT_VERSION_TS104000_REV0) {
|
||||
// NOTE: These fields were always bugged; older taisei only wrote zeroes here.
|
||||
uint8_t buf[5] = { 0 };
|
||||
SDL_RWwrite(file, buf, sizeof(buf), 1);
|
||||
}
|
||||
|
||||
if(version >= REPLAY_STRUCT_VERSION_TS104000_REV1) {
|
||||
SDL_WriteU8(file, stg->plr_stage_lives_used_final);
|
||||
SDL_WriteU8(file, stg->plr_stage_bombs_used_final);
|
||||
SDL_WriteU8(file, stg->plr_stage_continues_used_final);
|
||||
}
|
||||
|
||||
if(stg->events.num_elements > UINT16_MAX) {
|
||||
|
@ -122,9 +141,7 @@ bool replay_write(Replay *rpy, SDL_RWops *file, uint16_t version) {
|
|||
|
||||
if(compression) {
|
||||
abuf = SDL_RWAutoBuffer(&buf, 64);
|
||||
vfile = SDL_RWWrapZlibWriter(
|
||||
abuf, RW_DEFLATE_LEVEL_DEFAULT, REPLAY_COMPRESSION_CHUNK_SIZE, false
|
||||
);
|
||||
vfile = replay_wrap_stream_compress(version, abuf, false);
|
||||
}
|
||||
|
||||
replay_write_string(vfile, rpy->playername, base_version);
|
||||
|
@ -149,7 +166,7 @@ bool replay_write(Replay *rpy, SDL_RWops *file, uint16_t version) {
|
|||
SDL_WriteLE32(file, SDL_RWtell(file) + SDL_RWtell(abuf) + 4);
|
||||
SDL_RWwrite(file, buf, SDL_RWtell(abuf), 1);
|
||||
SDL_RWclose(abuf);
|
||||
vfile = SDL_RWWrapZlibWriter(file, RW_DEFLATE_LEVEL_DEFAULT, REPLAY_COMPRESSION_CHUNK_SIZE, false);
|
||||
vfile = replay_wrap_stream_compress(version, file, false);
|
||||
}
|
||||
|
||||
bool events_ok = replay_write_events(rpy, vfile);
|
||||
|
|
|
@ -341,7 +341,9 @@ static Replay *create_quicksave_replay(ReplayStage *rstg_src) {
|
|||
|
||||
dynarray_ensure_capacity(&rstg->events, rstg_src->events.num_elements + 1);
|
||||
dynarray_set_elements(&rstg->events, rstg_src->events.num_elements, rstg_src->events.data);
|
||||
|
||||
replay_stage_event(rstg, global.frames, EV_RESUME, 0);
|
||||
replay_stage_update_final_stats(rstg, &global.plr.stats);
|
||||
|
||||
auto rpy = ALLOC(Replay);
|
||||
rpy->stages.num_elements = rpy->stages.capacity = 1;
|
||||
|
@ -1193,6 +1195,8 @@ void stage_end_loop(void *ctx) {
|
|||
if(global.gameover == GAMEOVER_WIN) {
|
||||
global.replay.output.stage->flags |= REPLAY_SFLAG_CLEAR;
|
||||
}
|
||||
|
||||
replay_stage_update_final_stats(global.replay.output.stage, &global.plr.stats);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue