1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-10-18 06:30:41 +00:00

nilrider:: RLE encode manual replays, also do not save headings offsurface

This commit is contained in:
Zeno Rogue 2024-08-20 14:45:09 +02:00
parent f29104db50
commit 4fcc12fe91
3 changed files with 58 additions and 19 deletions

View File

@ -502,15 +502,8 @@ void replays() {
dialog::init(XLAT(planning_mode ? "saved plans" : "replays"), 0xC0C0FFFF, 150, 100);
if(!planning_mode) replays_of_type(curlev->manual_replays, [] (manual_replay& r) {
view_replay = false;
curlev->history.clear();
auto& current = curlev->current;
current = curlev->start;
loaded_or_planned = true;
for(auto h: r.headings) {
current.heading_angle = int_to_heading(h);
curlev->history.push_back(current);
if(!current.tick(curlev)) break;
}
curlev->history = curlev->headings_to_history(r);
toggle_replay();
popScreen();
});
@ -556,12 +549,7 @@ void main_menu() {
#if CAP_SAVE
dialog::addItem("save the replay", 's');
dialog::add_action([] {
vector<int> ang;
for(auto& h: curlev->history) ang.push_back(heading_to_int(h.heading_angle));
curlev->manual_replays.emplace_back(manual_replay{new_replay_name(), my_scheme, std::move(ang)});
save();
});
dialog::add_action(save_manual_replay);
dialog::addItem("saved replays", 'l');
dialog::add_action(pop_and_push_replays);

View File

@ -91,7 +91,7 @@ struct triangledata {
struct manual_replay {
string name;
colorscheme cs;
vector<int> headings;
vector<pair<int, int>> headings;
};
struct plan_replay {
@ -245,7 +245,9 @@ struct level {
vector<level*> res; gen_layer_list(res); return res;
}
vector<timestamp> headings_to_history(manual_replay&);
void load_plan_as_ghost(plan_replay&);
void load_manual_as_ghost(manual_replay&);
};
/** wheel radius */

View File

@ -27,6 +27,7 @@ void save() {
}
}
println(f, "*COLORS\n");
println(f, "*RLE\n");
for(auto l: all_levels) {
for(auto& p: l->manual_replays) {
println(f, "*MANUAL");
@ -34,7 +35,7 @@ void save() {
println(f, p.name);
fprintf(f.f, "%08x %08x %08x %08x\n", p.cs.wheel1, p.cs.wheel2, p.cs.seat, p.cs.seatpost);
println(f, isize(p.headings));
for(auto t: p.headings) println(f, t);
for(auto t: p.headings) println(f, t.first, " ", t.second);
println(f);
}
for(auto& p: l->plan_replays) {
@ -68,9 +69,22 @@ colorscheme load_colors(fhstream& f, bool have_colors) {
}
}
vector<pair<int, int>> apply_rle(const vector<int>& data) {
vector<pair<int, int>> rle;
if(data.empty()) return rle;
int last = data[0], count = 0;
for(int v: data) {
if(v != last) { rle.emplace_back(count, last); count = 0; last = v; }
count++;
}
rle.emplace_back(count, last);
return rle;
}
void load() {
#if CAP_SAVE
bool have_colors = false;
bool have_rle = false;
println(hlog, "load called");
fhstream f("nilrider.save", "rt");
if(!f.f) return;
@ -78,15 +92,25 @@ void load() {
while(!feof(f.f)) {
string s = scanline_noblank(f);
if(s == "") continue;
if(s == "*COLORS") { have_colors = true; }
if(s == "*COLORS") { have_colors = true; continue; }
if(s == "*RLE") { have_rle = true; continue; }
if(s == "*MANUAL") {
string lev = scanline_noblank(f);
string name = scanline_noblank(f);
colorscheme cs = load_colors(f, have_colors);
vector<int> headings;
vector<pair<int, int>> headings;
int size = scan<int> (f);
if(size < 0 || size > 1000000) throw hstream_exception();
for(int i=0; i<size; i++) headings.push_back(scan<int>(f));
if(have_rle) {
println(hlog, "reading a RLE replay");
for(int i=0; i<size; i++) { int rep = scan<int>(f); headings.emplace_back(rep, scan<int>(f)); }
}
else {
vector<int> h;
for(int i=0; i<size; i++) h.emplace_back(scan<int>(f));
headings = apply_rle(h);
println(hlog, "converted ", isize(h), " to ", isize(headings));
}
auto l = level_by_name(lev);
if(l) l->manual_replays.emplace_back(manual_replay{name, cs, std::move(headings)});
continue;
@ -143,4 +167,29 @@ void level::load_plan_as_ghost(plan_replay& r) {
swap(r.plan, plan);
}
vector<timestamp> level::headings_to_history(manual_replay& r) {
vector<timestamp> history;
timestamp cur = start;
for(auto [qty, h]: r.headings) {
println(hlog, "pair: ", tie(qty, h));
for(int i=0; i<qty; i++) {
cur.heading_angle = int_to_heading(h);
history.push_back(cur);
if(!cur.tick(this)) return history;
}
}
return history;
}
void level::load_manual_as_ghost(manual_replay& r) {
ghosts.emplace_back(ghost{r.cs, headings_to_history(r) });
}
void save_manual_replay() {
vector<int> ang;
for(auto& h: curlev->history) ang.push_back(h.on_surface ? heading_to_int(h.heading_angle) : 0);
curlev->manual_replays.emplace_back(manual_replay{new_replay_name(), my_scheme, apply_rle(ang)});
save();
}
}