mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	generalized PSL to ~SL (discrepancies still appear)
This commit is contained in:
		
							
								
								
									
										2
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -115,7 +115,7 @@ transmatrix hrmap::adj(heptagon *h, int i) { return relative_matrix(h->cmove(i), | ||||
|  | ||||
| vector<cell*>& hrmap::allcells() {  | ||||
|   static vector<cell*> default_allcells; | ||||
|   if(bounded && !(cgflags & qHUGE_BOUNDED) && !(prod && product::csteps == 0)) { | ||||
|   if(bounded && !(cgflags & qHUGE_BOUNDED) && !(hybri && hybrid::csteps == 0)) { | ||||
|     celllister cl(gamestart(), 1000000, 1000000, NULL); | ||||
|     default_allcells = cl.lst; | ||||
|     return default_allcells; | ||||
|   | ||||
							
								
								
									
										21
									
								
								drawing.cpp
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								drawing.cpp
									
									
									
									
									
								
							| @@ -615,6 +615,10 @@ void dqi_poly::gldraw() { | ||||
|     if(global_projection && global_projection != ed) continue; | ||||
|     current_display->set_all(ed); | ||||
|     bool draw = color; | ||||
|  | ||||
|     if(min_slr < max_slr) { | ||||
|       glhr::set_index_sl(band_shift + M_PI * min_slr * hybrid::csteps / cgi.psl_steps); | ||||
|       } | ||||
|      | ||||
|     flagtype sp = get_shader_flags(); | ||||
|      | ||||
| @@ -701,9 +705,8 @@ void dqi_poly::gldraw() { | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   if(min_slr < max_slr) { | ||||
|   if(min_slr+1 < max_slr) { | ||||
|     min_slr++; | ||||
|     glhr::set_index_sl(M_PI * min_slr); | ||||
|     goto next_slr; | ||||
|     } | ||||
|   } | ||||
| @@ -1521,15 +1524,19 @@ void dqi_poly::draw() { | ||||
|  | ||||
| #if CAP_GL | ||||
|   if(vid.usingGL && (current_display->set_all(global_projection), get_shader_flags() & SF_DIRECT)) { | ||||
|     if(sl2 && pmodel == mdGeodesic) { | ||||
|       ld z = atan2(V[2][3], V[3][3]); | ||||
|     if(sl2 && pmodel == mdGeodesic && hybrid::csteps) { | ||||
|       ld z = atan2(V[2][3], V[3][3]) + band_shift; | ||||
|       auto zr = sightranges[geometry]; | ||||
|       min_slr = ceil((-zr - z) / M_PI); | ||||
|       max_slr = floor((zr - z) / M_PI); | ||||
|       ld ns = stretch::not_squared(); | ||||
|       ld db = cgi.psl_steps / M_PI / ns / hybrid::csteps; | ||||
|  | ||||
|       min_slr = floor((-zr - z) * db); | ||||
|       max_slr = ceil((zr - z) * db); | ||||
|       if(min_slr > max_slr) return; | ||||
|       if(flags & POLY_ONE_LEVEL) min_slr = max_slr = 0; | ||||
|       glhr::set_index_sl(M_PI * min_slr); | ||||
|       max_slr++; | ||||
|       } | ||||
|     else min_slr = 0, max_slr = 1; | ||||
|     set_width(get_width(this)); | ||||
|     flags &= ~POLY_INVERSE; | ||||
|     gldraw(); | ||||
|   | ||||
| @@ -569,6 +569,8 @@ EX void select_quotient() { | ||||
|     } | ||||
|   else if(prod) | ||||
|     pushScreen(product::show_config); | ||||
|   else if(rotspace) | ||||
|     hybrid::configure_period(); | ||||
|   else { | ||||
|     vector<eGeometry> choices; | ||||
|     for(int i=0; i<isize(ginf); i++) if(same_tiling(eGeometry(i))) choices.push_back(eGeometry(i)); | ||||
| @@ -691,7 +693,7 @@ EX void showEuclideanMenu() { | ||||
|   nom *= euler; | ||||
|   denom *= 2; | ||||
|          | ||||
|   if(hybri && !prod) nom *= cgi.steps, denom *= cgi.single_step; | ||||
|   if(hybri) nom *= hybrid::csteps, denom *= cgi.single_step; | ||||
|  | ||||
|   int g = gcd(nom, denom); | ||||
|   if(g) { | ||||
| @@ -842,7 +844,7 @@ EX void showEuclideanMenu() { | ||||
|       }); | ||||
|     } | ||||
|   else if(hybri) { | ||||
|     dialog::addSelItem(XLAT("number of levels"), its(cgi.steps / cgi.single_step), 0); | ||||
|     dialog::addSelItem(XLAT("number of levels"), its(hybrid::csteps / cgi.single_step), 0); | ||||
|     } | ||||
|   else if(bt::in()) { | ||||
|     dialog::addSelItem(XLAT("width"), fts(vid.binary_width), 'v'); | ||||
|   | ||||
							
								
								
									
										17
									
								
								geometry.cpp
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								geometry.cpp
									
									
									
									
									
								
							| @@ -164,8 +164,8 @@ struct geometry_information { | ||||
|   ld plevel; | ||||
|   /** level for a z-step */ | ||||
|   int single_step; | ||||
|   /** the number of levels in SL2 */ | ||||
|   int steps; | ||||
|   /** the number of levels in PSL */ | ||||
|   int psl_steps; | ||||
|  | ||||
|   /** for binary tilings */ | ||||
|   transmatrix direct_tmatrix[14]; | ||||
| @@ -668,19 +668,18 @@ void geometry_information::prepare_basics() { | ||||
|     } | ||||
|    | ||||
|   plevel = vid.plevel_factor * scalefactor; | ||||
|   steps = product::csteps; | ||||
|   single_step = 1; | ||||
|   if(hybri && !prod) { | ||||
|     if(hybrid::underlying == gArchimedean)  | ||||
|       arcm::current.get_step_values(steps, single_step); | ||||
|       arcm::current.get_step_values(psl_steps, single_step); | ||||
|     else { | ||||
|       single_step = S3 * S7 - 2 * S7 - 2 * S3; | ||||
|       steps = 2 * S7;     | ||||
|       if(BITRUNCATED) steps *= S3; | ||||
|       psl_steps = 2 * S7;     | ||||
|       if(BITRUNCATED) psl_steps *= S3; | ||||
|       if(single_step < 0) single_step = -single_step; | ||||
|       } | ||||
|     DEBB(DF_GEOM | DF_POLY, ("steps = ", steps, " / ", single_step)); | ||||
|     plevel = M_PI * single_step / steps; | ||||
|     DEBB(DF_GEOM | DF_POLY, ("steps = ", psl_steps, " / ", single_step)); | ||||
|     plevel = M_PI * single_step / psl_steps; | ||||
|     } | ||||
|    | ||||
|   if(hybri) { | ||||
| @@ -1036,8 +1035,6 @@ EX string cgi_string() { | ||||
|    | ||||
|   if(prod) V("PL", fts(vid.plevel_factor)); | ||||
|  | ||||
|   if(prod) V("PS", its(product::csteps)); | ||||
|    | ||||
|   if(geometry == gFieldQuotient) { V("S3=", its(S3)); V("S7=", its(S7)); } | ||||
|   if(nil) V("NIL", its(S7)); | ||||
|    | ||||
|   | ||||
| @@ -1998,8 +1998,7 @@ EX namespace dq { | ||||
|   EX set<int> visited_by_matrix; | ||||
|   EX void enqueue_by_matrix(heptagon *h, const transmatrix& T) { | ||||
|     if(!h) return; | ||||
|     if(sl2 && T[3][3] < 0) { enqueue_by_matrix(h, centralsym * T); return; } | ||||
|     int b = bucketer(tC0(T)); | ||||
|     int b = bucketer(tC0(T)) + int(floor(band_shift*81527+.5)); | ||||
|     if(visited_by_matrix.count(b)) { return; } | ||||
|     visited_by_matrix.insert(b); | ||||
|     drawqueue.emplace(h, T, band_shift); | ||||
| @@ -2016,8 +2015,7 @@ EX namespace dq { | ||||
|  | ||||
|   EX void enqueue_by_matrix_c(cell *c, const transmatrix& T) { | ||||
|     if(!c) return; | ||||
|     if(sl2 && T[3][3] < 0) { enqueue_by_matrix_c(c, centralsym * T); return; } | ||||
|     int b = bucketer(tC0(T)); | ||||
|     unsigned b = bucketer(tC0(T)) + int(floor(band_shift*81527+.5)); | ||||
|     if(visited_by_matrix.count(b)) { return; } | ||||
|     visited_by_matrix.insert(b); | ||||
|     drawqueue_c.emplace(c, T, band_shift); | ||||
| @@ -2082,6 +2080,7 @@ EX bool do_draw(cell *c, const transmatrix& T) { | ||||
|       } | ||||
|     else if(pmodel == mdGeodesic && sl2) { | ||||
|       if(hypot(tC0(T)[2], tC0(T)[3]) > cosh(slr::range_xy)) return false; | ||||
|       if(band_shift * stretch::not_squared() > sightranges[geometry]) return false; | ||||
|       if(!limited_generation(c)) return false; | ||||
|       } | ||||
|     else if(vid.use_smart_range) { | ||||
|   | ||||
| @@ -464,9 +464,13 @@ namespace mapstream { | ||||
|       f.write(asonov::period_xy); | ||||
|       f.write(asonov::period_z); | ||||
|       } | ||||
|     if(geometry == gProduct) { | ||||
|       f.write(product::csteps); | ||||
|     if(prod) { | ||||
|       f.write(hybrid::csteps); | ||||
|       f.write(product::cspin); | ||||
|       f.write(product::cmirror); | ||||
|       } | ||||
|     if(rotspace) { | ||||
|       f.write(hybrid::csteps); | ||||
|       } | ||||
|     if(hybri) { | ||||
|       hybrid::in_underlying_geometry([&] { save_geometry(f); }); | ||||
| @@ -550,8 +554,12 @@ namespace mapstream { | ||||
|       asonov::set_flags(); | ||||
|       } | ||||
|     if(geometry == gProduct && f.vernum >= 0xA80C) { | ||||
|       f.read(product::csteps); | ||||
|       f.read(hybrid::csteps); | ||||
|       if(f.vernum >= 0xA80D) f.read(product::cspin); | ||||
|       if(f.vernum >= 0xA833) f.read(product::cmirror); | ||||
|       } | ||||
|     if(geometry == gRotSpace && f.vernum >= 0xA833) { | ||||
|       f.read(hybrid::csteps); | ||||
|       } | ||||
|     if(hybri && f.vernum >= 0xA80C) { | ||||
|       auto g = geometry; | ||||
|   | ||||
							
								
								
									
										199
									
								
								nonisotropic.cpp
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								nonisotropic.cpp
									
									
									
									
									
								
							| @@ -1065,6 +1065,8 @@ EX namespace hybrid { | ||||
|  | ||||
|   EX eGeometryClass under_class() { return ginf[hybrid::underlying].cclass; }   | ||||
|  | ||||
|   EX int csteps; | ||||
|    | ||||
|   EX transmatrix ray_iadj(cell *c, int i) { | ||||
|     if(prod && i == c->type-2) return (mscale(Id, +cgi.plevel)); | ||||
|     if(prod && i == c->type-1) return (mscale(Id, -cgi.plevel)); | ||||
| @@ -1109,7 +1111,7 @@ EX namespace hybrid { | ||||
|       ginf[g].g.gameplay_dimension++; | ||||
|       ginf[g].g.graphical_dimension++; | ||||
|       ginf[g].tiling_name += "xZ"; | ||||
|       if(product::csteps) ginf[g].flags |= qANYQ, ginf[g].tiling_name += its(product::csteps); | ||||
|       if(csteps) ginf[g].flags |= qANYQ, ginf[g].tiling_name += its(csteps); | ||||
|       } | ||||
|     ginf[g].flags |= qHYBRID; | ||||
|     } | ||||
| @@ -1146,6 +1148,73 @@ EX namespace hybrid { | ||||
|     map<cell*, pair<cell*, int>> where; | ||||
|      | ||||
|     heptagon *getOrigin() override { return underlying_map->getOrigin(); } | ||||
|  | ||||
|     const int SHIFT_UNKNOWN = 30000; | ||||
|     map<cell*, vector<int>> shifts; | ||||
|    | ||||
|     EX vector<int>& make_shift(cell *c) { | ||||
|       auto& res = shifts[c]; | ||||
|       if(res.empty()) res = vector<int> (c->type, SHIFT_UNKNOWN); | ||||
|       return res; | ||||
|       } | ||||
|      | ||||
|     EX int& get_shift_current(cell *c, int i) { | ||||
|       return make_shift(c)[i]; | ||||
|       } | ||||
|      | ||||
|     EX bool have_shift(cell *c, int i) { | ||||
|       return shifts.count(c) && get_shift_current(c, i) != SHIFT_UNKNOWN; | ||||
|       } | ||||
|    | ||||
|     EX int get_shift(cell *c, int i) { | ||||
|       auto& v = get_shift_current(c, i); | ||||
|       if(v != SHIFT_UNKNOWN) return v; | ||||
|        | ||||
|       vector<int> candidates; | ||||
|        | ||||
|       for(int a: {1, -1}) { | ||||
|         cellwalker cw0(c, i); | ||||
|         cellwalker cw = cw0; | ||||
|         cw += wstep; cw += a; | ||||
|         int s = 0; | ||||
|         while(cw != cw0) { | ||||
|           if(!have_shift(cw.at, cw.spin)) goto next; | ||||
|           s += shifts[cw.at][cw.spin]; | ||||
|           cw += wstep; | ||||
|           cw += a; | ||||
|           } | ||||
|         candidates.push_back(-a * cgi.single_step - s); | ||||
|         next: ; | ||||
|         } | ||||
|        | ||||
|       if(candidates.size() == 2 && candidates[0] != candidates[1]) { | ||||
|         println(hlog, "discrepancy found ", candidates); | ||||
|         } | ||||
|    | ||||
|       int val = 0; | ||||
|       if(!candidates.empty()) val = candidates[0]; | ||||
|        | ||||
|       v = val; | ||||
|       get_shift_current(c->move(i), c->c.spin(i)) = -val; | ||||
|  | ||||
|       for(int a: {1, -1}) { | ||||
|         cellwalker cw0(c, i); | ||||
|         cellwalker cw = cw0; | ||||
|         cw += wstep; cw += a; | ||||
|         int s = 0; | ||||
|         while(cw != cw0) { | ||||
|           if(!have_shift(cw.at, cw.spin)) goto next1; | ||||
|           s += shifts[cw.at][cw.spin]; | ||||
|           cw += wstep; | ||||
|           cw += a; | ||||
|           } | ||||
|         if(val != -a * cgi.single_step - s) | ||||
|           println(hlog, "incorrect val after setting"); | ||||
|         next1: ; | ||||
|         } | ||||
|              | ||||
|       return val; | ||||
|       }   | ||||
|      | ||||
|     template<class T> auto in_underlying(const T& t) -> decltype(t()) { | ||||
|       pcgip = cgip;  | ||||
| @@ -1162,11 +1231,11 @@ EX namespace hybrid { | ||||
|         if(!spins.count(u)) | ||||
|           println(hlog, "link missing: ", u); | ||||
|         else { | ||||
|           while(h >= cgi.steps) h -= cgi.steps, u = spins[u].first.at; | ||||
|           while(h < 0) h += cgi.steps, u = spins[u].second.at; | ||||
|           while(h >= csteps) h -= csteps, u = spins[u].first.at; | ||||
|           while(h < 0) h += csteps, u = spins[u].second.at; | ||||
|           } | ||||
|         } | ||||
|       h = zgmod(h, cgi.steps); | ||||
|       h = zgmod(h, csteps); | ||||
|       cell*& c = at[make_pair(u, h)]; | ||||
|       if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; } | ||||
|       return c; | ||||
| @@ -1190,6 +1259,8 @@ EX namespace hybrid { | ||||
|  | ||||
|     void draw() override { | ||||
|       cell* start = centerover; | ||||
|       band_shift = 0; | ||||
|       auto period = (M_PI * csteps) / cgi.psl_steps; | ||||
|        | ||||
|       dq::visited_by_matrix.clear(); | ||||
|       dq::enqueue_by_matrix_c(start, cview()); | ||||
| @@ -1198,6 +1269,7 @@ EX namespace hybrid { | ||||
|         auto& p = dq::drawqueue_c.front(); | ||||
|         cell *c = get<0>(p); | ||||
|         transmatrix V = get<1>(p); | ||||
|         band_shift = get<2>(p); | ||||
|         dq::drawqueue_c.pop(); | ||||
|          | ||||
|         if(!do_draw(c, V)) continue; | ||||
| @@ -1207,7 +1279,24 @@ EX namespace hybrid { | ||||
|  | ||||
|         for(int i=0; i<c->type; i++) { | ||||
|           cell *c1 = c->cmove(i); | ||||
|           dq::enqueue_by_matrix_c(c1, V * adj(c, i)); | ||||
|           transmatrix V1 = V * adj(c, i); | ||||
|           dynamicval<ld> bs(band_shift, band_shift); | ||||
|           if(sl2) { | ||||
|             ld alpha = atan2(V1[2][3], V1[3][3]); | ||||
|             band_shift += alpha; | ||||
|             ld ca = cos(alpha), sa = sin(alpha); | ||||
|             if(alpha) for(int a=0; a<4; a++) { | ||||
|               tie(V1[2][a], V1[3][a]) = make_pair(V1[2][a] * ca - V1[3][a] * sa, V1[3][a] * ca + V1[2][a] * sa); | ||||
|               tie(V1[0][a], V1[1][a]) = make_pair(V1[0][a] * ca - V1[1][a] * sa, V1[1][a] * ca + V1[0][a] * sa); | ||||
|               } | ||||
|             if(csteps) { | ||||
|               while(band_shift > period*.4999) | ||||
|                 band_shift -= period; | ||||
|               while(band_shift < -period*.5001) | ||||
|                 band_shift += period; | ||||
|               } | ||||
|             } | ||||
|           dq::enqueue_by_matrix_c(c1, V1); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| @@ -1220,19 +1309,28 @@ EX namespace hybrid { | ||||
|     } | ||||
|    | ||||
|   EX pair<cell*, int> get_where(cell *c) { return hmap()->where[c]; } | ||||
|  | ||||
|    | ||||
|   EX void find_cell_connection(cell *c, int d) { | ||||
|     auto m = hmap(); | ||||
|     if(d >= c->type - 2) { | ||||
|       int s = cgi.single_step; | ||||
|       cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? s : -s)); | ||||
|       int lev = m->where[c].second + (d == c->type-1 ? s : -s); | ||||
|       cell *c1 = get_at(m->where[c].first, lev); | ||||
|       c->c.connect(d, c1, c1->type - 3 + c->type - d, false); | ||||
|       } | ||||
|     else { | ||||
|       auto cu = m->where[c].first; | ||||
|       auto cu1 = m->in_underlying([&] { return cu->cmove(d); }); | ||||
|       int d1 = cu->c.spin(d); | ||||
|       int s = (geometry == gRotSpace && cgi.steps) ? d*cgi.steps / cu->type - d1*cgi.steps / cu1->type + cgi.steps/2 : 0; | ||||
|       int s = 0; | ||||
|       if(geometry == gRotSpace) { | ||||
|         if(csteps && cgi.psl_steps % csteps == 0) { | ||||
|           auto ps = cgi.psl_steps; | ||||
|           s = d*ps / cu->type - d1*ps / cu1->type + ps/2; | ||||
|           } | ||||
|         else  | ||||
|           s = ((hrmap_hybrid*)currentmap)->get_shift(cu, d); | ||||
|         } | ||||
|       cell *c1 = get_at(cu1, m->where[c].second + s); | ||||
|       c->c.connect(d, c1, d1, cu->c.mirror(d)); | ||||
|       } | ||||
| @@ -1397,7 +1495,7 @@ EX namespace hybrid { | ||||
|       auto w1 = hybrid::get_where(c1), w2 = hybrid::get_where(c2);  | ||||
|       return PIU (hr::celldistance(w1.first, w2.first)); | ||||
|       } | ||||
|     else if(cgi.steps == 0) { | ||||
|     else if(csteps == 0) { | ||||
|       auto w1 = hybrid::get_where(c1), w2 = hybrid::get_where(c2);  | ||||
|       return PIU (hr::celldistance(w1.first, w2.first)) + abs(w1.second - w2.second); | ||||
|       } | ||||
| @@ -1419,6 +1517,40 @@ EX namespace hybrid { | ||||
|       } | ||||
|     } | ||||
|  | ||||
|   EX void configure_period() { | ||||
|     static int s; | ||||
|     s = csteps / cgi.single_step; | ||||
|     dialog::editNumber(s, 0, 16, 1, 0, XLAT("%1 period", "Z"), ""); | ||||
|     dialog::bound_low(0); | ||||
|     auto set_s = [] (int s1) { | ||||
|       return [s1] { | ||||
|         if(csteps == s1) return; | ||||
|         stop_game(); | ||||
|         csteps = s1 * cgi.single_step; | ||||
|         hybrid::reconfigure(); | ||||
|         start_game(); | ||||
|         }; | ||||
|       }; | ||||
|     dialog::extra_options = [=] () {  | ||||
|       if(rotspace) { | ||||
|         int e_steps = cgi.psl_steps / gcd(cgi.single_step, cgi.psl_steps);  | ||||
|         dialog::addSelItem( XLAT(sphere ? "elliptic" : "PSL(2,R)"), its(e_steps), 'P'); | ||||
|         dialog::add_action(set_s(e_steps)); | ||||
|         dialog::addSelItem( XLAT(sphere ? "sphere" : "SL(2,R)"), its(2*e_steps), 'P'); | ||||
|         dialog::add_action(set_s(2*e_steps)); | ||||
|         if(sl2) { | ||||
|           dialog::addSelItem( XLAT("universal cover"), its(0), 'P'); | ||||
|           dialog::add_action(set_s(0)); | ||||
|           } | ||||
|         } | ||||
|       else { | ||||
|         dialog::addSelItem( XLAT("non-periodic"), its(0), 'N'); | ||||
|         dialog::add_action(set_s(0)); | ||||
|         } | ||||
|       dialog::reaction_final = set_s(s); | ||||
|       }; | ||||
|     } | ||||
|  | ||||
| EX } | ||||
|    | ||||
| EX namespace product { | ||||
| @@ -1427,11 +1559,11 @@ EX namespace product { | ||||
|    | ||||
|   struct hrmap_product : hybrid::hrmap_hybrid { | ||||
|     transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& hint) override { | ||||
|       return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, hint); }) * mscale(Id, cgi.plevel * szgmod(where[c2].second - where[c1].second, csteps)); | ||||
|       return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, hint); }) * mscale(Id, cgi.plevel * szgmod(where[c2].second - where[c1].second, hybrid::csteps)); | ||||
|       } | ||||
|  | ||||
|     transmatrix adj(cell *c, int i) override { | ||||
|       if(twisted && i == c->type-1 && where[c].second == cgi.steps-1) { | ||||
|       if(twisted && i == c->type-1 && where[c].second == hybrid::csteps-1) { | ||||
|         auto b = spins[where[c].first].first; | ||||
|         transmatrix T = mscale(Id, cgi.plevel); | ||||
|         T = T * spin(2 * M_PI * b.spin / b.at->type); | ||||
| @@ -1453,6 +1585,7 @@ EX namespace product { | ||||
|    | ||||
|     hrmap_product() { | ||||
|       current_spin_invalid = false; | ||||
|       using hybrid::csteps; | ||||
|       if((cspin || cmirror) && csteps) { | ||||
|         in_underlying([&] { | ||||
|           twisted = validate_spin(); | ||||
| @@ -1475,11 +1608,9 @@ EX namespace product { | ||||
|       } | ||||
|     }; | ||||
|  | ||||
|   EX bool current_spin_invalid; | ||||
|  | ||||
|   EX int csteps, cspin; | ||||
|   EX bool cmirror; | ||||
|    | ||||
|   EX bool current_spin_invalid, cmirror; | ||||
|   EX int cspin; | ||||
|      | ||||
|   EX hyperpoint inverse_exp(hyperpoint h) { | ||||
|     hyperpoint res; | ||||
|     res[2] = zlevel(h); | ||||
| @@ -1533,43 +1664,30 @@ EX namespace product { | ||||
|       } | ||||
|     return true; | ||||
|     } | ||||
|      | ||||
|  | ||||
|   EX void show_config() { | ||||
|     cmode = sm::SIDE | sm::MAYDARK; | ||||
|     gamescreen(1);   | ||||
|     gamescreen(1); | ||||
|     dialog::init(XLAT("quotient product spaces")); | ||||
|     dialog::addSelItem(XLAT("%1 period", "Z"), its(product::csteps), 'z'); | ||||
|     dialog::add_action([] { | ||||
|       static int s; | ||||
|       s = product::csteps; | ||||
|       dialog::editNumber(s, 0, 16, 1, 0, XLAT("%1 period", "Z"), | ||||
|             XLAT("Set to 0 to make it non-periodic.")); | ||||
|       dialog::bound_low(0); | ||||
|       dialog::reaction_final = [] { | ||||
|         product::csteps = s; | ||||
|         if(product::csteps == cgi.steps) return; | ||||
|         hybrid::reconfigure(); | ||||
|         start_game(); | ||||
|         println(hlog, "csteps = ", cgi.steps); | ||||
|         }; | ||||
|       }); | ||||
|     dialog::addSelItem(XLAT("rotation"), its(product::cspin), 'r'); | ||||
|     dialog::addSelItem(XLAT("%1 period", "Z"), its(hybrid::csteps), 'z'); | ||||
|     dialog::add_action(hybrid::configure_period); | ||||
|     dialog::addSelItem(XLAT("rotation"), its(cspin), 'r'); | ||||
|     dialog::add_action([] { | ||||
|       static int s; | ||||
|       dialog::editNumber(s, 0, 16, 1, 0, XLAT("rotation", "Z"),  | ||||
|         XLAT("Works if the underlying space is symmetric.") | ||||
|         ); | ||||
|       dialog::reaction_final = [] { | ||||
|         if(s == product::cspin) return; | ||||
|         if(s == cspin) return; | ||||
|         stop_game(); | ||||
|         product::cspin = s; | ||||
|         cspin = s; | ||||
|         start_game(); | ||||
|         }; | ||||
|       }); | ||||
|     dialog::addBoolItem(XLAT("reflect"), product::cmirror, 'f'); | ||||
|     dialog::addBoolItem(XLAT("reflect"), cmirror, 'f'); | ||||
|     dialog::add_action([]{ | ||||
|       stop_game(); | ||||
|       product::cmirror = !product::cmirror; | ||||
|       cmirror = !cmirror; | ||||
|       start_game(); | ||||
|       }); | ||||
|     if(current_spin_invalid)  | ||||
| @@ -1797,10 +1915,11 @@ EX namespace slr { | ||||
|       "vec4 res = vec4(sqrt(-1.),sqrt(-1.),sqrt(-1.),sqrt(-1.));" | ||||
|        | ||||
|       "bool flipped = phi > 0.;" | ||||
|       "if(flipped) phi = -phi, h[2] *= -1, h[0] *= -1;" | ||||
|        | ||||
|       "float alpha = atan2(h[1], -h[0]) + uIndexSL;" | ||||
|        | ||||
|       "if(flipped) phi = -phi, alpha = atan2(h[1], h[0]) - uIndexSL;" | ||||
|        | ||||
|       "float fiber_barrier = atan(1./uSV);" | ||||
|      | ||||
|       "float flip_barrier = atan(1. / tanh(asinh(xy)) / uSV);"       | ||||
| @@ -2502,7 +2621,7 @@ EX namespace nisot { | ||||
|     else if(argis("-prodperiod")) { | ||||
|       PHASEFROM(2); | ||||
|       if(prod) stop_game(); | ||||
|       shift(); product::csteps = argi(); | ||||
|       shift(); hybrid::csteps = argi(); | ||||
|       hybrid::reconfigure(); | ||||
|       return 0; | ||||
|       } | ||||
|   | ||||
							
								
								
									
										11
									
								
								system.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								system.cpp
									
									
									
									
									
								
							| @@ -119,7 +119,10 @@ EX void welcomeMessage() { | ||||
|   else if(nil) | ||||
|     addMessage(XLAT("Welcome to NilRogue!")); | ||||
|   else if(sl2) { | ||||
|     addMessage(XLAT("Welcome to PSL(2,R)-ogue!")); | ||||
|     if(cgi.psl_steps % hybrid::csteps == 0) | ||||
|       addMessage(XLAT("Welcome to PSL(2,R)-ogue!")); | ||||
|     else | ||||
|       addMessage(XLAT("Welcome to SL(2,R)-ogue!")); | ||||
|     if(hybrid::underlying == gNormal && BITRUNCATED) | ||||
|       addMessage(XLAT("Hint: this is more playable with pure {7,3} or pure {5,4}")); | ||||
|     } | ||||
| @@ -1262,6 +1265,7 @@ EX void set_geometry(eGeometry target) { | ||||
|     ors::reset(); | ||||
|     if(among(target, gProduct, gRotSpace)) { | ||||
|       if(vid.always3) { vid.always3 = false; geom3::apply_always3(); } | ||||
|       if(target == gRotSpace) hybrid::csteps = 0; | ||||
|       hybrid::configure(target); | ||||
|       } | ||||
|     geometry = target; | ||||
| @@ -1296,6 +1300,11 @@ EX void set_geometry(eGeometry target) { | ||||
|     if(prod) { pmodel = mdPerspective; if(vid.texture_step < 4) vid.texture_step = 4; } | ||||
|     if(WDIM == 3 && (cgflags & qIDEAL) && vid.texture_step < 4) vid.texture_step = 4; | ||||
|     if(sl2) nisot::geodesic_movement = true; | ||||
|  | ||||
|     if(rotspace) { | ||||
|       check_cgi(); cgi.require_basics();             | ||||
|       hybrid::csteps = cgi.psl_steps; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								util.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								util.cpp
									
									
									
									
									
								
							| @@ -370,6 +370,8 @@ cld exp_parser::parse(int prio) { | ||||
|     else if(number == "mousex") res = mousex; | ||||
|     else if(number == "deg") res = degree; | ||||
|     else if(number == "ultra_mirror_dist") res = cgi.ultra_mirror_dist; | ||||
|     else if(number == "psl_steps") res = cgi.psl_steps; | ||||
|     else if(number == "single_step") res = cgi.single_step; | ||||
|     else if(number == "step") res = hdist0(tC0(currentmap->adj(cwt.at, 0))); | ||||
|     else if(number == "mousey") res = mousey; | ||||
|     else if(number == "random") res = randd(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue