1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-23 21:07:17 +00:00

a menu for changing pattern geometries

This commit is contained in:
Zeno Rogue 2017-12-19 14:35:34 +01:00
parent 37cc910031
commit 49bd1a0b2b
9 changed files with 332 additions and 83 deletions

View File

@ -216,3 +216,8 @@ extern monstertype minf[motypes];
extern itemtype iinf[ittypes]; extern itemtype iinf[ittypes];
extern const landtype linf[landtypes]; extern const landtype linf[landtypes];
enum cpatterntype {
cpFootball, cpThree, cpChess, cpSingle, cpLarge, cpUnknown
};

View File

@ -136,6 +136,8 @@ void showTorusConfig() {
dialog::display(); dialog::display();
} }
string truncatenames[2] = {" (t)", " (n)"};
void showEuclideanMenu() { void showEuclideanMenu() {
cmode = sm::SIDE; cmode = sm::SIDE;
gamescreen(0); gamescreen(0);
@ -270,7 +272,6 @@ void showEuclideanMenu() {
} }
else { else {
dialog::init(XLAT("experiment with geometry")); dialog::init(XLAT("experiment with geometry"));
string truncatenames[2] = {" (t)", " (n)"};
dialog::addSelItem(XLAT("geometry"), XLAT(ginf[geometry].name) + XLAT(truncatenames[nontruncated]), '5'); dialog::addSelItem(XLAT("geometry"), XLAT(ginf[geometry].name) + XLAT(truncatenames[nontruncated]), '5');
dialog::addBreak(50); dialog::addBreak(50);

View File

@ -3895,9 +3895,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
if(patterns::displaycodes) { if(patterns::displaycodes) {
int pf = patterns::displaycodes == 2 ? patterns::subpattern_flags : 0; auto si = patterns::getpatterninfo0(c);
auto si = patterns::getpatterninfo(c, patterns::whichPattern, pf);
for(int i=0; i<c->type; i += si.symmetries) { for(int i=0; i<c->type; i += si.symmetries) {
queuepoly(V * applyPatterndir(c,si), shAsymmetric, darkena(0x000000, 0, 0xC0)); queuepoly(V * applyPatterndir(c,si), shAsymmetric, darkena(0x000000, 0, 0xC0));

14
hyper.h
View File

@ -295,7 +295,7 @@ typedef int cellfunction(cell*);
int towerval(cell *c, cellfunction* cf = &coastvalEdge); int towerval(cell *c, cellfunction* cf = &coastvalEdge);
#define HRANDMAX 0x7FFFFFFF #define HRANDMAX 0x7FFFFFFF
int hrandpos(); // 0 to HRANDMAX int hrandpos(); // 0 to HRANDMAX
void restartGame(char switchWhat = 0, bool push = false); void restartGame(char switchWhat = 0, bool push = false, bool keep_screens = true);
int landMultiplier(eLand l); int landMultiplier(eLand l);
eItem treasureType(eLand l); eItem treasureType(eLand l);
void buildBarrier(cell *c, int d, eLand l = laNone); void buildBarrier(cell *c, int d, eLand l = laNone);
@ -674,6 +674,7 @@ namespace patterns {
static const char PAT_DOWN = 'H'; static const char PAT_DOWN = 'H';
static const char PAT_COLORING = 'C'; static const char PAT_COLORING = 'C';
static const char PAT_SIBLING = 'S'; static const char PAT_SIBLING = 'S';
static const char PAT_CHESS = 'c';
extern int subpattern_flags; extern int subpattern_flags;
@ -684,12 +685,14 @@ namespace patterns {
static const int SPF_CHANGEROT = 16; static const int SPF_CHANGEROT = 16;
static const int SPF_TWOCOL = 32; static const int SPF_TWOCOL = 32;
static const int SPF_EXTRASYM = 64; static const int SPF_EXTRASYM = 64;
static const int SPF_ALTERNATE = 128;
static const int SPF_FOOTBALL = 256;
static const int SPF_SYM0123 = 14; static const int SPF_SYM0123 = SPF_SYM01 | SPF_SYM02 | SPF_SYM03;
extern char whichCanvas; extern char whichCanvas;
extern int displaycodes; extern bool displaycodes;
int generateCanvas(cell *c); int generateCanvas(cell *c);
@ -2384,9 +2387,11 @@ namespace texture {
extern vector<unsigned> texture_pixels; extern vector<unsigned> texture_pixels;
void showMenu(); void showMenu();
void update(); void update();
void drawPixel(cell *c, hyperpoint h, int col); void drawPixel(cell *c, hyperpoint h, int col);
extern cpatterntype cgroup;
} }
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 = 0, int prio = PPR_LINE);
@ -2410,3 +2415,4 @@ inline hyperpoint tC0(const transmatrix &T) {
transmatrix actualV(const heptspin& hs, const transmatrix& V); transmatrix actualV(const heptspin& hs, const transmatrix& V);
transmatrix cview(); transmatrix cview();
extern string truncatenames[2];

View File

@ -364,6 +364,8 @@ void addMessage(string s, char spamtype = 0);
#define smallsphere (S7 < 5) #define smallsphere (S7 < 5)
#define bigsphere (S7 == 5) #define bigsphere (S7 == 5)
#define ap4 (a4 && nontruncated) #define ap4 (a4 && nontruncated)
#define euclid4 (euclid && a4)
#define euclid6 (euclid && !a4)
#define S6 (S3*2) #define S6 (S3*2)
#define S42 (S7*S6) #define S42 (S7*S6)

View File

@ -471,12 +471,27 @@ namespace patterns {
if(sym03 && (i&2)) i ^= 3; if(sym03 && (i&2)) i ^= 3;
} }
void applyAlt(patterninfo& si, int sub, int pat) {
if(sub & SPF_ALTERNATE) {
si.id += 4;
si.id %= 12;
}
if(pat == PAT_COLORING && (sub & SPF_FOOTBALL)) {
if(si.id == 4) si.dir++;
si.id = !si.id;
if(si.id && (sub & SPF_EXTRASYM))
si.symmetries = si.id ? 1 : 2;
return;
}
}
void val46(cell *c, patterninfo &si, int sub, int pat) { void val46(cell *c, patterninfo &si, int sub, int pat) {
if(ctof(c)) { if(ctof(c)) {
si.id = c->master->emeraldval >> 1; si.id = c->master->emeraldval >> 1;
applySym0123(si.id, sub); applySym0123(si.id, sub);
si.dir = (c->master->emeraldval&1) ^ (c->master->emeraldval>>1); si.dir = (c->master->emeraldval&1) ^ (c->master->emeraldval>>1);
si.symmetries = 2; si.symmetries = 2;
applyAlt(si, sub, pat);
/* printf("[%3d] ", c->master->emeraldval); /* printf("[%3d] ", c->master->emeraldval);
for(int i=0; i<6; i++) printf("%2d", val46(createMov(c, i))); for(int i=0; i<6; i++) printf("%2d", val46(createMov(c, i)));
printf("\n"); */ printf("\n"); */
@ -488,11 +503,13 @@ namespace patterns {
si.dir += 4; si.dir += 4;
if((sub & SPF_TWOCOL) && (pat == PAT_COLORING)) si.id = 4; if((sub & SPF_TWOCOL) && (pat == PAT_COLORING)) si.id = 4;
else if(si.id == 4) si.dir++; else if(pat == PAT_COLORING && si.id == 4) si.dir++;
if(sub & SPF_SYM01) si.symmetries = 2; if(sub & SPF_SYM01) si.symmetries = 2;
else if(sub & SPF_SYM03) si.symmetries = 2; else if(sub & SPF_SYM03) si.symmetries = 2;
else if(sub & SPF_SYM02) si.symmetries = 4; else if(sub & SPF_SYM02) si.symmetries = 4;
applyAlt(si, sub, pat);
} }
} }
@ -519,7 +536,7 @@ namespace patterns {
else si.dir = (zebra40(createMov(c, 0)) & 4) ? 2 : 0; else si.dir = (zebra40(createMov(c, 0)) & 4) ? 2 : 0;
} }
} }
void val38(cell *c, patterninfo &si, int sub, int pat) { void val38(cell *c, patterninfo &si, int sub, int pat) {
bool symRotation = sub & SPF_ROT; bool symRotation = sub & SPF_ROT;
@ -534,6 +551,9 @@ namespace patterns {
si.id += 4; si.id += 4;
si.dir = (pat == PAT_COLORING ? 1 : 0) + (c->master->fiftyval | (c->master->fiftyval & 8 ? 0 : 2)); si.dir = (pat == PAT_COLORING ? 1 : 0) + (c->master->fiftyval | (c->master->fiftyval & 8 ? 0 : 2));
si.symmetries = 2; si.symmetries = 2;
si.id += 8;
si.id %= 12;
applyAlt(si, sub, pat);
} }
else { else {
si.id = 8 * ((c->master->fiftyval & 1) ^ (c->spin(0) & 1)); si.id = 8 * ((c->master->fiftyval & 1) ^ (c->spin(0) & 1));
@ -542,11 +562,13 @@ namespace patterns {
if(fv == 0) si.dir = (si.id == 8 && pat == PAT_COLORING ? 1 : 0) + i; if(fv == 0) si.dir = (si.id == 8 && pat == PAT_COLORING ? 1 : 0) + i;
} }
if(symRotation) si.symmetries = 2; if(symRotation) si.symmetries = 2;
si.id += 8;
si.id %= 12;
applyAlt(si, sub, pat);
} }
} }
void valEuclid(cell *c, patterninfo &si, int sub) { void valEuclid6(cell *c, patterninfo &si, int sub) {
bool symRotation = sub & SPF_ROT; bool symRotation = sub & SPF_ROT;
si.id = ishept(c) ? 4 : ishex1(c) ? 8 : 0; si.id = ishept(c) ? 4 : ishex1(c) ? 8 : 0;
if(sub & SPF_CHANGEROT) { if(sub & SPF_CHANGEROT) {
@ -555,11 +577,28 @@ namespace patterns {
if(symRotation) si.id = 0; if(symRotation) si.id = 0;
} }
void valEuclid4(cell *c, patterninfo &si, int sub) {
si.id = eupattern4(c);
applySym0123(si.id, sub);
if(sub & SPF_CHANGEROT) {
int dirt[] = {0,1,3,2};
si.dir = dirt[si.id];
if(c->type == 8) si.dir *= 2;
}
if(sub & SPF_SYM03) {
si.id *= 4;
applyAlt(si, sub, PAT_COLORING);
}
else
si.symmetries = (sub & SPF_EXTRASYM) ? c->type/4 : c->type;
}
void val_all(cell *c, patterninfo &si, int sub, int pat) { void val_all(cell *c, patterninfo &si, int sub, int pat) {
if(a46) val46(c, si, sub, pat); if(a46) val46(c, si, sub, pat);
else if(a38) val38(c, si, sub, pat); else if(a38) val38(c, si, sub, pat);
else if(sphere) valSibling(c, si, sub); else if(sphere) valSibling(c, si, sub);
else if(euclid) valEuclid(c, si, sub); else if(euclid4) valEuclid4(c, si, sub);
else if(euclid) valEuclid6(c, si, sub);
else if(a4) val457(c, si, sub); else if(a4) val457(c, si, sub);
else si.symmetries = ctof(c) ? 1 : 2; else si.symmetries = ctof(c) ? 1 : 2;
} }
@ -643,6 +682,9 @@ namespace patterns {
} }
if(sphere && !(nontruncated) && !(S7 == 3)) if(sphere && !(nontruncated) && !(S7 == 3))
si.symmetries = ctof(c) ? 1 : 2; si.symmetries = ctof(c) ? 1 : 2;
if(sphere && (sub & SPF_EXTRASYM)) {
si.symmetries = ctof(c) ? 1 : 2;
}
if(a38) if(a38)
si.symmetries = (ctof(c) && !nontruncated) ? 1 : 2; si.symmetries = (ctof(c) && !nontruncated) ? 1 : 2;
if(a457) { if(a457) {
@ -659,7 +701,6 @@ namespace patterns {
int subpattern_flags; int subpattern_flags;
// also works with 38
void val_threecolors(cell *c, patterninfo& si, int sub) { void val_threecolors(cell *c, patterninfo& si, int sub) {
int pcol = pattern_threecolor(c); int pcol = pattern_threecolor(c);
si.id = pcol * 4; si.id = pcol * 4;
@ -673,11 +714,13 @@ namespace patterns {
break; break;
} }
} }
if(euclid && (sub & SPF_CHANGEROT)) si.dir = 0; if(euclid6 && (sub & SPF_CHANGEROT)) si.dir = 0;
if(sub & SPF_ROT) si.id = 0; if(sub & SPF_ROT) si.id = 0;
if(!(sub & SPF_EXTRASYM)) { if(euclid6 && !(sub & SPF_EXTRASYM)) {
if(euclid) si.symmetries = 6; si.symmetries = 6;
} }
if(S7 == 4)
applyAlt(si, sub, PAT_COLORING);
} }
patterninfo getpatterninfo(cell *c, char pat, int sub) { patterninfo getpatterninfo(cell *c, char pat, int sub) {
@ -815,6 +858,11 @@ namespace patterns {
else if(pat == PAT_COLORING && (a46 || a38)) { else if(pat == PAT_COLORING && (a46 || a38)) {
val_all(c, si, sub, pat); val_all(c, si, sub, pat);
} }
else if(pat == PAT_CHESS) {
val_nopattern(c, si, sub);
si.id = celldist(c) & 1;
}
else else
val_nopattern(c, si, sub); val_nopattern(c, si, sub);
@ -882,6 +930,11 @@ int pattern_threecolor(cell *c) {
if(z == 14 || z == 11) return 4; if(z == 14 || z == 11) return 4;
return 1; return 1;
} }
if(a46 && nontruncated) {
patterns::patterninfo si;
patterns::val46(c, si, 0, patterns::PAT_COLORING);
return si.id;
}
if(S7 == 5 && nontruncated) { if(S7 == 5 && nontruncated) {
const int codes[12] = {1, 2, 0, 3, 2, 0, 0, 1, 3, 1, 2, 3}; const int codes[12] = {1, 2, 0, 3, 2, 0, 0, 1, 3, 1, 2, 3};
return codes[c->master->fiftyval]; return codes[c->master->fiftyval];
@ -911,7 +964,7 @@ bool warptype(cell *c) {
namespace patterns { namespace patterns {
int canvasback = linf[laCanvas].color >> 2; int canvasback = linf[laCanvas].color >> 2;
int subcanvas; int subcanvas;
int displaycodes; bool displaycodes;
char whichShape = 0; char whichShape = 0;
char whichCanvas = 0; char whichCanvas = 0;
@ -1033,7 +1086,10 @@ namespace patterns {
col[2] /= 4; col[2] /= 4;
return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0); return (0x202020 + col[0] + (col[1] << 8) + (col[2] << 16)) >> (err?2:0);
} }
if(whichCanvas == PAT_FIELD) { if(whichPattern == 'c') {
return (c->master->distance&1) ? 0xC0C0C0 : 0x202020;
}
if(whichCanvas == 'F') {
return pseudohept(c) ? 0x202020 : 0xC0C0C0; return pseudohept(c) ? 0x202020 : 0xC0C0C0;
} }
if(whichCanvas == 'T') { if(whichCanvas == 'T') {
@ -1045,18 +1101,25 @@ namespace patterns {
void showPrePattern() { void showPrePattern() {
dialog::init("predesigned patterns"); dialog::init("predesigned patterns");
dialog::addItem(XLAT("Gameboard"), 'g'); dialog::addItem(XLAT("single color"), 'g');
dialog::addItem(XLAT("random colors"), 'r'); dialog::addItem(XLAT("random colors"), 'r');
dialog::addItem(XLAT("rainbow landscape"), 'l');
dialog::addItem(XLAT("dark rainbow landscape"), 'd'); if(stdeuc) {
dialog::addItem(XLAT("rainbow landscape"), 'l');
dialog::addItem(XLAT("dark rainbow landscape"), 'd');
}
dialog::addItem(XLAT("football"), 'F'); dialog::addItem(XLAT("football"), 'F');
if(S3 == 4 && nontruncated)
dialog::addItem(XLAT("chessboard"), 'c');
dialog::addItem(XLAT("nice coloring"), 'T'); dialog::addItem(XLAT("nice coloring"), 'T');
dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e'); if(stdhyperbolic) {
dialog::addSelItem(XLAT("emerald pattern"), "emerald", 'e');
dialog::addSelItem(XLAT("four elements"), "palace", 'b'); dialog::addSelItem(XLAT("four elements"), "palace", 'b');
dialog::addSelItem(XLAT("eight domains"), "palace", 'a'); dialog::addSelItem(XLAT("eight domains"), "palace", 'a');
}
dialog::addSelItem(XLAT("zebra pattern"), "zebra", 'z'); dialog::addSelItem(XLAT("zebra pattern"), "zebra", 'z');
dialog::addSelItem(XLAT("four triangles"), "zebra", 't'); dialog::addSelItem(XLAT("four triangles"), "zebra", 't');
@ -1064,21 +1127,37 @@ namespace patterns {
dialog::addSelItem(XLAT("random black-and-white"), "current", 'w'); dialog::addSelItem(XLAT("random black-and-white"), "current", 'w');
dialog::addSelItem(XLAT("field pattern C"), "field", 'C'); if(!sphere) {
dialog::addSelItem(XLAT("field pattern D"), "field", 'D'); dialog::addSelItem(XLAT("field pattern C"), "field", 'C');
dialog::addSelItem(XLAT("field pattern N"), "field", 'N'); dialog::addSelItem(XLAT("field pattern D"), "field", 'D');
dialog::addSelItem(XLAT("field pattern S"), "field", 'S'); dialog::addSelItem(XLAT("field pattern N"), "field", 'N');
dialog::addSelItem(XLAT("field pattern S"), "field", 'S');
}
dialog::display(); dialog::display();
keyhandler = [] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
if((uni >= 'a' && uni <= 'z') || (uni >= 'A' && uni <= 'Z')) { if(uni == 'g') {
static unsigned c = (canvasback << 8) | 0xFF;
unsigned canvasbacks[] = {
5, 0xFFFFFFFF, 0x101010FF, 0x404040FF, 0x808080FF, 0x800000FF
};
dialog::openColorDialog(c, canvasbacks);
dialog::reaction = [] () {
whichCanvas = 'g';
canvasback = c >> 8;
firstland = specialland = laCanvas;
randomPatternsMode = false;
restartGame(0, false, true);
};
}
else if((uni >= 'a' && uni <= 'z') || (uni >= 'A' && uni <= 'Z')) {
whichCanvas = uni; whichCanvas = uni;
subcanvas = rand(); subcanvas = rand();
firstland = specialland = laCanvas; firstland = specialland = laCanvas;
randomPatternsMode = false; randomPatternsMode = false;
restartGame(); restartGame(0, false, true);
} }
else if(doexiton(sym, uni)) popScreen(); else if(doexiton(sym, uni)) popScreen();
}; };
@ -1087,7 +1166,7 @@ namespace patterns {
void showPattern() { void showPattern() {
cmode = sm::SIDE | sm::MAYDARK; cmode = sm::SIDE | sm::MAYDARK;
{ {
dynamicval<int> dc(displaycodes, displaycodes ? displaycodes : 2); dynamicval<bool> dc(displaycodes, true);
gamescreen(0); gamescreen(0);
} }
dialog::init(); dialog::init();
@ -1102,6 +1181,9 @@ namespace patterns {
if(stdhyperbolic || euclid) if(stdhyperbolic || euclid)
dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == PAT_PALACE), PAT_PALACE); dialog::addBoolItem(XLAT("Palace Pattern"), (whichPattern == PAT_PALACE), PAT_PALACE);
if(nontruncated && S3 == 4)
dialog::addBoolItem(XLAT("chessboard"), (whichPattern == PAT_CHESS), PAT_CHESS);
if(a38 || a46 || euclid || S3 == 4) if(a38 || a46 || euclid || S3 == 4)
dialog::addBoolItem(XLAT("coloring"), (whichPattern == PAT_COLORING), PAT_COLORING); dialog::addBoolItem(XLAT("coloring"), (whichPattern == PAT_COLORING), PAT_COLORING);
@ -1149,9 +1231,21 @@ namespace patterns {
} }
if(euclid && among(whichPattern, PAT_COLORING, 0)) if(euclid && among(whichPattern, PAT_COLORING, 0))
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '='); dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
if(a38 && nontruncated && whichPattern == 0) {
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
}
if(a46 && nontruncated && whichPattern == PAT_COLORING) {
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
}
if((a38 || (sphere && S7 == 4) || euclid4 || a46) && !nontruncated) {
dialog::addBoolItem(XLAT("alternate coloring"), subpattern_flags & SPF_ALTERNATE, '\'');
dialog::addBoolItem(XLAT("football pattern"), subpattern_flags & SPF_FOOTBALL, '*');
}
dialog::addBoolItem(XLAT("display pattern codes (full)"), (displaycodes == 1), 'd'); dialog::addBoolItem(XLAT("display pattern codes (full)"), displaycodes, '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 hexagons"), (whichShape == '6'), '6');
dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7'); dialog::addBoolItem(XLAT("display only heptagons"), (whichShape == '7'), '7');
@ -1166,28 +1260,34 @@ namespace patterns {
keyhandler = [] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
printf("uni = %c\n", uni);
if(among(uni, PAT_EMERALD, PAT_PALACE, PAT_ZEBRA, PAT_DOWN, PAT_FIELD, PAT_COLORING, PAT_SIBLING)) { if(among(uni, PAT_EMERALD, PAT_PALACE, PAT_ZEBRA, PAT_DOWN, PAT_FIELD, PAT_COLORING, PAT_SIBLING, PAT_CHESS)) {
if(whichPattern == uni) whichPattern = 0; if(whichPattern == uni) whichPattern = 0;
else whichPattern = uni; else whichPattern = uni;
mapeditor::modelcell.clear(); mapeditor::modelcell.clear();
} }
else if(printf("not among\n"), 0) ;
else if(uni >= '0' && uni <= '5') else if(uni >= '0' && uni <= '5')
subpattern_flags ^= (1 << (uni - '0')); subpattern_flags ^= (1 << (uni - '0'));
else if(uni == '=') else if(uni == '=')
subpattern_flags ^= SPF_EXTRASYM; subpattern_flags ^= SPF_EXTRASYM;
else if(uni == '\'') {
subpattern_flags ^= SPF_ALTERNATE;
subpattern_flags &= ~SPF_FOOTBALL;
}
else if(uni == '*') {
subpattern_flags ^= SPF_FOOTBALL;
subpattern_flags &= ~SPF_ALTERNATE;
}
else if(uni == '6' || uni == '7' || uni == '8') { else if(uni == '6' || uni == '7' || uni == '8') {
if(whichShape == uni) whichShape = 0; if(whichShape == uni) whichShape = 0;
else whichShape = uni; else whichShape = uni;
} }
else if(uni == 'd') displaycodes = displaycodes == 1 ? 0 : 1; else if(uni == 'd') displaycodes = !displaycodes;
else if(uni == 's') displaycodes = displaycodes == 2 ? 0 : 2;
else if(uni == 'l' && (cheater || autocheat)) else if(uni == 'l' && (cheater || autocheat))
pushScreen(linepatterns::showMenu); pushScreen(linepatterns::showMenu);
@ -1198,6 +1298,145 @@ namespace patterns {
}; };
} }
bool compatible(cpatterntype oldp, cpatterntype newp) {
// larges are not incompatible between themselves
if(newp == cpLarge)
return false;
// other cps are compatible with themselves
if(newp == oldp) return true;
// Single can be upgraded to everything
if(oldp == cpSingle) return true;
// Football can be upgraded to Three colors
if(oldp == cpFootball) return newp == cpThree;
// incompatible otherwise
return false;
}
struct changeable_pattern_geometry {
eGeometry geo;
bool nontrunc;
char whichPattern;
int subpattern_flags;
};
struct changeable_pattern {
string name;
vector<changeable_pattern_geometry> geometries;
};
vector<changeable_pattern> cpatterns = {
{"football", {
{gNormal, false, 0, 0},
{gSphere, false, 0, 0},
{gEuclid, false, 0, SPF_EXTRASYM},
{gOctagon, false, 0, 0},
{gOctagon, true, PAT_COLORING, SPF_FOOTBALL | SPF_EXTRASYM},
{g45, false, 0, 0},
{g46, false, 0, SPF_EXTRASYM},
{g47, false, 0, 0},
{gSmallSphere, false, 0, 0},
{gSmallSphere, true, PAT_COLORING, SPF_FOOTBALL | SPF_EXTRASYM},
{gTinySphere, false, 0, SPF_EXTRASYM},
{gEuclidSquare, false, 0, SPF_EXTRASYM},
}},
{"three colors", {
{gEuclid, false, PAT_COLORING, SPF_SYM0123 | SPF_EXTRASYM},
{gSmallSphere, false, PAT_COLORING, 0},
{gSmallSphere, false, PAT_COLORING, SPF_ALTERNATE},
{gSmallSphere, true, PAT_COLORING},
{gOctagon, false, PAT_COLORING, SPF_ROT | SPF_EXTRASYM},
{gOctagon, false, PAT_COLORING, SPF_ROT | SPF_EXTRASYM | SPF_ALTERNATE},
{gOctagon, true, PAT_COLORING, 0},
{gEuclidSquare, false, PAT_COLORING, SPF_SYM03 | SPF_EXTRASYM},
{gEuclidSquare, false, PAT_COLORING, SPF_SYM03 | SPF_EXTRASYM | SPF_ALTERNATE},
{g46, false, PAT_COLORING, SPF_SYM0123},
{g46, false, PAT_COLORING, SPF_SYM0123 | SPF_EXTRASYM | SPF_ALTERNATE}
}},
{"chessboard", {
{gEuclidSquare, true, PAT_CHESS, SPF_EXTRASYM},
{g45, true, PAT_CHESS, 0},
{g46, true, PAT_CHESS, 0},
{g47, true, PAT_CHESS, 0}
}},
{"single type", {
{gNormal, true, 0, 0},
{gSphere, true, 0, SPF_EXTRASYM},
{gEuclid, false, 0, SPF_EXTRASYM},
{gOctagon, true, 0, SPF_EXTRASYM},
{g45, true, 0, 0},
{g46, true, 0, 0},
{g47, true, 0, 0},
{gSmallSphere, true, 0, SPF_EXTRASYM},
{gTinySphere, true, 0, SPF_EXTRASYM},
{gEuclidSquare, true, 0, SPF_EXTRASYM},
}},
{"large picture", {
{gNormal, false, PAT_PALACE, SPF_SYM0123},
{gNormal, true, PAT_PALACE, SPF_SYM0123},
{gElliptic, false, PAT_FIELD, 0},
{gElliptic, true, PAT_FIELD, 0},
{gEuclid, false, PAT_PALACE, 0}
}}
};
cpatterntype cgroup, old_cgroup;
void showChangeablePatterns() {
cmode = sm::SIDE | sm::MAYDARK;
{
dynamicval<bool> dc(displaycodes, true);
gamescreen(0);
}
dialog::init();
for(int i=0; i<size(cpatterns); i++)
dialog::addBoolItem(XLAT(cpatterns[i].name), cgroup == i, '0'+i);
dialog::addBreak(100);
if(cgroup != cpUnknown && cgroup < size(cpatterns))
for(int j=0; j<size(cpatterns[cgroup].geometries); j++) {
auto &g = cpatterns[cgroup].geometries[j];
string s = XLAT(ginf[g.geo].name);
s += truncatenames[g.nontrunc];
if(g.subpattern_flags & SPF_ALTERNATE) s += " (alt)";
dialog::addBoolItem(s, geometry == g.geo && nontruncated == g.nontrunc && whichPattern == g.whichPattern && subpattern_flags == g.subpattern_flags, 'a'+j);
if(texture::tstate == texture::tsActive && !compatible(texture::cgroup, (cpatterntype) j))
dialog::lastItem().value = XLAT("BAD");
}
dialog::addBreak(100);
dialog::addItem("more tuning", 'r');
dialog::display();
keyhandler = [] (int sym, int uni) {
if(uni == 'r')
pushScreen(showPattern);
else if(uni >= '0' && uni < '0' + size(cpatterns))
cgroup = cpatterntype(uni - '0');
else if(cgroup != cpUnknown && uni >= 'a' && uni < 'a' + size(cpatterns[cgroup].geometries)) {
auto &g = cpatterns[cgroup].geometries[uni - 'a'];
if(g.geo != geometry) { targetgeometry = g.geo; restartGame('g', false, true); }
if(g.nontrunc != nontruncated) restartGame('7', false, true);
whichPattern = g.whichPattern;
subpattern_flags = g.subpattern_flags;
}
else if(doexiton(sym, uni))
popScreen();
};
}
void computeCgroup() {
cgroup = cpUnknown;
for(int i=0; i<size(cpatterns); i++)
for(int j=0; j<size(cpatterns[i].geometries); j++) {
auto &g = cpatterns[i].geometries[j];
if(geometry == g.geo && nontruncated == g.nontrunc && whichPattern == g.whichPattern && subpattern_flags == g.subpattern_flags)
cgroup = cpatterntype(i);
}
old_cgroup = cgroup;
}
void pushChangeablePatterns() {
pushScreen(showChangeablePatterns);
computeCgroup();
}
} }
namespace linepatterns { namespace linepatterns {
@ -1468,7 +1707,7 @@ namespace linepatterns {
else if(doexiton(sym,uni)) popScreen(); else if(doexiton(sym,uni)) popScreen();
}; };
} }
}; };
int val46(cell *c) { int val46(cell *c) {

View File

@ -1274,7 +1274,7 @@ void buildpolys() {
double eps = hexhexdist * .05; double eps = hexhexdist * .05;
if(euclid) trihepta0 = hexhexdist * .5 - eps * sqrt(3)/2, trihepta1 = hexhexdist * sqrt(3)/2 - eps; // .5-.1; .75-.05 if(euclid) trihepta0 = hexhexdist * .5 - eps * sqrt(3)/2, trihepta1 = hexhexdist * sqrt(3)/2 - eps; // .5-.1; .75-.05
if(euclid && a4) if(euclid4)
trihepta0 = trihepta1 = crossf * 1.35 / 2; trihepta0 = trihepta1 = crossf * 1.35 / 2;
if(sphere&&S7==3) trihepta0 *= 1.3, trihepta1 *= 1.6; if(sphere&&S7==3) trihepta0 *= 1.3, trihepta1 *= 1.6;
@ -1327,7 +1327,7 @@ void buildpolys() {
double floorrad1 = strict ? hcrossf : euclid ? shexf*fac80*spzoom : shexf*fac94; double floorrad1 = strict ? hcrossf : euclid ? shexf*fac80*spzoom : shexf*fac94;
if(euclid && a4) { if(euclid4) {
if(nontruncated) if(nontruncated)
floorrad0 = floorrad1 = rhexf * .94; floorrad0 = floorrad1 = rhexf * .94;
else else
@ -1764,7 +1764,7 @@ void buildpolys() {
// if(euclid) espzoom6 *= 1.5, espzoomd7 *= 1.2; // if(euclid) espzoom6 *= 1.5, espzoomd7 *= 1.2;
double octroll = a38 ? .2 : a46 ? -.2 : a47 ? .1 : 0; double octroll = a38 ? .2 : a46 ? -.2 : a47 ? .1 : 0;
if(euclid && a4) octroll += M_PI/4; if(euclid4) octroll += M_PI/4;
double ffscale6 = gsca(a4,.675); double ffscale6 = gsca(a4,.675);
double ffspin6 = grot(a4,.125); double ffspin6 = grot(a4,.125);
@ -1791,7 +1791,7 @@ void buildpolys() {
bshape(shChargedFloor[0], PPR_FLOOR, scalef*espzoom6*gsca(sphere,.9)*ffscale2, 7, ffspin2); bshape(shChargedFloor[0], PPR_FLOOR, scalef*espzoom6*gsca(sphere,.9)*ffscale2, 7, ffspin2);
bshape(shChargedFloor[1], PPR_FLOOR, scalef*spzoomd7, 9); bshape(shChargedFloor[1], PPR_FLOOR, scalef*spzoomd7, 9);
bshape(shChargedFloor[2], PPR_FLOOR, scalef*espzoom6, 7); bshape(shChargedFloor[2], PPR_FLOOR, scalef*espzoom6, 7);
bshape(shChargedFloor[3], 12, spzoomd7 * gsca(a4 && euclid, .4, a4,1.2,sphere&&nontruncated,.9)* ntscale, 10, ntrot + grot(euclid && a4 && nontruncated, M_PI/4 + .1)); // nontruncated variant bshape(shChargedFloor[3], 12, spzoomd7 * gsca(a4 && euclid, .4, a4,1.2,sphere&&nontruncated,.9)* ntscale, 10, ntrot + grot(euclid4 && nontruncated, M_PI/4 + .1)); // nontruncated variant
bshape(shSStarFloor[0], PPR_FLOOR, scalef*spzoom6*gsca(sphere,.8)*ffscale2, 11, grot(a4,.775)); bshape(shSStarFloor[0], PPR_FLOOR, scalef*spzoom6*gsca(sphere,.8)*ffscale2, 11, grot(a4,.775));
bshape(shSStarFloor[1], PPR_FLOOR, scalef*spzoomd7*gsca(a4,.85), 12, octroll); bshape(shSStarFloor[1], PPR_FLOOR, scalef*spzoomd7*gsca(a4,.85), 12, octroll);

View File

@ -1028,8 +1028,8 @@ void popAllGames() {
} }
} }
void restartGame(char switchWhat, bool push) { void restartGame(char switchWhat, bool push, bool keep_screens) {
popScreenAll(); if(!keep_screens) popScreenAll();
DEBB(DF_INIT, (debugfile,"restartGame\n")); DEBB(DF_INIT, (debugfile,"restartGame\n"));
@ -1094,27 +1094,15 @@ void restartGame(char switchWhat, bool push) {
} }
#endif #endif
if(switchWhat == '7') { if(switchWhat == '7') {
if(euclid) geometry = gNormal; if(euclid6) geometry = gNormal;
nontruncated = !nontruncated; nontruncated = !nontruncated;
resetGeometry(); resetGeometry();
} }
if(switchWhat == 'g') { if(switchWhat == 'g') {
// transform coloring
eGeometry old = geometry;
if(euclid && targetgeometry == gOctagon && patterns::whichPattern == 'C')
patterns::subpattern_flags |= patterns::SPF_ROT;
if(euclid && targetgeometry == g46 && patterns::whichPattern == 'C')
patterns::subpattern_flags |= patterns::SPF_SYM01 | patterns::SPF_SYM02 | patterns::SPF_SYM03;
if(geometry == targetgeometry) geometry = gNormal; if(geometry == targetgeometry) geometry = gNormal;
else geometry = targetgeometry; else geometry = targetgeometry;
if(chaosmode && (euclid || sphere || quotient)) chaosmode = false; if(chaosmode && (euclid || sphere || quotient)) chaosmode = false;
if(nontruncated && euclid) nontruncated = false; if(nontruncated && euclid6) nontruncated = false;
if(euclid && old == gOctagon && patterns::whichPattern == 'C')
patterns::subpattern_flags |= patterns::SPF_EXTRASYM;
resetGeometry(); resetGeometry();
} }

View File

@ -4,6 +4,8 @@ namespace texture {
GLuint textureid = 0; GLuint textureid = 0;
cpatterntype cgroup;
SDL_Surface *convertSurface(SDL_Surface* s) { SDL_Surface *convertSurface(SDL_Surface* s) {
SDL_PixelFormat fmt; SDL_PixelFormat fmt;
// fmt.format = SDL_PIXELFORMAT_BGRA8888; // fmt.format = SDL_PIXELFORMAT_BGRA8888;
@ -311,6 +313,9 @@ void perform_mapping() {
texture_map[si.id].matrices.push_back(p.second * applyPatterndir(c, si)); texture_map[si.id].matrices.push_back(p.second * applyPatterndir(c, si));
} }
} }
computeCgroup();
texture::cgroup = patterns::cgroup;
} }
int forgeArgs() { int forgeArgs() {
@ -623,19 +628,21 @@ void showMenu() {
dialog::init(XLAT("texture mode")); dialog::init(XLAT("texture mode"));
if(tstate == tsOff) { if(tstate == tsOff) {
dialog::addSelItem(XLAT("select the texture's pattern"), XLAT("..."), 'r'); dialog::addItem(XLAT("select the texture's pattern"), 'r');
if(tstate_max == tsAdjusting) if(tstate_max == tsAdjusting)
dialog::addSelItem(XLAT("readjust the texture"), texturename, 't'); dialog::addItem(XLAT("readjust the texture"), 't');
if(tstate_max == tsActive) if(tstate_max == tsActive)
dialog::addSelItem(XLAT("reactivate the texture"), texturename, 't'); dialog::addItem(XLAT("reactivate the texture"), 't');
dialog::addSelItem(XLAT("open texture file"), texturename, 'o'); dialog::addItem(XLAT("open PNG as texture"), 'o');
dialog::addSelItem(XLAT("load texture config"), "...", 'l'); dialog::addItem(XLAT("load texture config"), 'l');
dialog::addSelItem(XLAT("texture size"), its(twidth), 'w'); dialog::addSelItem(XLAT("texture size"), its(twidth), 'w');
dialog::addSelItem(XLAT("paint a new texture"), "...", 'n'); dialog::addItem(XLAT("paint a new texture"), 'n');
} }
if(tstate == tsAdjusting) { if(tstate == tsAdjusting) {
dialog::addSelItem(XLAT("enable the texture"), texturename, 't'); dialog::addItem(XLAT("select the texture's pattern"), 'r');
dialog::addItem(XLAT("enable the texture"), 't');
dialog::addItem(XLAT("cancel the texture"), 'T');
dialog::addBoolItem(XLAT("move the model"), panstate == tpsModel, 'm'); dialog::addBoolItem(XLAT("move the model"), panstate == tpsModel, 'm');
dialog::addBoolItem(XLAT("move the texture"), panstate == tpsMove, 'a'); dialog::addBoolItem(XLAT("move the texture"), panstate == tpsMove, 'a');
dialog::addBoolItem(XLAT("zoom/scale the texture"), panstate == tpsScale, 'x'); dialog::addBoolItem(XLAT("zoom/scale the texture"), panstate == tpsScale, 'x');
@ -644,12 +651,12 @@ void showMenu() {
dialog::addBoolItem(XLAT("affine transformations"), panstate == tpsAffine, 'y'); dialog::addBoolItem(XLAT("affine transformations"), panstate == tpsAffine, 'y');
dialog::addBoolItem(XLAT("magic"), panstate == tpsMagic, 'A'); dialog::addBoolItem(XLAT("magic"), panstate == tpsMagic, 'A');
dialog::addBoolItem(XLAT("grid color (master)"), "...", 'M'); dialog::addColorItem(XLAT("grid color (master)"), master_color, 'M');
dialog::addBoolItem(XLAT("grid color (copy)"), "...", 'C'); dialog::addColorItem(XLAT("grid color (copy)"), slave_color, 'C');
if(panstate == tpsMagic) { if(panstate == tpsMagic) {
dialog::addSelItem(XLAT("delete markers"), its(size(amp)), 'D'); dialog::addSelItem(XLAT("delete markers"), its(size(amp)), 'D');
dialog::addSelItem(XLAT("perform auto-adjustment"), "...", 'R'); dialog::addItem(XLAT("perform auto-adjustment"), 'R');
} }
dialog::addSelItem(XLAT("precision"), its(gsplits), 'p'); dialog::addSelItem(XLAT("precision"), its(gsplits), 'p');
@ -660,12 +667,14 @@ void showMenu() {
dialog::addSelItem(XLAT("texture angle"), fts(irotate), 'a'); dialog::addSelItem(XLAT("texture angle"), fts(irotate), 'a');
dialog::addSelItem(XLAT("texture position X"), fts(ix), 'x'); dialog::addSelItem(XLAT("texture position X"), fts(ix), 'x');
dialog::addSelItem(XLAT("texture position Y"), fts(iy), 'y'); */ dialog::addSelItem(XLAT("texture position Y"), fts(iy), 'y'); */
dialog::addBoolItem(XLAT("deactivate the texture"), true, 't'); dialog::addItem(XLAT("deactivate the texture"), 't');
dialog::addBoolItem(XLAT("readjust the texture"), true, 'r'); dialog::addItem(XLAT("readjust the texture"), 'T');
dialog::addSelItem(XLAT("grid alpha"), "...", 'g'); dialog::addItem(XLAT("change the geometry"), 'r');
dialog::addSelItem(XLAT("mesh alpha"), "...", 'm'); dialog::addColorItem(XLAT("grid color"), grid_color, 'g');
dialog::addColorItem(XLAT("mesh color"), mesh_color, 'm');
dialog::addSelItem(XLAT("color alpha"), its(color_alpha), 'c'); dialog::addSelItem(XLAT("color alpha"), its(color_alpha), 'c');
dialog::addSelItem(XLAT("save the texture config"), "...", 's'); dialog::addItem(XLAT("save the texture image"), 'S');
dialog::addItem(XLAT("save the texture config"), 's');
} }
dialog::addItem(XLAT("help"), SDLK_F1); dialog::addItem(XLAT("help"), SDLK_F1);
@ -737,8 +746,8 @@ void showMenu() {
return load_textureconfig(); return load_textureconfig();
}); });
else if(uni == 'r' && tstate == tsOff) else if(uni == 'r')
pushScreen(patterns::showPattern); patterns::pushChangeablePatterns();
else if(uni == 'o' && tstate == tsOff) else if(uni == 'o' && tstate == tsOff)
dialog::openFileDialog(texturename, XLAT("texture to load:"), ".png", dialog::openFileDialog(texturename, XLAT("texture to load:"), ".png",
@ -770,7 +779,7 @@ void showMenu() {
else if(uni == 't' && tstate == tsOff) else if(uni == 't' && tstate == tsOff)
tstate = tstate_max; tstate = tstate_max;
else if((uni == 't' || uni == 'r') && tstate == tsAdjusting) { else if(uni == 't' && tstate == tsAdjusting) {
tstate = tstate_max = tsActive; tstate = tstate_max = tsActive;
perform_mapping(); perform_mapping();
} }
@ -778,7 +787,10 @@ void showMenu() {
else if(uni == 't' && tstate == tsActive) else if(uni == 't' && tstate == tsActive)
tstate = tsOff; tstate = tsOff;
else if(uni == 'r' && tstate == tsActive) { else if(uni == 'T' && tstate == tsAdjusting)
tstate = tsOff;
else if(uni == 'T' && tstate == tsActive) {
tstate = tsAdjusting; tstate = tsAdjusting;
texture_map.clear(); texture_map.clear();
} }
@ -911,5 +923,3 @@ void drawPixel(cell *c, hyperpoint h, int col) {
} }
// todo `three octagons` with two colors