Better rotation and inversion, also does single pixel translation

This commit is contained in:
jacksonmj
2011-03-18 19:33:38 +00:00
parent d924a5554a
commit d46a3bdcb0
3 changed files with 141 additions and 9 deletions

View File

@@ -5,6 +5,7 @@
#include "graphics.h"
#include "defines.h"
#include "interface.h"
#include "misc.h"
#define CM_COUNT 11
#define CM_CRACK 10
@@ -863,5 +864,6 @@ int flood_parts(int x, int y, int c, int cm, int bm);
int create_parts(int x, int y, int rx, int ry, int c);
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);
#endif

View File

@@ -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
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'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL)))
{
save_mode = 1;
copy_mode = 3;//rotate
}
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)))
{

View File

@@ -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;
}