Fixes from jacksonmj

This commit is contained in:
Simon 2011-03-22 16:15:41 +00:00
commit cf4572ec5f
14 changed files with 475 additions and 312 deletions

View File

@ -174,8 +174,10 @@ void thumb_cache_inval(char *id);
void thumb_cache_add(char *id, void *thumb, int size); void thumb_cache_add(char *id, void *thumb, int size);
int thumb_cache_find(char *id, void **thumb, int *size); int thumb_cache_find(char *id, void **thumb, int *size);
void *build_thumb(int *size, int bzip2); void *build_thumb(int *size, int bzip2);
void *build_save(int *size, int x0, int y0, int w, int h); void *build_save(int *size, int x0, int y0, int w, int h, unsigned char bmap[YRES/CELL][XRES/CELL], float fvx[YRES/CELL][XRES/CELL], float fvy[YRES/CELL][XRES/CELL], sign signs[MAXSIGNS], void* partsptr);
int parse_save(void *save, int size, int replace, int x0, int y0); int parse_save(void *save, int size, int replace, int x0, int y0, unsigned char bmap[YRES/CELL][XRES/CELL], float fvx[YRES/CELL][XRES/CELL], float fvy[YRES/CELL][XRES/CELL], sign signs[MAXSIGNS], void* partsptr, unsigned pmap[YRES][XRES]);
void clear_sim(void);
void del_stamp(int d); void del_stamp(int d);
void sdl_seticon(void); void sdl_seticon(void);
int process_command(pixel *vid_buf, char *console, char *console_error);
#endif #endif

View File

@ -121,7 +121,7 @@ void xor_line(int x1, int y1, int x2, int y2, pixel *vid);
void xor_rect(pixel *vid, int x, int y, int w, int h); void xor_rect(pixel *vid, int x, int y, int w, int h);
void draw_parts(pixel *vid); void draw_parts(pixel *vid);
void draw_wavelengths(pixel *vid, int x, int y, int h, int wl);
void render_signs(pixel *vid_buf); void render_signs(pixel *vid_buf);
void render_fire(pixel *dst); void render_fire(pixel *dst);

File diff suppressed because one or more lines are too long

View File

@ -71,4 +71,27 @@ void *file_load(char *fn, int *size);
int cpu_check(void); int cpu_check(void);
// a b
// c d
struct matrix2d {float a,b,c,d;};
typedef struct matrix2d matrix2d;
// column vector
struct vector2d {float x,y;};
typedef struct vector2d vector2d;
matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2);
vector2d m2d_multiply_v2d(matrix2d m, vector2d v);
matrix2d m2d_multiply_float(matrix2d m, float s);
vector2d v2d_multiply_float(vector2d v, float s);
vector2d v2d_add(vector2d v1, vector2d v2);
vector2d v2d_sub(vector2d v1, vector2d v2);
matrix2d m2d_new(float me0, float me1, float me2, float me3);
vector2d v2d_new(float x, float y);
extern vector2d v2d_zero;
extern matrix2d m2d_identity;
#endif #endif

View File

@ -5,6 +5,7 @@
#include "graphics.h" #include "graphics.h"
#include "defines.h" #include "defines.h"
#include "interface.h" #include "interface.h"
#include "misc.h"
#define CM_COUNT 11 #define CM_COUNT 11
#define CM_CRACK 10 #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); 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 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 #endif

View File

@ -16,7 +16,7 @@ int update_FWRK(UPDATE_FUNC_ARGS) {
} }
if (parts[i].life>=45) if (parts[i].life>=45)
parts[i].life=0; parts[i].life=0;
if ((parts[i].life<3&&parts[i].life>0)||parts[i].vy>6&&parts[i].life>0) if ((parts[i].life<3&&parts[i].life>0)||(parts[i].vy>6&&parts[i].life>0))
{ {
int q = (rand()%255+1); int q = (rand()%255+1);
int w = (rand()%255+1); int w = (rand()%255+1);

View File

@ -6,8 +6,8 @@ int update_PRTO(UPDATE_FUNC_ARGS) {
parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1); parts[i].tmp = (int)((parts[i].temp-73.15f)/100+1);
if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1; if (parts[i].tmp>=CHANNELS) parts[i].tmp = CHANNELS-1;
else if (parts[i].tmp<0) parts[i].tmp = 0; else if (parts[i].tmp<0) parts[i].tmp = 0;
for (rx=-1; rx<2; rx++) for (rx=1; rx>-2; rx--)
for (ry=-1; ry<2; ry++) for (ry=1; ry>-2; ry--)
if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
{ {
r = pmap[y+ry][x+rx]; r = pmap[y+ry][x+rx];
@ -21,8 +21,8 @@ int update_PRTO(UPDATE_FUNC_ARGS) {
int randomness = count + rand()%3-1; int randomness = count + rand()%3-1;
if (randomness<1) if (randomness<1)
randomness=1; randomness=1;
if (randomness>8) if (randomness>9)
randomness=8; randomness=9;
if (portal[parts[i].tmp][randomness-1][nnx]==PT_SPRK)// TODO: make it look better if (portal[parts[i].tmp][randomness-1][nnx]==PT_SPRK)// TODO: make it look better
{ {
create_part(-1,x+1,y,portal[parts[i].tmp][randomness-1][nnx]); create_part(-1,x+1,y,portal[parts[i].tmp][randomness-1][nnx]);

View File

@ -184,9 +184,11 @@ int update_STKM(UPDATE_FUNC_ARGS) {
if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
{ {
r = pmap[y+ry][x+rx]; r = pmap[y+ry][x+rx];
if (!r || (r>>8)>=NPART)
r = photons[y+ry][x+rx];
if (!r || (r>>8)>=NPART) if (!r || (r>>8)>=NPART)
continue; continue;
if (ptypes[r&0xFF].falldown!=0 || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT) // TODO: photons are not in the pmap. This line may not work as intended. if (ptypes[r&0xFF].falldown!=0 || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT)
{ {
player[2] = r&0xFF; //Current element player[2] = r&0xFF; //Current element
} }
@ -225,26 +227,27 @@ int update_STKM(UPDATE_FUNC_ARGS) {
} }
else else
{ {
int np = -1;
if (player[2] == SPC_AIR) if (player[2] == SPC_AIR)
create_parts(rx + 3*((((int)player[1])&0x02) == 0x02) - 3*((((int)player[1])&0x01) == 0x01), ry, 4, 4, SPC_AIR); create_parts(rx + 3*((((int)player[1])&0x02) == 0x02) - 3*((((int)player[1])&0x01) == 0x01), ry, 4, 4, SPC_AIR);
else else
create_part(-1, rx, ry, player[2]); np = create_part(-1, rx, ry, player[2]);
if ( (np < NPART) && np>=0 && player[2] != PT_PHOT && player[2] != SPC_AIR)
r = pmap[ry][rx]; parts[np].vx = parts[np].vx + 5*((((int)player[1])&0x02) == 0x02) - 5*(((int)(player[1])&0x01) == 0x01);
if ( ((r>>8) < NPART) && (r>>8)>=0 && player[2] != PT_PHOT && player[2] != SPC_AIR) if ((np < NPART) && np>=0 && player[2] == PT_PHOT)
parts[r>>8].vx = parts[r>>8].vx + 5*((((int)player[1])&0x02) == 0x02) - 5*(((int)(player[1])&0x01) == 0x01);
if (((r>>8) < NPART) && (r>>8)>=0 && player[2] == PT_PHOT)
{ {
int random = abs(rand()%3-1)*3; int random = abs(rand()%3-1)*3;
if (random==0) if (random==0)
{ {
parts[r>>8].life = 0; kill_part(np);
parts[r>>8].type = PT_NONE;
} }
else else
{ {
parts[r>>8].vy = 0; parts[np].vy = 0;
parts[r>>8].vx = (((((int)player[1])&0x02) == 0x02) - (((int)(player[1])&0x01) == 0x01))*random; if (((int)player[1])&(0x01|0x02))
parts[np].vx = (((((int)player[1])&0x02) == 0x02) - (((int)(player[1])&0x01) == 0x01))*random;
else
parts[np].vx = random;
} }
} }

View File

@ -184,9 +184,11 @@ int update_STKM2(UPDATE_FUNC_ARGS) {
if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry)) if (x+rx>=0 && y+ry>0 && x+rx<XRES && y+ry<YRES && (rx || ry))
{ {
r = pmap[y+ry][x+rx]; r = pmap[y+ry][x+rx];
if (!r || (r>>8)>=NPART)
r = photons[y+ry][x+rx];
if (!r || (r>>8)>=NPART) if (!r || (r>>8)>=NPART)
continue; continue;
if (ptypes[r&0xFF].falldown!=0 || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT) // TODO: photons are not in the pmap. This line may not work as intended. if (ptypes[r&0xFF].falldown!=0 || (r&0xFF) == PT_NEUT || (r&0xFF) == PT_PHOT)
{ {
player2[2] = r&0xFF; //Current element player2[2] = r&0xFF; //Current element
} }
@ -225,26 +227,27 @@ int update_STKM2(UPDATE_FUNC_ARGS) {
} }
else else
{ {
int np = -1;
if (player2[2] == SPC_AIR) if (player2[2] == SPC_AIR)
create_parts(rx + 3*((((int)player2[1])&0x02) == 0x02) - 3*((((int)player2[1])&0x01) == 0x01), ry, 4, 4, SPC_AIR); create_parts(rx + 3*((((int)player2[1])&0x02) == 0x02) - 3*((((int)player2[1])&0x01) == 0x01), ry, 4, 4, SPC_AIR);
else else
create_part(-1, rx, ry, player2[2]); np = create_part(-1, rx, ry, player2[2]);
if ((np < NPART) && np>=0 && player2[2] != PT_PHOT && player2[2] != SPC_AIR)
r = pmap[ry][rx]; parts[np].vx = parts[np].vx + 5*((((int)player2[1])&0x02) == 0x02) - 5*(((int)(player2[1])&0x01) == 0x01);
if ( ((r>>8) < NPART) && (r>>8)>=0 && player2[2] != PT_PHOT && player2[2] != SPC_AIR) if ((np < NPART) && np>=0 && player2[2] == PT_PHOT)
parts[r>>8].vx = parts[r>>8].vx + 5*((((int)player2[1])&0x02) == 0x02) - 5*(((int)(player2[1])&0x01) == 0x01);
if (((r>>8) < NPART) && (r>>8)>=0 && player2[2] == PT_PHOT)
{ {
int random = abs(rand()%3-1)*3; int random = abs(rand()%3-1)*3;
if (random==0) if (random==0)
{ {
parts[r>>8].life = 0; kill_part(np);
parts[r>>8].type = PT_NONE;
} }
else else
{ {
parts[r>>8].vy = 0; parts[np].vy = 0;
parts[r>>8].vx = (((((int)player2[1])&0x02) == 0x02) - (((int)(player2[1])&0x01) == 0x01))*random; if (((int)player2[1])&(0x01|0x02))
parts[np].vx = (((((int)player2[1])&0x02) == 0x02) - (((int)(player2[1])&0x01) == 0x01))*random;
else
parts[np].vx = random;
} }
} }

View File

@ -1573,31 +1573,27 @@ void draw_parts(pixel *vid)
} }
else if (parts[i].type==PT_GLOW) else if (parts[i].type==PT_GLOW)
{ {
fg = 0; fr = restrict_flt(parts[i].temp-(275.13f+32.0f), 0, 128)/50.0f;
fb = 0; fg = restrict_flt(parts[i].ctype, 0, 128)/50.0f;
fr = 0; fb = restrict_flt(parts[i].tmp, 0, 128)/50.0f;
if (pv[ny/CELL][nx/CELL]>0) {
fg = 6 * pv[ny/CELL][nx/CELL];
fb = 4 * pv[ny/CELL][nx/CELL];
fr = 2 * pv[ny/CELL][nx/CELL];
}
vid[ny*(XRES+BARSIZE)+nx] = PIXRGB((int)restrict_flt(0x44 + fr*8, 0, 255), (int)restrict_flt(0x88 + fg*8, 0, 255), (int)restrict_flt(0x44 + fb*8, 0, 255));
/*x = nx/CELL; cr = restrict_flt(64.0f+parts[i].temp-(275.13f+32.0f), 0, 255);
cg = restrict_flt(64.0f+parts[i].ctype, 0, 255);
cb = restrict_flt(64.0f+parts[i].tmp, 0, 255);
vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(cr, cg, cb);
x = nx/CELL;
y = ny/CELL; y = ny/CELL;
fg += fire_g[y][x]; fg += fire_g[y][x];
if(fg > 255) fg = 255; if (fg > 255) fg = 255;
fire_g[y][x] = fg; fire_g[y][x] = fg;
fb += fire_b[y][x]; fb += fire_b[y][x];
if(fb > 255) fb = 255; if (fb > 255) fb = 255;
fire_b[y][x] = fb; fire_b[y][x] = fb;
fr += fire_r[y][x]; fr += fire_r[y][x];
if(fr > 255) fr = 255; if (fr > 255) fr = 255;
fire_r[y][x] = fr;*/ fire_r[y][x] = fr;
cr = (int)restrict_flt(0x44 + fr*8, 0, 255);
cg = (int)restrict_flt(0x88 + fg*8, 0, 255);
cb = (int)restrict_flt(0x44 + fb*8, 0, 255);
for (x=-1; x<=1; x++) for (x=-1; x<=1; x++)
{ {
for (y=-1; y<=1; y++) for (y=-1; y<=1; y++)
@ -1893,10 +1889,16 @@ void draw_parts(pixel *vid)
} }
if (cr>255) if (cr>255)
cr=255; cr=255;
if (cr<0)
cr=0;
if (cg>255) if (cg>255)
cg=255; cg=255;
if (cg<0)
cg=0;
if (cb>255) if (cb>255)
cb=255; cb=255;
if (cb<0)
cb=0;
blendpixel(vid, nx, ny, cr, cg, cb, 255); blendpixel(vid, nx, ny, cr, cg, cb, 255);
} }
else if (t==PT_WIFI) else if (t==PT_WIFI)
@ -2143,6 +2145,7 @@ void draw_parts(pixel *vid)
else if (t==PT_BRAY && parts[i].tmp==0) else if (t==PT_BRAY && parts[i].tmp==0)
{ {
int trans = parts[i].life * 7; int trans = parts[i].life * 7;
if (trans>255) trans = 255;
if (parts[i].ctype) { if (parts[i].ctype) {
cg = 0; cg = 0;
cb = 0; cb = 0;
@ -2167,6 +2170,7 @@ void draw_parts(pixel *vid)
else if (t==PT_BRAY && parts[i].tmp==1) else if (t==PT_BRAY && parts[i].tmp==1)
{ {
int trans = parts[i].life/4; int trans = parts[i].life/4;
if (trans>255) trans = 255;
if (parts[i].ctype) { if (parts[i].ctype) {
cg = 0; cg = 0;
cb = 0; cb = 0;
@ -2191,6 +2195,7 @@ void draw_parts(pixel *vid)
else if (t==PT_BRAY && parts[i].tmp==2) else if (t==PT_BRAY && parts[i].tmp==2)
{ {
int trans = parts[i].life*100; int trans = parts[i].life*100;
if (trans>255) trans = 255;
blendpixel(vid, nx, ny, 255, 150, 50, trans); blendpixel(vid, nx, ny, 255, 150, 50, trans);
} }
else if (t==PT_PHOT) else if (t==PT_PHOT)
@ -2920,6 +2925,36 @@ void draw_parts(pixel *vid)
} }
void draw_wavelengths(pixel *vid, int x, int y, int h, int wl)
{
int i,cr,cg,cb,j;
int tmp;
fillrect(vid,x-1,y-1,30+1,h+1,64,64,64,255); // coords -1 size +1 to work around bug in fillrect - TODO: fix fillrect
for (i=0;i<30;i++)
{
if ((wl>>i)&1)
{
// Need a spread of wavelengths to get a smooth spectrum, 5 bits seems to work reasonably well
if (i>2) tmp = 0x1F << (i-2);
else tmp = 0x1F >> (2-i);
cg = 0;
cb = 0;
cr = 0;
for (j=0; j<12; j++) {
cr += (tmp >> (j+18)) & 1;
cb += (tmp >> j) & 1;
}
for (j=0; j<14; j++)
cg += (tmp >> (j+9)) & 1;
tmp = 624/(cr+cg+cb+1);
cr *= tmp;
cg *= tmp;
cb *= tmp;
for (j=0;j<h;j++) blendpixel(vid,x+29-i,y+j,cr>255?255:cr,cg>255?255:cg,cb>255?255:cb,255);
}
}
}
void render_signs(pixel *vid_buf) void render_signs(pixel *vid_buf)
{ {
int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq; int i, j, x, y, w, h, dx, dy,mx,my,b=1,bq;

View File

@ -479,7 +479,7 @@ void draw_svf_ui(pixel *vid_buf)
c = svf_login ? 255 : 128; c = svf_login ? 255 : 128;
drawtext(vid_buf, 40, YRES+(MENUSIZE-14), "\x82", c, c, c, 255); drawtext(vid_buf, 40, YRES+(MENUSIZE-14), "\x82", c, c, c, 255);
if (svf_open) if (svf_open)
drawtext(vid_buf, 58, YRES+(MENUSIZE-12), svf_name, c, c, c, 255); drawtextmax(vid_buf, 58, YRES+(MENUSIZE-12), 125, svf_name, c, c, c, 255);
else else
drawtext(vid_buf, 58, YRES+(MENUSIZE-12), "[untitled simulation]", c, c, c, 255); drawtext(vid_buf, 58, YRES+(MENUSIZE-12), "[untitled simulation]", c, c, c, 255);
drawrect(vid_buf, 37, YRES+(MENUSIZE-16), 150, 14, c, c, c, 255); drawrect(vid_buf, 37, YRES+(MENUSIZE-16), 150, 14, c, c, c, 255);
@ -505,7 +505,7 @@ void draw_svf_ui(pixel *vid_buf)
drawtext(vid_buf, 222, YRES+(MENUSIZE-15), "\x83", c, c, c, 255); drawtext(vid_buf, 222, YRES+(MENUSIZE-15), "\x83", c, c, c, 255);
if (svf_tags[0]) if (svf_tags[0])
drawtextmax(vid_buf, 240, YRES+(MENUSIZE-12), 154, svf_tags, c, c, c, 255); drawtextmax(vid_buf, 240, YRES+(MENUSIZE-12), XRES+BARSIZE-405, svf_tags, c, c, c, 255);
else else
drawtext(vid_buf, 240, YRES+(MENUSIZE-12), "[no tags set]", c, c, c, 255); drawtext(vid_buf, 240, YRES+(MENUSIZE-12), "[no tags set]", c, c, c, 255);
@ -516,7 +516,7 @@ void draw_svf_ui(pixel *vid_buf)
drawtext(vid_buf, XRES-122+BARSIZE/*388*/, YRES+(MENUSIZE-13), "\x84", 255, 255, 255, 255); drawtext(vid_buf, XRES-122+BARSIZE/*388*/, YRES+(MENUSIZE-13), "\x84", 255, 255, 255, 255);
if (svf_login) if (svf_login)
drawtext(vid_buf, XRES-104+BARSIZE/*406*/, YRES+(MENUSIZE-12), svf_user, 255, 255, 255, 255); drawtextmax(vid_buf, XRES-104+BARSIZE/*406*/, YRES+(MENUSIZE-12), 66, svf_user, 255, 255, 255, 255);
else else
drawtext(vid_buf, XRES-104+BARSIZE/*406*/, YRES+(MENUSIZE-12), "[sign in]", 255, 255, 255, 255); drawtext(vid_buf, XRES-104+BARSIZE/*406*/, YRES+(MENUSIZE-12), "[sign in]", 255, 255, 255, 255);
drawrect(vid_buf, XRES-125+BARSIZE/*385*/, YRES+(MENUSIZE-16), 91, 14, 255, 255, 255, 255); drawrect(vid_buf, XRES-125+BARSIZE/*385*/, YRES+(MENUSIZE-16), 91, 14, 255, 255, 255, 255);
@ -1203,8 +1203,9 @@ finish:
int save_name_ui(pixel *vid_buf) int save_name_ui(pixel *vid_buf)
{ {
int x0=(XRES-420)/2,y0=(YRES-68-YRES/4)/2,b=1,bq,mx,my,ths,nd=0; int x0=(XRES-420)/2,y0=(YRES-68-YRES/4)/2,b=1,bq,mx,my,ths,idtxtwidth,nd=0;
void *th; void *th;
char *save_id_text;
ui_edit ed; ui_edit ed;
ui_edit ed2; ui_edit ed2;
ui_checkbox cb; ui_checkbox cb;
@ -1241,6 +1242,10 @@ int save_name_ui(pixel *vid_buf)
ed2.multiline = 1; ed2.multiline = 1;
strcpy(ed2.str, svf_description); strcpy(ed2.str, svf_description);
save_id_text = malloc(strlen("Current save id: ")+strlen(svf_id)+1);
sprintf(save_id_text,"Current save id: %s",svf_id);
idtxtwidth = textwidth(save_id_text);
cb.x = x0+10; cb.x = x0+10;
cb.y = y0+53+YRES/4; cb.y = y0+53+YRES/4;
cb.focus = 0; cb.focus = 0;
@ -1276,6 +1281,12 @@ int save_name_ui(pixel *vid_buf)
draw_line(vid_buf, x0+192, y0, x0+192, y0+90+YRES/4, 150, 150, 150, XRES+BARSIZE); draw_line(vid_buf, x0+192, y0, x0+192, y0+90+YRES/4, 150, 150, 150, XRES+BARSIZE);
if (svf_id[0])
{
fillrect(vid_buf, (XRES+BARSIZE-idtxtwidth)/2-5, YRES+(MENUSIZE-16), idtxtwidth+10, 14, 0, 0, 0, 255);
drawtext(vid_buf, (XRES+BARSIZE-idtxtwidth)/2, YRES+MENUSIZE-12, save_id_text, 255, 255, 255, 255);
}
sdl_blit(0, 0, (XRES+BARSIZE), YRES+MENUSIZE, vid_buf, (XRES+BARSIZE)); sdl_blit(0, 0, (XRES+BARSIZE), YRES+MENUSIZE, vid_buf, (XRES+BARSIZE));
ui_edit_process(mx, my, b, &ed); ui_edit_process(mx, my, b, &ed);
@ -1332,6 +1343,7 @@ int save_name_ui(pixel *vid_buf)
} }
} }
free(th); free(th);
if (save_id_text) free(save_id_text);
return 0; return 0;
} }
@ -2732,7 +2744,7 @@ int open_ui(pixel *vid_buf, char *save_id, char *save_date)
int nyd,nyu,ry,lv; int nyd,nyu,ry,lv;
float ryf; float ryf;
char *uri, *uri_2, *o_uri; char *uri, *uri_2, *o_uri, *save_id_text;
void *data, *info_data; void *data, *info_data;
save_info *info = malloc(sizeof(save_info)); save_info *info = malloc(sizeof(save_info));
void *http = NULL, *http_2 = NULL; void *http = NULL, *http_2 = NULL;
@ -2751,6 +2763,9 @@ int open_ui(pixel *vid_buf, char *save_id, char *save_date)
drawrect(vid_buf, 50+(XRES/2)+1, 50, XRES+BARSIZE-100-((XRES/2)+1), YRES+MENUSIZE-100, 155, 155, 155, 255); drawrect(vid_buf, 50+(XRES/2)+1, 50, XRES+BARSIZE-100-((XRES/2)+1), YRES+MENUSIZE-100, 155, 155, 155, 255);
drawtext(vid_buf, 50+(XRES/4)-textwidth("Loading...")/2, 50+(YRES/4), "Loading...", 255, 255, 255, 128); drawtext(vid_buf, 50+(XRES/4)-textwidth("Loading...")/2, 50+(YRES/4), "Loading...", 255, 255, 255, 128);
save_id_text = malloc(strlen("Save id: ")+strlen(save_id)+1);
sprintf(save_id_text,"Save id: %s",save_id);
ed.x = 57+(XRES/2)+1; ed.x = 57+(XRES/2)+1;
ed.y = YRES+MENUSIZE-118; ed.y = YRES+MENUSIZE-118;
ed.w = XRES+BARSIZE-114-((XRES/2)+1); ed.w = XRES+BARSIZE-114-((XRES/2)+1);
@ -2825,11 +2840,12 @@ int open_ui(pixel *vid_buf, char *save_id, char *save_date)
data = http_async_req_stop(http, &status, &data_size); data = http_async_req_stop(http, &status, &data_size);
if (status == 200) if (status == 200)
{ {
pixel *full_save;
if (!data||!data_size) { if (!data||!data_size) {
error_ui(vid_buf, 0, "Save data is empty (may be corrupt)"); error_ui(vid_buf, 0, "Save data is empty (may be corrupt)");
break; break;
} }
pixel *full_save = prerender_save(data, data_size, &imgw, &imgh); full_save = prerender_save(data, data_size, &imgw, &imgh);
if (full_save!=NULL) { if (full_save!=NULL) {
save_pic = rescale_img(full_save, imgw, imgh, &thumb_w, &thumb_h, 2); save_pic = rescale_img(full_save, imgw, imgh, &thumb_w, &thumb_h, 2);
data_ready = 1; data_ready = 1;
@ -2940,6 +2956,10 @@ int open_ui(pixel *vid_buf, char *save_id, char *save_date)
drawtext(vid_buf, XRES+BARSIZE-90, YRES+MENUSIZE-63, "Submit", 255, 255, 255, 255); drawtext(vid_buf, XRES+BARSIZE-90, YRES+MENUSIZE-63, "Submit", 255, 255, 255, 255);
} }
cix = textwidth(save_id_text);
fillrect(vid_buf, (XRES+BARSIZE-cix)/2-5, YRES+(MENUSIZE-16), cix+10, 14, 0, 0, 0, 255);
drawtext(vid_buf, (XRES+BARSIZE-cix)/2, YRES+MENUSIZE-12, save_id_text, 255, 255, 255, 255);
//Open Button //Open Button
bc = openable?255:150; bc = openable?255:150;
drawrect(vid_buf, 50, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, bc); drawrect(vid_buf, 50, YRES+MENUSIZE-68, 50, 18, 255, 255, 255, bc);
@ -3056,7 +3076,7 @@ int open_ui(pixel *vid_buf, char *save_id, char *save_date)
if (queue_open) { if (queue_open) {
if (info_ready && data_ready) { if (info_ready && data_ready) {
// Do Open! // Do Open!
status = parse_save(data, data_size, 1, 0, 0); status = parse_save(data, data_size, 1, 0, 0, bmap, fvx, fvy, signs, parts, pmap);
if (!status) { if (!status) {
//if(svf_last) //if(svf_last)
//free(svf_last); //free(svf_last);
@ -3125,6 +3145,7 @@ int open_ui(pixel *vid_buf, char *save_id, char *save_date)
if (!b) if (!b)
break; break;
} }
if (save_id_text) free(save_id_text);
//Close open connections //Close open connections
if (http) if (http)
http_async_req_close(http); http_async_req_close(http);
@ -3577,7 +3598,7 @@ void execute_save(pixel *vid_buf)
plens[0] = strlen(svf_name); plens[0] = strlen(svf_name);
parts[1] = svf_description; parts[1] = svf_description;
plens[1] = strlen(svf_description); plens[1] = strlen(svf_description);
parts[2] = build_save(plens+2, 0, 0, XRES, YRES); parts[2] = build_save(plens+2, 0, 0, XRES, YRES, bmap, fvx, fvy, signs, parts);
parts[3] = build_thumb(plens+3, 1); parts[3] = build_thumb(plens+3, 1);
parts[4] = (svf_publish==1)?"Public":"Private"; parts[4] = (svf_publish==1)?"Public":"Private";
plens[4] = strlen((svf_publish==1)?"Public":"Private"); plens[4] = strlen((svf_publish==1)?"Public":"Private");

View File

@ -210,7 +210,7 @@ void sdl_seticon(void)
//SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(app_icon_w32, 32, 32, 32, 128, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); //SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(app_icon_w32, 32, 32, 32, 128, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
//SDL_WM_SetIcon(icon, NULL/*app_icon_mask*/); //SDL_WM_SetIcon(icon, NULL/*app_icon_mask*/);
#else #else
SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(app_icon, 16, 16, 32, 128, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(app_icon, 16, 16, 32, 64, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
SDL_WM_SetIcon(icon, NULL/*app_icon_mask*/); SDL_WM_SetIcon(icon, NULL/*app_icon_mask*/);
#endif #endif
#endif #endif
@ -296,11 +296,12 @@ void *build_thumb(int *size, int bzip2)
return d; return d;
} }
void *build_save(int *size, int x0, int y0, int w, int h) void *build_save(int *size, int x0, int y0, int w, int h, unsigned char bmap[YRES/CELL][XRES/CELL], float fvx[YRES/CELL][XRES/CELL], float fvy[YRES/CELL][XRES/CELL], sign signs[MAXSIGNS], void* partsptr)
{ {
unsigned char *d=calloc(1,3*(XRES/CELL)*(YRES/CELL)+(XRES*YRES)*11+MAXSIGNS*262), *c; unsigned char *d=calloc(1,3*(XRES/CELL)*(YRES/CELL)+(XRES*YRES)*11+MAXSIGNS*262), *c;
int i,j,x,y,p=0,*m=calloc(XRES*YRES, sizeof(int)); int i,j,x,y,p=0,*m=calloc(XRES*YRES, sizeof(int));
int bx0=x0/CELL, by0=y0/CELL, bw=(w+CELL-1)/CELL, bh=(h+CELL-1)/CELL; int bx0=x0/CELL, by0=y0/CELL, bw=(w+CELL-1)/CELL, bh=(h+CELL-1)/CELL;
particle *parts = partsptr;
// normalize coordinates // normalize coordinates
x0 = bx0*CELL; x0 = bx0*CELL;
@ -339,7 +340,8 @@ void *build_save(int *size, int x0, int y0, int w, int h)
y = (int)(parts[i].y+0.5f); y = (int)(parts[i].y+0.5f);
if (x>=x0 && x<x0+w && y>=y0 && y<y0+h) { if (x>=x0 && x<x0+w && y>=y0 && y<y0+h) {
if (!m[(x-x0)+(y-y0)*w] || if (!m[(x-x0)+(y-y0)*w] ||
parts[m[(x-x0)+(y-y0)*w]-1].type == PT_PHOT) parts[m[(x-x0)+(y-y0)*w]-1].type == PT_PHOT ||
parts[m[(x-x0)+(y-y0)*w]-1].type == PT_NEUT)
m[(x-x0)+(y-y0)*w] = i+1; m[(x-x0)+(y-y0)*w] = i+1;
} }
} }
@ -465,12 +467,13 @@ void *build_save(int *size, int x0, int y0, int w, int h)
return c; return c;
} }
int parse_save(void *save, int size, int replace, int x0, int y0) int parse_save(void *save, int size, int replace, int x0, int y0, unsigned char bmap[YRES/CELL][XRES/CELL], float fvx[YRES/CELL][XRES/CELL], float fvy[YRES/CELL][XRES/CELL], sign signs[MAXSIGNS], void* partsptr, unsigned pmap[YRES][XRES])
{ {
unsigned char *d,*c=save; unsigned char *d,*c=save;
int q,i,j,k,x,y,p=0,*m=calloc(XRES*YRES, sizeof(int)), ver, pty, ty, legacy_beta=0; int q,i,j,k,x,y,p=0,*m=calloc(XRES*YRES, sizeof(int)), ver, pty, ty, legacy_beta=0;
int bx0=x0/CELL, by0=y0/CELL, bw, bh, w, h; int bx0=x0/CELL, by0=y0/CELL, bw, bh, w, h;
int fp[NPART], nf=0, new_format = 0, ttv = 0; int fp[NPART], nf=0, new_format = 0, ttv = 0;
particle *parts = partsptr;
//New file header uses PSv, replacing fuC. This is to detect if the client uses a new save format for temperatures //New file header uses PSv, replacing fuC. This is to detect if the client uses a new save format for temperatures
//This creates a problem for old clients, that display and "corrupt" error instead of a "newer version" error //This creates a problem for old clients, that display and "corrupt" error instead of a "newer version" error
@ -550,19 +553,7 @@ int parse_save(void *save, int size, int replace, int x0, int y0)
gravityMode = 0; gravityMode = 0;
airMode = 0; airMode = 0;
} }
memset(bmap, 0, sizeof(bmap)); clear_sim();
memset(emap, 0, sizeof(emap));
memset(signs, 0, sizeof(signs));
memset(parts, 0, sizeof(particle)*NPART);
memset(pmap, 0, sizeof(pmap));
memset(vx, 0, sizeof(vx));
memset(vy, 0, sizeof(vy));
memset(pv, 0, sizeof(pv));
memset(photons, 0, sizeof(photons));
memset(wireless, 0, sizeof(wireless));
memset(gol2, 0, sizeof(gol2));
memset(portal, 0, sizeof(portal));
death = death2 = ISSPAWN1 = ISSPAWN2 = 0;
} }
// make a catalog of free parts // make a catalog of free parts
@ -894,13 +885,35 @@ corrupt:
if (replace) if (replace)
{ {
legacy_enable = 0; legacy_enable = 0;
memset(signs, 0, sizeof(signs)); clear_sim();
memset(parts, 0, sizeof(particle)*NPART);
memset(bmap, 0, sizeof(bmap));
} }
return 1; return 1;
} }
void clear_sim(void)
{
memset(bmap, 0, sizeof(bmap));
memset(emap, 0, sizeof(emap));
memset(signs, 0, sizeof(signs));
memset(parts, 0, sizeof(particle)*NPART);
memset(pmap, 0, sizeof(pmap));
memset(pv, 0, sizeof(pv));
memset(vx, 0, sizeof(vx));
memset(vy, 0, sizeof(vy));
memset(fvx, 0, sizeof(fvx));
memset(fvy, 0, sizeof(fvy));
memset(photons, 0, sizeof(photons));
memset(wireless, 0, sizeof(wireless));
memset(gol2, 0, sizeof(gol2));
memset(portal, 0, sizeof(portal));
death = death2 = ISSPAWN1 = ISSPAWN2 = 0;
memset(pers_bg, 0, (XRES+BARSIZE)*YRES*PIXELSIZE);
memset(fire_bg, 0, XRES*YRES*PIXELSIZE);
memset(fire_r, 0, sizeof(fire_r));
memset(fire_g, 0, sizeof(fire_g));
memset(fire_b, 0, sizeof(fire_b));
}
// stamps library // stamps library
stamp stamps[STAMP_MAX];//[STAMP_X*STAMP_Y]; stamp stamps[STAMP_MAX];//[STAMP_X*STAMP_Y];
@ -985,7 +998,7 @@ void stamp_save(int x, int y, int w, int h)
FILE *f; FILE *f;
int n; int n;
char fn[64], sn[16]; char fn[64], sn[16];
void *s=build_save(&n, x, y, w, h); void *s=build_save(&n, x, y, w, h, bmap, fvx, fvy, signs, parts);
#ifdef WIN32 #ifdef WIN32
_mkdir("stamps"); _mkdir("stamps");
@ -1193,6 +1206,7 @@ int main(int argc, char *argv[])
#ifdef INTERNAL #ifdef INTERNAL
int vs = 0; int vs = 0;
#endif #endif
int wavelength_gfx = 0;
int x, y, b = 0, sl=1, sr=0, su=0, c, lb = 0, lx = 0, ly = 0, lm = 0;//, tx, ty; int x, y, b = 0, sl=1, sr=0, su=0, c, lb = 0, lx = 0, ly = 0, lm = 0;//, tx, ty;
int da = 0, db = 0, it = 2047, mx, my, bsx = 2, bsy = 2; int da = 0, db = 0, it = 2047, mx, my, bsx = 2, bsy = 2;
float nfvx, nfvy; float nfvx, nfvy;
@ -1202,6 +1216,7 @@ int main(int argc, char *argv[])
int save_mode=0, save_x=0, save_y=0, save_w=0, save_h=0, copy_mode=0; int save_mode=0, save_x=0, save_y=0, save_w=0, save_h=0, copy_mode=0;
SDL_AudioSpec fmt; SDL_AudioSpec fmt;
int username_flash = 0, username_flash_t = 1; int username_flash = 0, username_flash_t = 1;
pers_bg = calloc((XRES+BARSIZE)*YRES, PIXELSIZE);
GSPEED = 1; GSPEED = 1;
/* Set 16-bit stereo audio at 22Khz */ /* Set 16-bit stereo audio at 22Khz */
@ -1236,8 +1251,7 @@ int main(int argc, char *argv[])
parts[NPART-1].life = -1; parts[NPART-1].life = -1;
pfree = 0; pfree = 0;
fire_bg=calloc(XRES*YRES, PIXELSIZE); fire_bg=calloc(XRES*YRES, PIXELSIZE);
pers_bg=calloc((XRES+BARSIZE)*YRES, PIXELSIZE); clear_sim();
memset(signs, 0, sizeof(signs));
//fbi_img = render_packed_rgb(fbi, FBI_W, FBI_H, FBI_CMP); //fbi_img = render_packed_rgb(fbi, FBI_W, FBI_H, FBI_CMP);
@ -1523,7 +1537,7 @@ int main(int argc, char *argv[])
free(load_data); free(load_data);
} }
} }
if (sdl_key=='s' && (sdl_mod & (KMOD_CTRL)) || (sdl_key=='s' && !isplayer2)) if ((sdl_key=='s' && (sdl_mod & (KMOD_CTRL))) || (sdl_key=='s' && !isplayer2))
{ {
if (it > 50) if (it > 50)
it = 50; it = 50;
@ -1657,7 +1671,7 @@ int main(int argc, char *argv[])
bsy = 0; bsy = 0;
} }
} }
if (sdl_key=='d'&&(sdl_mod & (KMOD_CTRL)) || (sdl_key=='d' && !isplayer2)) if ((sdl_key=='d'&&(sdl_mod & (KMOD_CTRL))) || (sdl_key=='d' && !isplayer2))
DEBUG_MODE = !DEBUG_MODE; DEBUG_MODE = !DEBUG_MODE;
if (sdl_key=='i') if (sdl_key=='i')
{ {
@ -1783,17 +1797,41 @@ int main(int argc, char *argv[])
} }
} }
} }
if (load_mode==1)
{
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))) if (sdl_key=='r'&&(sdl_mod & (KMOD_CTRL))&&(sdl_mod & (KMOD_SHIFT)))
{ {
save_mode = 1; transform = m2d_new(-1,0,0,1); //horizontal invert
copy_mode = 4;//invert doTransform = 1;
} }
else if (sdl_key=='r'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL))) else if (sdl_key=='r'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL)))
{ {
save_mode = 1; transform = m2d_new(0,1,-1,0); //rotate anticlockwise 90 degrees
copy_mode = 3;//rotate doTransform = 1;
} }
else if (sdl_key=='r') 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);
}
}
if (sdl_key=='r'&&!(sdl_mod & (KMOD_CTRL|KMOD_SHIFT)))
GENERATION = 0; GENERATION = 0;
if (sdl_key=='x'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL))) if (sdl_key=='x'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL)))
{ {
@ -1944,8 +1982,13 @@ int main(int argc, char *argv[])
if (DEBUG_MODE) if (DEBUG_MODE)
{ {
int tctype = parts[cr>>8].ctype; int tctype = parts[cr>>8].ctype;
if (tctype>=PT_NUM) if (tctype>=PT_NUM || (cr&0xFF)==PT_PHOT)
tctype = 0; tctype = 0;
if ((cr&0xFF)==PT_PIPE)
{
if (parts[cr>>8].tmp<PT_NUM) tctype = parts[cr>>8].tmp;
else tctype = 0;
}
sprintf(heattext, "%s (%s), Pressure: %3.2f, Temp: %4.2f C, Life: %d", ptypes[cr&0xFF].name, ptypes[tctype].name, pv[(y/sdl_scale)/CELL][(x/sdl_scale)/CELL], parts[cr>>8].temp-273.15f, parts[cr>>8].life); sprintf(heattext, "%s (%s), Pressure: %3.2f, Temp: %4.2f C, Life: %d", ptypes[cr&0xFF].name, ptypes[tctype].name, pv[(y/sdl_scale)/CELL][(x/sdl_scale)/CELL], parts[cr>>8].temp-273.15f, parts[cr>>8].life);
sprintf(coordtext, "#%d, X:%d Y:%d", cr>>8, x/sdl_scale, y/sdl_scale); sprintf(coordtext, "#%d, X:%d Y:%d", cr>>8, x/sdl_scale, y/sdl_scale);
} else { } else {
@ -1955,6 +1998,7 @@ int main(int argc, char *argv[])
sprintf(heattext, "%s, Pressure: %3.2f, Temp: %4.2f C", ptypes[cr&0xFF].name, pv[(y/sdl_scale)/CELL][(x/sdl_scale)/CELL], parts[cr>>8].temp-273.15f); sprintf(heattext, "%s, Pressure: %3.2f, Temp: %4.2f C", ptypes[cr&0xFF].name, pv[(y/sdl_scale)/CELL][(x/sdl_scale)/CELL], parts[cr>>8].temp-273.15f);
#endif #endif
} }
if ((cr&0xFF)==PT_PHOT) wavelength_gfx = parts[cr>>8].ctype;
} }
else else
{ {
@ -2128,7 +2172,7 @@ int main(int argc, char *argv[])
if (load_y<0) load_y=0; if (load_y<0) load_y=0;
if (bq==1 && !b) if (bq==1 && !b)
{ {
parse_save(load_data, load_size, 0, load_x, load_y); parse_save(load_data, load_size, 0, load_x, load_y, bmap, fvx, fvy, signs, parts, pmap);
free(load_data); free(load_data);
free(load_img); free(load_img);
load_mode = 0; load_mode = 0;
@ -2170,35 +2214,19 @@ int main(int argc, char *argv[])
{ {
if (copy_mode==1) if (copy_mode==1)
{ {
clipboard_data=build_save(&clipboard_length, save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL); clipboard_data=build_save(&clipboard_length, save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL, bmap, fvx, fvy, signs, parts);
clipboard_ready = 1; clipboard_ready = 1;
save_mode = 0; save_mode = 0;
copy_mode = 0; copy_mode = 0;
} }
else if (copy_mode==2) else if (copy_mode==2)
{ {
clipboard_data=build_save(&clipboard_length, save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL); clipboard_data=build_save(&clipboard_length, save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL, bmap, fvx, fvy, signs, parts);
clipboard_ready = 1; clipboard_ready = 1;
save_mode = 0; save_mode = 0;
copy_mode = 0; copy_mode = 0;
clear_area(save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL); clear_area(save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL);
} }
else if (copy_mode==3)//rotation
{
if (save_h>save_w)
save_w = save_h;
rotate_area(save_x*CELL, save_y*CELL, save_w*CELL, save_w*CELL,0);//just do squares for now
save_mode = 0;
copy_mode = 0;
}
else if (copy_mode==4)//invertion
{
if (save_h>save_w)
save_w = save_h;
rotate_area(save_x*CELL, save_y*CELL, save_w*CELL, save_w*CELL,1);//just do squares for now
save_mode = 0;
copy_mode = 0;
}
else else
{ {
stamp_save(save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL); stamp_save(save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL);
@ -2256,19 +2284,7 @@ int main(int argc, char *argv[])
} }
if (x>=(XRES+BARSIZE-(510-367)) && x<=(XRES+BARSIZE-(510-383)) && !bq) if (x>=(XRES+BARSIZE-(510-367)) && x<=(XRES+BARSIZE-(510-383)) && !bq)
{ {
memset(signs, 0, sizeof(signs)); clear_sim();
memset(pv, 0, sizeof(pv));
memset(vx, 0, sizeof(vx));
memset(vy, 0, sizeof(vy));
memset(fvx, 0, sizeof(fvx));
memset(fvy, 0, sizeof(fvy));
memset(bmap, 0, sizeof(bmap));
memset(emap, 0, sizeof(emap));
memset(parts, 0, sizeof(particle)*NPART);
memset(photons, 0, sizeof(photons));
memset(wireless, 0, sizeof(wireless));
memset(gol2, 0, sizeof(gol2));
memset(portal, 0, sizeof(portal));
for (i=0; i<NPART-1; i++) for (i=0; i<NPART-1; i++)
parts[i].life = i+1; parts[i].life = i+1;
parts[NPART-1].life = -1; parts[NPART-1].life = -1;
@ -2285,17 +2301,8 @@ int main(int argc, char *argv[])
svf_description[0] = 0; svf_description[0] = 0;
gravityMode = 0; gravityMode = 0;
airMode = 0; airMode = 0;
death = death2 = 0;
isplayer2 = 0; isplayer2 = 0;
isplayer = 0; isplayer = 0;
ISSPAWN1 = 0;
ISSPAWN2 = 0;
memset(fire_bg, 0, XRES*YRES*PIXELSIZE);
memset(pers_bg, 0, (XRES+BARSIZE)*YRES*PIXELSIZE);
memset(fire_r, 0, sizeof(fire_r));
memset(fire_g, 0, sizeof(fire_g));
memset(fire_b, 0, sizeof(fire_b));
} }
if (x>=(XRES+BARSIZE-(510-385)) && x<=(XRES+BARSIZE-(510-476))) if (x>=(XRES+BARSIZE-(510-385)) && x<=(XRES+BARSIZE-(510-476)))
{ {
@ -2330,7 +2337,7 @@ int main(int argc, char *argv[])
} }
if (x>=19 && x<=35 && svf_last && svf_open && !bq) { if (x>=19 && x<=35 && svf_last && svf_open && !bq) {
//int tpval = sys_pause; //int tpval = sys_pause;
parse_save(svf_last, svf_lsize, 1, 0, 0); parse_save(svf_last, svf_lsize, 1, 0, 0, bmap, fvx, fvy, signs, parts, pmap);
//sys_pause = tpval; //sys_pause = tpval;
} }
if (x>=(XRES+BARSIZE-(510-476)) && x<=(XRES+BARSIZE-(510-491)) && !bq) if (x>=(XRES+BARSIZE-(510-476)) && x<=(XRES+BARSIZE-(510-491)) && !bq)
@ -2420,7 +2427,7 @@ int main(int argc, char *argv[])
{ {
for (j=-bsy; j<=bsy; j++) for (j=-bsy; j<=bsy; j++)
for (i=-bsx; i<=bsx; i++) for (i=-bsx; i<=bsx; i++)
if ((CURRENT_BRUSH==CIRCLE_BRUSH && (pow(i,2))/(pow(bsx,2))+(pow(j,2))/(pow(bsy,2))<=1)||(CURRENT_BRUSH==SQUARE_BRUSH&&i*j<=bsy*bsx)) if (x+i>0 && y+j>0 && x+i<XRES && y+j<YRES && ((CURRENT_BRUSH==CIRCLE_BRUSH && (pow(i,2))/(pow(bsx,2))+(pow(j,2))/(pow(bsy,2))<=1)||(CURRENT_BRUSH==SQUARE_BRUSH&&i*j<=bsy*bsx)))
{ {
vx[(y+j)/CELL][(x+i)/CELL] += (x-lx)*0.01f; vx[(y+j)/CELL][(x+i)/CELL] += (x-lx)*0.01f;
vy[(y+j)/CELL][(x+i)/CELL] += (y-ly)*0.01f; vy[(y+j)/CELL][(x+i)/CELL] += (y-ly)*0.01f;
@ -2541,13 +2548,6 @@ int main(int argc, char *argv[])
if (save_mode) if (save_mode)
{ {
if (copy_mode==3||copy_mode==4)//special drawing for rotate, can remove once it can do rectangles
{
if (save_h>save_w)
save_w = save_h;
xor_rect(vid_buf, save_x*CELL, save_y*CELL, save_w*CELL, save_w*CELL);
}
else
xor_rect(vid_buf, save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL); xor_rect(vid_buf, save_x*CELL, save_y*CELL, save_w*CELL, save_h*CELL);
da = 51; da = 51;
db = 269; db = 269;
@ -2703,6 +2703,8 @@ int main(int argc, char *argv[])
fillrect(vid_buf, XRES-20-textwidth(coordtext), 280, textwidth(coordtext)+8, 13, 0, 0, 0, 140); fillrect(vid_buf, XRES-20-textwidth(coordtext), 280, textwidth(coordtext)+8, 13, 0, 0, 0, 140);
drawtext(vid_buf, XRES-16-textwidth(coordtext), 282, coordtext, 255, 255, 255, 200); drawtext(vid_buf, XRES-16-textwidth(coordtext), 282, coordtext, 255, 255, 255, 200);
} }
if (wavelength_gfx)
draw_wavelengths(vid_buf,XRES-20-textwidth(heattext),265,2,wavelength_gfx);
} }
else else
{ {
@ -2713,6 +2715,8 @@ int main(int argc, char *argv[])
fillrect(vid_buf, 12, 280, textwidth(coordtext)+8, 13, 0, 0, 0, 140); fillrect(vid_buf, 12, 280, textwidth(coordtext)+8, 13, 0, 0, 0, 140);
drawtext(vid_buf, 16, 282, coordtext, 255, 255, 255, 200); drawtext(vid_buf, 16, 282, coordtext, 255, 255, 255, 200);
} }
if (wavelength_gfx)
draw_wavelengths(vid_buf,12,265,2,wavelength_gfx);
} }
} }
else else
@ -2724,7 +2728,10 @@ int main(int argc, char *argv[])
fillrect(vid_buf, XRES-20-textwidth(coordtext), 26, textwidth(coordtext)+8, 11, 0, 0, 0, 140); fillrect(vid_buf, XRES-20-textwidth(coordtext), 26, textwidth(coordtext)+8, 11, 0, 0, 0, 140);
drawtext(vid_buf, XRES-16-textwidth(coordtext), 27, coordtext, 255, 255, 255, 200); drawtext(vid_buf, XRES-16-textwidth(coordtext), 27, coordtext, 255, 255, 255, 200);
} }
if (wavelength_gfx)
draw_wavelengths(vid_buf,XRES-20-textwidth(heattext),11,2,wavelength_gfx);
} }
wavelength_gfx = 0;
fillrect(vid_buf, 12, 12, textwidth(uitext)+8, 15, 0, 0, 0, 140); fillrect(vid_buf, 12, 12, textwidth(uitext)+8, 15, 0, 0, 0, 140);
drawtext(vid_buf, 16, 16, uitext, 32, 216, 255, 200); drawtext(vid_buf, 16, 16, uitext, 32, 216, 255, 200);
@ -2738,7 +2745,7 @@ int main(int argc, char *argv[])
console = console_ui(vid_buf,console_error); console = console_ui(vid_buf,console_error);
console = mystrdup(console); console = mystrdup(console);
strcpy(console_error,""); strcpy(console_error,"");
if(process_command(vid_buf,console,&console_error)==-1) if(process_command(vid_buf,console,console_error)==-1)
{ {
free(console); free(console);
break; break;
@ -2788,7 +2795,7 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
{ {
return -1; return -1;
} }
else if(strcmp(console2, "file")==0 && console3) else if(strcmp(console2, "file")==0)
{ {
if(file_script){ if(file_script){
FILE *f=fopen(console3, "r"); FILE *f=fopen(console3, "r");
@ -2802,7 +2809,6 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
ny = 0; ny = 0;
j = 0; j = 0;
m = 0; m = 0;
if(console4)
console_parse_coords(console4, &nx , &ny, console_error); console_parse_coords(console4, &nx , &ny, console_error);
memset(pch,0,sizeof(pch)); memset(pch,0,sizeof(pch));
memset(fileread,0,sizeof(fileread)); memset(fileread,0,sizeof(fileread));
@ -2878,12 +2884,12 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
} }
} }
else if(strcmp(console2, "sound")==0 && console3) else if(strcmp(console2, "sound")==0)
{ {
if (sound_enable) play_sound(console3); if (sound_enable) play_sound(console3);
else strcpy(console_error, "Audio device not available - cannot play sounds"); else strcpy(console_error, "Audio device not available - cannot play sounds");
} }
else if(strcmp(console2, "load")==0 && console3) else if(strcmp(console2, "load")==0)
{ {
j = atoi(console3); j = atoi(console3);
if(j) if(j)
@ -2892,7 +2898,7 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
console_mode = 0; console_mode = 0;
} }
} }
else if(strcmp(console2, "if")==0 && console3) else if(strcmp(console2, "if")==0)
{ {
if(strcmp(console3, "type")==0)//TODO: add more than just type, and be able to check greater/less than if(strcmp(console3, "type")==0)//TODO: add more than just type, and be able to check greater/less than
{ {
@ -2908,7 +2914,7 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
return 0; return 0;
} }
} }
else if (strcmp(console2, "create")==0 && console3 && console4) else if (strcmp(console2, "create")==0)
{ {
if (console_parse_type(console3, &j, console_error) if (console_parse_type(console3, &j, console_error)
&& console_parse_coords(console4, &nx, &ny, console_error)) && console_parse_coords(console4, &nx, &ny, console_error))
@ -2919,12 +2925,12 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
strcpy(console_error, "Could not create particle"); strcpy(console_error, "Could not create particle");
} }
} }
else if ((strcmp(console2, "delete")==0 || strcmp(console2, "kill")==0) && console3) else if (strcmp(console2, "delete")==0 || strcmp(console2, "kill")==0)
{ {
if (console_parse_partref(console3, &i, console_error)) if (console_parse_partref(console3, &i, console_error))
kill_part(i); kill_part(i);
} }
else if(strcmp(console2, "reset")==0 && console3) else if(strcmp(console2, "reset")==0)
{ {
if(strcmp(console3, "pressure")==0) if(strcmp(console3, "pressure")==0)
{ {
@ -2965,7 +2971,7 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
} }
} }
} }
else if(strcmp(console2, "set")==0 && console3 && console4 && console5) else if(strcmp(console2, "set")==0)
{ {
if(strcmp(console3, "life")==0) if(strcmp(console3, "life")==0)
{ {
@ -3230,7 +3236,7 @@ int process_command(pixel *vid_buf,char *console,char *console_error) {
} }
} }
else else
sprintf(console_error, "Invalid Command", console2); strcpy(console_error, "Invalid Command");
} }
return 1; return 1;
} }

View File

@ -306,3 +306,68 @@ int cpu_check(void)
#endif #endif
return 0; return 0;
} }
matrix2d m2d_multiply_m2d(matrix2d m1, matrix2d m2)
{
matrix2d result = {
m1.a*m2.a+m1.b*m2.c, m1.a*m2.b+m1.b*m2.d,
m1.c*m2.a+m1.d*m2.c, m1.c*m2.b+m1.d*m2.d
};
return result;
}
vector2d m2d_multiply_v2d(matrix2d m, vector2d v)
{
vector2d result = {
m.a*v.x+m.b*v.y,
m.c*v.x+m.d*v.y
};
return result;
}
matrix2d m2d_multiply_float(matrix2d m, float s)
{
matrix2d result = {
m.a*s, m.b*s,
m.c*s, m.d*s,
};
return result;
}
vector2d v2d_multiply_float(vector2d v, float s)
{
vector2d result = {
v.x*s,
v.y*s
};
return result;
}
vector2d v2d_add(vector2d v1, vector2d v2)
{
vector2d result = {
v1.x+v2.x,
v1.y+v2.y
};
return result;
}
vector2d v2d_sub(vector2d v1, vector2d v2)
{
vector2d result = {
v1.x-v2.x,
v1.y-v2.y
};
return result;
}
matrix2d m2d_new(float me0, float me1, float me2, float me3)
{
matrix2d result = {me0,me1,me2,me3};
return result;
}
vector2d v2d_new(float x, float y)
{
vector2d result = {x, y};
return result;
}
vector2d v2d_zero = {0,0};
matrix2d m2d_identity = {1,0,0,1};

View File

@ -139,6 +139,8 @@ int try_move(int i, int x, int y, int nx, int ny)
if (x==nx && y==ny) if (x==nx && y==ny)
return 1; return 1;
if (nx<0 || ny<0 || nx>=XRES || ny>=YRES)
return 1;
e = eval_move(parts[i].type, nx, ny, &r); e = eval_move(parts[i].type, nx, ny, &r);
@ -253,9 +255,23 @@ int try_move(int i, int x, int y, int nx, int ny)
e = r >> 8; e = r >> 8;
if (r && e<NPART) if (r && e<NPART)
{ {
if (parts[e].type == PT_PHOT) if (parts[e].type == PT_PHOT||parts[e].type == PT_NEUT)
return 1; return 1;
if (parts[i].type==PT_NEUT) {
// target material is NEUTPENETRATE, meaning it gets moved around when neutron passes
unsigned s = pmap[y][x];
if ((s&0xFF) && (s&0xFF)<PT_NUM && !(ptypes[s&0xFF].properties&PROP_NEUTPENETRATE))
return 1; // if the element currently underneath neutron isn't NEUTPENETRATE, don't move it around
if ((pmap[ny][nx]>>8)==e) pmap[ny][nx] = (s&~(0xFF))|parts[s>>8].type;
parts[e].x = x;
parts[e].y = y;
pmap[y][x] = (e<<8)|parts[e].type;
parts[s>>8].x = nx;
parts[s>>8].y = ny;
return 1;
}
if ((pmap[ny][nx]>>8)==e) pmap[ny][nx] = 0; if ((pmap[ny][nx]>>8)==e) pmap[ny][nx] = 0;
parts[e].x += x-nx; parts[e].x += x-nx;
parts[e].y += y-ny; parts[e].y += y-ny;
@ -460,7 +476,7 @@ inline void part_change_type(int i, int x, int y, int t)
if (x<0 || y<0 || x>=XRES || y>=YRES || i>=NPART || t<0 || t>=PT_NUM) if (x<0 || y<0 || x>=XRES || y>=YRES || i>=NPART || t<0 || t>=PT_NUM)
return; return;
parts[i].type = t; parts[i].type = t;
if (t==PT_PHOT)// || t==PT_NEUT) if (t==PT_PHOT || t==PT_NEUT)
{ {
photons[y][x] = t|(i<<8); photons[y][x] = t|(i<<8);
if ((pmap[y][x]>>8)==i) if ((pmap[y][x]>>8)==i)
@ -491,7 +507,7 @@ inline int create_n_parts(int n, int x, int y, float vx, float vy, int t)
if (x<0 || y<0 || x>=XRES || y>=YRES || t<0 || t>=PT_NUM) if (x<0 || y<0 || x>=XRES || y>=YRES || t<0 || t>=PT_NUM)
return -1; return -1;
for (c; c<n; c++) { for (c=0; c<n; c++) {
float r = (rand()%128+128)/127.0f; float r = (rand()%128+128)/127.0f;
float a = (rand()%360)*3.14159f/180.0f; float a = (rand()%360)*3.14159f/180.0f;
if (pfree == -1) if (pfree == -1)
@ -508,9 +524,9 @@ inline int create_n_parts(int n, int x, int y, float vx, float vy, int t)
parts[i].ctype = 0; parts[i].ctype = 0;
parts[i].temp += (n*17); parts[i].temp += (n*17);
parts[i].tmp = 0; parts[i].tmp = 0;
if (t!=PT_STKM&&t!=PT_STKM2 && t!=PT_PHOT && !pmap[y][x])// && t!=PT_NEUT) if (t!=PT_STKM&&t!=PT_STKM2 && t!=PT_PHOT && t!=PT_NEUT && !pmap[y][x])
pmap[y][x] = t|(i<<8); pmap[y][x] = t|(i<<8);
else if (t==PT_PHOT && !photons[y][x]) else if ((t==PT_PHOT||t==PT_NEUT) && !photons[y][x])
photons[y][x] = t|(i<<8); photons[y][x] = t|(i<<8);
pv[y/CELL][x/CELL] += 6.0f * CFDS; pv[y/CELL][x/CELL] += 6.0f * CFDS;
@ -630,7 +646,7 @@ inline int create_part(int p, int x, int y, int t)
} }
return -1; return -1;
} }
if (photons[y][x] && t==PT_PHOT) if (photons[y][x] && (t==PT_PHOT||t==PT_NEUT))
return -1; return -1;
if (pfree == -1) if (pfree == -1)
return -1; return -1;
@ -738,23 +754,9 @@ inline int create_part(int p, int x, int y, int t)
parts[i].vx = 3.0f*cosf(a); parts[i].vx = 3.0f*cosf(a);
parts[i].vy = 3.0f*sinf(a); parts[i].vy = 3.0f*sinf(a);
} }
if (t==PT_PHOT)
photons[y][x] = t|(i<<8);
if (t==PT_STKM) if (t==PT_STKM)
{ {
if (isplayer==0) if (isplayer==0)
{
if (pmap[y][x]&0xFF==PT_SPAWN)
{
parts[pmap[y][x]>>8].type = PT_STKM;
parts[pmap[y][x]>>8].vx = 0;
parts[pmap[y][x]>>8].vy = 0;
parts[pmap[y][x]>>8].life = 100;
parts[pmap[y][x]>>8].ctype = 0;
parts[pmap[y][x]>>8].temp = ptypes[t].heat;
}
else
{ {
parts[i].x = (float)x; parts[i].x = (float)x;
parts[i].y = (float)y; parts[i].y = (float)y;
@ -764,9 +766,6 @@ inline int create_part(int p, int x, int y, int t)
parts[i].life = 100; parts[i].life = 100;
parts[i].ctype = 0; parts[i].ctype = 0;
parts[i].temp = ptypes[t].heat; parts[i].temp = ptypes[t].heat;
}
player[3] = x-1; //Setting legs positions player[3] = x-1; //Setting legs positions
player[4] = y+6; player[4] = y+6;
@ -794,25 +793,12 @@ inline int create_part(int p, int x, int y, int t)
{ {
return -1; return -1;
} }
//kill_part(playerspawn);
create_part(-1,x,y,PT_SPAWN); create_part(-1,x,y,PT_SPAWN);
ISSPAWN1 = 1; ISSPAWN1 = 1;
} }
if (t==PT_STKM2) if (t==PT_STKM2)
{ {
if (isplayer2==0) if (isplayer2==0)
{
if (pmap[y][x]&0xFF==PT_SPAWN2)
{
parts[pmap[y][x]>>8].type = PT_STKM2;
parts[pmap[y][x]>>8].vx = 0;
parts[pmap[y][x]>>8].vy = 0;
parts[pmap[y][x]>>8].life = 100;
parts[pmap[y][x]>>8].ctype = 0;
parts[pmap[y][x]>>8].temp = ptypes[t].heat;
}
else
{ {
parts[i].x = (float)x; parts[i].x = (float)x;
parts[i].y = (float)y; parts[i].y = (float)y;
@ -822,9 +808,6 @@ inline int create_part(int p, int x, int y, int t)
parts[i].life = 100; parts[i].life = 100;
parts[i].ctype = 0; parts[i].ctype = 0;
parts[i].temp = ptypes[t].heat; parts[i].temp = ptypes[t].heat;
}
player2[3] = x-1; //Setting legs positions player2[3] = x-1; //Setting legs positions
player2[4] = y+6; player2[4] = y+6;
@ -852,13 +835,14 @@ inline int create_part(int p, int x, int y, int t)
{ {
return -1; return -1;
} }
//kill_part(player2spawn);
create_part(-1,x,y,PT_SPAWN2); create_part(-1,x,y,PT_SPAWN2);
ISSPAWN2 = 1; ISSPAWN2 = 1;
} }
if (t==PT_BIZR||t==PT_BIZRG) if (t==PT_BIZR||t==PT_BIZRG)
parts[i].ctype = 0x47FFFF; parts[i].ctype = 0x47FFFF;
if (t!=PT_STKM&&t!=PT_STKM2 && t!=PT_PHOT)// && t!=PT_NEUT) is this needed? it breaks floodfill, Yes photons should not be placed in the PMAP if (t==PT_PHOT||t==PT_NEUT)
photons[y][x] = t|(i<<8);
if (t!=PT_STKM&&t!=PT_STKM2 && t!=PT_PHOT && t!=PT_NEUT) // is this needed? it breaks floodfill, Yes photons should not be placed in the PMAP
pmap[y][x] = t|(i<<8); pmap[y][x] = t|(i<<8);
return i; return i;
@ -1342,7 +1326,7 @@ void update_particles_i(pixel *vid, int start, int inc)
{ {
r = pmap[ny][nx]; r = pmap[ny][nx];
neighbors = gol2[nx][ny][0]; neighbors = gol2[nx][ny][0];
if(neighbors==0 || !(ptypes[r&0xFF].properties&PROP_LIFE || !r&0xFF) || (r>>8)>=NPART) if(neighbors==0 || !(ptypes[r&0xFF].properties&PROP_LIFE || !(r&0xFF)) || (r>>8)>=NPART)
continue; continue;
for ( golnum = 1; golnum<=NGOL; golnum++) for ( golnum = 1; golnum<=NGOL; golnum++)
for ( goldelete = 0; goldelete<9; goldelete++) for ( goldelete = 0; goldelete<9; goldelete++)
@ -2054,13 +2038,13 @@ killed:
if (ny!=y || nx!=x) if (ny!=y || nx!=x)
{ {
if ((pmap[y][x]>>8)==i) pmap[y][x] = 0; if ((pmap[y][x]>>8)==i) pmap[y][x] = 0;
else if (t==PT_PHOT&&(photons[y][x]>>8)==i) photons[y][x] = 0; else if ((photons[y][x]>>8)==i) photons[y][x] = 0;
if (nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL) if (nx<CELL || nx>=XRES-CELL || ny<CELL || ny>=YRES-CELL)
{ {
kill_part(i); kill_part(i);
continue; continue;
} }
if (t==PT_PHOT) if (t==PT_PHOT||t==PT_NEUT)
photons[ny][nx] = t|(i<<8); photons[ny][nx] = t|(i<<8);
else else
pmap[ny][nx] = t|(i<<8); pmap[ny][nx] = t|(i<<8);
@ -2095,12 +2079,13 @@ void update_particles(pixel *vid)
t = parts[i].type; t = parts[i].type;
x = (int)(parts[i].x+0.5f); x = (int)(parts[i].x+0.5f);
y = (int)(parts[i].y+0.5f); y = (int)(parts[i].y+0.5f);
if (x>=0 && y>=0 && x<XRES && y<YRES && t!=PT_PHOT) { if (x>=0 && y>=0 && x<XRES && y<YRES)
if (t!=PT_NEUT || (pmap[y][x]&0xFF)!=PT_GLAS) {
if (t==PT_PHOT||t==PT_NEUT)
photons[y][x] = t|(i<<8);
else
pmap[y][x] = t|(i<<8); pmap[y][x] = t|(i<<8);
} }
if (t==PT_PHOT)
photons[y][x] = t|(i<<8);
NUM_PARTS ++; NUM_PARTS ++;
} }
else else
@ -2610,90 +2595,6 @@ void update_particles(pixel *vid)
} }
void rotate_area(int area_x, int area_y, int area_w, int area_h, int invert)
{
//TODO: MSCC doesn't like arrays who's size is determined at runtime.
#if !(defined(WIN32) && !defined(__GNUC__))
int cx = 0;
int cy = 0;
unsigned tpmap[area_h][area_w];
unsigned rtpmap[area_w][area_h];
unsigned char tbmap[area_h/CELL][area_w/CELL];
unsigned char rtbmap[area_w/CELL][area_h/CELL];
float tfvy[area_h/CELL][area_w/CELL];
float tfvx[area_h/CELL][area_w/CELL];
for (cy=0; cy<area_h; cy++)
{
for (cx=0; cx<area_w; cx++)//save walls to temp
{
if (area_x + cx<XRES&&area_y + cy<YRES)
{
if (bmap[(cy+area_y)/CELL][(cx+area_x)/CELL]) {
tbmap[cy/CELL][cx/CELL] = bmap[(cy+area_y)/CELL][(cx+area_x)/CELL];
if (bmap[(cy+area_y)/CELL][(cx+area_x)/CELL]==WL_FAN) {
tfvx[cy/CELL][cx/CELL] = fvx[(cy+area_y)/CELL][(cx+area_x)/CELL];
tfvy[cy/CELL][cx/CELL] = fvy[(cy+area_y)/CELL][(cx+area_x)/CELL];
}
} else {
tbmap[cy/CELL][cx/CELL] = 0;
tfvx[cy/CELL][cx/CELL] = 0;
tfvy[cy/CELL][cx/CELL] = 0;
}
}
}
}
for (cy=0; cy<area_h; cy++)
{
for (cx=0; cx<area_w; cx++)//save particles to temp
{
if ((area_x + cx<XRES&&area_y + cy<YRES))
{
tpmap[cy][cx] = pmap[(int)(cy+area_y+0.5f)][(int)(cx+area_x+0.5f)];
}
else
tpmap[(int)(cy+0.5f)][(int)(cx+0.5f)] = 0;
}
}
for (cy=0; cy<area_w; cy++)
{
for (cx=0; cx<area_h; cx++)//rotate temp arrays
{
if (invert)
{
rtbmap[cy/CELL][((area_h-1)-cx)/CELL] = tbmap[cy/CELL][cx/CELL];
rtpmap[cy][(area_h-1)-cx] = tpmap[(int)(cy+0.5f)][(int)(cx+0.5f)];
tfvx[cy/CELL][((area_h-1)-cx)/CELL] = -tfvx[cy/CELL][cx/CELL];
tfvy[cy/CELL][((area_h-1)-cx)/CELL] = tfvy[cy/CELL][cx/CELL];
}
else
{
rtbmap[((area_h-1)-cx)/CELL][cy/CELL] = tbmap[cy/CELL][cx/CELL];
rtpmap[(area_h-1)-cx][cy] = tpmap[(int)(cy+0.5f)][(int)(cx+0.5f)];
tfvy[((area_h-1)-cx)/CELL][cy/CELL] = -tfvx[cy/CELL][cx/CELL];
tfvx[((area_h-1)-cx)/CELL][cy/CELL] = tfvy[cy/CELL][cx/CELL];
}
}
}
for (cy=0; cy<area_w; cy++)
{
for (cx=0; cx<area_h; cx++)//move particles and walls
{
if (area_x + cx<XRES&&area_y + cy<YRES)
{
if ((rtpmap[cy][cx]>>8)<=NPART&&rtpmap[cy][cx])
{
parts[rtpmap[(int)(cy+0.5f)][(int)(cx+0.5f)]>>8].x = area_x +cx;
parts[rtpmap[(int)(cy+0.5f)][(int)(cx+0.5f)]>>8].y = area_y +cy;
}
bmap[(area_y+cy)/CELL][(area_x+cx)/CELL] = rtbmap[cy/CELL][cx/CELL];
fvy[(area_y+cy)/CELL][(area_x+cx)/CELL] = tfvy[cy/CELL][cx/CELL];
fvx[(area_y+cy)/CELL][(area_x+cx)/CELL] = tfvx[cy/CELL][cx/CELL];
}
}
}
#endif
}
void clear_area(int area_x, int area_y, int area_w, int area_h) void clear_area(int area_x, int area_y, int area_w, int area_h)
{ {
int cx = 0; int cx = 0;
@ -2731,14 +2632,10 @@ void create_box(int x1, int y1, int x2, int y2, int c)
int flood_parts(int x, int y, int c, int cm, int bm) int flood_parts(int x, int y, int c, int cm, int bm)
{ {
int x1, x2, dy = (c<PT_NUM)?1:CELL; int x1, x2, dy = (c<PT_NUM)?1:CELL;
int co = c, wall; int co = c;
if (cm==PT_INST&&co==PT_SPRK) if (cm==PT_INST&&co==PT_SPRK)
if ((pmap[y][x]&0xFF)==PT_SPRK) if ((pmap[y][x]&0xFF)==PT_SPRK)
return 0; return 0;
if (c>=UI_WALLSTART&&c<=UI_WALLSTART+UI_WALLCOUNT)
{
wall = c-100;
}
if (cm==-1) if (cm==-1)
{ {
if (c==0) if (c==0)
@ -2754,7 +2651,7 @@ int flood_parts(int x, int y, int c, int cm, int bm)
} }
if (bm==-1) if (bm==-1)
{ {
if (wall==WL_ERASE) if (c-UI_WALLSTART+UI_ACTUALSTART==WL_ERASE)
{ {
bm = bmap[y/CELL][x/CELL]; bm = bmap[y/CELL][x/CELL];
if (!bm) if (!bm)
@ -3073,3 +2970,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;
}