mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-23 15:36:59 +00:00
nilrider:: RLE encode manual replays, also do not save headings offsurface
This commit is contained in:
parent
f29104db50
commit
4fcc12fe91
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user