From 1e6970ca28318c23415e588cf05605defb5938f9 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 24 Aug 2019 14:07:46 +0200 Subject: [PATCH] hybrid:: refactored the common parts of prod and sl2, also used them when applicable --- barriers.cpp | 2 +- basegraph.cpp | 2 +- bigstuff.cpp | 26 +++---- cell.cpp | 26 +++---- complex.cpp | 10 +-- config.cpp | 2 +- floorshapes.cpp | 6 +- geometry.cpp | 41 ++++------- geometry2.cpp | 6 +- graph.cpp | 13 ++-- hyper.h | 1 + hypgraph.cpp | 14 ++-- landgen.cpp | 24 +++---- landlock.cpp | 4 +- monstergen.cpp | 2 +- nonisotropic.cpp | 184 ++++++++++++++++++----------------------------- pattern2.cpp | 16 ++--- polygons.cpp | 2 +- system.cpp | 8 +-- yendor.cpp | 4 +- 20 files changed, 169 insertions(+), 224 deletions(-) diff --git a/barriers.cpp b/barriers.cpp index a47cf6e6..d7dd5707 100644 --- a/barriers.cpp +++ b/barriers.cpp @@ -37,7 +37,7 @@ EX bool hasbardir(cell *c) { } EX void preventbarriers(cell *c) { - if(prod) c = product::get_where(c).first; + if(hybri) c = hybrid::get_where(c).first; if(c && c->bardir == NODIR) c->bardir = NOBARRIERS; } diff --git a/basegraph.cpp b/basegraph.cpp index 4aa4e931..bc78dcd7 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -1389,7 +1389,7 @@ EX void initgraph() { loadConfig(); #endif arcm::current.parse(); - if(geometry == gProduct) geometry = product::underlying; + if(hybri) geometry = hybrid::underlying; #if CAP_COMMANDLINE arg::read(2); diff --git a/bigstuff.cpp b/bigstuff.cpp index a9e57a87..289c802b 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -132,7 +132,7 @@ EX bool grailWasFound(cell *c) { } void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) { - if(prod) { product::in_underlying_map([&] { generateAlts(h, levs, link_cdata); }); } + if(hybri) { hybrid::in_underlying_map([&] { generateAlts(h, levs, link_cdata); }); } if(!h->alt) return; preventbarriers(h->c7); if(h->c7) forCellEx(c2, h->c7) preventbarriers(c2); @@ -183,10 +183,10 @@ void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) { EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special IS(0)) { - if(prod) { - c = product::get_where(c).first; + if(hybri) { + c = hybrid::get_where(c).first; heptagon *res; - product::in_underlying_map([&] { res = createAlternateMap(c, rad, firststate, special); }); + hybrid::in_underlying_map([&] { res = createAlternateMap(c, rad, firststate, special); }); return res; } @@ -246,7 +246,7 @@ EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special alt->emeraldval = 0; alt->zebraval = 0; alt->distance = 0; - alt->fieldval = nisot::current_view_level; + alt->fieldval = hybrid::current_view_level; alt->c7 = NULL; alt->alt = alt; h->alt = alt; @@ -758,10 +758,10 @@ EX void buildEquidistant(cell *c) { chance = hrand(100) < 10; } - if(c->landparam > 30 && b == laOcean && !generatingEquidistant && !prod && hrand(10) < 5 && chance) + if(c->landparam > 30 && b == laOcean && !generatingEquidistant && !hybri && hrand(10) < 5 && chance) buildAnotherEquidistant(c); - if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !prod && hrand(100) < (PURE?25:5) && items[itBone] >= 10 && chance) + if(c->landparam > HAUNTED_RADIUS+5 && b == laGraveyard && !generatingEquidistant && !hybri && hrand(100) < (PURE?25:5) && items[itBone] >= 10 && chance) buildAnotherEquidistant(c); } @@ -978,8 +978,8 @@ EX void setLandSol(cell *c) { } } -EX void setLandProduct(cell *c) { - auto wc = product::get_where(c).first; +EX void setLandHybrid(cell *c) { + auto wc = hybrid::get_where(c).first; c->barleft = wc->barleft; c->barright = wc->barright; c->bardir = wc->bardir; @@ -1278,7 +1278,7 @@ EX int wallchance(cell *c, bool deepOcean) { /** should we generate the horocycles in the current geometry? */ EX bool horo_ok() { - return hyperbolic && !binarytiling && !archimedean && !penrose && !experimental && !prod; + return hyperbolic && !binarytiling && !archimedean && !penrose && !experimental && !hybri; } EX bool gp_wall_test() { @@ -1336,7 +1336,7 @@ EX void buildBigStuff(cell *c, cell *from) { // buildgreatwalls - if(prod) ; /* Great Walls generated via the underlying geometry */ + if(hybri) ; /* Great Walls generated via the underlying geometry */ else if(geometry == gNormal && celldist(c) < 3 && !GOLDBERG) { if(top_land && c == cwt.at->master->move(3)->c7) { @@ -1666,8 +1666,8 @@ EX void moreBigStuff(cell *c) { else if(geometry == gKiteDart3) { if(kite::getshape(c->master) == kite::pKite) c->wall = waColumn; } - else if(prod) { - auto d = product::get_where(c); + else if(hybri) { + auto d = hybrid::get_where(c); if(d.first->wall == waColumn || (d.second&1)) c->wall = waColumn; } else if(WDIM == 3) { diff --git a/cell.cpp b/cell.cpp index 35d89ee6..ce761de6 100644 --- a/cell.cpp +++ b/cell.cpp @@ -146,10 +146,8 @@ EX cell *createMov(cell *c, int d) { } if(c->move(d)) return c->move(d); - else if(geometry == gProduct) - product::find_cell_connection(c, d); - else if(sl2) - slr::find_cell_connection(c, d); + else if(hybri) + hybrid::find_cell_connection(c, d); #if CAP_BT else if(penrose) kite::find_cell_connection(c, d); @@ -455,9 +453,11 @@ EX int compdist(int dx[]) { EX int celldist(cell *c) { if(experimental) return 0; - if(prod) { auto w = product::get_where(c); + if(hybri) { + auto w = hybrid::get_where(c); + if(sl2) w.second = 0; int d; - product::in_underlying_map([&] { d = celldist(w.first) + abs(w.second); }); + hybrid::in_underlying_map([&] { d = celldist(w.first) + abs(w.second); }); return d; } if(fulltorus && WDIM == 2) @@ -490,10 +490,11 @@ static const int ALTDIST_ERROR = 90000; EX int celldistAlt(cell *c) { if(experimental) return 0; - if(prod) { auto w = product::get_where(c); + if(hybri) { + auto w = hybrid::get_where(c); int d = c->master->alt && c->master->alt->alt ? c->master->alt->alt->fieldval : 0; - d = abs(w.second - d); - product::in_underlying_map([&] { d += celldistAlt(w.first); }); + d = sl2 ? 0 : abs(w.second - d); + hybrid::in_underlying_map([&] { d += celldistAlt(w.first); }); return d; } if(masterless) { @@ -1000,9 +1001,10 @@ EX cell *random_in_distance(cell *c, int d) { EX int celldistance(cell *c1, cell *c2) { - if(prod) { auto w1 = product::get_where(c1), w2 = product::get_where(c2); + if(prod) { + auto w1 = hybrid::get_where(c1), w2 = hybrid::get_where(c2); int d; - product::in_underlying_map([&] { d = celldistance(w1.first, w2.first) + abs(w1.second - w2.second); }); + hybrid::in_underlying_map([&] { d = celldistance(w1.first, w2.first) + abs(w1.second - w2.second); }); return d; } @@ -1039,7 +1041,7 @@ EX int celldistance(cell *c1, cell *c2) { if(cryst) return crystal::precise_distance(c1, c2); #endif - if(masterless || archimedean || quotient || sol || (penrose && euclid) || experimental) { + if(masterless || archimedean || quotient || sol || (penrose && euclid) || experimental || sl2) { if(saved_distances.count(make_pair(c1,c2))) return saved_distances[make_pair(c1,c2)]; diff --git a/complex.cpp b/complex.cpp index b4c4716f..2928df5b 100644 --- a/complex.cpp +++ b/complex.cpp @@ -2668,7 +2668,7 @@ EX namespace sword { }; /** dimensions available to the Sword */ - #define SWORDDIM ((prod || sl2) ? 2 : WDIM) + #define SWORDDIM (hybri ? 2 : WDIM) #endif @@ -2695,7 +2695,7 @@ EX namespace sword { cell *pos2(cell *c, int s) { int t = c->type; - if(prod || sl2) t -= 2; + if(hybri) t -= 2; s *= 2; s += sword_angles/t; s %= (2 * sword_angles); @@ -2748,7 +2748,7 @@ EX namespace sword { int s2 = neighborId(c2, c1); if(s1 < 0 || s2 < 0) return d; if(SWORDDIM == 2) { - int sub = (prod || sl2) ? 2 : 0; + int sub = (hybri) ? 2 : 0; int t2 = c2->type - sub; int t1 = c1->type - sub; if(c1->c.mirror(s1)) @@ -3397,7 +3397,7 @@ EX namespace windmap { // cw.spin = 0; neighbors.emplace_back(); auto &v = neighbors.back(); - if(NONSTDVAR && !sphere && !archimedean && !prod) + if(NONSTDVAR && !sphere && !archimedean && !hybri) for(int l=0; lrhexf = cgi.rhexf; - t->hexf = cgi.hexf; - t->crossf = cgi.crossf; - t->hcrossf = cgi.crossf; - t->tessf = cgi.tessf; - t->hexvdist = cgi.hexvdist; - t->hexhexdist = cgi.hexhexdist; + ld d = sl2 ? 2 : 1; + hybrid::in_underlying_geometry([&] { + t->rhexf = cgi.rhexf / d; + t->hexf = cgi.hexf / d; + t->crossf = cgi.crossf / d; + t->hcrossf = cgi.crossf / d; + t->tessf = cgi.tessf / d; + t->hexvdist = cgi.hexvdist / d; + t->hexhexdist = cgi.hexhexdist / d; t->base_distlimit = cgi.base_distlimit-1; }); - goto prod_finish; + goto hybrid_finish; } - if(sl2) { - dynamicval g(geometry, gNormal); - check_cgi(); - cgi.prepare_basics(); - rhexf = cgi.rhexf/2; - hexf = cgi.hexf/2; - crossf = cgi.crossf/2; - hcrossf = cgi.hcrossf/2; - tessf = cgi.tessf/2; - hexvdist = cgi.hexvdist/2; - hexhexdist = cgi.hexhexdist/2; - base_distlimit = cgi.base_distlimit-1; - cgip = this; - goto prod_finish; - } - if((sphere || hyperbolic) && WDIM == 3 && !binarytiling) { rhexf = hexf = 0.378077; crossf = hcrossf = 0.620672; @@ -561,7 +546,7 @@ void geometry_information::prepare_basics() { if(binarytiling) binary::build_tmatrix(); #endif - prod_finish: + hybrid_finish: scalefactor = crossf / hcrossf7; orbsize = crossf; @@ -935,7 +920,7 @@ EX void check_cgi() { cgip = &cgis[s]; cgi.timestamp = ++ntimestamp; - if(prod) product::underlying_cgip->timestamp = ntimestamp; + if(hybri) hybrid::underlying_cgip->timestamp = ntimestamp; if(isize(cgis) > 4) { vector> timestamps; diff --git a/geometry2.cpp b/geometry2.cpp index 128337fd..1889a7c9 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -243,14 +243,14 @@ struct horo_distance { template void virtualRebase(cell*& base, T& at, bool tohex, const U& check) { if(prod) { - auto w = product::get_where(base); + auto w = hybrid::get_where(base); auto d = product_decompose(check(at)).first; at = mscale(at, -d); - product::in_underlying_map([&] { virtualRebase(w.first, at, tohex, check); }); + hybrid::in_underlying_map([&] { virtualRebase(w.first, at, tohex, check); }); if(d > cgi.plevel / 2) { w.second++; d -= cgi.plevel; } if(d < -cgi.plevel / 2) { w.second--; d += cgi.plevel; } at = mscale(at, +d); - base = product::get_at(w.first, w.second); + base = hybrid::get_at(w.first, w.second); return; } if((euclid || sphere) && WDIM == 2) { diff --git a/graph.cpp b/graph.cpp index 840b8277..f65f8c2a 100644 --- a/graph.cpp +++ b/graph.cpp @@ -409,7 +409,7 @@ EX void drawPlayerEffects(const transmatrix& V, cell *c, bool onplayer) { int adj = 1 - ((sword_angles/cwt.at->type)&1); #if CAP_QUEUE - if(!euclid && !prod) for(int a=0; a= c->type - 2 ? 4 : 0; } const int darkval_hbt[9] = {0,2,2,0,6,6,8,8,0}; @@ -5056,7 +5056,7 @@ void drawcell_in_radar(cell *c, transmatrix V) { EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { - if(product::pmap) { product::drawcell_stack(c, V, spinv, mirrored); return; } + if(hybrid::pmap) { product::drawcell_stack(c, V, spinv, mirrored); return; } cells_drawn++; @@ -6031,7 +6031,7 @@ EX void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { for(int a=0; atype; a++) if(c->move(a) && !isWall3(c->move(a), dummy)) { - if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic && !prod && !experimental) { + if(pmodel == mdPerspective && !sphere && !quotient && !penrose && !nonisotropic && !hybri && !experimental) { if(a < 4 && among(geometry, gHoroTris, gBinary3) && celldistAlt(c) >= celldistAlt(viewcenter())) continue; else if(a < 2 && among(geometry, gHoroRec) && celldistAlt(c) >= celldistAlt(viewcenter())) continue; else if(c->move(a)->master->distance > c->master->distance && c->master->distance > viewctr.at->distance && !quotient) continue; @@ -6999,7 +6999,7 @@ EX void drawMarkers() { #endif - if(prod && !shmup::on) { + if(hybri && !shmup::on) { using namespace sword; int& ang = sword::dir[multi::cpid].angle; @@ -8043,8 +8043,7 @@ EX void drawBug(const cellwalker& cw, color_t col) { EX cell *viewcenter() { if(masterless) return centerover.at; - else if(prod) return product::get_at(viewctr.at->c7, nisot::current_view_level); - else if(sl2) return slr::get_at(viewctr.at->c7, nisot::current_view_level); + else if(hybri) return hybrid::get_at(viewctr.at->c7, hybrid::current_view_level); else return viewctr.at->c7; } diff --git a/hyper.h b/hyper.h index 4d8ad176..404cd7cc 100644 --- a/hyper.h +++ b/hyper.h @@ -127,6 +127,7 @@ void addMessage(string s, char spamtype = 0); #define nil (cgclass == gcNil) #define sl2 (cgclass == gcSL2) #define prod (cgclass == gcProduct) +#define hybri (prod || sl2) #define hyperbolic (cgclass == gcHyperbolic) #define nonisotropic (sol || nil || sl2) #define translatable (euclid || nonisotropic) diff --git a/hypgraph.cpp b/hypgraph.cpp index b88bd252..3c4d7db3 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -911,7 +911,7 @@ EX bool confusingGeometry() { } EX ld master_to_c7_angle() { - if(prod) return product::in_underlying_geometry(master_to_c7_angle); + if(prod) return hybrid::in_underlying_geometry(master_to_c7_angle); ld alpha = 0; #if CAP_GP if(cgi.gpdata) alpha = cgi.gpdata->alpha; @@ -1395,7 +1395,7 @@ EX void optimizeview() { if(cbest) { View = View * currentmap->relative_matrix(cbest, c, C0); viewctr.at = cbest->master; - nisot::current_view_level = slr::get_where(cbest).second; + hybrid::current_view_level = hybrid::get_where(cbest).second; } return; } @@ -1403,9 +1403,9 @@ EX void optimizeview() { if(prod) { ld z = zlevel(tC0(View)); View = mscale(View, -z); - product::in_underlying_map(optimizeview); - if(z > cgi.plevel / 2) { nisot::current_view_level--; z -= cgi.plevel; } - if(z < -cgi.plevel / 2) { nisot::current_view_level++; z += cgi.plevel; } + hybrid::in_underlying_map(optimizeview); + if(z > cgi.plevel / 2) { hybrid::current_view_level--; z -= cgi.plevel; } + if(z < -cgi.plevel / 2) { hybrid::current_view_level++; z += cgi.plevel; } View = mscale(View, z); return; } @@ -1500,7 +1500,7 @@ EX void resetview() { else centerover = cwt; cwtV = View; nisot::local_perspective = Id; - if(prod || sl2) nisot::current_view_level = product::get_where(cwt.at).second; + if(hybri) hybrid::current_view_level = hybrid::get_where(cwt.at).second; // SDL_LockSurface(s); // SDL_UnlockSurface(s); } @@ -1987,7 +1987,7 @@ bool limited_generation(cell *c) { EX bool do_draw(cell *c, const transmatrix& T) { - if(product::pmap) return product::in_actual([&] { return do_draw(product::get_at(c, nisot::current_view_level), T); }); + if(hybrid::pmap) return hybrid::in_actual([&] { return do_draw(hybrid::get_at(c, hybrid::current_view_level), T); }); if(WDIM == 3) { if(cells_drawn > vid.cells_drawn_limit) return false; if(nil && pmodel == mdGeodesic) { diff --git a/landgen.cpp b/landgen.cpp index 4d7bcc27..620db20d 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -315,7 +315,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) { if(d == 8 && !sphere) { - if(prod && polarb50(c) && (product::get_where(c).second & 3) == 2) { + if(prod && polarb50(c) && (hybrid::get_where(c).second & 3) == 2) { c->wall = waPalace; break; } @@ -353,19 +353,19 @@ EX void giantLandSwitch(cell *c, int d, cell *from) { if(GOLDBERG) ; else { int q = 0, s = 0; - if(!ishept(c)) for(int i=0; itype - (prod ? 2 : 0); i++) + if(!ishept(c)) for(int i=0; itype - (hybri ? 2 : 0); i++) if(cdist50(c->move(i)) == 3 && polarb50(c->move(i)) && !ishept(c->move(i))) q++, s += i; if(q == 1 && c->move(s)->land == laPalace) { switch(princess::generating ? 0 : hrand(2)) { case 0: c->wall = waClosedGate; - if(prod) toggleGates(c, waClosePlate, 1); + if(hybri) toggleGates(c, waClosePlate, 1); c->move(s)->wall = waClosedGate; break; case 1: c->wall = waOpenGate; - if(prod) toggleGates(c, waOpenPlate, 1); + if(hybri) toggleGates(c, waOpenPlate, 1); c->move(s)->wall = waOpenGate; break; } @@ -704,7 +704,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) { else if(v == 25 || v == 59 || v == 27 || v == 57) c->wall = waVineHalfB; else c->wall = waNone; - if(prod && cellHalfvine(c)) c->wall = waNone; + if(hybri && cellHalfvine(c)) c->wall = waNone; if(NONSTDVAR && cellHalfvine(c)) { c->wall = waNone; forCellCM(c2, c) if(emeraldval(c2) == (v^1)) @@ -1331,8 +1331,8 @@ EX void giantLandSwitch(cell *c, int d, cell *from) { while(i) { if(i&1) b++; i>>=1; } if(ctof(c) && (b&1) && hrand(100) < 20) c->wall = (z&2) ? waCharged : waGrounded; } - else if(prod) { - cell *c1 = product::get_where(c).first; + else if(hybri) { + cell *c1 = hybrid::get_where(c).first; if(among(c1->wall, waCharged, waGrounded)) c->wall = c1->wall; else if(hrand(100) < 15) @@ -2565,11 +2565,11 @@ EX void setdist(cell *c, int d, cell *from) { if(d <= 10 - getDistLimit()) lastexplore = shmup::on ? shmup::curtime : turncount; - if(prod) { - auto wc = product::get_where(c).first; - auto wf = from ? product::get_where(from).first : NULL; + if(hybri) { + auto wc = hybrid::get_where(c).first; + auto wf = from ? hybrid::get_where(from).first : NULL; if(c->land && !wc->land) wc->land = c->land; - product::in_underlying_map([&] { setdist(wc, d, wf); }); + hybrid::in_underlying_map([&] { setdist(wc, d, wf); }); } if(buggyGeneration) { @@ -2634,7 +2634,7 @@ EX void setdist(cell *c, int d, cell *from) { #if MAXMDIM == 4 else if(euclid && WDIM == 3) euclid3::set_land(c); #endif - else if(prod) setLandProduct(c); + else if(hybri) setLandHybrid(c); else if(sphere || fulltorus) setLandSphere(c); else if(euclid) setLandEuclid(c); else if(quotient) { setland(c, specialland); setLandQuotient(c); } diff --git a/landlock.cpp b/landlock.cpp index b531c6e1..d467f6c8 100644 --- a/landlock.cpp +++ b/landlock.cpp @@ -679,13 +679,13 @@ EX land_validity_t& land_validity(eLand l) { using namespace lv; - if(prod || product::pmap) { + if(hybri || hybrid::pmap) { if(among(l, laPrincessQuest, laPrairie, laMirrorOld, laMirror, laDual, laWarpCoast, laKraken, laBrownian, laWhirlpool, laWestWall, laHive, laClearing, laWhirlwind, laBlizzard, laBull, laTerracotta, laCrossroads5, laEndorian, laDungeon, laMountain)) return lv::not_implemented; if(among(l, laReptile, laDragon, laTortoise)) return lv::bad_graphics; - if(prod) return *PIU(&land_validity(l)); + if(hybri) return *PIU(&land_validity(l)); } #if !CAP_FIELD diff --git a/monstergen.cpp b/monstergen.cpp index 5585e87e..13e3ac20 100644 --- a/monstergen.cpp +++ b/monstergen.cpp @@ -748,7 +748,7 @@ EX void generateSnake(cell *c, int i, int snakecolor) { c2 = c3; c2->monst = moHexSnakeTail; c2->hitpoints = snakecolor; int t = c2->type; - if(prod) t -= 2; + if(hybri) t -= 2; i = (j + (t%4 == 0 ? t/2 : (len%2 ? 2 : t - 2))) % t; createMov(c2, i); if(!inpair(c2->move(i), cpair)) { diff --git a/nonisotropic.cpp b/nonisotropic.cpp index 2ea984b2..215c11df 100644 --- a/nonisotropic.cpp +++ b/nonisotropic.cpp @@ -10,7 +10,6 @@ namespace hr { EX namespace nisot { typedef array ptlow; - EX int current_view_level; EX transmatrix local_perspective; #if HDR inline bool local_perspective_used() { return nonisotropic || prod; } @@ -549,24 +548,26 @@ EX namespace nilv { } EX } -EX namespace product { +EX namespace hybrid { + EX int current_view_level; EX eGeometry underlying; EX geometry_information *underlying_cgip; - void configure() { + EX void configure(eGeometry g) { + if(g == gSL2) variation = eVariation::pure; if(vid.always3) { vid.always3 = false; geom3::apply_always3(); } check_cgi(); cgi.prepare_basics(); underlying = geometry; underlying_cgip = cgip; - geometry = gProduct; + geometry = g; ginf[gProduct] = ginf[underlying]; ginf[gProduct].cclass = gcProduct; ginf[gProduct].g.gameplay_dimension++; ginf[gProduct].g.graphical_dimension++; } - + hrmap *pmap; geometry_information *pcgip; @@ -578,7 +579,7 @@ EX namespace product { return t(); } - struct hrmap_product : hrmap { + struct hrmap_hybrid : hrmap { hrmap *underlying_map; @@ -597,6 +598,7 @@ EX namespace product { } cell *getCell(cell *u, int h) { + if(sl2) h = gmod(h, 14); cell*& c = at[make_pair(u, h)]; if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; } return c; @@ -604,38 +606,78 @@ EX namespace product { cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); } - transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override { - return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, point_hint); }) * mscale(Id, cgi.plevel * (where[c2].second - where[c1].second)); - } - - hrmap_product() { + hrmap_hybrid() { in_underlying([this] { initcells(); underlying_map = currentmap; }); for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL; } - ~hrmap_product() { + ~hrmap_hybrid() { in_underlying([this] { delete currentmap; }); for(auto& p: at) tailored_delete(p.second); } + }; + + hrmap_hybrid* hmap() { return (hrmap_hybrid*) currentmap; } + + EX cell *get_at(cell *base, int level) { + return hmap()->getCell(base, level); + } + + EX pair get_where(cell *c) { return hmap()->where[c]; } + + void find_cell_connection(cell *c, int d) { + auto m = hmap(); + if(d >= c->type - 2) { + cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1)); + 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 = sl2 ? - d1*2 + d*2 + 7 : 0; + cell *c1 = get_at(cu1, m->where[c].second + s); + c->c.connect(d, c1, d1, cu->c.mirror(d)); + } + } + + EX void in_underlying_map(const reaction_t& f) { + if(!hybri) f(); + else hmap()->in_underlying(f); + } + + #if HDR + template auto in_underlying_geometry(const T& f) -> decltype(f()) { + if(!hybri) return f(); + dynamicval g(geometry, underlying); + dynamicval gc(cgip, underlying_cgip); + return f(); + } + + #define PIU(x) hr::hybrid::in_underlying_geometry([&] { return (x); }) + #endif +EX } + +EX namespace product { + + struct hrmap_product : hybrid::hrmap_hybrid { + transmatrix relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hint) override { + return in_underlying([&] { return calc_relative_matrix(where[c2].first, where[c1].first, point_hint); }) * mscale(Id, cgi.plevel * (where[c2].second - where[c1].second)); + } + void draw() override { in_underlying([this] { currentmap->draw(); }); } }; - - EX cell *get_at(cell *base, int level) { - return ((hrmap_product*)currentmap)->getCell(base, level); - } - - EX pair get_where(cell *c) { return ((hrmap_product*)currentmap)->where[c]; } - + EX int cwall_offset, cwall_mask; void drawcell_stack(cell *c, transmatrix V, int spinv, bool mirrored) { if(sphere) gmatrix[c] = V; /* some computations need gmatrix0 for underlying geometry */ bool s = sphere; - in_actual([&] { - cell *c0 = get_at(c, nisot::current_view_level); + hybrid::in_actual([&] { + cell *c0 = hybrid::get_at(c, hybrid::current_view_level); cwall_offset = wall_offset(c0); if(s) cwall_mask = (1<type) - 1; else { @@ -653,47 +695,33 @@ EX namespace product { for(int z=-max_z; z<=max_z; z++) { if(z == 0) cwall_mask ^= (2<type); if(z == 1) cwall_mask ^= (1<type); - cell *c1 = get_at(c, nisot::current_view_level+z); + cell *c1 = hybrid::get_at(c, hybrid::current_view_level+z); setdist(c1, 7, NULL); drawcell(c1, V * mscale(Id, cgi.plevel * z), spinv, mirrored); } }); } - void find_cell_connection(cell *c, int d) { - auto m = (hrmap_product*)currentmap; - if(d >= c->type - 2) { - cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1)); - 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); }); - cell *c1 = get_at(cu1, m->where[c].second); - c->c.connect(d, c1, cu->c.spin(d), cu->c.mirror(d)); - } - } - EX hyperpoint get_corner(cell *c, int i, ld z) { ld lev = cgi.plevel * z / 2; - dynamicval g(geometry, underlying); - dynamicval gc(cgip, underlying_cgip); + dynamicval g(geometry, hybrid::underlying); + dynamicval gc(cgip, hybrid::underlying_cgip); return mscale(get_corner_position(c, i), exp(lev)); } EX int wall_offset(cell *c) { - int id = underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c); + int id = hybrid::underlying == gArchimedean ? arcm::id_of(c->master) + 20 * arcm::parent_index_of(c->master) : shvid(c); if(isize(cgi.walloffsets) <= id) cgi.walloffsets.resize(id+1, -1); int &wo = cgi.walloffsets[id]; if(wo == -1) { - cell *c1 = get_where(c).first; + cell *c1 = hybrid::get_where(c).first; wo = isize(cgi.shWall3D); int won = wo + c->type; cgi.reserve_wall3d(won); for(int i=0; itype; i++) { hyperpoint w; - in_underlying_geometry([&] { + hybrid::in_underlying_geometry([&] { /* mirror image of C0 in the axis h1-h2 */ hyperpoint h1 = get_corner_position(c1, i); hyperpoint h2 = get_corner_position(c1, i+1); @@ -722,7 +750,7 @@ EX namespace product { return wo; } - EX bool product_sphere() { return ginf[underlying].cclass == gcSphere; } + EX bool product_sphere() { return ginf[hybrid::underlying].cclass == gcSphere; } EX hyperpoint inverse_exp(hyperpoint h) { hyperpoint res; @@ -752,22 +780,6 @@ EX namespace product { return zshift(res, h[2]); } - EX void in_underlying_map(const reaction_t& f) { - if(!prod) f(); - else ((hrmap_product*)currentmap)->in_underlying(f); - } - - #if HDR - template auto in_underlying_geometry(const T& f) -> decltype(f()) { - if(!prod) return f(); - dynamicval g(geometry, underlying); - dynamicval gc(cgip, underlying_cgip); - return f(); - } - - #define PIU(x) hr::product::in_underlying_geometry([&] { return (x); }) - #endif - EX } EX namespace slr { @@ -1025,30 +1037,8 @@ EX namespace slr { return spin(2 * M_PI * i / 7) * xpush(tessf7/2) * spin(M_PI - 2 * M_PI * j / 7); } - struct hrmap_psl2 : hrmap { + struct hrmap_psl2 : hybrid::hrmap_hybrid { - hrmap *underlying_map; - - map, cell*> at; - map> where; - - heptagon *getOrigin() override { return underlying_map->getOrigin(); } - - template auto in_underlying(const T& t) -> decltype(t()) { - dynamicval g(geometry, gNormal); - dynamicval gu(currentmap, underlying_map); - return t(); - } - - cell *getCell(cell *u, int h) { - h = gmod(h, 14); - cell*& c = at[make_pair(u, h)]; - if(!c) { c = newCell(u->type+2, u->master); where[c] = {u, h}; } - return c; - } - - cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); } - virtual transmatrix relative_matrix(cell *c2, cell *c1, const struct hyperpoint& point_hint) override { for(int i=0; itype; i++) if(c1->move(i) == c2) return adjmatrix(i, c1->c.spin(i)); if(gmatrix0.count(c2) && gmatrix0.count(c1)) @@ -1082,40 +1072,8 @@ EX namespace slr { } } } - - hrmap_psl2() { - in_underlying([this] { initcells(); underlying_map = currentmap; }); - for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL; - } - - ~hrmap_psl2() { - in_underlying([this] { delete currentmap; }); - for(auto& p: at) tailored_delete(p.second); - } - }; - EX cell *get_at(cell *base, int level) { - return ((hrmap_psl2*)currentmap)->getCell(base, level); - } - - EX pair get_where(cell *c) { return ((hrmap_psl2*)currentmap)->where[c]; } - - void find_cell_connection(cell *c, int d) { - auto m = (hrmap_psl2*)currentmap; - if(d >= c->type - 2) { - cell *c1 = get_at(m->where[c].first, m->where[c].second + (d == c->type-1 ? 1 : -1)); - 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); - cell *c1 = get_at(cu1, m->where[c].second - d1*2 + d*2 + 7); - c->c.connect(d, c1, d1, false); - } - } - EX } EX namespace nisot { diff --git a/pattern2.cpp b/pattern2.cpp index 89a5285c..c11df658 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -56,7 +56,7 @@ int eupattern4(cell *c) { EX bool ishept(cell *c) { // EUCLIDEAN if(euclid) return eupattern(c) == 0; - else return c->type == S7 + (prod ? 2 : 0); + else return c->type == S7 + (hybri ? 2 : 0); } EX bool ishex1(cell *c) { @@ -372,10 +372,10 @@ EX pair fieldval(cell *c) { EX int fieldval_uniq(cell *c) { if(experimental) return 0; - else if(prod) { - auto c1 = product::get_where(c).first; + else if(hybri) { + auto c1 = hybrid::get_where(c).first; int res; - product::in_underlying_map([&] { res = fieldval_uniq(c1); }); + hybrid::in_underlying_map([&] { res = fieldval_uniq(c1); }); return res; } else if(sphere) { @@ -409,10 +409,10 @@ EX int fieldval_uniq(cell *c) { } EX int fieldval_uniq_rand(cell *c, int randval) { - if(prod) { - auto c1 = product::get_where(c).first; + if(hybri) { + auto c1 = hybrid::get_where(c).first; int res; - product::in_underlying_map([&] { res = fieldval_uniq_rand(c1, randval); }); + hybrid::in_underlying_map([&] { res = fieldval_uniq_rand(c1, randval); }); return res; } if(sphere || euclid || NONSTDVAR) @@ -1374,7 +1374,7 @@ EX bool pseudohept(cell *c) { #if CAP_IRR if(IRREGULAR) return irr::pseudohept(c); #endif - if(prod) { auto d = product::get_where(c); return (d.second & 1) && PIU(pseudohept(d.first)); } + if(hybri) { auto d = hybrid::get_where(c); return (sl2 ? true : (d.second & 1)) && PIU(pseudohept(d.first)); } #if CAP_BT if(nil) return c->master->zebraval & c->master->emeraldval & c->master->fieldval & 1; if(sol) return (c->master->emeraldval % 3 == 2) && (c->master->zebraval % 3 == 2) && (c->master->distance % 2); diff --git a/polygons.cpp b/polygons.cpp index ebcad020..06a808a8 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1113,7 +1113,7 @@ void geometry_information::prepare_shapes() { #endif DEBBI(DF_POLY, ("buildpolys")); - if(WDIM == 3 && !prod) { + if(WDIM == 3 && !hybri) { if(sphere) SD3 = 3, SD7 = 5; else SD3 = SD7 = 4; } diff --git a/system.cpp b/system.cpp index 7d225c94..7e9a6298 100644 --- a/system.cpp +++ b/system.cpp @@ -872,7 +872,7 @@ EX void saveStats(bool emergency IS(false)) { if(randomPatternsMode) return; if(dual::state) return; if(archimedean) return; - if(prod) return; + if(hybri) return; if(daily::on) return; if(peace::on) return; if(!gold()) return; @@ -1159,7 +1159,7 @@ EX void set_geometry(eGeometry target) { int old_DIM = GDIM; stop_game(); ors::reset(); - if(target == gProduct) product::configure(); + if(among(target, gProduct, gSL2)) hybrid::configure(target); geometry = target; if(chaosmode && bounded) chaosmode = false; @@ -1288,7 +1288,7 @@ EX void switch_game_mode(char switchWhat) { chaosmode = false; princess::challenge = false; if(sol || bounded) set_geometry(gNormal); - if(prod) set_geometry(product::underlying); + if(prod) set_geometry(hybrid::underlying); dual::disable(); break; #endif @@ -1310,7 +1310,7 @@ EX void switch_game_mode(char switchWhat) { shmup::on = !shmup::on; princess::challenge = false; if(!shmup::on) racing::on = false; - if(prod) set_geometry(product::underlying); + if(prod) set_geometry(hybrid::underlying); break; case rg::randpattern: diff --git a/yendor.cpp b/yendor.cpp index e8f6dabc..07776a1f 100644 --- a/yendor.cpp +++ b/yendor.cpp @@ -219,7 +219,7 @@ EX namespace yendor { nyi.path[0] = yendor; } - else if(prod) { + else if(hybri) { /* I am lazy */ for(int i=1; i<=YDIST-1; i++) nyi.path[i] = nyi.path[i-1]->cmove(nyi.path[i-1]->type-1); } @@ -1055,7 +1055,7 @@ int modecodetable[42][6] = { modecode_t modecode() { // bit 61: product - if(prod) return PIU(modecode()) | (1ll << 61); + if(hybri) return PIU(modecode()) | (1ll << 61); #if CAP_SAVE if(anticheat::tampered || cheater || geometry >= gGUARD) return 6; #endif