diff --git a/src/demo.c b/src/demo.c index f667c90..2210e3c 100644 --- a/src/demo.c +++ b/src/demo.c @@ -53,7 +53,12 @@ static inline void _sar_data_free(struct sar_data data) { free(data.speedrun_time.splits[i].name); free(data.speedrun_time.splits[i].segs); } + for (size_t i = 0; i < data.speedrun_time.nrules; ++i) { + free(data.speedrun_time.rules[i].name); + free(data.speedrun_time.rules[i].data); + } free(data.speedrun_time.splits); + if (data.speedrun_time.rules) free(data.speedrun_time.rules); break; case SAR_DATA_FILE_CHECKSUM: @@ -310,6 +315,42 @@ static int _parse_sar_data(struct sar_data *out, FILE *f, size_t len) { } } + out->speedrun_time.nrules = 0; + out->speedrun_time.rules = NULL; + + if (data > data_orig + len - 1) { + fprintf(g_errfile, "[SAR] Speedrun time data length mismatch %zu %zu\n", data - data_orig, len - 1); + out->type = SAR_DATA_INVALID; + break; + } + + if (data == data_orig + len - 1) { + break; + } + + size_t rule_ver = _read_u32(data); + data += 4; + switch (rule_ver) { + case 1: + out->speedrun_time.nrules = _read_u32(data); + data += 4; + + out->speedrun_time.rules = malloc(out->speedrun_time.nrules * sizeof out->speedrun_time.rules[0]); + + for (size_t i = 0; i < out->speedrun_time.nrules; ++i) { + out->speedrun_time.rules[i].name = strdup((char *)data); + data += strlen(out->speedrun_time.rules[i].name) + 1; + + out->speedrun_time.rules[i].data = strdup((char *)data); + data += strlen(out->speedrun_time.rules[i].data) + 1; + } + break; + default: + fprintf(g_errfile, "[SAR] Unhandled speedrun time rule version %zu\n", rule_ver); + out->type = SAR_DATA_INVALID; + break; + } + if (data != data_orig + len - 1) { fprintf(g_errfile, "[SAR] Speedrun time data length mismatch %zu %zu\n", data - data_orig, len - 1); out->type = SAR_DATA_INVALID; diff --git a/src/demo.h b/src/demo.h index af1bb22..6d75947 100644 --- a/src/demo.h +++ b/src/demo.h @@ -102,6 +102,11 @@ struct sar_data { int ticks; } *segs; } *splits; + size_t nrules; + struct { + char *name; + char *data; + } *rules; } speedrun_time; struct { diff --git a/src/main.c b/src/main.c index 34dde08..4d73343 100644 --- a/src/main.c +++ b/src/main.c @@ -131,6 +131,12 @@ static void _output_sar_data(struct demo *demo, uint32_t tick, struct sar_data d ticks += data.speedrun_time.splits[i].segs[j].ticks; } } + if (data.speedrun_time.nrules > 0) { + fprintf(g_outfile, "\t\t\tRules:\n"); + for (size_t i = 0; i < data.speedrun_time.nrules; ++i) { + fprintf(g_outfile, "\t\t\t\t%s = %s\n", data.speedrun_time.rules[i].name, data.speedrun_time.rules[i].data); + } + } size_t total = roundf((float)(ticks * 1000) / demo->tickrate);