1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-10-31 19:36:16 +00:00

more intuitive file dialogs; texture config saving

This commit is contained in:
Zeno Rogue 2017-12-14 12:10:40 +01:00
parent ebd159825c
commit e2080cd91e
5 changed files with 293 additions and 129 deletions

View File

@ -63,7 +63,9 @@ struct supersaver {
virtual void reset() = 0; virtual void reset() = 0;
}; };
vector<shared_ptr<supersaver>> savers; typedef vector<shared_ptr<supersaver>> saverlist;
saverlist savers;
template<class T> struct dsaver : supersaver { template<class T> struct dsaver : supersaver {
T& val; T& val;
@ -77,7 +79,7 @@ template<class T> struct saver : dsaver<T> {};
template<class T, class U, class V> void addsaver(T& i, U name, V dft) { template<class T, class U, class V> void addsaver(T& i, U name, V dft) {
auto s = make_shared<saver<T>> (i); auto s = make_shared<saver<T>> (i);
s->dft = i = dft; s->dft = dft;
s->name = name; s->name = name;
savers.push_back(s); savers.push_back(s);
} }
@ -96,13 +98,17 @@ template<class T> struct saverenum : supersaver {
void load(const string& s) { val = (T) atoi(s.c_str()); } void load(const string& s) { val = (T) atoi(s.c_str()); }
}; };
template<class T, class U> void addsaverenum(T& i, U name) { template<class T, class U> void addsaverenum(T& i, U name, T dft) {
auto s = make_shared<saverenum<T>> (i); auto s = make_shared<saverenum<T>> (i);
s->dft = i; s->dft = dft;
s->name = name; s->name = name;
savers.push_back(s); savers.push_back(s);
} }
template<class T, class U> void addsaverenum(T& i, U name) {
addsaverenum(i, name, i);
}
template<> struct saver<int> : dsaver<int> { template<> struct saver<int> : dsaver<int> {
saver<int>(int& val) : dsaver<int>(val) { } saver<int>(int& val) : dsaver<int>(val) { }
string save() { return its(val); } string save() { return its(val); }
@ -127,6 +133,12 @@ template<> struct saver<unsigned> : dsaver<unsigned> {
void load(const string& s) { val = (unsigned) strtoll(s.c_str(), NULL, 16); } void load(const string& s) { val = (unsigned) strtoll(s.c_str(), NULL, 16); }
}; };
template<> struct saver<string> : dsaver<string> {
saver<string>(string& val) : dsaver<string>(val) { }
string save() { return val; }
void load(const string& s) { val = s; }
};
template<> struct saver<ld> : dsaver<ld> { template<> struct saver<ld> : dsaver<ld> {
saver<ld>(ld& val) : dsaver<ld>(val) { } saver<ld>(ld& val) : dsaver<ld>(val) { }
string save() { return ftssmart(val); } string save() { return ftssmart(val); }
@ -318,6 +330,8 @@ void initConfig() {
#if CAP_SHMUP #if CAP_SHMUP
shmup::initConfig(); shmup::initConfig();
#endif #endif
for(auto s: savers) s->reset();
} }
bool inSpecialMode() { bool inSpecialMode() {

View File

@ -854,6 +854,8 @@ namespace dialog {
string *cfileptr; string *cfileptr;
bool editext = false; bool editext = false;
bool_reaction_t file_action;
bool handleKeyFile(int sym, int uni); bool handleKeyFile(int sym, int uni);
void drawFileDialog() { void drawFileDialog() {
@ -916,14 +918,14 @@ namespace dialog {
string& s(*cfileptr); string& s(*cfileptr);
int i = size(s) - (editext?0:4); int i = size(s) - (editext?0:4);
if(uni > 2000) sym = uni - 2000; if(uni > 2000) sym = uni - 2000;
if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER || sym == SDLK_ESCAPE) { if(sym == SDLK_ESCAPE) {
popScreen(); popScreen();
return true;
} }
/* else if(sym == SDLK_F2 || sym == SDLK_F3) { else if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER) {
// we pop and re-push, in case if action opens something
popScreen(); popScreen();
return false; if(!file_action()) pushScreen(drawFileDialog);
} */ }
else if(sym == SDLK_F4) { else if(sym == SDLK_F4) {
editext = !editext; editext = !editext;
} }
@ -955,10 +957,11 @@ namespace dialog {
return true; return true;
} }
void openFileDialog(string& filename, string fcap, string ext) { void openFileDialog(string& filename, string fcap, string ext, bool_reaction_t action) {
cfileptr = &filename; cfileptr = &filename;
filecaption = fcap; filecaption = fcap;
cfileext = ext; cfileext = ext;
file_action = action;
pushScreen(dialog::drawFileDialog); pushScreen(dialog::drawFileDialog);
} }

View File

@ -569,6 +569,7 @@ extern bool mousepressed, anyshiftclick;
extern string help; extern string help;
typedef function<void()> reaction_t; typedef function<void()> reaction_t;
typedef function<bool()> bool_reaction_t;
extern reaction_t help_delegate; extern reaction_t help_delegate;
@ -1173,7 +1174,7 @@ namespace dialog {
extern int dialogflags; extern int dialogflags;
extern int dcenter; extern int dcenter;
void openFileDialog(string& filename, string fcap, string ext); void openFileDialog(string& filename, string fcap, string ext, bool_reaction_t action);
extern string infix; extern string infix;
bool hasInfix(const string &s); bool hasInfix(const string &s);

View File

@ -435,7 +435,6 @@ namespace mapeditor {
displayButton(8, vid.yres-8-fs*11, XLAT("F1 = help"), SDLK_F1, 0); displayButton(8, vid.yres-8-fs*11, XLAT("F1 = help"), SDLK_F1, 0);
displayButton(8, vid.yres-8-fs*10, XLAT("F2 = save"), SDLK_F2, 0); displayButton(8, vid.yres-8-fs*10, XLAT("F2 = save"), SDLK_F2, 0);
displayButton(8, vid.yres-8-fs*9, XLAT("F3 = load"), SDLK_F3, 0); displayButton(8, vid.yres-8-fs*9, XLAT("F3 = load"), SDLK_F3, 0);
displayButton(8, vid.yres-8-fs*8, XLAT("F4 = file"), SDLK_F3, 0);
displayButton(8, vid.yres-8-fs*7, XLAT("F5 = restart"), SDLK_F5, 0); displayButton(8, vid.yres-8-fs*7, XLAT("F5 = restart"), SDLK_F5, 0);
displayButton(8, vid.yres-8-fs*6, XLAT("F6 = HQ shot"), SDLK_F6, 0); displayButton(8, vid.yres-8-fs*6, XLAT("F6 = HQ shot"), SDLK_F6, 0);
displayButton(8, vid.yres-8-fs*5, XLAT("F7 = player on/off"), SDLK_F7, 0); displayButton(8, vid.yres-8-fs*5, XLAT("F7 = player on/off"), SDLK_F7, 0);
@ -763,23 +762,32 @@ namespace mapeditor {
paintwhat_str = "paint"; paintwhat_str = "paint";
dialog::openColorDialog((unsigned&)(paintwhat = (painttype ==6 ? paintwhat : 0x808080))); dialog::openColorDialog((unsigned&)(paintwhat = (painttype ==6 ? paintwhat : 0x808080)));
} }
else if(sym == SDLK_F2) {
if(mapstream::saveMap(levelfile.c_str()))
addMessage(XLAT("Map saved to %1", levelfile));
else
addMessage(XLAT("Failed to save map to %1", levelfile));
}
else if(sym == SDLK_F5) { else if(sym == SDLK_F5) {
restartGame(); restartGame();
} }
else if(sym == SDLK_F3) { else if(sym == SDLK_F2) {
if(mapstream::loadMap(levelfile.c_str())) dialog::openFileDialog(levelfile, XLAT("level to save/load:"), ".lev", [] () {
addMessage(XLAT("Map loaded from %1", levelfile)); if(mapstream::saveMap(levelfile.c_str())) {
else addMessage(XLAT("Map saved to %1", levelfile));
addMessage(XLAT("Failed to load map from %1", levelfile)); return true;
}
else {
addMessage(XLAT("Failed to save map to %1", levelfile));
return false;
}
});
} }
else if(sym == SDLK_F4) else if(sym == SDLK_F3)
dialog::openFileDialog(levelfile, XLAT("level to save/load:"), ".lev"); dialog::openFileDialog(levelfile, XLAT("level to save/load:"), ".lev", [] () {
if(mapstream::loadMap(levelfile.c_str())) {
addMessage(XLAT("Map loaded from %1", levelfile));
return true;
}
else {
addMessage(XLAT("Failed to load map from %1", levelfile));
return false;
}
});
#if CAP_SDL #if CAP_SDL
else if(sym == SDLK_F6) { else if(sym == SDLK_F6) {
saveHighQualityShot(); saveHighQualityShot();
@ -1177,17 +1185,17 @@ namespace mapeditor {
bool onelayeronly; bool onelayeronly;
void loadPicFile(const string& s) { bool loadPicFile(const string& s) {
FILE *f = fopen(picfile.c_str(), "rt"); FILE *f = fopen(picfile.c_str(), "rt");
if(!f) { if(!f) {
addMessage(XLAT("Failed to load pictures from %1", picfile)); addMessage(XLAT("Failed to load pictures from %1", picfile));
return; return false;
} }
int err; int err;
char buf[200]; char buf[200];
if(!fgets(buf, 200, f)) { if(!fgets(buf, 200, f)) {
addMessage(XLAT("Failed to load pictures from %1", picfile)); addMessage(XLAT("Failed to load pictures from %1", picfile));
fclose(f); return; fclose(f); return false;
} }
int vernum; err = fscanf(f, "%x", &vernum); int vernum; err = fscanf(f, "%x", &vernum);
printf("vernum = %x\n", vernum); printf("vernum = %x\n", vernum);
@ -1213,13 +1221,14 @@ namespace mapeditor {
addMessage(XLAT("Pictures loaded from %1", picfile)); addMessage(XLAT("Pictures loaded from %1", picfile));
buildpolys(); buildpolys();
return true;
} }
void savePicFile(const string& s) { bool savePicFile(const string& s) {
FILE *f = fopen(picfile.c_str(), "wt"); FILE *f = fopen(picfile.c_str(), "wt");
if(!f) { if(!f) {
addMessage(XLAT("Failed to save pictures to %1", picfile)); addMessage(XLAT("Failed to save pictures to %1", picfile));
return; return false;
} }
fprintf(f, "HyperRogue saved picture\n"); fprintf(f, "HyperRogue saved picture\n");
fprintf(f, "%x\n", VERNUM_HEX); fprintf(f, "%x\n", VERNUM_HEX);
@ -1241,6 +1250,7 @@ namespace mapeditor {
fprintf(f, "\n-1\n"); fprintf(f, "\n-1\n");
fclose(f); fclose(f);
addMessage(XLAT("Pictures saved to %1", picfile)); addMessage(XLAT("Pictures saved to %1", picfile));
return true;
} }
void drawHandleKey(int sym, int uni) { void drawHandleKey(int sym, int uni) {
@ -1303,14 +1313,17 @@ namespace mapeditor {
colorkey = true; colorkey = true;
} }
if(sym == SDLK_F4)
dialog::openFileDialog(picfile, XLAT("pics to save/load:"), ".pic");
if(sym == SDLK_F2) if(sym == SDLK_F2)
savePicFile(picfile); dialog::openFileDialog(picfile, XLAT("pics to save/load:"), ".pic",
[] () {
return savePicFile(picfile);
});
if(sym == SDLK_F3) if(sym == SDLK_F3)
loadPicFile(picfile); dialog::openFileDialog(picfile, XLAT("pics to save/load:"), ".pic",
[] () {
return loadPicFile(picfile);
});
if(sym == SDLK_F7) { if(sym == SDLK_F7) {
drawplayer = !drawplayer; drawplayer = !drawplayer;

View File

@ -2,7 +2,7 @@
namespace texture { namespace texture {
GLuint textureid; GLuint textureid = 0;
SDL_Surface *convertSurface(SDL_Surface* s) { SDL_Surface *convertSurface(SDL_Surface* s) {
SDL_PixelFormat fmt; SDL_PixelFormat fmt;
@ -29,15 +29,15 @@ SDL_Surface *convertSurface(SDL_Surface* s) {
return SDL_ConvertSurface(s, &fmt, SDL_SWSURFACE); return SDL_ConvertSurface(s, &fmt, SDL_SWSURFACE);
} }
bool texture_read = false;
int twidth = 2048; int twidth = 2048;
vector<int> expanded_data; vector<int> expanded_data;
string texturename; string texturename;
string configname = "hyperrogue.txc";
eTextureState tstate; eTextureState tstate;
eTextureState tstate_max;
template<class T, class U> void scale_colorarray(int origdim, const T& src, const U& dest) { template<class T, class U> void scale_colorarray(int origdim, const T& src, const U& dest) {
int ox = 0, tx = 0, partials[4]; int ox = 0, tx = 0, partials[4];
@ -65,12 +65,15 @@ template<class T, class U> void scale_colorarray(int origdim, const T& src, cons
} }
} }
void readtexture() { bool readtexture() {
texture_read = true;
glGenTextures(1, &textureid ); if(textureid == 0) glGenTextures(1, &textureid );
SDL_Surface *txt = IMG_Load(texturename.c_str()); SDL_Surface *txt = IMG_Load(texturename.c_str());
if(!txt) {
addMessage(XLAT("Failed to load %1", texturename));
return false;
}
auto txt2 = convertSurface(txt); auto txt2 = convertSurface(txt);
int tx = txt->w, ty = txt->h; int tx = txt->w, ty = txt->h;
@ -111,6 +114,7 @@ void readtexture() {
GL_BGRA, GL_UNSIGNED_BYTE, GL_BGRA, GL_UNSIGNED_BYTE,
&expanded_data[0] ); &expanded_data[0] );
return true;
} }
transmatrix itt = Id; transmatrix itt = Id;
@ -258,7 +262,6 @@ void perform_mapping() {
if(gsplits < 0) gsplits = 0; if(gsplits < 0) gsplits = 0;
if(gsplits > 4) gsplits = 4; if(gsplits > 4) gsplits = 4;
using namespace patterns; using namespace patterns;
if(!texture_read) readtexture();
texture_map.clear(); texture_map.clear();
for(auto p: gmatrix) { for(auto p: gmatrix) {
cell *c = p.first; cell *c = p.first;
@ -286,7 +289,7 @@ int forgeArgs() {
using namespace arg; using namespace arg;
if(0) ; if(0) ;
else if(argis("-forge")) { else if(argis("-txpic")) {
shift(); texturename = args(); shift(); texturename = args();
} }
@ -294,6 +297,10 @@ int forgeArgs() {
shift(); gsplits = argf(); shift(); gsplits = argf();
} }
else if(argis("-txc")) {
shift(); configname = args();
}
else return 1; else return 1;
return 0; return 0;
} }
@ -304,7 +311,6 @@ auto texture_hook =
addHook(hooks_args, 100, forgeArgs); addHook(hooks_args, 100, forgeArgs);
void drawRawTexture() { void drawRawTexture() {
if(!texture_read) readtexture();
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@ -339,6 +345,157 @@ void drawRawTexture() {
enum eTexturePanstate {tpsModel, tpsMove, tpsScale, tpsAffine, tpsZoom, tpsProjection}; enum eTexturePanstate {tpsModel, tpsMove, tpsScale, tpsAffine, tpsZoom, tpsProjection};
eTexturePanstate panstate; eTexturePanstate panstate;
void mousemovement() {
static hyperpoint lastmouse;
hyperpoint mouseeu = hpxyz((mousex - vid.xcenter + .0) / vid.scrsize, (mousey - vid.ycenter + .0) / vid.scrsize, 1);
bool nonzero = mouseeu[0] || mouseeu[1];
switch(panstate) {
case tpsModel:
if(!newmove && mouseh[2] < 50 && lastmouse[2] < 50) {
panning(lastmouse, mouseh);
perform_mapping();
}
lastmouse = mouseh; newmove = false;
break;
case tpsMove: {
if(!newmove)
itt = itt * inverse(eupush(mouseeu)) * eupush(lastmouse);
lastmouse = mouseeu; newmove = false;
break;
}
case tpsScale: {
if(nonzero && !newmove)
itt = itt * inverse(euscalezoom(mouseeu)) * euscalezoom(lastmouse);
if(nonzero) lastmouse = mouseeu;
newmove = false;
break;
}
case tpsAffine: {
if(!newmove)
itt = itt * inverse(euaffine(mouseeu)) * euaffine(lastmouse);
lastmouse = mouseeu; newmove = false;
break;
}
case tpsZoom: {
// do not zoom in portrait!
if(nonzero && !newmove) {
View = View * inverse(spintox(mouseeu)) * spintox(lastmouse);
vid.scale = vid.scale * sqrt(intvalxy(C0, mouseeu)) / sqrt(intvalxy(C0, lastmouse));
}
if(nonzero) lastmouse = mouseeu;
newmove = false;
break;
}
case tpsProjection: {
if(nonzero && !newmove) {
vid.alpha = vid.alpha * sqrt(intvalxy(C0, mouseeu)) / sqrt(intvalxy(C0, lastmouse));
}
if(nonzero) lastmouse = mouseeu;
newmove = false;
}
default: break;
}
}
patterns::patterninfo si_save;
saverlist texturesavers;
bool target_nontrunc;
void init_textureconfig() {
texturesavers = move(savers);
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
addsaver(itt[i][j], "texturematrix_" + its(i) + its(j), i==j ? 1 : 0);
for(int i=0; i<3; i++)
for(int j=0; j<3; j++)
addsaver(View[i][j], "viewmatrix_" + its(i) + its(j), i==j ? 1 : 0);
addsaverenum(targetgeometry, "geometry", gNormal);
addsaverenum(target_nontrunc, "chamfering", false);
// ... geometry parameters
addsaver(patterns::whichPattern, "pattern", 0);
addsaver(patterns::subpattern_flags, "pattern flags", 0);
cell *ctr = euclid ? centerover : viewctr.h->c7;
si_save = patterns::getpatterninfo0(ctr);
addsaver(si_save.id, "center type", 1);
addsaver(si_save.dir, "center direction", 0);
addsaver(si_save.reflect, "center reflection", false);
addsaver(twidth, "texture resolution", 2048);
addsaver(gsplits, "precision", 1);
addsaver(grid_alpha, "alpha grid", 0);
addsaver(color_alpha, "alpha color", 0);
addsaver(mesh_alpha, "alpha mesh", 0);
addsaver(vid.alpha, "projection", 1);
addsaver(vid.scale, "scale", 1);
addsaver(texturename, "texture filename", "");
swap(texturesavers, savers);
}
bool save_textureconfig() {
init_textureconfig();
FILE *f = fopen(configname.c_str(), "wt");
if(!f) return false;
targetgeometry = geometry;
target_nontrunc = nontruncated;
for(auto s: texturesavers) if(s->dosave())
fprintf(f, "%s=%s\n", s->name.c_str(), s->save().c_str());
fclose(f);
return true;
}
bool load_textureconfig() {
init_textureconfig();
FILE *f = fopen(configname.c_str(), "rt");
if(!f) return false;
swap(texturesavers, savers);
for(auto s: savers) s->reset();
loadNewConfig(f);
swap(texturesavers, savers);
fclose(f);
if(1) {
dynamicval<char> d1(patterns::whichPattern, patterns::whichPattern);
dynamicval<int> d2(patterns::subpattern_flags, patterns::subpattern_flags);
if(targetgeometry != geometry) {
restartGame('g');
return load_textureconfig();
}
if(nontruncated != target_nontrunc) {
restartGame('7');
}
}
if(!readtexture()) return false;
drawthemap();
perform_mapping();
tstate = tstate_max = tsActive;
return true;
}
void showMenu() { void showMenu() {
cmode = sm::SIDE | sm::MAYDARK | sm::DIALOG_STRICT_X; cmode = sm::SIDE | sm::MAYDARK | sm::DIALOG_STRICT_X;
gamescreen(0); gamescreen(0);
@ -348,17 +505,25 @@ void showMenu() {
dialog::init(XLAT("texture mode")); dialog::init(XLAT("texture mode"));
dialog::addSelItem(XLAT("select the texture's pattern"), XLAT("..."), 'r'); if(tstate == tsOff) {
dialog::addSelItem(XLAT("texture file"), texturename, 'f'); dialog::addSelItem(XLAT("select the texture's pattern"), XLAT("..."), 'r');
dialog::addSelItem(XLAT("texture mode enabled"), its(tstate), 't'); if(tstate_max == tsAdjusting)
dialog::addSelItem(XLAT("readjust the texture"), texturename, 't');
if(tstate_max == tsActive)
dialog::addSelItem(XLAT("reactivate the texture"), texturename, 't');
dialog::addSelItem(XLAT("open texture file"), texturename, 'o');
dialog::addSelItem(XLAT("load texture config"), "...", 'l');
}
if(tstate == tsAdjusting) { if(tstate == tsAdjusting) {
dialog::addSelItem(XLAT("enable the texture"), texturename, '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');
dialog::addBoolItem(XLAT("zoom/scale the model"), panstate == tpsZoom, 'z'); dialog::addBoolItem(XLAT("zoom/scale the model"), panstate == tpsZoom, 'z');
dialog::addBoolItem(XLAT("projection"), panstate == tpsProjection, 'p'); dialog::addBoolItem(XLAT("projection"), panstate == tpsProjection, 'p');
dialog::addBoolItem(XLAT("affine transformations"), panstate == tpsAffine, 'y'); dialog::addBoolItem(XLAT("affine transformations"), panstate == tpsAffine, 'y');
dialog::addSelItem(XLAT("precision"), its(gsplits), 'p');
} }
if(tstate == tsActive) { if(tstate == tsActive) {
@ -366,10 +531,12 @@ 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::addBoolItem(XLAT("readjust the texture"), true, 'r');
dialog::addSelItem(XLAT("grid alpha"), its(grid_alpha), 'g'); dialog::addSelItem(XLAT("grid alpha"), its(grid_alpha), 'g');
dialog::addSelItem(XLAT("mesh alpha"), its(mesh_alpha), 'm'); dialog::addSelItem(XLAT("mesh alpha"), its(mesh_alpha), 'm');
dialog::addSelItem(XLAT("precision"), its(gsplits), 'p');
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("help"), SDLK_F1); dialog::addItem(XLAT("help"), SDLK_F1);
@ -379,65 +546,7 @@ void showMenu() {
dialog::display(); dialog::display();
if(holdmouse) { if(holdmouse) mousemovement();
static hyperpoint lastmouse;
hyperpoint mouseeu = hpxyz((mousex - vid.xcenter + .0) / vid.scrsize, (mousey - vid.ycenter + .0) / vid.scrsize, 1);
bool nonzero = mouseeu[0] || mouseeu[1];
switch(panstate) {
case tpsModel:
if(!newmove && mouseh[2] < 50 && lastmouse[2] < 50) {
panning(lastmouse, mouseh);
perform_mapping();
}
lastmouse = mouseh; newmove = false;
break;
case tpsMove: {
if(!newmove)
itt = itt * inverse(eupush(mouseeu)) * eupush(lastmouse);
lastmouse = mouseeu; newmove = false;
break;
}
case tpsScale: {
if(nonzero && !newmove)
itt = itt * inverse(euscalezoom(mouseeu)) * euscalezoom(lastmouse);
if(nonzero) lastmouse = mouseeu;
newmove = false;
break;
}
case tpsAffine: {
if(!newmove)
itt = itt * inverse(euaffine(mouseeu)) * euaffine(lastmouse);
lastmouse = mouseeu; newmove = false;
break;
}
case tpsZoom: {
// do not zoom in portrait!
if(nonzero && !newmove) {
View = View * inverse(spintox(mouseeu)) * spintox(lastmouse);
vid.scale = vid.scale * sqrt(intvalxy(C0, mouseeu)) / sqrt(intvalxy(C0, lastmouse));
}
if(nonzero) lastmouse = mouseeu;
newmove = false;
break;
}
case tpsProjection: {
if(nonzero && !newmove) {
vid.alpha = vid.alpha * sqrt(intvalxy(C0, mouseeu)) / sqrt(intvalxy(C0, lastmouse));
}
if(nonzero) lastmouse = mouseeu;
newmove = false;
}
default: break;
}
}
keyhandler = [] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
// handlePanning(sym, uni); // handlePanning(sym, uni);
@ -457,37 +566,61 @@ void showMenu() {
else if(uni == 'z' && tstate == tsAdjusting) panstate = tpsZoom; else if(uni == 'z' && tstate == tsAdjusting) panstate = tpsZoom;
else if(uni == 'p' && tstate == tsAdjusting) panstate = tpsProjection; else if(uni == 'p' && tstate == tsAdjusting) panstate = tpsProjection;
else if(uni == 'r') else if(uni == 's' && tstate == tsActive)
dialog::openFileDialog(configname, XLAT("texture config to save:"), ".txc",
[] () {
return save_textureconfig();
});
else if(uni == 'l' && tstate == tsOff)
dialog::openFileDialog(configname, XLAT("texture config to load:"), ".txc",
[] () {
return load_textureconfig();
});
else if(uni == 'r' && tstate == tsOff)
pushScreen(patterns::showPattern); pushScreen(patterns::showPattern);
else if(uni == 'f')
dialog::openFileDialog(texturename, XLAT("texture to load:"), ".png"); else if(uni == 'o' && tstate == tsOff)
else if(uni == 't') { dialog::openFileDialog(texturename, XLAT("texture to load:"), ".png",
if(tstate == tsOff) { [] () {
tstate = tsAdjusting; if(readtexture()) {
perform_mapping(); if(tstate_max == tsOff) tstate_max = tsAdjusting;
} tstate = tstate_max;
else if(tstate == tsAdjusting) { return true;
tstate = tsActive; }
perform_mapping(); else return false;
} });
else {
tstate = tsOff; else if(uni == 't' && tstate == tsOff)
texture_map.clear(); tstate = tstate_max;
}
else if((uni == 't' || uni == 'r') && tstate == tsAdjusting) {
tstate = tstate_max = tsActive;
perform_mapping();
} }
else if(uni == 'g') {
else if(uni == 't' && tstate == tsActive)
tstate = tsOff;
else if(uni == 'r' && tstate == tsActive) {
tstate = tsAdjusting;
texture_map.clear();
}
else if(uni == 'g' && tstate == tsActive) {
dialog::editNumber(grid_alpha, 0, 255, 15, 0, XLAT("grid alpha"), dialog::editNumber(grid_alpha, 0, 255, 15, 0, XLAT("grid alpha"),
XLAT("Grid alpha.")); XLAT("Grid alpha."));
} }
else if(uni == 'm') { else if(uni == 'm' && tstate == tsActive) {
dialog::editNumber(mesh_alpha, 0, 255, 15, 0, XLAT("mesh alpha"), dialog::editNumber(mesh_alpha, 0, 255, 15, 0, XLAT("mesh alpha"),
XLAT("Mesh alpha.")); XLAT("Mesh alpha."));
} }
else if(uni == 'c') { else if(uni == 'c' && tstate == tsActive) {
dialog::editNumber(color_alpha, 0, 255, 15, 0, XLAT("color alpha"), dialog::editNumber(color_alpha, 0, 255, 15, 0, XLAT("color alpha"),
XLAT("The higher the value, the less important the color of underlying terrain is.")); XLAT("The higher the value, the less important the color of underlying terrain is."));
} }
else if(uni == 'p') { else if(uni == 'p' && tstate == tsAdjusting) {
dialog::editNumber(gsplits, 0, 4, 1, 1, XLAT("precision"), dialog::editNumber(gsplits, 0, 4, 1, 1, XLAT("precision"),
XLAT("precision")); XLAT("precision"));
dialog::reaction = perform_mapping; dialog::reaction = perform_mapping;
@ -498,6 +631,6 @@ void showMenu() {
} }
} }
// - dual grid
// todo save/load texture configuration
// todo texture editor // todo texture editor
// todo `three octagons` with two colors