mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-10-26 03:17:39 +00:00
ads-game:: underlying/spacetime views
This commit is contained in:
163
rogueviz/ads/views.cpp
Normal file
163
rogueviz/ads/views.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
/* underlying/spacetime views, and also replaying */
|
||||
|
||||
namespace hr {
|
||||
|
||||
namespace ads_game {
|
||||
|
||||
hrmap *map_hyp;
|
||||
|
||||
bool hv_klein = false;
|
||||
|
||||
transmatrix Duality;
|
||||
|
||||
void switch_underlying() {
|
||||
clearMessages();
|
||||
|
||||
if(main_rock) {
|
||||
|
||||
if(sphere) {
|
||||
cgi.use_count++;
|
||||
geometry = gSpace435;
|
||||
variation = eVariation::pure;
|
||||
swap(currentmap, map_hyp);
|
||||
pmodel = hv_klein ? mdDisk : mdPerspective;
|
||||
if(hv_klein) pconf.alpha = 0;
|
||||
check_cgi();
|
||||
cgi.require_basics();
|
||||
cgi.use_count++;
|
||||
|
||||
initcells();
|
||||
initgame();
|
||||
nomap = false;
|
||||
}
|
||||
|
||||
else if(hyperbolic) {
|
||||
nomap = true;
|
||||
geometry = gSphere;
|
||||
variation = eVariation::bitruncated;
|
||||
swap(currentmap, map_hyp);
|
||||
pmodel = mdDisk;
|
||||
check_cgi();
|
||||
nomap = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
check_cgi();
|
||||
cgi.use_count++;
|
||||
if(hyperbolic) {
|
||||
hybrid::switch_to_actual();
|
||||
pmodel = mdRelPerspective;
|
||||
hyperpoint res;
|
||||
nomap = false;
|
||||
nonisotropic_weird_transforms = true;
|
||||
NLP = Id;
|
||||
/* Duality = Id;
|
||||
for(int a=0; a<4; a++) for(int b=0; b<4; b++) Duality[a][b] = (a^2) == b; */
|
||||
}
|
||||
|
||||
else if(hybri) {
|
||||
hybrid::switch_to_underlying();
|
||||
pmodel = mdDisk;
|
||||
nomap = true;
|
||||
}
|
||||
cgi.use_count++;
|
||||
}
|
||||
|
||||
View = Id;
|
||||
cwt = centerover = currentmap->gamestart();
|
||||
}
|
||||
|
||||
bool ads_draw_cell(cell *c, const shiftmatrix& V) {
|
||||
auto cur_w = hybrid::get_where(c);
|
||||
auto& ci = ci_at[cur_w.first];
|
||||
if(ci.type) {
|
||||
c->wall = waWaxWall;
|
||||
c->landparam =
|
||||
ci.type == wtSolid ? 0x603000 :
|
||||
ci.type == wtDestructible ? 0x301800 :
|
||||
0x080828;
|
||||
}
|
||||
else {
|
||||
c->wall = waNone;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void replay_animation() {
|
||||
if(in_replay) {
|
||||
view_pt = (ticks / 1000.) * DS_(simspeed);
|
||||
ld maxt = history.back().start + 0.001;
|
||||
view_pt -= maxt * floor(view_pt / maxt);
|
||||
for(auto& ss: history)
|
||||
if(ss.start + ss.duration > view_pt) {
|
||||
current = ss.current;
|
||||
if(main_rock) {
|
||||
dynamicval<eGeometry> g(geometry, gSpace435);
|
||||
current.T = inverse(ss.at.T * spin(-(ss.ang)*degree));
|
||||
current.T = lorentz(3, 2, view_pt - ss.start) * current.T;
|
||||
}
|
||||
else PIA({
|
||||
vctr = new_vctr = ss.vctr;
|
||||
vctrV = new_vctrV = ss.vctrV;
|
||||
current.T = cspin(3, 2, view_pt - ss.start) * current.T;
|
||||
if(auto_rotate)
|
||||
current.T = cspin(1, 0, view_pt - ss.start) * current.T;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(main_rock && hyperbolic) {
|
||||
View = Id;
|
||||
centerover = currentmap->gamestart();
|
||||
ld s = current.shift;
|
||||
while(s > +1) { View = lorentz(2, 3, -1) * View; optimizeview(); s--; }
|
||||
while(s < -1) { View = lorentz(2, 3, 1) * View; optimizeview(); s++; }
|
||||
View = current.T * lorentz(2, 3, -s) * View; optimizeview();
|
||||
centerover->wall = waNone;
|
||||
}
|
||||
|
||||
if(!main_rock && rotspace) {
|
||||
check_cgi();
|
||||
|
||||
ads_matrix CV = current * vctrV;
|
||||
centerover = hybrid::get_at(vctr, 0);
|
||||
|
||||
View = Id;
|
||||
|
||||
// chg_shift(CV.shift) * CV.T
|
||||
|
||||
auto sub_optimizeview = [&] {
|
||||
/* the important difference from optimizeview() is that we do not try to fix */
|
||||
transmatrix iView = inverse(View);
|
||||
virtualRebase(centerover, iView);
|
||||
View = inverse(iView);
|
||||
};
|
||||
|
||||
ld s = CV.shift;
|
||||
View = CV.T * View; optimizeview();
|
||||
while(s > 1) { View = chg_shift(1) * View; sub_optimizeview(); s--; }
|
||||
while(s < -1) { View = chg_shift(-1) * View; sub_optimizeview(); s++; }
|
||||
View = chg_shift(s) * View; sub_optimizeview();
|
||||
|
||||
centerover->wall = waNone;
|
||||
}
|
||||
}
|
||||
|
||||
void switch_replay() {
|
||||
in_replay = !in_replay;
|
||||
if(in_replay) {
|
||||
paused = true;
|
||||
anims::period = 1000. * history.back().start / DS_(simspeed);
|
||||
anims::noframes = anims::period * 60 / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
auto view_hooks =
|
||||
+ arg::add3("-ds-recenter", [] { current = Id; })
|
||||
+ arg::add3("-ds-record", switch_replay)
|
||||
+ arg::add3("-ds-switchu", switch_underlying);
|
||||
|
||||
}}
|
||||
Reference in New Issue
Block a user