1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-20 15:40:26 +00:00

undo in texture editor

This commit is contained in:
Zeno Rogue 2017-12-22 20:59:04 +01:00
parent 102b9cb4c3
commit 4bee0c85a7
3 changed files with 65 additions and 8 deletions

View File

@ -2398,6 +2398,9 @@ namespace texture {
void remap(eTextureState old_tstate, eTextureState old_tstate_max); void remap(eTextureState old_tstate, eTextureState old_tstate_max);
void undoLock();
void undo();
extern cpatterntype cgroup; extern cpatterntype cgroup;
} }
#endif #endif

View File

@ -975,6 +975,7 @@ namespace mapeditor {
else if(texture::tstate == texture::tsActive) { else if(texture::tstate == texture::tsActive) {
displayButton(8, 8+fs*7, XLAT("p = color"), 'p', 0); displayButton(8, 8+fs*7, XLAT("p = color"), 'p', 0);
displayButton(8, 8+fs*8, XLAT("w = pen size: %1", fts4(texture::penwidth)), 'w', 0); displayButton(8, 8+fs*8, XLAT("w = pen size: %1", fts4(texture::penwidth)), 'w', 0);
displayButton(8, 8+fs*9, XLAT("u = undo"), 'u', 0);
} }
#endif #endif
else { else {
@ -1339,10 +1340,15 @@ namespace mapeditor {
#if CAP_TEXTURE #if CAP_TEXTURE
if(texture::tstate == texture::tsActive) { if(texture::tstate == texture::tsActive) {
if(uni == '-') { if(uni == '-') {
if(!holdmouse) texture::undoLock();
texture::drawPixel(mouseover, mouseh, (texture::paint_color >> 8) | ((texture::paint_color & 0xFF) << 24)); texture::drawPixel(mouseover, mouseh, (texture::paint_color >> 8) | ((texture::paint_color & 0xFF) << 24));
holdmouse = true; holdmouse = true;
} }
if(uni == 'u') {
texture::undo();
}
if(uni == 'p') { if(uni == 'p') {
static unsigned texture_colors[] = { static unsigned texture_colors[] = {
11, 11,

View File

@ -42,6 +42,10 @@ unsigned paint_color = 0x000000FF;
vector<unsigned> texture_pixels; vector<unsigned> 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 texturename = "textures/hyperrogue-texture.png";
string configname = "textures/hyperrogue.txc"; string configname = "textures/hyperrogue.txc";
@ -50,6 +54,13 @@ bool saving = false;
eTextureState tstate; eTextureState tstate;
eTextureState tstate_max; eTextureState tstate_max;
struct undo {
unsigned* pix;
unsigned last;
};
vector<pair<unsigned*, unsigned>> undos;
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];
int omissing = twidth, tmissing = origdim; int omissing = twidth, tmissing = origdim;
@ -92,6 +103,7 @@ bool loadTextureGL() {
} }
bool whitetexture() { bool whitetexture() {
undos.clear();
texture_pixels.resize(0); texture_pixels.resize(0);
texture_pixels.resize(twidth * twidth, 0xFFFFFFFF); texture_pixels.resize(twidth * twidth, 0xFFFFFFFF);
return true; return true;
@ -99,6 +111,7 @@ bool whitetexture() {
bool readtexture() { bool readtexture() {
undos.clear();
texture_pixels.resize(twidth * twidth); texture_pixels.resize(twidth * twidth);
#if CAP_SDL_IMG #if CAP_SDL_IMG
@ -176,10 +189,6 @@ bool readtexture() {
ZZ = 0; // outside is black ZZ = 0; // outside is black
/* for(int y=0; y<twidth; y++)
for(int x=0; x<twidth; x++)
texture_pixels[y*twidth+x] = qpixel(txt2, y%ty, x%tx); */
vector<int> half_expanded(twidth * ty); vector<int> half_expanded(twidth * ty);
for(int y=0; y<ty; y++) for(int y=0; y<ty; y++)
scale_colorarray(origdim, scale_colorarray(origdim,
@ -190,7 +199,7 @@ bool readtexture() {
for(int x=0; x<twidth; x++) for(int x=0; x<twidth; x++)
scale_colorarray(origdim, scale_colorarray(origdim,
[&] (int y) { return base_y+y < 0 || base_y+y >= ty ? 0 : half_expanded[x + (base_y + y) * twidth]; }, [&] (int y) { return base_y+y < 0 || base_y+y >= ty ? 0 : half_expanded[x + (base_y + y) * twidth]; },
[&] (int y, int v) { texture_pixels[twidth * y + x] = v; } [&] (int y, int v) { get_texture_pixel(x, y) = v; }
); );
} }
@ -206,7 +215,7 @@ void saveRawTexture() {
SDL_Surface *sraw = SDL_CreateRGBSurface(SDL_SWSURFACE,twidth,twidth,32,0,0,0,0); SDL_Surface *sraw = SDL_CreateRGBSurface(SDL_SWSURFACE,twidth,twidth,32,0,0,0,0);
for(int y=0; y<twidth; y++) for(int y=0; y<twidth; y++)
for(int x=0; x<twidth; x++) for(int x=0; x<twidth; x++)
qpixel(sraw,x,y) = texture_pixels[y * twidth + x]; qpixel(sraw,x,y) = get_texture_pixel(x, y);
IMAGESAVE(sraw, texturename.c_str()); IMAGESAVE(sraw, texturename.c_str());
SDL_FreeSurface(sraw); SDL_FreeSurface(sraw);
addMessage(XLAT("Saved the raw texture to %1", texturename)); addMessage(XLAT("Saved the raw texture to %1", texturename));
@ -337,7 +346,7 @@ bool apply(cell *c, const transmatrix &V, int col) {
int vi[2] = {int(v[0] * twidth), int(v[1] * twidth)}; int vi[2] = {int(v[0] * twidth), int(v[1] * twidth)};
col = texture_pixels[(vi[0] & (twidth-1)) + (vi[1] & (twidth-1)) * twidth]; col = get_texture_pixel(vi[0], vi[1]);
hyperpoint h = hpxyz(mi.vertices[i], mi.vertices[i+1], mi.vertices[i+2]); hyperpoint h = hpxyz(mi.vertices[i], mi.vertices[i+1], mi.vertices[i+2]);
addaura(V*h, col, 0); addaura(V*h, col, 0);
} }
@ -942,6 +951,45 @@ int near(pair<int, int> p1, pair<int, int> p2) {
return max(abs(p1.first-p2.first), abs(p1.second - p2.second)); return max(abs(p1.first-p2.first), abs(p1.second - p2.second));
} }
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(pix != col) {
undos.emplace_back(&pix, pix);
pix = col;
}
}
void undo() {
while(!undos.empty()) {
auto p = undos.back();
undos.pop_back();
if(!p.first) {
loadTextureGL();
return;
}
*p.first = p.second;
}
}
void undoLock() {
printf("undos size = %d\n", size(undos));
if(size(undos) > 2000000) {
// limit undo memory
int moveto = 0;
for(int i=0; i < size(undos) - 1000000; i++)
if(!undos[i].first) moveto = i;
if(moveto) {
for(int i=0; i+moveto < size(undos); i++)
undos[i] = undos[i+moveto];
undos.resize(size(undos) - moveto);
printf("undos sized to = %d\n", size(undos));
}
}
undos.emplace_back(nullptr, 1);
}
void filltriangle(const array<hyperpoint, 3>& v, const array<point, 3>& p, int col, int lev) { void filltriangle(const array<hyperpoint, 3>& v, const array<point, 3>& p, int col, int lev) {
int d2 = near(p[0], p[1]), d1 = near(p[0], p[2]), d0 = near(p[1], p[2]); int d2 = near(p[0], p[1]), d1 = near(p[0], p[2]), d0 = near(p[1], p[2]);
@ -950,7 +998,7 @@ void filltriangle(const array<hyperpoint, 3>& v, const array<point, 3>& p, int c
if((d0 <= 1 && d1 <= 1 && d2 <= 1) || lev >= 20) { if((d0 <= 1 && d1 <= 1 && d2 <= 1) || lev >= 20) {
for(int i=0; i<3; i++) for(int i=0; i<3; i++)
texture_pixels[((p[i].first) & (twidth-1)) + (p[i].second & (twidth-1)) * twidth] = col; fillpixel(p[i].first, p[i].second, col);
return; return;
} }
else if(d1 >= d0 && d1 >= d2) else if(d1 >= d0 && d1 >= d2)