mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 22:12:59 +00:00 
			
		
		
		
	ads-game:: underlying/spacetime views
This commit is contained in:
		| @@ -39,6 +39,7 @@ namespace rogueviz { std::vector<hr::reaction_t> cleanup; } | |||||||
| #include "menu.cpp" | #include "menu.cpp" | ||||||
| #include "ds-game.cpp" | #include "ds-game.cpp" | ||||||
| #include "ds-texture.cpp" | #include "ds-texture.cpp" | ||||||
|  | #include "underlying.cpp" | ||||||
|  |  | ||||||
| namespace hr { | namespace hr { | ||||||
|  |  | ||||||
| @@ -101,6 +102,7 @@ void run_ads_game() { | |||||||
|   rogueviz::rv_hook(hooks_frame, 100, view_ads_game); |   rogueviz::rv_hook(hooks_frame, 100, view_ads_game); | ||||||
|   rogueviz::rv_hook(hooks_prestats, 100, display_rsrc); |   rogueviz::rv_hook(hooks_prestats, 100, display_rsrc); | ||||||
|   rogueviz::rv_hook(hooks_handleKey, 0, handleKey); |   rogueviz::rv_hook(hooks_handleKey, 0, handleKey); | ||||||
|  |   rogueviz::rv_hook(hooks_drawcell, 0, ads_draw_cell); | ||||||
|   rogueviz::rv_hook(shmup::hooks_turn, 0, ads_turn); |   rogueviz::rv_hook(shmup::hooks_turn, 0, ads_turn); | ||||||
|   rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation); |   rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation); | ||||||
|    |    | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ struct cell_to_draw { | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
| void draw_game_cell(const cell_to_draw& cd) { | void draw_game_cell(const cell_to_draw& cd) { | ||||||
|  |   bool hv = rotspace; | ||||||
|   using cellptr = cell*; |   using cellptr = cell*; | ||||||
|   const cellptr& c = cd.c; |   const cellptr& c = cd.c; | ||||||
|   const ads_matrix& V = cd.V; |   const ads_matrix& V = cd.V; | ||||||
| @@ -36,12 +36,15 @@ void draw_game_cell(const cell_to_draw& cd) { | |||||||
|     if(!gen_budget) return; |     if(!gen_budget) return; | ||||||
|     gen_budget--; |     gen_budget--; | ||||||
|     } |     } | ||||||
|  |   PIU({ | ||||||
|     gen_terrain(c, ci); |     gen_terrain(c, ci); | ||||||
|     gen_rocks(c, ci, 0); |     gen_rocks(c, ci, 0); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|   auto& t = ci.type; |   auto& t = ci.type; | ||||||
|  |  | ||||||
|   if(t == wtGate) { |   if(hv) ; | ||||||
|  |   else if(t == wtGate) { | ||||||
|     ld minv = hlist[0].shift; |     ld minv = hlist[0].shift; | ||||||
|     ld maxv = hlist[0].shift; |     ld maxv = hlist[0].shift; | ||||||
|     for(auto& h: hlist) { |     for(auto& h: hlist) { | ||||||
| @@ -121,12 +124,27 @@ void draw_game_cell(const cell_to_draw& cd) { | |||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|      |      | ||||||
|  |     if(hv) { | ||||||
|  |       ads_point M = current * (V * rock.at) * ads_matrix(Id, rock.pt_main.shift) * C0; | ||||||
|  |       optimize_shift(M); | ||||||
|  |       for(ld z=-5; z<=5; z+=0.2) { | ||||||
|  |         for(int i=0; i<isize(shape); i += 2) { | ||||||
|  |           auto h = rots::uxpush(shape[i] * ads_scale) * rots::uypush(shape[i+1] * ads_scale) * C0; | ||||||
|  |           curvepoint(h); | ||||||
|  |           } | ||||||
|  |         curvepoint_first(); | ||||||
|  |         queuecurve(current * V * rock.at * ads_matrix(Id, rock.pt_main.shift+z), rock.col, 0, PPR::LINE); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     else { | ||||||
|       for(auto h: rock.pts) curvepoint(h.h); |       for(auto h: rock.pts) curvepoint(h.h); | ||||||
|       curvepoint(rock.pts[0].h); |       curvepoint(rock.pts[0].h); | ||||||
|       queuecurve(shiftless(Id), |       queuecurve(shiftless(Id), | ||||||
|         rock.type == oMissile ? missile_color : |         rock.type == oMissile ? missile_color : | ||||||
|         rock.type == oParticle ? rock.col : |         rock.type == oParticle ? rock.col : | ||||||
|         0x000000FF, rock.col, obj_prio[rock.type]); |         0x000000FF, rock.col, obj_prio[rock.type]); | ||||||
|  |       } | ||||||
|  |  | ||||||
|     if(view_proper_times && rock.type != oParticle) { |     if(view_proper_times && rock.type != oParticle) { | ||||||
|       string str = format(tformat, rock.pt_main.shift / ads_time_unit); |       string str = format(tformat, rock.pt_main.shift / ads_time_unit); | ||||||
| @@ -137,6 +155,18 @@ void draw_game_cell(const cell_to_draw& cd) { | |||||||
|   /* todo: binary search */ |   /* todo: binary search */ | ||||||
|   if(paused) for(auto& rock: ci.shipstates) { |   if(paused) for(auto& rock: ci.shipstates) { | ||||||
|     cross_result cr; |     cross_result cr; | ||||||
|  |  | ||||||
|  |     if(hv) { | ||||||
|  |       auto& shape = shape_ship; | ||||||
|  |       for(int i=0; i<isize(shape); i += 2) { | ||||||
|  |         auto h = rots::uxpush(shape[i] * ads_scale) * rots::uypush(shape[i+1] * ads_scale) * C0; | ||||||
|  |         curvepoint(h); | ||||||
|  |         } | ||||||
|  |       curvepoint_first(); | ||||||
|  |       queuecurve(current * V * rock.at, shipcolor, 0, PPR::LINE); | ||||||
|  |       continue; | ||||||
|  |       } | ||||||
|  |  | ||||||
|     hybrid::in_actual([&]{ |     hybrid::in_actual([&]{ | ||||||
|       dynamicval<eGeometry> b(geometry, gRotSpace); |       dynamicval<eGeometry> b(geometry, gRotSpace); | ||||||
|       auto h = V * rock.at; |       auto h = V * rock.at; | ||||||
| @@ -164,7 +194,7 @@ void draw_game_cell(const cell_to_draw& cd) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   if(paused && c == vctr_ship && !game_over && !inHighQual) { |   if(paused && c == vctr_ship && !game_over && !in_replay && !hv) { | ||||||
|     cross_result cr; |     cross_result cr; | ||||||
|     hybrid::in_actual([&]{ |     hybrid::in_actual([&]{ | ||||||
|       auto h = ads_inverse(current_ship * vctrV_ship); |       auto h = ads_inverse(current_ship * vctrV_ship); | ||||||
| @@ -202,6 +232,8 @@ void view_footer() { | |||||||
| void view_ads_game() { | void view_ads_game() { | ||||||
|   displayed.clear(); |   displayed.clear(); | ||||||
|    |    | ||||||
|  |   bool hv = hybri; | ||||||
|  |  | ||||||
|   hybrid::in_actual([&] { |   hybrid::in_actual([&] { | ||||||
|     gen_budget = max_gen_per_frame; |     gen_budget = max_gen_per_frame; | ||||||
|      |      | ||||||
| @@ -284,7 +316,7 @@ void view_ads_game() { | |||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     if(!game_over && !paused && !in_replay) { |     if(!game_over && !paused && !in_replay && !hv) { | ||||||
|       poly_outline = 0xFF; |       poly_outline = 0xFF; | ||||||
|       if(ship_pt < invincibility_pt) { |       if(ship_pt < invincibility_pt) { | ||||||
|         ld u = (invincibility_pt-ship_pt) / ads_how_much_invincibility; |         ld u = (invincibility_pt-ship_pt) / ads_how_much_invincibility; | ||||||
|   | |||||||
| @@ -261,6 +261,7 @@ void ds_crash_ship() { | |||||||
|  |  | ||||||
| void ds_handle_crashes() { | void ds_handle_crashes() { | ||||||
|   if(paused) return; |   if(paused) return; | ||||||
|  |   dynamicval<eGeometry> g(geometry, gSphere); | ||||||
|   vector<ads_object*> dmissiles; |   vector<ads_object*> dmissiles; | ||||||
|   vector<ads_object*> drocks; |   vector<ads_object*> drocks; | ||||||
|   vector<ads_object*> dresources; |   vector<ads_object*> dresources; | ||||||
| @@ -457,9 +458,12 @@ bool invalid(cross_result& res) { | |||||||
| void view_ds_game() { | void view_ds_game() { | ||||||
|   displayed.clear(); |   displayed.clear(); | ||||||
|  |  | ||||||
|   draw_textures(); |   bool hv = hyperbolic; | ||||||
|  |   bool hvrel = among(pmodel, mdRelPerspective, mdRelOrthogonal); | ||||||
|  |  | ||||||
|   sphereflip = sphereflipped() ? MirrorZ : Id; |   sphereflip = hv ? Id : sphereflipped() ? MirrorZ : Id; | ||||||
|  |  | ||||||
|  |   if(!hv) draw_textures(); | ||||||
|  |  | ||||||
|   if(1) { |   if(1) { | ||||||
|     for(auto& r: rocks) { |     for(auto& r: rocks) { | ||||||
| @@ -505,8 +509,39 @@ void view_ds_game() { | |||||||
|  |  | ||||||
|       if(area > 0) continue; |       if(area > 0) continue; | ||||||
|  |  | ||||||
|  |       if(hv) { | ||||||
|  |         ld t = rock.at.shift; | ||||||
|  |         if(rock.type == oMainRock) t = floor(10*t + .5) / 10; | ||||||
|  |         transmatrix at = current.T * lorentz(2, 3, t - current.shift) * rock.at.T; | ||||||
|  |         for(ld s=-3; s<=3; s+=0.1) { | ||||||
|  |           transmatrix at1 = at * lorentz(2, 3, s); | ||||||
|  |           if((at1 * pov) [2] < 0) continue; | ||||||
|  |  | ||||||
|  |           auto& sh = *rock.shape; | ||||||
|  |  | ||||||
|  |           for(int i=0; i<isize(sh); i+=2) { | ||||||
|  |             hyperpoint h = hvrel ? tpt(sh[i], sh[i+1]) * pov: hpxy(sh[i], sh[i+1]); | ||||||
|  |             curvepoint(h); | ||||||
|  |             } | ||||||
|  |           curvepoint_first(); | ||||||
|  |           color_t col = rock.col; | ||||||
|  |           if(col == 0xFF) col = 0xFFD500FF; | ||||||
|  |           if(col != 0xFFD500FF && !hvrel) part(col, 0) = part(col, 0) / 4; | ||||||
|  |           queuecurve(shiftless(at1), col, 0, PPR::TRANSPARENT_WALL); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       if(!hv) { | ||||||
|         for(auto p: rock.pts) curvepoint(p.h); |         for(auto p: rock.pts) curvepoint(p.h); | ||||||
|         queuecurve(shiftless(sphereflip), rock.col, rock.col, obj_prio[rock.type]); |         queuecurve(shiftless(sphereflip), rock.col, rock.col, obj_prio[rock.type]); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       if(pmodel == mdPerspective) { | ||||||
|  |         for(auto p: rock.pts) curvepoint(p.h); | ||||||
|  |         curvepoint_first(); | ||||||
|  |         color_t col = rock.col; part(col, 0) /= 2; | ||||||
|  |         queuecurve(shiftless(sphereflip), col, 0, obj_prio[rock.type]).flags |= POLY_NO_FOG; | ||||||
|  |         } | ||||||
|  |  | ||||||
|       if(view_proper_times && rock.type != oParticle) { |       if(view_proper_times && rock.type != oParticle) { | ||||||
|         ld t = rock.pt_main.shift; |         ld t = rock.pt_main.shift; | ||||||
| @@ -524,6 +559,19 @@ void view_ds_game() { | |||||||
|     if(paused) for(auto& ss: history) { |     if(paused) for(auto& ss: history) { | ||||||
|       if(ss.at.shift < current.shift - 4 * TAU) continue; |       if(ss.at.shift < current.shift - 4 * TAU) continue; | ||||||
|       if(ss.at.shift > current.shift + 4 * TAU) continue; |       if(ss.at.shift > current.shift + 4 * TAU) continue; | ||||||
|  |  | ||||||
|  |       auto& shape = shape_ship; | ||||||
|  |  | ||||||
|  |       if(hv) { | ||||||
|  |         for(int i=0; i<isize(shape); i+=2) { | ||||||
|  |           hyperpoint h = hvrel ? tpt(shape[i], shape[i+1]) * pov: hpxy(shape[i], shape[i+1]); | ||||||
|  |           curvepoint(h); | ||||||
|  |           } | ||||||
|  |         curvepoint_first(); | ||||||
|  |         queuecurve(shiftless(current.T * lorentz(2, 3, ss.at.shift - current.shift) * ss.at.T), shipcolor, 0, PPR::TRANSPARENT_WALL); | ||||||
|  |         continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|       dynamicval<eGeometry> g(geometry, gSpace435); |       dynamicval<eGeometry> g(geometry, gSpace435); | ||||||
|       cross_result cr = ds_cross0(current.T * lorentz(2, 3, ss.at.shift - current.shift) * ss.at.T); |       cross_result cr = ds_cross0(current.T * lorentz(2, 3, ss.at.shift - current.shift) * ss.at.T); | ||||||
|       if(cr.shift < delta) continue; |       if(cr.shift < delta) continue; | ||||||
| @@ -532,15 +580,22 @@ void view_ds_game() { | |||||||
|        |        | ||||||
|       vector<hyperpoint> pts; |       vector<hyperpoint> pts; | ||||||
|        |        | ||||||
|       auto& shape = shape_ship; |  | ||||||
|       for(int i=0; i<isize(shape); i += 2) { |       for(int i=0; i<isize(shape); i += 2) { | ||||||
|         transmatrix at1 = at * tpt(shape[i], shape[i+1]); |         transmatrix at1 = at * tpt(shape[i], shape[i+1]); | ||||||
|         pts.push_back(ds_cross0(at1).h); |         pts.push_back(ds_cross0(at1).h); | ||||||
|         } |         } | ||||||
|        |        | ||||||
|       geometry = g.backup; |       geometry = g.backup; | ||||||
|  |  | ||||||
|  |       if(!hv) { | ||||||
|         for(auto pt: pts) curvepoint(pt); |         for(auto pt: pts) curvepoint(pt); | ||||||
|         queuecurve(shiftless(sphereflip), 0xFF, shipcolor, PPR::MONSTER_FOOT); |         queuecurve(shiftless(sphereflip), 0xFF, shipcolor, PPR::MONSTER_FOOT); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       if(pmodel == mdPerspective) { | ||||||
|  |         for(auto pt: pts) curvepoint(pt); | ||||||
|  |         queuecurve(shiftless(sphereflip), 0xFF, shipcolor, PPR::MONSTER_FOOT).flags |= POLY_NO_FOG; | ||||||
|  |         } | ||||||
|  |  | ||||||
|       if(view_proper_times) { |       if(view_proper_times) { | ||||||
|         string str = format(tformat, (cr.shift + ss.start) / ds_time_unit); |         string str = format(tformat, (cr.shift + ss.start) / ds_time_unit); | ||||||
| @@ -554,7 +609,17 @@ void view_ds_game() { | |||||||
|         ld u = (invincibility_pt-ship_pt) / ds_how_much_invincibility; |         ld u = (invincibility_pt-ship_pt) / ds_how_much_invincibility; | ||||||
|         poly_outline = gradient(shipcolor, rsrc_color[rtHull], 0, 0.5 + cos(5*u*TAU), 1); |         poly_outline = gradient(shipcolor, rsrc_color[rtHull], 0, 0.5 + cos(5*u*TAU), 1); | ||||||
|         } |         } | ||||||
|  |       if(hv) { | ||||||
|  |         auto& shape = shape_ship; | ||||||
|  |         for(int i=0; i<isize(shape); i += 2) { | ||||||
|  |           transmatrix at1 = tpt(shape[i], shape[i+1]); | ||||||
|  |           curvepoint(ds_cross0(at1).h); | ||||||
|  |           } | ||||||
|  |         queuecurve(shiftless(sphereflip * spin(ang*degree)), shipcolor, 0, PPR::MONSTER_HAIR).flags |= POLY_NO_FOG; | ||||||
|  |         } | ||||||
|  |       else { | ||||||
|         queuepolyat(shiftless(sphereflip * spin(ang*degree)), make_shape(), shipcolor, PPR::MONSTER_HAIR); |         queuepolyat(shiftless(sphereflip * spin(ang*degree)), make_shape(), shipcolor, PPR::MONSTER_HAIR); | ||||||
|  |         } | ||||||
|       poly_outline = 0xFF; |       poly_outline = 0xFF; | ||||||
|  |  | ||||||
|       if(view_proper_times) { |       if(view_proper_times) { | ||||||
| @@ -568,7 +633,7 @@ void view_ds_game() { | |||||||
|       queuestr(shiftless(sphereflip), .1, str, 0xFFFF00, 8); |       queuestr(shiftless(sphereflip), .1, str, 0xFFFF00, 8); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     if(paused && !game_over && !in_replay) { |     if(paused && !game_over && !in_replay && !hv) { | ||||||
|       vector<hyperpoint> pts; |       vector<hyperpoint> pts; | ||||||
|       int ok = 0, bad = 0; |       int ok = 0, bad = 0; | ||||||
|       for(int i=0; i<=360; i++) { |       for(int i=0; i<=360; i++) { | ||||||
| @@ -606,30 +671,6 @@ void ds_restart() { | |||||||
|   init_rsrc(); |   init_rsrc(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void replay_animation() { |  | ||||||
|   if(!in_replay) return; |  | ||||||
|   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(sphere) { |  | ||||||
|         dynamicval<eGeometry> g(geometry, gSpace435); |  | ||||||
|         current.T = inverse(ss.at.T * spin(-(ss.ang+90)*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; |  | ||||||
|       } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
| void run_ds_game() { | void run_ds_game() { | ||||||
|  |  | ||||||
|   stop_game(); |   stop_game(); | ||||||
| @@ -648,19 +689,8 @@ void run_ds_game() { | |||||||
|   rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation); |   rogueviz::rv_hook(anims::hooks_anim, 100, replay_animation); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| 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 ds_hooks =  | auto ds_hooks =  | ||||||
|   arg::add3("-ds-game", run_ds_game) |   arg::add3("-ds-game", run_ds_game); | ||||||
| + arg::add3("-ds-recenter", [] { current = Id; }) |  | ||||||
| + arg::add3("-ds-record", switch_replay); |  | ||||||
|  |  | ||||||
| } | } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -128,5 +128,9 @@ void run_ds_game(); | |||||||
| /** in the replay mode */ | /** in the replay mode */ | ||||||
| bool in_replay; | bool in_replay; | ||||||
| void switch_replay(); | void switch_replay(); | ||||||
|  | void replay_animation(); | ||||||
|  |  | ||||||
|  | void switch_underlying(); | ||||||
|  | bool ads_draw_cell(cell *c, const shiftmatrix& V); | ||||||
|  |  | ||||||
| }} | }} | ||||||
|   | |||||||
| @@ -247,6 +247,11 @@ void ads_crash_ship() { | |||||||
|  |  | ||||||
| void handle_crashes() { | void handle_crashes() { | ||||||
|   if(paused) return; |   if(paused) return; | ||||||
|  |   if(rotspace) { | ||||||
|  |     if(!currentmap) { println(hlog, "no currentmap!"); return; } | ||||||
|  |     PIU({ handle_crashes(); }); | ||||||
|  |     return; | ||||||
|  |     } | ||||||
|   vector<ads_object*> missiles; |   vector<ads_object*> missiles; | ||||||
|   vector<ads_object*> rocks; |   vector<ads_object*> rocks; | ||||||
|   vector<ads_object*> resources; |   vector<ads_object*> resources; | ||||||
|   | |||||||
							
								
								
									
										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
	 Zeno Rogue
					Zeno Rogue