From 635d1f911c2c1168317678563a195a0e57f17446 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 9 Dec 2017 03:48:30 +0100 Subject: [PATCH] Refactoring: moved all the remaining pattern code from mapeditor to pattern2 --- commandline.cpp | 6 +- geometry.cpp | 2 - graph.cpp | 30 +- hyper.h | 29 +- init.cpp | 1 + landgen.cpp | 4 +- mapeditor.cpp | 754 ++++++------------------------------------------ pattern2.cpp | 596 +++++++++++++++++++++++++++++++++++++- polygons.cpp | 2 +- rogueviz.cpp | 4 +- system.cpp | 3 +- textures.cpp | 6 +- tour.cpp | 14 +- 13 files changed, 734 insertions(+), 717 deletions(-) diff --git a/commandline.cpp b/commandline.cpp index a962d733..ec0cfac9 100644 --- a/commandline.cpp +++ b/commandline.cpp @@ -72,8 +72,8 @@ int arg::readCommon() { else if(argis("-canvas")) { firstland = specialland = laCanvas; shift(); - if(args()[1] == 0) mapeditor::whichCanvas = args()[0]; - else mapeditor::canvasback = strtol(args(), NULL, 16); + if(args()[1] == 0) patterns::whichCanvas = args()[0]; + else patterns::canvasback = strtol(args(), NULL, 16); } else if(argis("-noplayer")) mapeditor::drawplayer = !mapeditor::drawplayer; @@ -81,7 +81,7 @@ int arg::readCommon() { PHASE(3); shift(); char *c = args(); - using namespace mapeditor; + using namespace patterns; sym01 = sym02 = sym03 = symRotation = false; while(*c) { if(*c == '1') sym01 = true; diff --git a/geometry.cpp b/geometry.cpp index 699259d0..8964144a 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -15,8 +15,6 @@ ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf; // hepvdist: distance between heptagon vertex and hexagon center (either hcrossf or something else) // rhexf: distance from heptagon center to heptagon vertex (either hexf or hcrossf) -#define ALPHA (M_PI*2/S7) - hyperpoint Crad[MAX_S84]; transmatrix heptmove[MAX_EDGE], hexmove[MAX_EDGE]; diff --git a/graph.cpp b/graph.cpp index d799a020..f2721632 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2187,17 +2187,17 @@ int countMinesAround(cell *c) { return mines; } -transmatrix applyPatterndir(cell *c, char patt = mapeditor::whichPattern) { - transmatrix V = ddspin(c, mapeditor::patterndir(c, patt), S42); +transmatrix applyPatterndir(cell *c, char patt = patterns::whichPattern) { + transmatrix V = ddspin(c, patterns::patterndir(c, patt), S42); - if(mapeditor::reflectPatternAt(c, patt)) + if(patterns::reflectPatternAt(c, patt)) return V * Mirror; return V; } transmatrix applyDowndir(cell *c, cellfunction *cf) { - return ddspin(c, mapeditor::downdir(c, cf), S42); + return ddspin(c, patterns::downdir(c, cf), S42); } void drawTowerFloor(const transmatrix& V, cell *c, int col, cellfunction *cf = coastvalEdge) { @@ -2883,7 +2883,7 @@ void plainfloor(cell *c, bool warp, const transmatrix &V, int col, int prio) { queuepolyat(V, shTriheptaFloor[ctof(c)], col, prio); } else - queuepolyat(V * applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : mapeditor::nopattern(c)], col, prio); + queuepolyat(V * applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : patterns::nopattern(c)], col, prio); } else if(c->land == laDual && !nontruncated) { if(euclid && ishex1(c)) @@ -2907,7 +2907,7 @@ void qplainfloor(cell *c, bool warp, const transmatrix &V, int col) { qfloor(c, V, applyPatterndir(c), shTriheptaFloor[ctof(c)], col); } else - qfloor(c, V, applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : mapeditor::nopattern(c)], col); + qfloor(c, V, applyPatterndir(c), shTriheptaFloor[sphere ? ctof(c) : patterns::nopattern(c)], col); } else if(c->land == laDual && !nontruncated) qfloor_eswap(c, V, shBigTriangle, col); @@ -3518,21 +3518,21 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } #if CAP_EDIT - if(mapeditor::drawUserShape(Vpdir, mapeditor::cellShapeGroup(), mapeditor::realpattern(c), + if(mapeditor::drawUserShape(Vpdir, mapeditor::cellShapeGroup(), patterns::realpattern(c), darkena(fcol, fd, (cmode & sm::DRAW) ? 0xC0 : 0xFF), c)); - else if(mapeditor::whichShape == '7') { + else if(patterns::whichShape == '7') { if(ishept(c)) qfloor(c, Vf, wmblack ? shBFloor[ct6] : euclid ? shBigHex : shBigHepta, darkena(fcol, fd, 0xFF)); } - else if(mapeditor::whichShape == '8') { + else if(patterns::whichShape == '8') { qfloor_eswap(c, Vf, shTriheptaFloor[ctof(c)], darkena(fcol, fd, 0xFF)); } - else if(mapeditor::whichShape == '6') { + else if(patterns::whichShape == '6') { if(!ishept(c)) qfloor(c, Vf, wmblack ? shBFloor[ct6] : @@ -3675,7 +3675,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { } else if(isWarped(c) && !nontruncated && !shmup::on) { - int np = mapeditor::nopattern(c); + int np = patterns::nopattern(c); if(c->landparam == 1337) np = 0; // for the achievement screenshot if(np < 13) qfloor(c, Vf, applyPatterndir(c), shTriheptaFloor[np], darkena(fcol, fd, 0xFF)); @@ -3903,9 +3903,9 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if CAP_EDIT - if(mapeditor::displaycodes) { + if(patterns::displaycodes) { - int labeli = mapeditor::displaycodes == 1 ? mapeditor::realpattern(c) : mapeditor::subpattern(c); + int labeli = patterns::displaycodes == 1 ? patterns::realpattern(c) : patterns::subpattern(c); string label = its(labeli); queuestr(V, .5, label, 0xFF000000 + forecolor); @@ -4582,7 +4582,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if CAP_EDIT if((cmode & sm::MAP) && lmouseover && darken == 0 && !mouseout() && - (mapeditor::whichPattern ? mapeditor::subpattern(c) == mapeditor::subpattern(lmouseover) : c == lmouseover)) { + (patterns::whichPattern ? patterns::subpattern(c) == patterns::subpattern(lmouseover) : c == lmouseover)) { queuecircle(V, .78, 0x00FFFFFF); } @@ -5157,7 +5157,7 @@ void drawfullmap() { if(pmodel == mdPolygonal || pmodel == mdPolynomial) polygonal::drawBoundary(darkena(0xFF, 0, 0xFF)); - /* if(vid.wallmode < 2 && !euclid && !mapeditor::whichShape) { + /* if(vid.wallmode < 2 && !euclid && !patterns::whichShape) { int ls = size(lines); if(ISMOBILE) ls /= 10; for(int t=0; t> (darken+1)); diff --git a/hyper.h b/hyper.h index 7b5c30db..01ac13ef 100644 --- a/hyper.h +++ b/hyper.h @@ -652,19 +652,28 @@ extern string mouseovers; extern struct SDL_Surface *s; -namespace mapeditor { - extern bool drawplayer; - extern char whichPattern, whichShape; - extern char whichCanvas; +namespace patterns { + extern char whichShape; + extern char whichPattern; extern bool symRotation, sym01, sym02, sym03; - extern int displaycodes; - int generateCanvas(cell *c); - void applyModelcell(cell *c); + extern char whichCanvas; + extern int displaycodes; + + int generateCanvas(cell *c); int realpattern(cell *c, char w = whichPattern); int patterndir(cell *c, char w = whichPattern); bool reflectPatternAt(cell *c, char p = whichPattern); int subpattern(cell *c, char w = whichPattern); + } + +namespace mapeditor { +#if CAP_EDIT + extern map modelcell; +#endif + + extern bool drawplayer; + void applyModelcell(cell *c); extern cell *drawcell; void initdraw(cell *c); @@ -2311,3 +2320,9 @@ extern const unsigned int nestcolors[8]; extern bool texture_on; void showTextureMenu(); + +void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf = 0, int prio = PPR_LINE); + +hyperpoint ddi0(ld dir, ld dist); +extern ld tessf, crossf, hexf, hcrossf, hexhexdist, hexvdist, hepvdist, rhexf; +unsigned char& part(int& col, int i); diff --git a/init.cpp b/init.cpp index f1870421..e6839b3d 100644 --- a/init.cpp +++ b/init.cpp @@ -345,6 +345,7 @@ using namespace std; void addMessage(string s, char spamtype = 0); +#define ALPHA (M_PI*2/S7) #define S7 ginf[geometry].sides #define S3 ginf[geometry].vertex #define weirdhyperbolic (S7 > 7 || S3 > 3) diff --git a/landgen.cpp b/landgen.cpp index 59bf6bdd..fa2f6563 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -2161,7 +2161,7 @@ void setdist(cell *c, int d, cell *from) { } if(d == BARLEV && c->land == laCanvas) { - c->landparam = mapeditor::generateCanvas(c); + c->landparam = patterns::generateCanvas(c); } if(d >= BARLEV-1 && c->land == laPrairie) @@ -2225,7 +2225,7 @@ void setdist(cell *c, int d, cell *from) { if(d == 7) playSeenSound(c); #if CAP_EDIT - if(d >= 7 && mapeditor::whichPattern) + if(d >= 7 && patterns::whichPattern) mapeditor::applyModelcell(c); #endif } diff --git a/mapeditor.cpp b/mapeditor.cpp index 91cba38e..ae50d16b 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -12,8 +12,6 @@ #endif namespace mapeditor { - int subcanvas; - int displaycodes; struct editwhat { double dist; @@ -30,9 +28,8 @@ namespace mapeditor { bool handleKeyFile(int sym, int uni); void applyModelcell(cell *c) { - if(mapeditor::whichPattern == 'H') return; - if(mapeditor::whichPattern == 'H') return; - int i = realpattern(c); + if(patterns::whichPattern == 'H') return; + int i = patterns::realpattern(c); cell *c2 = modelcell[i]; if(c2) { c->wall = c2->wall; @@ -45,7 +42,7 @@ namespace mapeditor { c->stuntime = c2->stuntime; c->hitpoints = c2->hitpoints; if(c2->mondir != NODIR) - c->mondir = (c2->mondir - patterndir(c2) + patterndir(c) + MODFIXER) % c->type; + c->mondir = (c2->mondir - patterns::patterndir(c2) + patterns::patterndir(c) + MODFIXER) % c->type; } } #endif @@ -87,7 +84,7 @@ namespace mapstream { f = fopen(fname, "wb"); if(!f) return false; int32_t i = VERNUM; save(i); - save(mapeditor::whichPattern); + save(patterns::whichPattern); save(geometry); save(nontruncated); if(geometry == gTorus) { @@ -170,7 +167,7 @@ namespace mapstream { if(!f) return false; clearMemory(); int vernum = loadInt(); - if(vernum >= 7400) load(mapeditor::whichPattern); + if(vernum >= 7400) load(patterns::whichPattern); if(vernum >= 10203) { load(geometry); @@ -241,8 +238,8 @@ namespace mapstream { c->stuntime = loadChar(); c->hitpoints = loadChar(); - if(mapeditor::whichPattern) - mapeditor::modelcell[mapeditor::realpattern(c)] = c; + if(patterns::whichPattern) + mapeditor::modelcell[patterns::realpattern(c)] = c; } int32_t whereami = loadInt(); @@ -311,57 +308,7 @@ namespace mapstream { namespace mapeditor { bool drawplayer = true; - char whichPattern = 0; - char whichShape = 0; - char whichCanvas = 0; - bool symRotation, sym01, sym02, sym03; - - int subpattern(int i, char w) { - if(euclid) { - if(w == 'p') - return i; - if(w == 'z' || w == 'f') - return (symRotation && (i<3)) ? 0 : i; - } - - if(a38 && w == 'p') { - if(sym01 && i == 5) i = 4; - if(symRotation && i < 4) i = 0; - return i; - } - - if(w == 'z' || w == 'f' || w == 'p') { - if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3; - if(sym01 && (i&1)) i ^= 1; - if(sym02 && (i&2)) i ^= 2; - if(sym03 && (i&2)) i ^= 3; - } - - if(w == 'z' && symRotation) { - if(a4 && !a46) { - if(i >= 4 && i < 7) i -= 4; - } - else { - if(i >= 8 && i < 12) i -= 4; - if(i >= 12 && i < 16) i -= 8; - if(i >= 20 && i < 24) i -= 4; - if(i >= 24 && i < 28) i -= 8; - if(i >= 32 && i < 36) i -= 4; - if(i >= 36 && i < 40) i -= 8; - } - } - - if(w == 'p' && stdhyperbolic && symRotation && i >= 3) - i -= ((i/4-1) % 7) * 4; - - return i; - } - - int subpattern(cell *c, char w) { - return subpattern(realpattern(c, w), w); - } - string infix; bool hasInfix(const string &s) { @@ -598,205 +545,6 @@ namespace mapeditor { v.push_back(make_pair(s, i)); } - void showPrePattern() { - dialog::init("predesigned patterns"); - dialog::addItem(XLAT("Gameboard"), 'g'); - dialog::addItem(XLAT("random colors"), 'r'); - dialog::addItem(XLAT("rainbow landscape"), 'l'); - dialog::addItem(XLAT("dark rainbow landscape"), 'd'); - dialog::addItem(XLAT("football"), 'F'); - - dialog::addItem(XLAT("nice coloring"), 'T'); - - dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e'); - - dialog::addSelItem(XLAT("four elements"), "palace", 'b'); - dialog::addSelItem(XLAT("eight domains"), "palace", 'a'); - - dialog::addSelItem(XLAT("zebra pattern"), "zebra", 'z'); - dialog::addSelItem(XLAT("four triangles"), "zebra", 't'); - dialog::addSelItem(XLAT("three stripes"), "zebra", 'x'); - - dialog::addSelItem(XLAT("random black-and-white"), "current", 'w'); - - dialog::addSelItem(XLAT("field pattern C"), "field", 'C'); - dialog::addSelItem(XLAT("field pattern D"), "field", 'D'); - dialog::addSelItem(XLAT("field pattern N"), "field", 'N'); - dialog::addSelItem(XLAT("field pattern S"), "field", 'S'); - - dialog::display(); - - keyhandler = [] (int sym, int uni) { - dialog::handleNavigation(sym, uni); - if((uni >= 'a' && uni <= 'z') || (uni >= 'A' && uni <= 'Z')) { - whichCanvas = uni; - subcanvas = rand(); - firstland = specialland = laCanvas; - randomPatternsMode = false; - restartGame(); - } - else if(doexiton(sym, uni)) popScreen(); - }; - } - - void showPattern() { - cmode = sm::SIDE | sm::MAYDARK; - { - dynamicval dc(displaycodes, displaycodes ? displaycodes : 2); - gamescreen(0); - } - dialog::init(); - - if(a46) { - dialog::addBoolItem(XLAT("two colors"), (whichPattern == 'f'), 'f'); - dialog::addBoolItem(XLAT("two colors rotated"), (whichPattern == 'z'), 'z'); - } - else if(a4) { - dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z'); - } - else if(a38) { - dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z'); - dialog::addBoolItem(XLAT("broken Emerald Pattern"), (whichPattern == 'f'), 'f'); - dialog::addBoolItem(XLAT("rotated pattern"), (whichPattern == 'p'), 'p'); - } - else if(euclid) { - dialog::addBoolItem(XLAT("three colors"), (whichPattern == 'f'), 'f'); - dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p'); - dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z'); - } - else if(sphere) { - dialog::addBoolItem(XLAT("siblings"), (whichPattern == 'p'), 'p'); - } - else { - if(!stdhyperbolic) - dialog::addInfo("patterns do not work correctly in this geometry!"); - - dialog::addBoolItem(XLAT("Emerald Pattern"), (whichPattern == 'f'), 'f'); - dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p'); - dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z'); - } - if(euclid) - dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F'); - else if(sphere) - dialog::addBoolItem(XLAT("single cells"), (whichPattern == 'F'), 'F'); - else - dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F'); - - if(whichPattern == 'f' && stdhyperbolic) symRotation = true; - if(whichPattern == 'F') ; - else if(!euclid) { - dialog::addBoolItem(XLAT("rotational symmetry"), (symRotation), '0'); - dialog::addBoolItem(XLAT("symmetry 0-1"), (sym01), '1'); - dialog::addBoolItem(XLAT("symmetry 0-2"), (sym02), '2'); - dialog::addBoolItem(XLAT("symmetry 0-3"), (sym03), '3'); - } - else - dialog::addBoolItem(XLAT("edit all three colors"), (symRotation), '0'); - - dialog::addBoolItem(XLAT("display pattern codes (full)"), (displaycodes == 1), 'd'); - dialog::addBoolItem(XLAT("display pattern codes (simplified)"), (displaycodes == 2), 's'); - - dialog::addBoolItem(XLAT("display only hexagons"), (whichShape == '6'), '6'); - dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7'); - dialog::addBoolItem(XLAT("display the triheptagonal grid"), (whichShape == '8'), '8'); - if(cheater || autocheat) dialog::addItem(XLAT("line patterns"), 'l'); - else dialog::addInfo("enable the cheat mode to use line patterns"); - - if(!needConfirmation()) dialog::addItem(XLAT("predesigned patterns"), 'r'); - else dialog::addInfo("start a new game to use predesigned patterns"); - - dialog::display(); - - keyhandler = [] (int sym, int uni) { - dialog::handleNavigation(sym, uni); - if(uni == 'f' || uni == 'p' || uni == 'z' || uni == 'H' || uni == 'F') { - if(whichPattern == uni) whichPattern = 0; - else whichPattern = uni; - modelcell.clear(); - } - - else if(uni == '0') symRotation = !symRotation; - else if(uni == '1') sym01 = !sym01; - else if(uni == '2') sym02 = !sym02; - else if(uni == '3') sym03 = !sym03; - else if(uni == '6' || uni == '7' || uni == '8') { - if(whichShape == uni) whichShape = 0; - else whichShape = uni; - } - else if(uni == '3') sym03 = !sym03; - else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1; - else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2; - - else if(uni == 'l' && (cheater || autocheat)) - pushScreen(linepatterns::showMenu); - - else if(uni == 'r' && !needConfirmation()) pushScreen(showPrePattern); - - else if(doexiton(sym, uni)) popScreen(); - }; - } - - void showList() { - v.clear(); - if(painttype == 4) painttype = 0; - switch(painttype) { - case 0: - for(int i=0; i= '1' && uni <= '9') uni = 1000 + uni - '1'; - if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER || sym == '-' || sym == SDLK_KP_MINUS) uni = 1000; - for(int z=0; zmonst) return drawcell->monst; if(drawcell->item) return drawcell->item; - return subpattern(drawcell); + return patterns::subpattern(drawcell); } bool editingShape(int group, int id) { if(group != mapeditor::drawcellShapeGroup()) return false; if(group < 3) return id == drawcellShapeID(); - return subpattern(id, whichPattern) == subpattern(drawcell); + return patterns::subpattern(id, patterns::whichPattern) == patterns::subpattern(drawcell); } void editCell(const pair& where) { @@ -982,7 +731,7 @@ namespace mapeditor { void allInPattern(cellwalker where) { - if(!whichPattern) { + if(!patterns::whichPattern) { editAt(where); return; } @@ -1004,13 +753,13 @@ namespace mapeditor { int cdir = where.spin; if(cdir >= 0) - cdir = cdir - patterndir(where.c); - int sp = subpattern(where.c); + cdir = cdir - patterns::patterndir(where.c); + int sp = patterns::subpattern(where.c); for(cell* c2: v) - if(subpattern(c2) == sp) { - editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + patterndir(c2), c2) : -1)); - modelcell[realpattern(c2)] = c2; + if(patterns::subpattern(c2) == sp) { + editAt(cellwalker(c2, cdir>=0 ? fixdir(cdir + patterns::patterndir(c2), c2) : -1)); + modelcell[patterns::realpattern(c2)] = c2; } } @@ -1063,6 +812,67 @@ namespace mapeditor { return cellwalker(mouseover, d); } + void showList() { + v.clear(); + if(painttype == 4) painttype = 0; + switch(painttype) { + case 0: + for(int i=0; i= '1' && uni <= '9') uni = 1000 + uni - '1'; + if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER || sym == '-' || sym == SDLK_KP_MINUS) uni = 1000; + for(int z=0; z> 2; - - int generateCanvas(cell *c) { - if(whichCanvas == 'C' && !torus) { - using namespace fieldpattern; - int z = currfp.getdist(fieldval(c), make_pair(0,false)); - if(z < currfp.circrad) return 0x00C000; - int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false)); - if(z2 < currfp.disthep[currfp.otherpole] - currfp.circrad) - return 0x3000; - return 0x6000; - } - if(whichCanvas == 'D' && !torus) { - using namespace fieldpattern; - int z = currfp.getdist(fieldval(c), make_pair(0,false)); - return 255 * (currfp.maxdist+1-z) / currfp.maxdist; - } - if(whichCanvas == 'N' && !torus) { - using namespace fieldpattern; - int z = currfp.getdist(fieldval(c), make_pair(0,false)); - int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false)); - if(z < z2) return 0x00C000; - if(z > z2) return 0xC00000; - return 0xCCCC00; - } - if(whichCanvas == 'S' && !torus) { - return 0x3F1F0F * fieldpattern::subval(c).second + 0x000080; - } - if(whichCanvas == 'g') - return canvasback; - if(whichCanvas == 'r') - return hrand(0xFFFFFF + 1); - if(whichCanvas == 'e') { - static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 }; - int fv = emeraldval(c); - return fcol[fv&3]; - } - if(whichCanvas == 'a') { - static unsigned int fcol8[8] = { - 0x800000, - 0x503000, - 0x206000, - 0x007010, - 0x004040, - 0x001070, - 0x200060, - 0x500030 - }; - - if(c->wall == waNone) { - int col = fcol8[land50(c)]; - if(polara50(c)) col += 0x181818; - return col; - } - } - if(whichCanvas == 'b') { - static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 }; - return fcol[polara50(c) + 2 * polarb50(c)]; - } - if(whichCanvas == 'z') { - static unsigned int fcol[4] = { 0xC0C0C0, 0xE0E0E0, 0x404040, 0x606060 }; - int fv = zebra40(c); - return fcol[fv&3]; - } - if(whichCanvas == 't') { - static unsigned int fcol[4] = { 0x804040, 0x408040, 0x404080, 0x808040 }; - int fv = zebra40(c); - if(fv/4 == 4 || fv/4 == 6 || fv/4 == 5 || fv/4 == 10) fv ^= 2; - return fcol[fv&3]; - } - if(whichCanvas == 'x') { - static unsigned int fcol[4] = { 0xC0C0C0, 0x800000, 0x008000, 0x000080 }; - return fcol[zebra3(c)]; - } - if(whichCanvas == 'w') { - static unsigned int fcol[2] = { 0x303030, 0xC0C0C0 }; - return fcol[randpattern(c, subcanvas) ? 1 : 0]; - } - if(whichCanvas == 'l') { - int col[4]; - bool err = false; - for(int j=0; j<4; j++) { - col[j] = getCdata(c, j); - col[j] *= 3; - col[j] %= 240; - if(col[j] > 120) col[j] = 240 - col[j]; - if(col[j] < -120) col[j] = -240 - col[j]; - } - return (0x808080 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); - } - if(whichCanvas == 'd') { - int col[4]; - bool err = false; - for(int j=0; j<4; j++) { - col[j] = getCdata(c, j); - col[j] *= 6; - col[j] %= 240; - if(col[j] > 120) col[j] = 240 - col[j]; - if(col[j] < -120) col[j] = -240 - col[j]; - } - col[0] /= 8; - col[1] /= 8; - col[2] /= 8; - return (0x101010 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); - } - if(whichCanvas == 'h') { - int col[4]; - bool err = false; - for(int j=0; j<4; j++) { - col[j] = getCdata(c, j); - col[j] *= 6; - col[j] %= 240; - if(col[j] > 120) col[j] = 240 - col[j]; - if(col[j] < -120) col[j] = -240 - col[j]; - } - col[0] /= 4; - col[1] /= 4; - col[2] /= 4; - return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); - } - if(whichCanvas == 'F') { - return pseudohept(c) ? 0x202020 : 0xC0C0C0; - } - if(whichCanvas == 'T') { - int fv = pattern_threecolor(c); - return nestcolors[fv&7]; - } - return canvasback; - } - void initdraw(cell *c) { mapeditor::drawcell = c; ew.c = c; @@ -1958,273 +1638,3 @@ namespace mapeditor { } -namespace linepatterns { - - int lessalpha(int col, int m) { - part(col, 0) /= m; - return col; - } - - int lessalphaif(int col, bool b) { - return b?lessalpha(col, 4):col; - } - - int lessalphaif(int col, bool b1, bool b2) { - if(b1) col = lessalpha(col, 2); - if(b2) col = lessalpha(col, 2); - return col; - } - - struct { - int id; - const char *lpname; - unsigned int color; - } patterns[] = { - - {patTriNet, "triangle grid: not rings", 0xFFFFFF00}, - {patTriRings, "triangle grid: rings", 0xFFFFFF00}, - {patHepta, "heptagonal grid", 0x0000C000}, - {patRhomb, "rhombic tesselation", 0x0000C000}, - {patTrihepta, "triheptagonal tesselation", 0x0000C000}, - {patNormal, "normal tesselation", 0x0000C000}, - {patBigTriangles, "big triangular grid", 0x00606000}, - {patBigRings, "big triangles: rings", 0x0000C000}, - - {patTree, "underlying tree", 0x00d0d000}, - {patAltTree, "circle/horocycle tree", 0xd000d000}, - - {patZebraTriangles, "zebra triangles", 0x40FF4000}, - {patZebraLines, "zebra lines", 0xFF000000}, - {patVine, "vineyard pattern", 0x8438A400}, - {patPalacelike, "firewall lines", 0xFF400000}, - {patPalace, "firewall lines: Palace", 0xFFD50000}, - {patPower, "firewall lines: Power", 0xFFFF0000}, - {0, NULL, 0} - }; - - void clearAll() { - for(int k=0; patterns[k].lpname; k++) patterns[k].color &= ~255; - } - - bool any() { - for(int k=0; patterns[k].lpname; k++) if(patterns[k].color & 255) return true; - return false; - } - - void setColor(ePattern id, int col) { - for(int k=0; patterns[k].lpname; k++) - if(patterns[k].id == id) patterns[k].color = col; - } - - void switchAlpha(ePattern id, int col) { - for(int k=0; patterns[k].lpname; k++) - if(patterns[k].id == id) patterns[k].color ^= col; - } - - void drawPattern(int id, int col, cell *c, const transmatrix& V) { - - switch(id) { - - case patZebraTriangles: - if(zebra40(c) / 4 == 10) { - bool all = true; - hyperpoint tri[3]; - for(int i=0; i<3; i++) { - cell *c2 = createMov(c, i*2); - if(!gmatrix.count(c2)) all = false; - else tri[i] = tC0(gmatrix[c2]); - } - - if(all) for(int i=0; i<3; i++) - queueline(tri[i], tri[(i+1)%3], col, 3); - } - break; - - case patZebraLines: - if(!pseudohept(c)) for(int i=0; itype; i+=2) { - cell *c2 = createMov(c, i); - int fv1 = zebra40(c); - if(fv1/4 == 4 || fv1/4 == 6 || fv1/4 == 5 || fv1/4 == 10) fv1 ^= 2; - int fv2 = zebra40(c2); - if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2; - if((fv1&1) == (fv2&1)) continue; - - double x = sphere?.3651:euclid?.2611:.2849; - - queueline(V * ddspin(c,i,-S14) * xpush0(x), - V * ddspin(c,i,+S14) * xpush0(x), - col, 1); - } - break; - - case patNormal: { - double x = sphere?.401:euclid?.3 : .328; - if(euclid || !pseudohept(c)) for(int t=0; ttype; t++) - if(euclid ? c->mov[t]mov[t] < c)) - queueline(V * ddspin(c,t,-S7) * xpush0(x), - V * ddspin(c,t,+S7) * xpush0(x), - col, 1); - break; - } - - case patTrihepta: - if(!pseudohept(c)) for(int i=0; i<6; i++) { - cell *c2 = c->mov[i]; - if(!c2 || !pseudohept(c2)) continue; - double x = sphere?.3651:euclid?.2611:.2849; - queueline(V * ddspin(c,i,-S14) * xpush0(x), - V * ddspin(c,i,+S14) * xpush0(x), - col, 1); - } - break; - - case patTriNet: - forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) { - queueline(tC0(V), gmatrix[c2]*C0, - darkena(backcolor ^ 0xFFFFFF, 0, col), - 2); - } - break; - - case patTriRings: - forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2)) - queueline(tC0(V), gmatrix[c2]*C0, - darkena(backcolor ^ 0xFFFFFF, 0, col), - 2); - break; - - case patHepta: - forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2)) - queueline(tC0(V), gmatrix[c2]*C0, - darkena(backcolor ^ 0xFFFFFF, 0, col), - 2); - break; - - case patRhomb: - forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2)) - queueline(tC0(V), gmatrix[c2]*C0, - darkena(backcolor ^ 0xFFFFFF, 0, col), - 2); - break; - - case patPalace: { - int a = polarb50(c); - if(pseudohept(c)) for(int i=0; i<7; i++) { - cell *c1 = createMov(c, (i+3) % 7); - cell *c2 = createMov(c, (i+4) % 7); - if(polarb50(c1) != a && polarb50(c2) != a) - queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2), - V * ddspin(c,i,84*9/14) * xpush0(tessf/2), - col, 1); - } - break; - } - - case patPalacelike: - if(pseudohept(c)) for(int i=0; i<7; i++) - queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2), - V * ddspin(c,i,84*9/14) * xpush0(tessf/2), - col, 1); - break; - - case patBigTriangles: { - if(pseudohept(c) && !euclid) for(int i=0; imaster->move[i] < c->master) { - queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2); - } - break; - } - - case patBigRings: { - if(pseudohept(c) && !euclid) for(int i=0; imaster->move[i] && c->master->move[i] < c->master && c->master->move[i]->dm4 == c->master->dm4) - queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2); - break; - } - - case patTree: - if(ctof(c) && !euclid) - queueline(tC0(V), V*ddi0(nontruncated?S42:0, tessf), col, 2); - break; - - case patAltTree: - if(ctof(c) && !euclid && c->master->alt) { - for(int i=0; imaster->move[i] && c->master->move[i]->alt == c->master->alt->move[0]) - queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2); - } - break; - - case patVine: { - int p = emeraldval(c); - double hdist = hdist0(heptmove[0] * heptmove[2] * C0); - if(pseudohept(c) && (p/4 == 10 || p/4 == 8)) - for(int i=0; imov[i] && emeraldval(c->mov[i]) == p-4) { - queueline(tC0(V), V*tC0(heptmove[i]), col, 2); - queueline(tC0(V), V*tC0(spin(-i * ALPHA) * xpush(-hdist/2)), col, 2); - } - break; - } - - case patPower: { - int a = emeraldval(c); - if(pseudohept(c) && a/4 == 8) for(int i=0; i<7; i++) { - heptagon *h1 = c->master->move[(i+1)%7]; - heptagon *h2 = c->master->move[(i+6)%7]; - if(!h1 || !h2) continue; - if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8) - queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2), - V * ddspin(c,i,84*9/14) * xpush0(tessf/2), - col, 1); - } - break; - } - } - } - - void drawAll() { - - if(any()) for(map::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) { - cell *c = it->first; - transmatrix& V = it->second; - - for(int k=0; patterns[k].lpname; k++) { - int col = patterns[k].color; - if(!(col & 255)) continue; - int id = patterns[k].id; - - drawPattern(id, col, c, V); - } - } - } - - int numpat = 0; - - void showMenu() { - cmode = sm::SIDE | sm::MAYDARK; - gamescreen(0); - - dialog::init(XLAT("line patterns")); - - for(numpat=0; patterns[numpat].lpname; numpat++) - dialog::addColorItem(XLAT(patterns[numpat].lpname), patterns[numpat].color, 'a'+numpat); - - dialog::addBreak(50); - dialog::addItem(XLAT("exit menu"), 'v'); - - dialog::addBreak(50); - dialog::addInfo("change the alpha parameter to show the lines"); - - dialog::display(); - - keyhandler = [] (int sym, int uni) { - dialog::handleNavigation(sym, uni); - if(uni >= 'a' && uni < 'a' + numpat) { - dialog::openColorDialog(patterns[uni - 'a'].color, NULL); - dialog::dialogflags |= sm::MAYDARK | sm::SIDE; - } - else if(doexiton(sym,uni)) popScreen(); - }; - } - - }; diff --git a/pattern2.cpp b/pattern2.cpp index 8614e1e0..f982990c 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -397,7 +397,7 @@ sphereinfo valsphere(cell *c) { return si; } -namespace mapeditor { +namespace patterns { int nopattern(cell *c) { if(isWarped(c) && !euclid) { @@ -618,6 +618,55 @@ namespace mapeditor { return 0; } + char whichPattern = 0; + + bool symRotation, sym01, sym02, sym03; + + int subpattern(int i, char w) { + if(euclid) { + if(w == 'p') + return i; + if(w == 'z' || w == 'f') + return (symRotation && (i<3)) ? 0 : i; + } + + if(a38 && w == 'p') { + if(sym01 && i == 5) i = 4; + if(symRotation && i < 4) i = 0; + return i; + } + + if(w == 'z' || w == 'f' || w == 'p') { + if((sym01?1:0)+(sym02?1:0)+(sym03?1:0) >= 2) i &= ~3; + if(sym01 && (i&1)) i ^= 1; + if(sym02 && (i&2)) i ^= 2; + if(sym03 && (i&2)) i ^= 3; + } + + if(w == 'z' && symRotation) { + if(a4 && !a46) { + if(i >= 4 && i < 7) i -= 4; + } + else { + if(i >= 8 && i < 12) i -= 4; + if(i >= 12 && i < 16) i -= 8; + if(i >= 20 && i < 24) i -= 4; + if(i >= 24 && i < 28) i -= 8; + if(i >= 32 && i < 36) i -= 4; + if(i >= 36 && i < 40) i -= 8; + } + } + + if(w == 'p' && stdhyperbolic && symRotation && i >= 3) + i -= ((i/4-1) % 7) * 4; + + return i; + } + + int subpattern(cell *c, char w) { + return subpattern(realpattern(c, w), w); + } + } int geosupport_threecolor() { @@ -687,3 +736,548 @@ bool pseudohept(cell *c) { return pattern_threecolor(c) == 0; } +namespace patterns { + int canvasback = linf[laCanvas].color >> 2; + int subcanvas; + int displaycodes; + char whichShape = 0; + char whichCanvas = 0; + + int generateCanvas(cell *c) { + if(whichCanvas == 'C' && !torus) { + using namespace fieldpattern; + int z = currfp.getdist(fieldval(c), make_pair(0,false)); + if(z < currfp.circrad) return 0x00C000; + int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false)); + if(z2 < currfp.disthep[currfp.otherpole] - currfp.circrad) + return 0x3000; + return 0x6000; + } + if(whichCanvas == 'D' && !torus) { + using namespace fieldpattern; + int z = currfp.getdist(fieldval(c), make_pair(0,false)); + return 255 * (currfp.maxdist+1-z) / currfp.maxdist; + } + if(whichCanvas == 'N' && !torus) { + using namespace fieldpattern; + int z = currfp.getdist(fieldval(c), make_pair(0,false)); + int z2 = currfp.getdist(fieldval(c), make_pair(currfp.otherpole,false)); + if(z < z2) return 0x00C000; + if(z > z2) return 0xC00000; + return 0xCCCC00; + } + if(whichCanvas == 'S' && !torus) { + return 0x3F1F0F * fieldpattern::subval(c).second + 0x000080; + } + if(whichCanvas == 'g') + return canvasback; + if(whichCanvas == 'r') + return hrand(0xFFFFFF + 1); + if(whichCanvas == 'e') { + static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 }; + int fv = emeraldval(c); + return fcol[fv&3]; + } + if(whichCanvas == 'a') { + static unsigned int fcol8[8] = { + 0x800000, + 0x503000, + 0x206000, + 0x007010, + 0x004040, + 0x001070, + 0x200060, + 0x500030 + }; + + if(c->wall == waNone) { + int col = fcol8[land50(c)]; + if(polara50(c)) col += 0x181818; + return col; + } + } + if(whichCanvas == 'b') { + static unsigned int fcol[4] = { 0x404040, 0x800000, 0x008000, 0x000080 }; + return fcol[polara50(c) + 2 * polarb50(c)]; + } + if(whichCanvas == 'z') { + static unsigned int fcol[4] = { 0xC0C0C0, 0xE0E0E0, 0x404040, 0x606060 }; + int fv = zebra40(c); + return fcol[fv&3]; + } + if(whichCanvas == 't') { + static unsigned int fcol[4] = { 0x804040, 0x408040, 0x404080, 0x808040 }; + int fv = zebra40(c); + if(fv/4 == 4 || fv/4 == 6 || fv/4 == 5 || fv/4 == 10) fv ^= 2; + return fcol[fv&3]; + } + if(whichCanvas == 'x') { + static unsigned int fcol[4] = { 0xC0C0C0, 0x800000, 0x008000, 0x000080 }; + return fcol[zebra3(c)]; + } + if(whichCanvas == 'w') { + static unsigned int fcol[2] = { 0x303030, 0xC0C0C0 }; + return fcol[randpattern(c, subcanvas) ? 1 : 0]; + } + if(whichCanvas == 'l') { + int col[4]; + bool err = false; + for(int j=0; j<4; j++) { + col[j] = getCdata(c, j); + col[j] *= 3; + col[j] %= 240; + if(col[j] > 120) col[j] = 240 - col[j]; + if(col[j] < -120) col[j] = -240 - col[j]; + } + return (0x808080 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); + } + if(whichCanvas == 'd') { + int col[4]; + bool err = false; + for(int j=0; j<4; j++) { + col[j] = getCdata(c, j); + col[j] *= 6; + col[j] %= 240; + if(col[j] > 120) col[j] = 240 - col[j]; + if(col[j] < -120) col[j] = -240 - col[j]; + } + col[0] /= 8; + col[1] /= 8; + col[2] /= 8; + return (0x101010 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); + } + if(whichCanvas == 'h') { + int col[4]; + bool err = false; + for(int j=0; j<4; j++) { + col[j] = getCdata(c, j); + col[j] *= 6; + col[j] %= 240; + if(col[j] > 120) col[j] = 240 - col[j]; + if(col[j] < -120) col[j] = -240 - col[j]; + } + col[0] /= 4; + col[1] /= 4; + col[2] /= 4; + return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); + } + if(whichCanvas == 'F') { + return pseudohept(c) ? 0x202020 : 0xC0C0C0; + } + if(whichCanvas == 'T') { + int fv = pattern_threecolor(c); + return nestcolors[fv&7]; + } + return canvasback; + } + + void showPrePattern() { + dialog::init("predesigned patterns"); + dialog::addItem(XLAT("Gameboard"), 'g'); + dialog::addItem(XLAT("random colors"), 'r'); + dialog::addItem(XLAT("rainbow landscape"), 'l'); + dialog::addItem(XLAT("dark rainbow landscape"), 'd'); + dialog::addItem(XLAT("football"), 'F'); + + dialog::addItem(XLAT("nice coloring"), 'T'); + + dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e'); + + dialog::addSelItem(XLAT("four elements"), "palace", 'b'); + dialog::addSelItem(XLAT("eight domains"), "palace", 'a'); + + dialog::addSelItem(XLAT("zebra pattern"), "zebra", 'z'); + dialog::addSelItem(XLAT("four triangles"), "zebra", 't'); + dialog::addSelItem(XLAT("three stripes"), "zebra", 'x'); + + dialog::addSelItem(XLAT("random black-and-white"), "current", 'w'); + + dialog::addSelItem(XLAT("field pattern C"), "field", 'C'); + dialog::addSelItem(XLAT("field pattern D"), "field", 'D'); + dialog::addSelItem(XLAT("field pattern N"), "field", 'N'); + dialog::addSelItem(XLAT("field pattern S"), "field", 'S'); + + dialog::display(); + + keyhandler = [] (int sym, int uni) { + dialog::handleNavigation(sym, uni); + if((uni >= 'a' && uni <= 'z') || (uni >= 'A' && uni <= 'Z')) { + whichCanvas = uni; + subcanvas = rand(); + firstland = specialland = laCanvas; + randomPatternsMode = false; + restartGame(); + } + else if(doexiton(sym, uni)) popScreen(); + }; + } + + void showPattern() { + cmode = sm::SIDE | sm::MAYDARK; + { + dynamicval dc(displaycodes, displaycodes ? displaycodes : 2); + gamescreen(0); + } + dialog::init(); + + if(a46) { + dialog::addBoolItem(XLAT("two colors"), (whichPattern == 'f'), 'f'); + dialog::addBoolItem(XLAT("two colors rotated"), (whichPattern == 'z'), 'z'); + } + else if(a4) { + dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z'); + } + else if(a38) { + dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z'); + dialog::addBoolItem(XLAT("broken Emerald Pattern"), (whichPattern == 'f'), 'f'); + dialog::addBoolItem(XLAT("rotated pattern"), (whichPattern == 'p'), 'p'); + } + else if(euclid) { + dialog::addBoolItem(XLAT("three colors"), (whichPattern == 'f'), 'f'); + dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p'); + dialog::addBoolItem(XLAT("three colors rotated"), (whichPattern == 'z'), 'z'); + } + else if(sphere) { + dialog::addBoolItem(XLAT("siblings"), (whichPattern == 'p'), 'p'); + } + else { + if(!stdhyperbolic) + dialog::addInfo("patterns do not work correctly in this geometry!"); + + dialog::addBoolItem(XLAT("Emerald Pattern"), (whichPattern == 'f'), 'f'); + dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == 'p'), 'p'); + dialog::addBoolItem(XLAT("Zebra Pattern"), (whichPattern == 'z'), 'z'); + } + if(euclid) + dialog::addBoolItem(XLAT("torus pattern"), (whichPattern == 'F'), 'F'); + else if(sphere) + dialog::addBoolItem(XLAT("single cells"), (whichPattern == 'F'), 'F'); + else + dialog::addBoolItem(XLAT("field pattern"), (whichPattern == 'F'), 'F'); + + if(whichPattern == 'f' && stdhyperbolic) symRotation = true; + if(whichPattern == 'F') ; + else if(!euclid) { + dialog::addBoolItem(XLAT("rotational symmetry"), (symRotation), '0'); + dialog::addBoolItem(XLAT("symmetry 0-1"), (sym01), '1'); + dialog::addBoolItem(XLAT("symmetry 0-2"), (sym02), '2'); + dialog::addBoolItem(XLAT("symmetry 0-3"), (sym03), '3'); + } + else + dialog::addBoolItem(XLAT("edit all three colors"), (symRotation), '0'); + + dialog::addBoolItem(XLAT("display pattern codes (full)"), (displaycodes == 1), 'd'); + dialog::addBoolItem(XLAT("display pattern codes (simplified)"), (displaycodes == 2), 's'); + + dialog::addBoolItem(XLAT("display only hexagons"), (whichShape == '6'), '6'); + dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7'); + dialog::addBoolItem(XLAT("display the triheptagonal grid"), (whichShape == '8'), '8'); + if(cheater || autocheat) dialog::addItem(XLAT("line patterns"), 'l'); + else dialog::addInfo("enable the cheat mode to use line patterns"); + + if(!needConfirmation()) dialog::addItem(XLAT("predesigned patterns"), 'r'); + else dialog::addInfo("start a new game to use predesigned patterns"); + + dialog::display(); + + keyhandler = [] (int sym, int uni) { + dialog::handleNavigation(sym, uni); + if(uni == 'f' || uni == 'p' || uni == 'z' || uni == 'H' || uni == 'F') { + if(whichPattern == uni) whichPattern = 0; + else whichPattern = uni; + mapeditor::modelcell.clear(); + } + + else if(uni == '0') symRotation = !symRotation; + else if(uni == '1') sym01 = !sym01; + else if(uni == '2') sym02 = !sym02; + else if(uni == '3') sym03 = !sym03; + else if(uni == '6' || uni == '7' || uni == '8') { + if(whichShape == uni) whichShape = 0; + else whichShape = uni; + } + else if(uni == '3') sym03 = !sym03; + else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1; + else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2; + + else if(uni == 'l' && (cheater || autocheat)) + pushScreen(linepatterns::showMenu); + + else if(uni == 'r' && !needConfirmation()) pushScreen(showPrePattern); + + else if(doexiton(sym, uni)) popScreen(); + }; + } + + } + +namespace linepatterns { + + int lessalpha(int col, int m) { + part(col, 0) /= m; + return col; + } + + int lessalphaif(int col, bool b) { + return b?lessalpha(col, 4):col; + } + + int lessalphaif(int col, bool b1, bool b2) { + if(b1) col = lessalpha(col, 2); + if(b2) col = lessalpha(col, 2); + return col; + } + + struct { + int id; + const char *lpname; + unsigned int color; + } patterns[] = { + + {patTriNet, "triangle grid: not rings", 0xFFFFFF00}, + {patTriRings, "triangle grid: rings", 0xFFFFFF00}, + {patHepta, "heptagonal grid", 0x0000C000}, + {patRhomb, "rhombic tesselation", 0x0000C000}, + {patTrihepta, "triheptagonal tesselation", 0x0000C000}, + {patNormal, "normal tesselation", 0x0000C000}, + {patBigTriangles, "big triangular grid", 0x00606000}, + {patBigRings, "big triangles: rings", 0x0000C000}, + + {patTree, "underlying tree", 0x00d0d000}, + {patAltTree, "circle/horocycle tree", 0xd000d000}, + + {patZebraTriangles, "zebra triangles", 0x40FF4000}, + {patZebraLines, "zebra lines", 0xFF000000}, + {patVine, "vineyard pattern", 0x8438A400}, + {patPalacelike, "firewall lines", 0xFF400000}, + {patPalace, "firewall lines: Palace", 0xFFD50000}, + {patPower, "firewall lines: Power", 0xFFFF0000}, + {0, NULL, 0} + }; + + void clearAll() { + for(int k=0; patterns[k].lpname; k++) patterns[k].color &= ~255; + } + + bool any() { + for(int k=0; patterns[k].lpname; k++) if(patterns[k].color & 255) return true; + return false; + } + + void setColor(ePattern id, int col) { + for(int k=0; patterns[k].lpname; k++) + if(patterns[k].id == id) patterns[k].color = col; + } + + void switchAlpha(ePattern id, int col) { + for(int k=0; patterns[k].lpname; k++) + if(patterns[k].id == id) patterns[k].color ^= col; + } + + void drawPattern(int id, int col, cell *c, const transmatrix& V) { + + switch(id) { + + case patZebraTriangles: + if(zebra40(c) / 4 == 10) { + bool all = true; + hyperpoint tri[3]; + for(int i=0; i<3; i++) { + cell *c2 = createMov(c, i*2); + if(!gmatrix.count(c2)) all = false; + else tri[i] = tC0(gmatrix[c2]); + } + + if(all) for(int i=0; i<3; i++) + queueline(tri[i], tri[(i+1)%3], col, 3); + } + break; + + case patZebraLines: + if(!pseudohept(c)) for(int i=0; itype; i+=2) { + cell *c2 = createMov(c, i); + int fv1 = zebra40(c); + if(fv1/4 == 4 || fv1/4 == 6 || fv1/4 == 5 || fv1/4 == 10) fv1 ^= 2; + int fv2 = zebra40(c2); + if(fv2/4 == 4 || fv2/4 == 6 || fv2/4 == 5 || fv2/4 == 10) fv2 ^= 2; + if((fv1&1) == (fv2&1)) continue; + + double x = sphere?.3651:euclid?.2611:.2849; + + queueline(V * ddspin(c,i,-S14) * xpush0(x), + V * ddspin(c,i,+S14) * xpush0(x), + col, 1); + } + break; + + case patNormal: { + double x = sphere?.401:euclid?.3 : .328; + if(euclid || !pseudohept(c)) for(int t=0; ttype; t++) + if(euclid ? c->mov[t]mov[t] < c)) + queueline(V * ddspin(c,t,-S7) * xpush0(x), + V * ddspin(c,t,+S7) * xpush0(x), + col, 1); + break; + } + + case patTrihepta: + if(!pseudohept(c)) for(int i=0; i<6; i++) { + cell *c2 = c->mov[i]; + if(!c2 || !pseudohept(c2)) continue; + double x = sphere?.3651:euclid?.2611:.2849; + queueline(V * ddspin(c,i,-S14) * xpush0(x), + V * ddspin(c,i,+S14) * xpush0(x), + col, 1); + } + break; + + case patTriNet: + forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2)) if(celldist(c) != celldist(c2)) { + queueline(tC0(V), gmatrix[c2]*C0, + darkena(backcolor ^ 0xFFFFFF, 0, col), + 2); + } + break; + + case patTriRings: + forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && celldist(c) == celldist(c2)) + queueline(tC0(V), gmatrix[c2]*C0, + darkena(backcolor ^ 0xFFFFFF, 0, col), + 2); + break; + + case patHepta: + forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) == pseudohept(c2)) + queueline(tC0(V), gmatrix[c2]*C0, + darkena(backcolor ^ 0xFFFFFF, 0, col), + 2); + break; + + case patRhomb: + forCellEx(c2, c) if(c2 > c) if(gmatrix.count(c2) && pseudohept(c) != pseudohept(c2)) + queueline(tC0(V), gmatrix[c2]*C0, + darkena(backcolor ^ 0xFFFFFF, 0, col), + 2); + break; + + case patPalace: { + int a = polarb50(c); + if(pseudohept(c)) for(int i=0; i<7; i++) { + cell *c1 = createMov(c, (i+3) % 7); + cell *c2 = createMov(c, (i+4) % 7); + if(polarb50(c1) != a && polarb50(c2) != a) + queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2), + V * ddspin(c,i,84*9/14) * xpush0(tessf/2), + col, 1); + } + break; + } + + case patPalacelike: + if(pseudohept(c)) for(int i=0; i<7; i++) + queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2), + V * ddspin(c,i,84*9/14) * xpush0(tessf/2), + col, 1); + break; + + case patBigTriangles: { + if(pseudohept(c) && !euclid) for(int i=0; imaster->move[i] < c->master) { + queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2); + } + break; + } + + case patBigRings: { + if(pseudohept(c) && !euclid) for(int i=0; imaster->move[i] && c->master->move[i] < c->master && c->master->move[i]->dm4 == c->master->dm4) + queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2); + break; + } + + case patTree: + if(ctof(c) && !euclid) + queueline(tC0(V), V*ddi0(nontruncated?S42:0, tessf), col, 2); + break; + + case patAltTree: + if(ctof(c) && !euclid && c->master->alt) { + for(int i=0; imaster->move[i] && c->master->move[i]->alt == c->master->alt->move[0]) + queueline(tC0(V), V*xspinpush0((nontruncated?M_PI:0) -2*M_PI*i/S7, tessf), col, 2); + } + break; + + case patVine: { + int p = emeraldval(c); + double hdist = hdist0(heptmove[0] * heptmove[2] * C0); + if(pseudohept(c) && (p/4 == 10 || p/4 == 8)) + for(int i=0; imov[i] && emeraldval(c->mov[i]) == p-4) { + queueline(tC0(V), V*tC0(heptmove[i]), col, 2); + queueline(tC0(V), V*tC0(spin(-i * ALPHA) * xpush(-hdist/2)), col, 2); + } + break; + } + + case patPower: { + int a = emeraldval(c); + if(pseudohept(c) && a/4 == 8) for(int i=0; i<7; i++) { + heptagon *h1 = c->master->move[(i+1)%7]; + heptagon *h2 = c->master->move[(i+6)%7]; + if(!h1 || !h2) continue; + if(emeraldval(h1->c7)/4 == 8 && emeraldval(h2->c7)/4 == 8) + queueline(V * ddspin(c,i,84*5/14) * xpush0(tessf/2), + V * ddspin(c,i,84*9/14) * xpush0(tessf/2), + col, 1); + } + break; + } + } + } + + void drawAll() { + + if(any()) for(map::iterator it = gmatrix.begin(); it != gmatrix.end(); it++) { + cell *c = it->first; + transmatrix& V = it->second; + + for(int k=0; patterns[k].lpname; k++) { + int col = patterns[k].color; + if(!(col & 255)) continue; + int id = patterns[k].id; + + drawPattern(id, col, c, V); + } + } + } + + int numpat = 0; + + void showMenu() { + cmode = sm::SIDE | sm::MAYDARK; + gamescreen(0); + + dialog::init(XLAT("line patterns")); + + for(numpat=0; patterns[numpat].lpname; numpat++) + dialog::addColorItem(XLAT(patterns[numpat].lpname), patterns[numpat].color, 'a'+numpat); + + dialog::addBreak(50); + dialog::addItem(XLAT("exit menu"), 'v'); + + dialog::addBreak(50); + dialog::addInfo("change the alpha parameter to show the lines"); + + dialog::display(); + + keyhandler = [] (int sym, int uni) { + dialog::handleNavigation(sym, uni); + if(uni >= 'a' && uni < 'a' + numpat) { + dialog::openColorDialog(patterns[uni - 'a'].color, NULL); + dialog::dialogflags |= sm::MAYDARK | sm::SIDE; + } + else if(doexiton(sym,uni)) popScreen(); + }; + } + + }; diff --git a/polygons.cpp b/polygons.cpp index 94910f13..6ce09275 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -2315,7 +2315,7 @@ void queuecurve(int linecol, int fillcol, int prio) { curvestart = size(curvedata); } -void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf = 0, int prio = PPR_LINE) { +void queueline(const hyperpoint& H1, const hyperpoint& H2, int col, int prf, int prio) { polytodraw& ptd = nextptd(); ptd.kind = pkLine; ptd.u.line.H1 = H1; diff --git a/rogueviz.cpp b/rogueviz.cpp index b5771ebb..2626ee1d 100644 --- a/rogueviz.cpp +++ b/rogueviz.cpp @@ -1380,7 +1380,7 @@ void rvvideo(const char *fname) { pngformat = 2; sightrange = 12; overgenerate = true; - dronemode = true; vid.camera_angle = -45; rog3 = true; mapeditor::whichShape = '8'; + dronemode = true; vid.camera_angle = -45; rog3 = true; patterns::whichShape = '8'; vid.aurastr = 512; long long reached = 763ll; while(reached < (1ll<<60)) { @@ -1666,7 +1666,7 @@ int readArgs() { shift(); collatz::cshift = argf(); } else if(argis("-rvwarp")) { - mapeditor::whichShape = '8'; + patterns::whichShape = '8'; } else if(argis("-lq")) { shift(); linequality = argf(); diff --git a/system.cpp b/system.cpp index bacedd55..0b2d85b3 100644 --- a/system.cpp +++ b/system.cpp @@ -241,8 +241,7 @@ void initgame() { if(!safety) { usedSafety = false; timerstart = time(NULL); turncount = 0; rosewave = 0; rosephase = 0; - if(!quotient) mapeditor::whichPattern = 0; - mapeditor::whichShape = 0; + patterns::whichShape = 0; noiseuntil = 0; sagephase = 0; hardcoreAt = 0; timerstopped = false; diff --git a/textures.cpp b/textures.cpp index a59d67ee..bad3fd5b 100644 --- a/textures.cpp +++ b/textures.cpp @@ -118,7 +118,7 @@ void mapTextureTriangle(textureinfo &mi, array v) { map texture_map; bool applyTextureMap(cell *c, const transmatrix &V, int col) { - using namespace mapeditor; + using namespace patterns; int t = subpattern(c, whichPattern); try { auto& mi = texture_map.at(t); @@ -154,7 +154,7 @@ bool applyTextureMap(cell *c, const transmatrix &V, int col) { } void perform_mapping() { - using namespace mapeditor; + using namespace patterns; if(!texture_read) readtexture(); texture_map.clear(); glfont_t& f(textures); int tabid = 1; @@ -251,7 +251,7 @@ void showTextureMenu() { keyhandler = [] (int sym, int uni) { dialog::handleNavigation(sym, uni); if(uni == 'r') - pushScreen(mapeditor::showPattern); + pushScreen(patterns::showPattern); else if(uni == 'f') { mapeditor::cfileptr = &texturename; mapeditor::filecaption = XLAT("texture to load:"); diff --git a/tour.cpp b/tour.cpp index e48e79f4..1645bfcb 100644 --- a/tour.cpp +++ b/tour.cpp @@ -22,14 +22,14 @@ void setCanvas(presmode mode, char canv) { static char wc; static eLand ld; if(mode == pmStart) { - wc = mapeditor::whichCanvas; - mapeditor::whichCanvas = canv; + wc = patterns::whichCanvas; + patterns::whichCanvas = canv; ld = firstland; firstland = laCanvas; restartGame(0, true); } if(mode == pmStop) { - mapeditor::whichCanvas = wc; + patterns::whichCanvas = wc; firstland = ld; popGame(); } @@ -595,11 +595,11 @@ slide default_slides[] = { [] (presmode mode) { setCanvas(mode, 't'); if(mode == 1) - mapeditor::displaycodes = 2, - mapeditor::whichPattern = 'z'; + patterns::displaycodes = 2, + patterns::whichPattern = 'z'; if(mode == 3) - mapeditor::displaycodes = 0, - mapeditor::whichPattern = 0; + patterns::displaycodes = 0, + patterns::whichPattern = 0; SHOWLAND ( l == laCanvas ); } },