summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjacksonmj <mj-pt@jacksonmj.co.uk>2011-03-18 19:33:38 (GMT)
committer jacksonmj <mj-pt@jacksonmj.co.uk>2011-03-18 19:33:38 (GMT)
commitd46a3bdcb083075a4737125f1c71899e6489ecfa (patch)
tree5a29d5fa7d9c52d4cb97684e0bae0c9d8f01df80 /src
parentd924a5554a8fa0ead5d17f69e10d46e14a64b5dc (diff)
downloadpowder-d46a3bdcb083075a4737125f1c71899e6489ecfa.zip
powder-d46a3bdcb083075a4737125f1c71899e6489ecfa.tar.gz
Better rotation and inversion, also does single pixel translation
Diffstat (limited to 'src')
-rw-r--r--src/main.c42
-rw-r--r--src/powder.c106
2 files changed, 139 insertions, 9 deletions
diff --git a/src/main.c b/src/main.c
index 41b5e4a..5f5e7a4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1797,17 +1797,41 @@ int main(int argc, char *argv[])
}
}
}
- if (sdl_key=='r'&&(sdl_mod & (KMOD_CTRL))&&(sdl_mod & (KMOD_SHIFT)))
+ if (load_mode==1)
{
- save_mode = 1;
- copy_mode = 4;//invert
- }
- else if (sdl_key=='r'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL)))
- {
- save_mode = 1;
- copy_mode = 3;//rotate
+ matrix2d transform = m2d_identity;
+ vector2d translate = v2d_zero;
+ void *ndata;
+ int doTransform = 0;
+ if (sdl_key=='r'&&(sdl_mod & (KMOD_CTRL))&&(sdl_mod & (KMOD_SHIFT)))
+ {
+ transform = m2d_new(-1,0,0,1); //horizontal invert
+ doTransform = 1;
+ }
+ else if (sdl_key=='r'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL)))
+ {
+ transform = m2d_new(0,-1,1,0); //rotate anticlockwise 90 degrees
+ doTransform = 1;
+ }
+ else if (sdl_mod & (KMOD_CTRL))
+ {
+ doTransform = 1;
+ if (sdl_key==SDLK_LEFT) translate = v2d_new(-1,0);
+ else if (sdl_key==SDLK_RIGHT) translate = v2d_new(1,0);
+ else if (sdl_key==SDLK_UP) translate = v2d_new(0,-1);
+ else if (sdl_key==SDLK_DOWN) translate = v2d_new(0,1);
+ else doTransform = 0;
+ }
+ if (doTransform)
+ {
+ ndata = transform_save(load_data, &load_size, transform, translate);
+ if (ndata!=load_data) free(load_data);
+ free(load_img);
+ load_data = ndata;
+ load_img = prerender_save(load_data, load_size, &load_w, &load_h);
+ }
}
- else if (sdl_key=='r')
+ if (sdl_key=='r'&&!(sdl_mod & (KMOD_CTRL|KMOD_SHIFT)))
GENERATION = 0;
if (sdl_key=='x'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL)))
{
diff --git a/src/powder.c b/src/powder.c
index 5ce7575..fc73276 100644
--- a/src/powder.c
+++ b/src/powder.c
@@ -3040,3 +3040,109 @@ void create_line(int x1, int y1, int x2, int y2, int rx, int ry, int c)
}
}
}
+
+void *transform_save(void *odata, int *size, matrix2d transform, vector2d translate)
+{
+ void *ndata;
+ unsigned char bmapo[YRES/CELL][XRES/CELL], bmapn[YRES/CELL][XRES/CELL];
+ particle *partst;
+ sign signst[MAXSIGNS];
+ unsigned pmapt[YRES][XRES];
+ float fvxo[YRES/CELL][XRES/CELL], fvyo[YRES/CELL][XRES/CELL];
+ float fvxn[YRES/CELL][XRES/CELL], fvyn[YRES/CELL][XRES/CELL];
+ int i, x, y, nx, ny, w, h, nw, nh;
+ vector2d pos, tmp, ctl, cbr;
+ vector2d cornerso[4];
+ unsigned char *odatac = odata;
+ memset(bmapo, 0, sizeof(bmapo));
+ memset(bmapn, 0, sizeof(bmapn));
+ memset(signst, 0, sizeof(signst));
+ memset(pmapt, 0, sizeof(pmapt));
+ memset(fvxo, 0, sizeof(fvxo));
+ memset(fvxn, 0, sizeof(fvxn));
+ memset(fvyo, 0, sizeof(fvyo));
+ memset(fvyn, 0, sizeof(fvyn));
+ partst = calloc(sizeof(particle), NPART);
+ if (parse_save(odata, *size, 0, 0, 0, bmapo, fvxo, fvyo, signst, partst, pmapt))
+ {
+ free(partst);
+ return odata;
+ }
+ w = odatac[6]*CELL;
+ h = odatac[7]*CELL;
+ // undo any translation caused by rotation
+ cornerso[0] = v2d_new(0,0);
+ cornerso[1] = v2d_new(w-1,0);
+ cornerso[2] = v2d_new(0,h-1);
+ cornerso[3] = v2d_new(w-1,h-1);
+ for (i=0;i<4;i++)
+ {
+ tmp = m2d_multiply_v2d(transform,cornerso[i]);
+ if (i==0) ctl = cbr = tmp; // top left, bottom right corner
+ if (tmp.x<ctl.x) ctl.x = tmp.x;
+ if (tmp.y<ctl.y) ctl.y = tmp.y;
+ if (tmp.x>cbr.x) cbr.x = tmp.x;
+ if (tmp.y>cbr.y) cbr.y = tmp.y;
+ }
+ // casting as int doesn't quite do what we want with negative numbers, so use floor()
+ tmp = v2d_new(floor(ctl.x+0.5f),floor(ctl.y+0.5f));
+ translate = v2d_sub(translate,tmp);
+ nw = floor(cbr.x+0.5f)-floor(ctl.x+0.5f)+1;
+ nh = floor(cbr.y+0.5f)-floor(ctl.y+0.5f)+1;
+ if (nw>XRES) nw = XRES;
+ if (nh>YRES) nh = YRES;
+ // rotate and translate signs, parts, walls
+ for (i=0; i<MAXSIGNS; i++)
+ {
+ if (!signst[i].text[0]) continue;
+ pos = v2d_new(signst[i].x, signst[i].y);
+ pos = v2d_add(m2d_multiply_v2d(transform,pos),translate);
+ nx = floor(pos.x+0.5f);
+ ny = floor(pos.y+0.5f);
+ if (nx<0 || nx>=nw || ny<0 || ny>=nh)
+ {
+ signst[i].text[0] = 0;
+ continue;
+ }
+ signst[i].x = nx;
+ signst[i].y = ny;
+ }
+ for (i=0; i<NPART; i++)
+ {
+ if (!partst[i].type) continue;
+ pos = v2d_new(partst[i].x, partst[i].y);
+ pos = v2d_add(m2d_multiply_v2d(transform,pos),translate);
+ nx = floor(pos.x+0.5f);
+ ny = floor(pos.y+0.5f);
+ if (nx<0 || nx>=nw || ny<0 || ny>=nh)
+ {
+ partst[i].type = PT_NONE;
+ continue;
+ }
+ partst[i].x = nx;
+ partst[i].y = ny;
+ }
+ for (y=0;y<YRES/CELL;y++)
+ for (x=0;x<XRES/CELL;x++)
+ {
+ pos = v2d_new(x*CELL+CELL*0.4f, y*CELL+CELL*0.4f);
+ pos = v2d_add(m2d_multiply_v2d(transform,pos),translate);
+ nx = pos.x/CELL;
+ ny = pos.y/CELL;
+ if (nx<0 || nx>=nw || ny<0 || ny>=nh)
+ continue;
+ if (bmapo[y][x])
+ {
+ bmapn[ny][nx] = bmapo[y][x];
+ if (bmapo[y][x]==WL_FAN)
+ {
+ fvxn[ny][nx] = fvxo[y][x];
+ fvyn[ny][nx] = fvyo[y][x];
+ }
+ }
+ }
+ ndata = build_save(size,0,0,nw,nh,bmapn,fvxn,fvyn,signst,partst);
+ free(partst);
+ return ndata;
+}
+