From 2c09c5ee5620a42ed2ff22da99a315e423f41bf1 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 17 Mar 2018 21:12:46 +0100 Subject: [PATCH] structurized textures.cpp --- graph.cpp | 10 +- hyper.h | 93 ++++++++++-- init.cpp | 1 + mapeditor.cpp | 40 ++--- menus.cpp | 2 +- pattern2.cpp | 8 +- polygons.cpp | 7 +- system.cpp | 16 +- textures.cpp | 398 ++++++++++++++++++++++---------------------------- 9 files changed, 298 insertions(+), 277 deletions(-) diff --git a/graph.cpp b/graph.cpp index f05b5961..f4f80e9d 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3112,7 +3112,7 @@ void warpfloor(cell *c, const transmatrix& V, int col, int prio, bool warp) { if(shmup::on || nonbitrunc) warp = false; #if CAP_TEXTURE if(qfi.tinf) { - queuetable(V*qfi.spin, qfi.tinf->vertices, size(qfi.tinf->vertices), 0, texture::recolor(col), prio); + queuetable(V*qfi.spin, qfi.tinf->vertices, size(qfi.tinf->vertices), 0, texture::config.recolor(col), prio); lastptd().u.poly.tinf = qfi.tinf; } else @@ -3460,7 +3460,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #if CAP_TEXTURE if(texture::saving) { - texture::apply(c, V, 0xFFFFFFFF); + texture::config.apply(c, V, 0xFFFFFFFF); return; } #endif @@ -3817,7 +3817,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { #endif #if CAP_TEXTURE - else if(texture::apply(c, Vf, darkena(fcol, fd, 0xFF))) ; + else if(texture::config.apply(c, Vf, darkena(fcol, fd, 0xFF))) ; #endif else if(c->land == laMirrorWall) { @@ -5547,8 +5547,8 @@ void gamescreen(int _darken) { darken = 0; #if CAP_TEXTURE - if(texture::tstate == texture::tsAdjusting) - texture::drawRawTexture(); + if(texture::config.tstate == texture::tsAdjusting) + texture::config.drawRawTexture(); #endif } diff --git a/hyper.h b/hyper.h index 4bea272b..e81eb8bb 100644 --- a/hyper.h +++ b/hyper.h @@ -2431,18 +2431,87 @@ namespace texture { tsOff, tsAdjusting, tsActive }; - extern eTextureState tstate, tstate_max; - extern unsigned paint_color; - extern ld penwidth; - extern transmatrix itt; - extern int twidth; - extern bool saving; + struct texture_data { + GLuint textureid = 0; - extern vector texture_pixels; + int twidth = 2048; + + vector texture_pixels; + + unsigned& get_texture_pixel(int x, int y) { + return texture_pixels[(y&(twidth-1))*twidth+(x&(twidth-1))]; + } + + vector> undos; + vector > pixels_to_draw; + + bool loadTextureGL(); + bool whitetexture(); + bool readtexture(string tn); + void saveRawTexture(string tn); + + void undo(); + void undoLock(); + void update(); + }; + + struct texture_config { + string texturename = "textures/hyperrogue-texture.png"; + string configname = "textures/hyperrogue.txc"; + unsigned paint_color = 0x000000FF; + eTextureState tstate; + eTextureState tstate_max; + + transmatrix itt = Id; + + unsigned grid_color = 0; + unsigned mesh_color = 0; + unsigned master_color = 0xFFFFFF30; + unsigned slave_color = 0xFF000008; + + int color_alpha = 128; + + int gsplits = 1; + + int recolor(int col); + + typedef tuple texture_parameters; + texture_parameters orig_texture_parameters; + + map texture_map, texture_map_orig; + set models; + + bool texture_tuned = false; + string texture_tuner; + vector tuned_vertices; + + bool apply(cell *c, const transmatrix &V, int col); + void mark_triangles(); + + void clear_texture_map(); + void perform_mapping(); + void mapTextureTriangle(textureinfo &mi, const array& v, const array& tv, int splits); + void mapTextureTriangle(textureinfo &mi, const array& v, const array& tv) { mapTextureTriangle(mi, v, tv, gsplits); } + void mapTexture2(textureinfo& mi); + void finish_mapping(); + void remap(eTextureState old_tstate, eTextureState old_tstate_max); + + void drawRawTexture(); + void saveFullTexture(string tn); + + bool save(); + bool load(); + + texture_data data; + }; + + extern texture_config config; + + extern ld penwidth; + extern bool saving; void showMenu(); - void update(); void drawPixel(cell *c, hyperpoint h, int col); extern cell *where; @@ -2450,15 +2519,7 @@ namespace texture { void drawPixel(hyperpoint h, int col); void drawLine(hyperpoint h1, hyperpoint h2, int col, int steps = 10); - void remap(eTextureState old_tstate, eTextureState old_tstate_max); - - void perform_mapping(); - void finish_mapping(); - - void undoLock(); - void undo(); extern bool texturesym; - extern cpatterntype cgroup; } diff --git a/init.cpp b/init.cpp index ca97f232..824d1c93 100644 --- a/init.cpp +++ b/init.cpp @@ -368,6 +368,7 @@ extern "C" { #include #include #include +#include #ifdef USE_UNORDERED_MAP #include diff --git a/mapeditor.cpp b/mapeditor.cpp index ea0e00f6..a854a3f2 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -43,12 +43,12 @@ namespace mapeditor { // printf("scale = " LDF "\n", vid.scale); #if CAP_TEXTURE // display(texture::itt); - texture::itt = xyscale(texture::itt, 1/z); - if(false && texture::tstate) { + texture::config.itt = xyscale(texture::config.itt, 1/z); + if(false && texture::config.tstate) { calcparam(); - texture::perform_mapping(); - if(texture::tstate == texture::tsAdjusting) - texture::finish_mapping(); + texture::config.perform_mapping(); + if(texture::config.tstate == texture::tsAdjusting) + texture::config.finish_mapping(); } #endif } @@ -952,11 +952,11 @@ namespace mapeditor { bool intexture = false; #if CAP_TEXTURE - if(texture::tstate == texture::tsActive) { + if(texture::config.tstate == texture::tsActive) { sg = 16; line1 = "texture"; line2 = ""; - texture::update(); + texture::config.data.update(); intexture = true; } #else @@ -1038,7 +1038,7 @@ namespace mapeditor { } #if CAP_TEXTURE - else if(texture::tstate == texture::tsActive) { + else if(texture::config.tstate == texture::tsActive) { displayButton(8, 8+fs*2, XLAT(texture::texturesym ? "0 = symmetry" : "0 = asymmetry"), '0', 0); if(mousekey == 'g') displayButton(8, 8+fs*16, XLAT("p = grid color"), 'p', 0); @@ -1069,7 +1069,7 @@ namespace mapeditor { getcstat = 2000+i; } - if(texture::tstate != texture::tsActive) + if(texture::config.tstate != texture::tsActive) displaymm('e', vid.xres-8, 8+fs, 2, vid.fsize, XLAT("e = edit this"), 16); #endif @@ -1455,16 +1455,16 @@ namespace mapeditor { if(sym == SDLK_F10) popScreen(); #if CAP_TEXTURE - if(texture::tstate == texture::tsActive) { + if(texture::config.tstate == texture::tsActive) { - int tcolor = (texture::paint_color >> 8) | ((texture::paint_color & 0xFF) << 24); + int tcolor = (texture::config.paint_color >> 8) | ((texture::config.paint_color & 0xFF) << 24); if(uni == '-' && !clickused) { if(mousekey == 'l' || mousekey == 'c') { if(!holdmouse) lstart = mouseh, lstartcell = mouseover, holdmouse = true; } else { - if(!holdmouse) texture::undoLock(); + if(!holdmouse) texture::config.data.undoLock(); texture::drawPixel(mouseover, mouseh, tcolor); holdmouse = true; lstartcell = NULL; } @@ -1473,14 +1473,14 @@ namespace mapeditor { if(sym == PSEUDOKEY_RELEASE) { printf("release\n"); if(mousekey == 'l') { - texture::undoLock(); + texture::config.data.undoLock(); texture::where = mouseover; texture::drawPixel(mouseover, mouseh, tcolor); texture::drawLine(mouseh, lstart, tcolor); lstartcell = NULL; } if(mousekey == 'c') { - texture::undoLock(); + texture::config.data.undoLock(); ld rad = hdist(lstart, mouseh); int circp = int(1 + 3 * (circlelength(rad) / texture::penwidth)); if(circp > 1000) circp = 1000; @@ -1493,7 +1493,7 @@ namespace mapeditor { } if(uni >= 1000 && uni < 1010) - texture::paint_color = texture_colors[uni - 1000 + 1]; + texture::config.paint_color = texture_colors[uni - 1000 + 1]; if(uni >= 2000 && uni < 2010) texture::penwidth = brush_sizes[uni - 2000]; @@ -1502,12 +1502,12 @@ namespace mapeditor { texture::texturesym = !texture::texturesym; if(uni == 'u') { - texture::undo(); + texture::config.data.undo(); } if(uni == 'p') { if(!clickused) - dialog::openColorDialog(texture::paint_color, texture_colors); + dialog::openColorDialog(texture::config.paint_color, texture_colors); } if(uni == 'b') @@ -1619,7 +1619,7 @@ namespace mapeditor { for(int j=0; j= 'a' && uni < 'a' + size(cpatterns[cgroup].geometries)) { #if CAP_TEXTURE - auto old_tstate = texture::tstate; - auto old_tstate_max = texture::tstate_max; + auto old_tstate = texture::config.tstate; + auto old_tstate_max = texture::config.tstate_max; #endif auto &g = cpatterns[cgroup].geometries[uni - 'a']; if(g.geo != geometry) { targetgeometry = g.geo; restartGame('g', false, true); } @@ -1485,7 +1485,7 @@ namespace patterns { whichPattern = g.whichPattern; subpattern_flags = g.subpattern_flags; #if CAP_TEXTURE - texture::remap(old_tstate, old_tstate_max); + texture::config.remap(old_tstate, old_tstate_max); #endif } else if(doexiton(sym, uni)) diff --git a/polygons.cpp b/polygons.cpp index e0a37794..f2252128 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -210,9 +210,10 @@ void drawTexturedTriangle(SDL_Surface *s, int *px, int *py, glvertex *tv, int co hyperpoint h = isource * hpxyz(mx, my, 1); if(h[0] >= -1e-7 && h[1] >= -1e-7 && h[2] >= -1e-7) { hyperpoint ht = target * h; - int x = int(ht[0] * texture::twidth) & (texture::twidth-1); - int y = int(ht[1] * texture::twidth) & (texture::twidth-1); - int c = texture::texture_pixels[y * texture::twidth + x]; + int tw = texture::config.data.twidth; + int x = int(ht[0] * tw) & (tw-1); + int y = int(ht[1] * tw) & (tw-1); + int c = texture::config.data.texture_pixels[y * tw + x]; auto& pix = qpixel(s, mx, my); for(int p=0; p<3; p++) { int alpha = part(c, 3) * part(col, 0); diff --git a/system.cpp b/system.cpp index a1edeceb..6f7c5f5c 100644 --- a/system.cpp +++ b/system.cpp @@ -1107,10 +1107,10 @@ void restartGame(char switchWhat, bool push, bool keep_screens) { nonbitrunc = !nonbitrunc; resetGeometry(); #if CAP_TEXTURE - if(texture::tstate == texture::tsActive) - texture::tstate = texture::tsAdjusting; - if(texture::tstate_max == texture::tsActive) - texture::tstate = texture::tsAdjusting; + if(texture::config.tstate == texture::tsActive) + texture::config.tstate = texture::tsAdjusting; + if(texture::config.tstate_max == texture::tsActive) + texture::config.tstate = texture::tsAdjusting; #endif } if(switchWhat == 'g') { @@ -1121,10 +1121,10 @@ void restartGame(char switchWhat, bool push, bool keep_screens) { resetGeometry(); #if CAP_TEXTURE - if(texture::tstate == texture::tsActive) - texture::tstate = texture::tsOff; - if(texture::tstate_max == texture::tsActive) - texture::tstate = texture::tsAdjusting; + if(texture::config.tstate == texture::tsActive) + texture::config.tstate = texture::tsOff; + if(texture::config.tstate_max == texture::tsActive) + texture::config.tstate = texture::tsAdjusting; #endif } if(switchWhat == 'y') { diff --git a/textures.cpp b/textures.cpp index 121279b8..91891039 100644 --- a/textures.cpp +++ b/textures.cpp @@ -10,8 +10,6 @@ #if CAP_TEXTURE namespace texture { -GLuint textureid = 0; - cpatterntype cgroup; SDL_Surface *convertSurface(SDL_Surface* s) { @@ -39,45 +37,28 @@ SDL_Surface *convertSurface(SDL_Surface* s) { return SDL_ConvertSurface(s, &fmt, SDL_SWSURFACE); } -int twidth = 2048; - -unsigned paint_color = 0x000000FF; - -vector texture_pixels; - -unsigned& get_texture_pixel(int x, int y) { - return texture_pixels[(y&(twidth-1))*twidth+(x&(twidth-1))]; - } - -string texturename = "textures/hyperrogue-texture.png"; -string configname = "textures/hyperrogue.txc"; - -bool saving = false; - -eTextureState tstate; -eTextureState tstate_max; - struct undo { unsigned* pix; unsigned last; }; -vector> undos; -vector > pixels_to_draw; +texture_config config; -template void scale_colorarray(int origdim, const T& src, const U& dest) { +bool saving = false; + +template void scale_colorarray(int origdim, int targetdim, const T& src, const U& dest) { int ox = 0, tx = 0, partials[4]; - int omissing = twidth, tmissing = origdim; + int omissing = targetdim, tmissing = origdim; for(int p=0; p<4; p++) partials[p] = 0; - while(tx < twidth) { + while(tx < targetdim) { int fv = min(omissing, tmissing); int c = src(ox); for(int p=0; p<4; p++) partials[p] += part(c, p) * fv; omissing -= fv; tmissing -= fv; if(omissing == 0) { - ox++; omissing = twidth; + ox++; omissing = targetdim; } if(tmissing == 0) { int target; @@ -91,11 +72,11 @@ template void scale_colorarray(int origdim, const T& src, cons } } -bool loadTextureGL() { +bool texture_data::loadTextureGL() { - if(textureid == 0) glGenTextures(1, &textureid ); + if(textureid == 0) glGenTextures(1, &textureid); - glBindTexture( GL_TEXTURE_2D, textureid); + glBindTexture( GL_TEXTURE_2D, config.data.textureid); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); @@ -106,7 +87,7 @@ bool loadTextureGL() { return true; } -bool whitetexture() { +bool texture_data::whitetexture() { undos.clear(); texture_pixels.resize(0); texture_pixels.resize(twidth * twidth, 0xFFFFFFFF); @@ -114,13 +95,13 @@ bool whitetexture() { return true; } -bool readtexture() { +bool texture_data::readtexture(string tn) { undos.clear(); texture_pixels.resize(twidth * twidth); #if CAP_SDL_IMG - SDL_Surface *txt = IMG_Load(texturename.c_str()); + SDL_Surface *txt = IMG_Load(tn.c_str()); if(!txt) { addMessage(XLAT("Failed to load %1", texturename)); return false; @@ -134,7 +115,7 @@ bool readtexture() { #elif CAP_PNG - FILE *f = fopen(texturename.c_str(), "rb"); + FILE *f = fopen(tn.c_str(), "rb"); if(!f) { printf("failed to open file\n"); return false; } png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png) { printf("failed to create_read_struct\n"); return false; } @@ -205,13 +186,13 @@ bool readtexture() { vector half_expanded(twidth * ty); for(int y=0; y= ty ? 0 : half_expanded[x + (base_y + y) * twidth]; }, [&] (int y, int v) { get_texture_pixel(x, y) = v; } ); @@ -225,28 +206,17 @@ bool readtexture() { return true; } -void saveRawTexture() { +void texture_data::saveRawTexture(string tn) { SDL_Surface *sraw = SDL_CreateRGBSurface(SDL_SWSURFACE,twidth,twidth,32,0,0,0,0); for(int y=0; y& v, const array& tv, int splits = gsplits) { +void texture_config::mapTextureTriangle(textureinfo &mi, const array& v, const array& tv, int splits) { if(splits) { array v2 = make_array( mid(v[1], v[2]), mid(v[2], v[0]), mid(v[0], v[1]) ); @@ -272,12 +242,6 @@ void mapTextureTriangle(textureinfo &mi, const array& v, const ar texture_triangle *edited_triangle; textureinfo *edited_tinfo; -vector tuned_vertices; - -map texture_map, texture_map_orig; - -set models; - array findTextureTriangle(cell *c, patterns::patterninfo& si, int i) { // auto si = getpatterninfo0(c); transmatrix M = shmup::ggmatrix(c) * applyPatterndir(c, si); @@ -318,27 +282,27 @@ void mapTexture(cell *c, textureinfo& mi, patterns::patterninfo &si, const trans } } -void mapTexture2(textureinfo& mi) { +void texture_config::mapTexture2(textureinfo& mi) { mi.vertices.clear(); mi.tvertices.clear(); for(auto& t: mi.triangles) mapTextureTriangle(mi, t.v, t.tv); } -int recolor(int col) { +int texture_config::recolor(int col) { if(color_alpha == 0) return col; for(int i=1; i<4; i++) part(col, i) = color_alpha + ((255-color_alpha) * part(col,i) + 127) / 255; return col; } -bool apply(cell *c, const transmatrix &V, int col) { - if(tstate == tsOff) return false; +bool texture_config::apply(cell *c, const transmatrix &V, int col) { + if(config.tstate == tsOff) return false; using namespace patterns; auto si = getpatterninfo0(c); - if(tstate == tsAdjusting) { + if(config.tstate == tsAdjusting) { queuepolyat(V, shFullCross[ctof(c)], 0, PPR_LINE); lastptd().u.poly.outline = slave_color; queuepolyat(V, shFullFloor[ctof(c)], 0, PPR_LINE); @@ -385,9 +349,9 @@ bool apply(cell *c, const transmatrix &V, int col) { for(int j=0; j<2; j++) for(int k=0; k<3; k++) v[j] += mi.tvertices[i+k][j] * p[k]; - int vi[2] = {int(v[0] * twidth), int(v[1] * twidth)}; + int vi[2] = {int(v[0] * config.data.twidth), int(v[1] * config.data.twidth)}; - col = get_texture_pixel(vi[0], vi[1]); + col = config.data.get_texture_pixel(vi[0], vi[1]); hyperpoint h = glhr::gltopoint(mi.vertices[i]); addaura(V*h, col, 0); } @@ -401,8 +365,8 @@ bool apply(cell *c, const transmatrix &V, int col) { } } -void mark_triangles() { - if(tstate == tsAdjusting) +void texture_config::mark_triangles() { + if(config.tstate == tsAdjusting) for(auto& mi: texture_map) { for(auto& t: mi.second.triangles) { vector t2; @@ -413,16 +377,9 @@ void mark_triangles() { } } -typedef tuple texture_parameters; - static const auto current_texture_parameters = tie(geometry, nonbitrunc, patterns::whichPattern, patterns::subpattern_flags, pmodel, vid.scale, vid.alpha); -texture_parameters orig_texture_parameters; - -bool texture_tuned = false; -string texture_tuner; - -void clear_texture_map() { +void texture_config::clear_texture_map() { texture_map.clear(); edited_triangle = nullptr; edited_tinfo = nullptr; @@ -432,7 +389,7 @@ void clear_texture_map() { texture_tuner = ""; } -void perform_mapping() { +void texture_config::perform_mapping() { if(gsplits < 0) gsplits = 0; if(gsplits > 4) gsplits = 4; using namespace patterns; @@ -454,7 +411,7 @@ void perform_mapping() { if(replace) { auto& mi = texture_map[si.id]; mapTexture(c, mi, si, p.second); - mi.texture_id = textureid; + mi.texture_id = config.data.textureid; } } @@ -476,28 +433,28 @@ void perform_mapping() { texture::cgroup = patterns::cgroup; texture_map_orig = texture_map; orig_texture_parameters = current_texture_parameters; - // printf("texture_map has %d elements (S%d)\n", size(texture_map), tstate); + // printf("texture_map has %d elements (S%d)\n", size(texture_map), config.tstate); } -void finish_mapping() { - if(tstate == tsActive) +void texture_config::finish_mapping() { + if(config.tstate == tsActive) for(auto& mi: texture_map) mapTexture2(mi.second); } -void saveFullTexture() { - addMessage(XLAT("Saving full texture to %1...", texturename)); +void texture_config::saveFullTexture(string tn) { + addMessage(XLAT("Saving full texture to %1...", tn)); dynamicval dd(grid_color, 0); dynamicval dm(mesh_color, 0); texture::saving = true; drawscreen(); - dynamicval dv(pngres, twidth); - saveHighQualityShot(texturename.c_str()); + dynamicval dv(pngres, data.twidth); + saveHighQualityShot(tn.c_str()); texture::saving = false; drawscreen(); - if(readtexture() && loadTextureGL()) { + if(data.readtexture(tn) && data.loadTextureGL()) { itt = Id; // xyscale(Id, vid.scrsize * 1. / vid.radius); perform_mapping(); finish_mapping(); @@ -508,10 +465,10 @@ bool newmove = false; vector rtver(4); -void drawRawTexture() { +void texture_config::drawRawTexture() { glhr::be_textured(); glhr::color2(0xFFFFFF20); - glBindTexture(GL_TEXTURE_2D, textureid); + glBindTexture(GL_TEXTURE_2D, config.data.textureid); for(int i=0; i<4; i++) { int cx[4] = {2, -2, -2, 2}; int cy[4] = {2, 2, -2, -2}; @@ -587,7 +544,7 @@ struct magic_param { transmatrix Ti = inverse(T); for(auto& p: amp) p.texture_coords = Ti * p.texture_coords; - itt = itt * T; + config.itt = config.itt * T; } void apply(ld delta) { @@ -672,21 +629,21 @@ void mousemovement() { case tpsModel: if(!newmove && mouseh[2] < 50 && lastmouse[2] < 50) { panning(lastmouse, mouseh); - perform_mapping(); + config.perform_mapping(); } lastmouse = mouseh; newmove = false; break; case tpsMove: { if(!newmove) - itt = itt * inverse(eupush(mouseeu)) * eupush(lastmouse); + config.itt = config.itt * inverse(eupush(mouseeu)) * eupush(lastmouse); lastmouse = mouseeu; newmove = false; break; } case tpsScale: { if(nonzero && !newmove) - itt = itt * inverse(euscalezoom(mouseeu)) * euscalezoom(lastmouse); + config.itt = config.itt * inverse(euscalezoom(mouseeu)) * euscalezoom(lastmouse); if(nonzero) lastmouse = mouseeu; newmove = false; break; @@ -694,7 +651,7 @@ void mousemovement() { case tpsAffine: { if(!newmove) - itt = itt * inverse(euaffine(mouseeu)) * euaffine(lastmouse); + config.itt = config.itt * inverse(euaffine(mouseeu)) * euaffine(lastmouse); lastmouse = mouseeu; newmove = false; break; } @@ -725,15 +682,15 @@ void mousemovement() { auto si = patterns::getpatterninfo0(c); if(newmove) { edited_tinfo = NULL; - if(texture_map.count(si.id)) { - edited_tinfo = &texture_map[si.id]; + if(config.texture_map.count(si.id)) { + edited_tinfo = &config.texture_map[si.id]; newmove = false; } } if(edited_tinfo && size(edited_tinfo->triangles) == c->type) { for(int i=0; itype; i++) edited_tinfo->triangles[i].tv = findTextureTriangle(c, si, i); - texture_tuned = true; + config.texture_tuned = true; } break; } @@ -745,14 +702,14 @@ void mousemovement() { int i = getTriangleID(c, si, mouseh); if(newmove) { edited_triangle = NULL; - if(texture_map.count(si.id)) { - edited_triangle = &texture_map[si.id].triangles[i]; + if(config.texture_map.count(si.id)) { + edited_triangle = &config.texture_map[si.id].triangles[i]; newmove = false; } } if(edited_triangle) { edited_triangle->tv = findTextureTriangle(c, si, i); - texture_tuned = true; + config.texture_tuned = true; } break; } @@ -760,22 +717,22 @@ void mousemovement() { case tpsTune: { ld tdist = 1e20; if(newmove) { - tuned_vertices.clear(); - for(auto& a: texture_map) + config.tuned_vertices.clear(); + for(auto& a: config.texture_map) for(auto& t: a.second.triangles) for(auto& v: t.tv) if(intval(v, mouseh) < tdist) tdist = intval(v, mouseh); - for(auto& a: texture_map) + for(auto& a: config.texture_map) for(auto& t: a.second.triangles) for(auto& v: t.tv) if(intval(v, mouseh) < tdist * (1.000001)) - tuned_vertices.push_back(&v); + config.tuned_vertices.push_back(&v); newmove = false; } - for(auto v: tuned_vertices) { + for(auto v: config.tuned_vertices) { *v = mouseh; - texture_tuned = true; + config.texture_tuned = true; } break; } @@ -794,7 +751,7 @@ 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); + addsaver(config.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++) @@ -819,30 +776,30 @@ void init_textureconfig() { addsaver(si_save.dir, "center direction", 0); addsaver(si_save.reflect, "center reflection", false); addsaver(viewctr.spin, "center spin", 0); - addsaver(twidth, "texture resolution", 2048); - addsaver(gsplits, "precision", 1); + addsaver(config.data.twidth, "texture resolution", 2048); + addsaver(config.gsplits, "precision", 1); - addsaver(grid_color, "grid color", 0); - addsaver(color_alpha, "alpha color", 0); - addsaver(mesh_color, "mesh color", 0); + addsaver(config.grid_color, "grid color", 0); + addsaver(config.color_alpha, "alpha color", 0); + addsaver(config.mesh_color, "mesh color", 0); addsaver(vid.alpha, "projection", 1); addsaver(vid.scale, "scale", 1); - addsaver(texturename, "texture filename", ""); - addsaver(texture_tuner, "texture tuning", ""); + addsaver(config.texturename, "texture filename", ""); + addsaver(config.texture_tuner, "texture tuning", ""); swap(texturesavers, savers); } -bool save_textureconfig() { +bool texture_config::save() { init_textureconfig(); FILE *f = fopen(configname.c_str(), "wt"); if(!f) return false; if(texture_tuned) { texture_tuner = ""; - for(auto& a: texture_map) + for(auto& a: config.texture_map) for(auto& t: a.second.triangles) for(auto& v: t.tv) for(int i=0; i<3; i++) { @@ -861,7 +818,7 @@ bool save_textureconfig() { return true; } -bool load_textureconfig() { +bool texture_config::load() { init_textureconfig(); FILE *f = fopen(configname.c_str(), "rt"); @@ -878,7 +835,7 @@ bool load_textureconfig() { if(targetgeometry != geometry) { restartGame('g'); - return load_textureconfig(); + return config.load(); } if(nonbitrunc != target_nonbitru) { @@ -903,11 +860,11 @@ bool load_textureconfig() { addMessage(XLAT("warning: unable to find the center")); } - if(!readtexture()) return false; - if(!loadTextureGL()) return false; + if(!data.readtexture(texturename)) return false; + if(!data.loadTextureGL()) return false; calcparam(); drawthemap(); - tstate = tstate_max = tsActive; + config.tstate = config.tstate_max = tsActive; string s = move(texture_tuner); perform_mapping(); @@ -916,7 +873,7 @@ bool load_textureconfig() { if(texture_tuner != "") { texture_tuned = true; vector coords; - for(auto& a: texture_map) + for(auto& a: config.texture_map) for(auto& t: a.second.triangles) for(auto& v: t.tv) for(int i=0; i<3; i++) @@ -973,7 +930,7 @@ void showMagicMenu() { amp.back().texture_coords = mouseeu; } - if(tstate == tsAdjusting) { + if(config.tstate == tsAdjusting) { initquickqueue(); char letter = 'A'; for(auto& am: amp) { @@ -1000,7 +957,7 @@ void showMagicMenu() { // handlePanning(sym, uni); dialog::handleNavigation(sym, uni); - if(uni == '-' && tstate == tsAdjusting) { + if(uni == '-' && config.tstate == tsAdjusting) { if(!holdmouse) { holdmouse = true; newmove = true; @@ -1032,25 +989,25 @@ string texturehelp = void showMenu() { cmode = sm::SIDE | sm::MAYDARK | sm::DIALOG_STRICT_X; gamescreen(0); - if(tstate == tsAdjusting) { + if(config.tstate == tsAdjusting) { ptds.clear(); - texture::mark_triangles(); + config.mark_triangles(); drawqueue(); } - if(tstate == tsOff) { + if(config.tstate == tsOff) { dialog::init(XLAT("texture mode (off)")); dialog::addItem(XLAT("select geometry/pattern"), 'r'); - if(tstate_max == tsAdjusting || tstate_max == tsActive) + if(config.tstate_max == tsAdjusting || config.tstate_max == tsActive) dialog::addItem(XLAT("reactivate the texture"), 't'); dialog::addItem(XLAT("open PNG as texture"), 'o'); dialog::addItem(XLAT("load texture config"), 'l'); - dialog::addSelItem(XLAT("texture size"), its(twidth), 'w'); + dialog::addSelItem(XLAT("texture size"), its(config.data.twidth), 'w'); dialog::addItem(XLAT("paint a new texture"), 'n'); - dialog::addSelItem(XLAT("precision"), its(gsplits), 'P'); + dialog::addSelItem(XLAT("precision"), its(config.gsplits), 'P'); } - if(tstate == tsAdjusting) { + if(config.tstate == tsAdjusting) { dialog::init(XLAT("texture mode (overlay)")); dialog::addItem(XLAT("select the texture's pattern"), 'r'); dialog::addItem(XLAT("enable the texture"), 't'); @@ -1069,16 +1026,16 @@ void showMenu() { dialog::addBoolItem(XLAT("select master triangles"), panstate == tpsTriangle, 'X'); dialog::addBoolItem(XLAT("fine tune vertices"), panstate == tpsTune, 'F'); - dialog::addColorItem(XLAT("grid color (master)"), master_color, 'M'); - dialog::addColorItem(XLAT("grid color (copy)"), slave_color, 'C'); + dialog::addColorItem(XLAT("grid color (master)"), config.master_color, 'M'); + dialog::addColorItem(XLAT("grid color (copy)"), config.slave_color, 'C'); dialog::addBreak(50); - dialog::addSelItem(XLAT("precision"), its(gsplits), 'P'); + dialog::addSelItem(XLAT("precision"), its(config.gsplits), 'P'); dialog::addItem(XLAT("save the raw texture"), 'S'); } - if(tstate == tsActive) { + if(config.tstate == tsActive) { dialog::init(XLAT("texture mode (active)")); /* dialog::addSelItem(XLAT("texture scale"), fts(iscale), 's'); dialog::addSelItem(XLAT("texture angle"), fts(irotate), 'a'); @@ -1087,10 +1044,10 @@ void showMenu() { dialog::addItem(XLAT("deactivate the texture"), 't'); dialog::addItem(XLAT("back to overlay mode"), 'T'); dialog::addItem(XLAT("change the geometry"), 'r'); - 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("precision"), its(gsplits), 'P'); + dialog::addColorItem(XLAT("grid color"), config.grid_color, 'g'); + dialog::addColorItem(XLAT("mesh color"), config.mesh_color, 'm'); + dialog::addSelItem(XLAT("color alpha"), its(config.color_alpha), 'c'); + dialog::addSelItem(XLAT("precision"), its(config.gsplits), 'P'); dialog::addItem(XLAT("edit the texture"), 'e'); dialog::addItem(XLAT("save the full texture image"), 'S'); dialog::addItem(XLAT("save texture config"), 's'); @@ -1109,121 +1066,122 @@ void showMenu() { // handlePanning(sym, uni); dialog::handleNavigation(sym, uni); - if(uni == '-' && tstate == tsAdjusting) { + if(uni == '-' && config.tstate == tsAdjusting) { if(!holdmouse) { holdmouse = true; newmove = true; } } - else if(uni == 'm' && tstate == tsAdjusting) panstate = tpsModel; - else if(uni == 'a' && tstate == tsAdjusting) panstate = tpsMove; - else if(uni == 'x' && tstate == tsAdjusting) panstate = tpsScale; - else if(uni == 'y' && tstate == tsAdjusting) panstate = tpsAffine; - else if(uni == 'z' && tstate == tsAdjusting) panstate = tpsZoom; - else if(uni == 'p' && tstate == tsAdjusting) panstate = tpsProjection; - else if(uni == 'C' && tstate == tsAdjusting) panstate = tpsCell; - else if(uni == 'X' && tstate == tsAdjusting) panstate = tpsTriangle; - else if(uni == 'F' && tstate == tsAdjusting) panstate = tpsTune; - else if(uni == 'A' && tstate == tsAdjusting) + else if(uni == 'm' && config.tstate == tsAdjusting) panstate = tpsModel; + else if(uni == 'a' && config.tstate == tsAdjusting) panstate = tpsMove; + else if(uni == 'x' && config.tstate == tsAdjusting) panstate = tpsScale; + else if(uni == 'y' && config.tstate == tsAdjusting) panstate = tpsAffine; + else if(uni == 'z' && config.tstate == tsAdjusting) panstate = tpsZoom; + else if(uni == 'p' && config.tstate == tsAdjusting) panstate = tpsProjection; + else if(uni == 'C' && config.tstate == tsAdjusting) panstate = tpsCell; + else if(uni == 'X' && config.tstate == tsAdjusting) panstate = tpsTriangle; + else if(uni == 'F' && config.tstate == tsAdjusting) panstate = tpsTune; + else if(uni == 'A' && config.tstate == tsAdjusting) pushScreen(showMagicMenu); - else if(uni == 's' && tstate == tsActive) - dialog::openFileDialog(configname, XLAT("save texture config"), ".txc", + else if(uni == 's' && config.tstate == tsActive) + dialog::openFileDialog(config.configname, XLAT("save texture config"), ".txc", [] () { - return save_textureconfig(); + return config.save(); }); - else if(uni == 'l' && tstate == tsOff) - dialog::openFileDialog(configname, XLAT("load texture config"), ".txc", + else if(uni == 'l' && config.tstate == tsOff) + dialog::openFileDialog(config.configname, XLAT("load texture config"), ".txc", [] () { - return load_textureconfig(); + return config.load(); }); else if(uni == 'r') patterns::pushChangeablePatterns(); - else if(uni == 'o' && tstate == tsOff) - dialog::openFileDialog(texturename, XLAT("open PNG as texture"), ".png", + else if(uni == 'o' && config.tstate == tsOff) + dialog::openFileDialog(config.texturename, XLAT("open PNG as texture"), ".png", [] () { - if(readtexture() && loadTextureGL()) { - if(tstate_max == tsOff) tstate_max = tsAdjusting; - tstate = tstate_max; - perform_mapping(); - finish_mapping(); + if(config.data.readtexture(config.texturename) && config.data.loadTextureGL()) { + if(config.tstate_max == tsOff) config.tstate_max = tsAdjusting; + config.tstate = config.tstate_max; + config.perform_mapping(); + config.finish_mapping(); return true; } else return false; }); - else if(uni == 'w' && tstate == tsOff) { - twidth *= 2; - if(twidth > 9000) twidth = 256; - tstate_max = tsOff; + else if(uni == 'w' && config.tstate == tsOff) { + config.data.twidth *= 2; + if(config.data.twidth > 9000) config.data.twidth = 256; + config.tstate_max = tsOff; } - else if(uni == 'e' && tstate == tsActive) { + else if(uni == 'e' && config.tstate == tsActive) { mapeditor::initdraw(cwt.c); pushScreen(mapeditor::showDrawEditor); } - else if(uni == 'n' && tstate == tsOff) { + else if(uni == 'n' && config.tstate == tsOff) { addMessage("white"); - if(whitetexture() && loadTextureGL()) { - tstate = tstate_max = tsActive; - perform_mapping(); - finish_mapping(); + if(config.data.whitetexture() && config.data.loadTextureGL()) { + config.tstate = config.tstate_max = tsActive; + config.perform_mapping(); + config.finish_mapping(); mapeditor::initdraw(cwt.c); pushScreen(mapeditor::showDrawEditor); } } - else if(uni == 't' && tstate == tsOff) - tstate = tstate_max; + else if(uni == 't' && config.tstate == tsOff) + config.tstate = config.tstate_max; - else if(uni == 't' && tstate == tsAdjusting) { - tstate = tstate_max = tsActive; - finish_mapping(); + else if(uni == 't' && config.tstate == tsAdjusting) { + config.tstate = config.tstate_max = tsActive; + config.finish_mapping(); } - else if(uni == 't' && tstate == tsActive) - tstate = tsOff; + else if(uni == 't' && config.tstate == tsActive) + config.tstate = tsOff; - else if(uni == 'T' && tstate == tsAdjusting) - tstate = tsOff; + else if(uni == 'T' && config.tstate == tsAdjusting) + config.tstate = tsOff; - else if(uni == 'T' && tstate == tsActive) - tstate = tsAdjusting; + else if(uni == 'T' && config.tstate == tsActive) + config.tstate = tsAdjusting; - else if(uni == 'g' && tstate == tsActive) - dialog::openColorDialog(grid_color, NULL); - else if(uni == 'm' && tstate == tsActive) - dialog::openColorDialog(mesh_color, NULL); + else if(uni == 'g' && config.tstate == tsActive) + dialog::openColorDialog(config.grid_color, NULL); + else if(uni == 'm' && config.tstate == tsActive) + dialog::openColorDialog(config.mesh_color, NULL); - else if(uni == 'M' && tstate == tsAdjusting) - dialog::openColorDialog(master_color, NULL); - else if(uni == 'C' && tstate == tsAdjusting) - dialog::openColorDialog(slave_color, NULL); + else if(uni == 'M' && config.tstate == tsAdjusting) + dialog::openColorDialog(config.master_color, NULL); + else if(uni == 'C' && config.tstate == tsAdjusting) + dialog::openColorDialog(config.slave_color, NULL); - else if(uni == 'c' && tstate == tsActive) { - dialog::editNumber(color_alpha, 0, 255, 15, 0, XLAT("color alpha"), + else if(uni == 'c' && config.tstate == tsActive) { + dialog::editNumber(config.color_alpha, 0, 255, 15, 0, XLAT("color alpha"), XLAT("The higher the value, the less important the color of underlying terrain is.")); } else if(uni == 'P') { - dialog::editNumber(gsplits, 0, 4, 1, 1, XLAT("precision"), + dialog::editNumber(config.gsplits, 0, 4, 1, 1, XLAT("precision"), XLAT("precision")); - if(tstate == tsActive) dialog::reaction = [] () { finish_mapping(); + if(config.tstate == tsActive) dialog::reaction = [] () { config.finish_mapping(); }; } - else if(uni == 'S' && tstate == tsAdjusting) - dialog::openFileDialog(texturename, XLAT("save the raw texture"), ".png", + else if(uni == 'S' && config.tstate == tsAdjusting) + dialog::openFileDialog(config.texturename, XLAT("save the raw texture"), ".png", [] () { - saveRawTexture(); return true; + config.data.saveRawTexture(config.texturename); return true; }); - else if(uni == 'S' && tstate == tsActive) - dialog::openFileDialog(texturename, XLAT("save the full texture image"), ".png", + else if(uni == 'S' && config.tstate == tsActive) + dialog::openFileDialog(config.texturename, XLAT("save the full texture image"), ".png", [] () { - saveFullTexture(); return true; + config.saveFullTexture(config.texturename); + return true; }); else if(uni == SDLK_F1) gotoHelp(texturehelp); @@ -1237,11 +1195,11 @@ typedef pair point; point ptc(hyperpoint h) { hyperpoint inmodel; applymodel(h, inmodel); - inmodel = itt * inmodel; + inmodel = config.itt * inmodel; inmodel[0] *= vid.radius * 1. / vid.scrsize; inmodel[1] *= vid.radius * 1. / vid.scrsize; - int x = (1 + inmodel[0]) * twidth / 2; - int y = (1 + inmodel[1]) * twidth / 2; + int x = (1 + inmodel[0]) * config.data.twidth / 2; + int y = (1 + inmodel[1]) * config.data.twidth / 2; return make_pair(x,y); } @@ -1256,15 +1214,15 @@ int texture_distance(pair p1, pair p2) { } void fillpixel(int x, int y, unsigned col) { - if(x<0 || y<0 || x >= twidth || y >= twidth) return; - auto& pix = get_texture_pixel(x, y); + if(x<0 || y<0 || x >= config.data.twidth || y >= config.data.twidth) return; + auto& pix = config.data.get_texture_pixel(x, y); if(pix != col) { - undos.emplace_back(&pix, pix); + config.data.undos.emplace_back(&pix, pix); pix = col; } } -void undo() { +void texture_data::undo() { while(!undos.empty()) { auto p = undos.back(); undos.pop_back(); @@ -1276,7 +1234,7 @@ void undo() { } } -void undoLock() { +void texture_data::undoLock() { printf("undos size = %d\n", size(undos)); if(size(undos) > 2000000) { // limit undo memory @@ -1356,7 +1314,7 @@ void actDrawPixel(cell *c, hyperpoint h, int col) { transmatrix M = gmatrix.at(c); auto si = patterns::getpatterninfo0(c); h = inverse(M * applyPatterndir(c, si)) * h; - auto& tinf = texture_map[si.id]; + auto& tinf = config.texture_map[si.id]; for(auto& M2: tinf.matrices) for(int i = 0; itype; i += si.symmetries) { fillcircle(M2 * spin(2 * M_PI * i / c->type) * h, col); if(texturesym) @@ -1367,7 +1325,7 @@ void actDrawPixel(cell *c, hyperpoint h, int col) { } void drawPixel(cell *c, hyperpoint h, int col) { - pixels_to_draw.emplace_back(c, h, col); + config.data.pixels_to_draw.emplace_back(c, h, col); } cell *where; @@ -1404,12 +1362,12 @@ void drawLine(hyperpoint h1, hyperpoint h2, int col, int steps) { drawPixel(h2, col); } -void remap(eTextureState old_tstate, eTextureState old_tstate_max) { +void texture_config::remap(eTextureState old_tstate, eTextureState old_tstate_max) { clear_texture_map(); if(old_tstate == tsActive && patterns::compatible(texture::cgroup, patterns::cgroup)) { - tstate = old_tstate; - tstate_max = old_tstate_max; + config.tstate = old_tstate; + config.tstate_max = old_tstate_max; for(cell *c: dcal) { auto si = patterns::getpatterninfo0(c); @@ -1443,13 +1401,13 @@ void remap(eTextureState old_tstate, eTextureState old_tstate_max) { catch(out_of_range) { printf("Unexpected missing cell #%d/%d", si.id, oldid); addMessage(XLAT("Unexpected missing cell #%d/%d", its(si.id), its(oldid))); - tstate_max = tstate = tsAdjusting; + config.tstate_max = config.tstate = tsAdjusting; return; } } } else if(old_tstate >= tsAdjusting) { - printf("perform_mapping %d/%d\n", tstate, tstate_max); + printf("perform_mapping %d/%d\n", config.tstate, config.tstate_max); calcparam(); drawthemap(); perform_mapping(); @@ -1463,24 +1421,24 @@ int textureArgs() { if(0) ; else if(argis("-txpic")) { - shift(); texturename = args(); + shift(); config.texturename = args(); } else if(argis("-txp")) { - shift(); gsplits = argf(); + shift(); config.gsplits = argf(); } else if(argis("-txc")) { - shift(); configname = args(); + shift(); config.configname = args(); } else if(argis("-txc")) { - shift(); configname = args(); + shift(); config.configname = args(); } else if(argis("-txcl")) { PHASE(3); drawscreen(); - load_textureconfig(); + config.load(); } else return 1; @@ -1489,11 +1447,11 @@ int textureArgs() { auto texture_hook = addHook(hooks_args, 100, textureArgs) -+ addHook(clearmemory, 100, [] () { pixels_to_draw.clear(); }); ++ addHook(clearmemory, 100, [] () { config.data.pixels_to_draw.clear(); }); int lastupdate; -void update() { +void texture_data::update() { if(!pixels_to_draw.empty()) { auto t = SDL_GetTicks(); while(SDL_GetTicks() < t + 75 && !pixels_to_draw.empty()) {