diff -urN powder-42.3/air.c powder-42.4/air.c --- powder-42.3/air.c 2010-09-03 10:20:00.000000000 -0400 +++ powder-42.4/air.c 2010-10-02 08:05:31.000000000 -0400 @@ -138,4 +138,4 @@ memcpy(vx, ovx, sizeof(vx)); memcpy(vy, ovy, sizeof(vy)); memcpy(pv, opv, sizeof(pv)); -} \ No newline at end of file +} diff -urN powder-42.3/air.h powder-42.4/air.h --- powder-42.3/air.h 2010-09-03 10:20:00.000000000 -0400 +++ powder-42.4/air.h 2010-10-02 08:05:26.000000000 -0400 @@ -18,4 +18,4 @@ void update_air(void); -#endif \ No newline at end of file +#endif diff -urN powder-42.3/defines.h powder-42.4/defines.h --- powder-42.3/defines.h 2010-09-22 15:07:00.000000000 -0400 +++ powder-42.4/defines.h 2010-10-02 10:18:19.000000000 -0400 @@ -8,8 +8,8 @@ #endif #define SAVE_VERSION 42 -#define MINOR_VERSION 3 -#define IDENT_VERSION "S" //Change this if you're not Simon! It should be a single letter. +#define MINOR_VERSION 4 +#define IDENT_VERSION "$" //Change this if you're not Simon! It should be a single letter. //#define BETA #define SERVER "powdertoy.co.uk" @@ -115,4 +115,4 @@ int parse_save(void *save, int size, int replace, int x0, int y0); void del_stamp(int d); void sdl_seticon(void); -#endif \ No newline at end of file +#endif diff -urN powder-42.3/font.h powder-42.4/font.h --- powder-42.3/font.h 2010-09-03 10:20:00.000000000 -0400 +++ powder-42.4/font.h 2010-10-02 08:10:42.000000000 -0400 @@ -21,5 +21,6 @@ #ifndef FONT_H_CHECK #define FONT_H_CHECK #define FONT_H 10 +#ifdef INCLUDE_FONTDATA static char font_data[] = { @@ -31,2 +32,3 @@ { -#endif \ No newline at end of file +#endif +#endif diff -urN powder-42.3/graphics.c powder-42.4/graphics.c --- powder-42.3/graphics.c 2010-09-22 14:05:00.000000000 -0400 +++ powder-42.4/graphics.c 2010-10-02 08:10:38.000000000 -0400 @@ -16,6 +16,7 @@ #include "air.h" #include "powder.h" #include "graphics.h" +#define INCLUDE_FONTDATA #include "font.h" #include "misc.h" diff -urN powder-42.3/interface.c powder-42.4/interface.c --- powder-42.3/interface.c 2010-09-22 14:05:00.000000000 -0400 +++ powder-42.4/interface.c 2010-10-02 08:10:56.000000000 -0400 @@ -6,10 +6,10 @@ #include #include "http.h" #include "md5.h" -#include "font.h" #include "defines.h" #include "powder.h" #include "interface.h" +#include "font.h" #include "misc.h" SDLMod sdl_mod; @@ -2958,4 +2958,4 @@ if(result) free(result); return 1; -} \ No newline at end of file +} diff -urN powder-42.3/main.c powder-42.4/main.c --- powder-42.3/main.c 2010-09-22 15:04:00.000000000 -0400 +++ powder-42.4/main.c 2010-10-02 10:14:46.000000000 -0400 @@ -38,7 +38,6 @@ #endif #include "misc.h" -#include "font.h" #include "defines.h" #include "powder.h" #include "graphics.h" @@ -1302,7 +1301,7 @@ if(sdl_key=='h') hud_enable = !hud_enable; if(sdl_key=='p') - dump_frame(vid_buf, XRES, YRES, XRES); + dump_frame(vid_buf, XRES, YRES, XRES+BARSIZE); if(sdl_key=='v'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL))) { if(clipboard_ready==1) @@ -1361,7 +1360,7 @@ if(sdl_key=='v') vs = !vs; if(vs) - dump_frame(vid_buf, XRES, YRES, XRES); + dump_frame(vid_buf, XRES, YRES, XRES+BARSIZE); #endif if(sdl_wheel) diff -urN powder-42.3/misc.c powder-42.4/misc.c --- powder-42.3/misc.c 2010-09-22 14:05:00.000000000 -0400 +++ powder-42.4/misc.c 2010-10-02 08:05:12.000000000 -0400 @@ -280,4 +280,4 @@ #endif #endif return 0; -} \ No newline at end of file +} diff -urN powder-42.3/misc.h powder-42.4/misc.h --- powder-42.3/misc.h 2010-09-22 14:05:00.000000000 -0400 +++ powder-42.4/misc.h 2010-10-02 08:05:47.000000000 -0400 @@ -69,4 +69,4 @@ int cpu_check(void); -#endif \ No newline at end of file +#endif diff -urN powder-42.3/powder.c powder-42.4/powder.c --- powder-42.3/powder.c 2010-09-22 14:05:00.000000000 -0400 +++ powder-42.4/powder.c 2010-10-02 10:07:00.000000000 -0400 @@ -21,80 +21,96 @@ unsigned pmap[YRES][XRES]; unsigned cb_pmap[YRES][XRES]; -int try_move(int i, int x, int y, int nx, int ny) +static int eval_move(int pt, int nx, int ny, unsigned *rr) { unsigned r; - if(nx<0 || ny<0 || nx>=XRES || ny>=YRES) return 0; - if(x==nx && y==ny) - return 1; + r = pmap[ny][nx]; if(r && (r>>8)>8].type; + if(rr) + *rr = r; + + if(pt==PT_PHOT&&((r&0xFF)==PT_GLAS||(r&0xFF)==PT_PHOT||(r&0xFF)==PT_CLNE||((r&0xFF)==PT_LCRY&&parts[r>>8].life > 5))) + return 2; - if(parts[i].type==PT_PHOT&&((r&0xFF)==PT_GLAS||(r&0xFF)==PT_PHOT||(r&0xFF)==PT_CLNE||((r&0xFF)==PT_LCRY&&parts[r>>8].life > 5))) + if(pt==PT_STKM) //Stick man's head shouldn't collide { - return 1; + return 2; } - if((r&0xFF)==PT_VOID) + if(bmap[ny/CELL][nx/CELL]==13 && ptypes[pt].falldown!=0 && pt!=PT_FIRE && pt!=PT_SMKE) { - parts[i].type=PT_NONE; return 0; } - if((r&0xFF)==PT_BHOL) - { - parts[i].type=PT_NONE; - if(!legacy_enable) - { - parts[r>>8].temp = restrict_flt(parts[r>>8].temp+parts[i].temp/2, MIN_TEMP, MAX_TEMP);//3.0f; - } + + if(ptypes[pt].falldown!=2 && bmap[ny/CELL][nx/CELL]==3) return 0; - } - if(parts[i].type==PT_STKM) //Stick man's head shouldn't collide - { + if((pt==PT_NEUT ||pt==PT_PHOT) && bmap[ny/CELL][nx/CELL]==7 && !emap[ny/CELL][nx/CELL]) + return 0; + + if(bmap[ny/CELL][nx/CELL]==9) + return 0; + + if(ptypes[pt].falldown!=1 && bmap[ny/CELL][nx/CELL]==10) + return 0; + + if (r && ((r&0xFF) >= PT_NUM || !can_move[pt][(r&0xFF)])) + return 0; + + return 1; +} + +int try_move(int i, int x, int y, int nx, int ny) +{ + unsigned r, e; + + if(x==nx && y==ny) return 1; - } + + e = eval_move(parts[i].type, nx, ny, &r); + if(!e) + return 0; + if(e == 2) + return 1; if(bmap[ny/CELL][nx/CELL]==12 && !emap[y/CELL][x/CELL]) { return 1; } - if(bmap[ny/CELL][nx/CELL]==13 && ptypes[parts[i].type].falldown!=0 && parts[i].type!=PT_FIRE && parts[i].type!=PT_SMKE) - { - return 0; - } if((bmap[y/CELL][x/CELL]==12 && !emap[y/CELL][x/CELL]) && (bmap[ny/CELL][nx/CELL]!=12 && !emap[ny/CELL][nx/CELL])) { return 0; } - - if(ptypes[parts[i].type].falldown!=2 && bmap[ny/CELL][nx/CELL]==3) - return 0; - if((parts[i].type==PT_NEUT ||parts[i].type==PT_PHOT) && bmap[ny/CELL][nx/CELL]==7 && !emap[ny/CELL][nx/CELL]) - return 0; if(r && (r>>8)= PT_NUM || !can_move[parts[i].type][(r&0xFF)])) + if((r&0xFF)==PT_BHOL) + { + parts[i].type=PT_NONE; + if(!legacy_enable) + { + parts[r>>8].temp = restrict_flt(parts[r>>8].temp+parts[i].temp/2, MIN_TEMP, MAX_TEMP);//3.0f; + } return 0; + } if(parts[i].type==PT_CNCT && y>8)>= 8; @@ -456,10 +472,147 @@ return id; } +#define SURF_RANGE 10 +#define NORMAL_MIN_EST 3 +#define NORMAL_INTERP 20 +#define NORMAL_FRAC 16 + +static unsigned direction_to_map(float dx, float dy) +{ + return (dx >= 0) | + (((dx + dy) >= 0) << 1) | /* 567 */ + ((dy >= 0) << 2) | /* 4+0 */ + (((dy - dx) >= 0) << 3) | /* 321 */ + ((dx <= 0) << 4) | + (((dx + dy) <= 0) << 5) | + ((dy <= 0) << 6) | + (((dy - dx) <= 0) << 7); +} + +static int is_blocking(int t, int x, int y) +{ + return eval_move(t, x, y, NULL); +} + +static int is_boundary(int pt, int x, int y) +{ + if(!is_blocking(pt,x,y)) + return 0; + if(is_blocking(pt,x,y-1) && is_blocking(pt,x,y+1) && is_blocking(pt,x-1,y) && is_blocking(pt,x+1,y)) + return 0; + return 1; +} + +static int find_next_boundary(int pt, int *x, int *y, int dm, int *em) +{ + static int dx[8] = {1,1,0,-1,-1,-1,0,1}; + static int dy[8] = {0,1,1,1,0,-1,-1,-1}; + static int de[8] = {0x83,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC1}; + int i, ii, i0; + + if(*x <= 0 || *x >= XRES-1 || *y <= 0 || *y >= YRES-1) + return 0; + + if(*em != -1) { + i0 = *em; + dm &= de[i0]; + } else + i0 = 0; + + for(ii=0; ii<8; ii++) { + i = (ii + i0) & 7; + if((dm & (1 << i)) && is_boundary(pt, *x+dx[i], *y+dy[i])) { + *x += dx[i]; + *y += dy[i]; + *em = i; + return 1; + } + } + + return 0; +} + +static int vec_colinear(float nx, float ny, float vx, float vy) +{ + float d = 1.0f/hypot(vx, vy); + d *= nx*vx + ny*vy; + return (d >= 0.99) || (d <= -0.99); +} + +int get_normal(int pt, int x, int y, float dx, float dy, float *nx, float *ny) +{ + int ldm, rdm, lm, rm; + int lx, ly, lv, rx, ry, rv; + int i, j; + float r, ex, ey; + + if(!dx && !dy) + return 0; + + if(!is_boundary(pt, x, y)) + return 0; + + ldm = direction_to_map(-dy, dx); + rdm = direction_to_map(dy, -dx); + lx = rx = x; + ly = ry = y; + lv = rv = 1; + lm = rm = -1; + + j = 0; + for(i=0; i= NORMAL_INTERP) + return 0; + + return get_normal(pt, x, y, dx, dy, nx, ny); +} + void update_particles_i(pixel *vid, int start, int inc) { int i, j, x, y, t, nx, ny, r, a, s, rt, fe, nt, lpv, nearp, pavg; - float mv, dx, dy, ix, iy, lx, ly, d, pp; + float mv, dx, dy, ix, iy, lx, ly, d, pp, nrx, nry, dp; float pt = R_TEMP; float c_heat = 0.0f; int h_count = 0; @@ -886,7 +1039,7 @@ r = pmap[y+ny][x+nx]; if((r>>8)>=NPART || !r) continue; - if(((r&0xFF)==PT_METL || (r&0xFF)==PT_ETRD || (r&0xFF)==PT_PSCN || (r&0xFF)==PT_NSCN || (r&0xFF)==PT_NTCT || (r&0xFF)==PT_PTCT || (r&0xFF)==PT_BMTL || (r&0xFF)==PT_RBDM || (r&0xFF)==PT_LRBD || (r&0xFF)==PT_BRMT||(r&0xFF)==PT_NBLE) || (r&0xFF)==PT_INWR && parts[r>>8].ctype!=PT_SPRK ) + if(((r&0xFF)==PT_METL || (r&0xFF)==PT_ETRD || (r&0xFF)==PT_PSCN || (r&0xFF)==PT_NSCN || (r&0xFF)==PT_NTCT || (r&0xFF)==PT_PTCT || (r&0xFF)==PT_BMTL || (r&0xFF)==PT_RBDM || (r&0xFF)==PT_LRBD || (r&0xFF)==PT_BRMT||(r&0xFF)==PT_NBLE) || (r&0xFF)==PT_INWR && parts[r>>8].ctype!=PT_SPRK) { t = parts[i].type = PT_NONE; parts[r>>8].ctype = parts[r>>8].type; @@ -2075,32 +2228,55 @@ else { parts[i].flags |= FLAG_STAGNANT; - if(nx>x+ISTP) nx=x+ISTP; - if(nxy+ISTP) ny=y+ISTP; - if(ny(rand()%1000)) { kill_part(i); continue; } - else if(try_move(i, x, y, 2*x-nx, ny)) - { - parts[i].x = (float)(2*x-nx); - parts[i].y = (float)iy; - parts[i].vx *= ptypes[t].collision; - } - else if(try_move(i, x, y, nx, 2*y-ny)) - { - parts[i].x = (float)ix; - parts[i].y = (float)(2*y-ny); - parts[i].vy *= ptypes[t].collision; - } - else - { - parts[i].vx *= ptypes[t].collision; - parts[i].vy *= ptypes[t].collision; - } + else if(t==PT_NEUT || t==PT_PHOT) + { + if(get_normal_interp(t, lx, ly, parts[i].vx, parts[i].vy, &nrx, &nry)) { + dp = nrx*parts[i].vx + nry*parts[i].vy; + parts[i].vx -= 2.0f*dp*nrx; + parts[i].vy -= 2.0f*dp*nry; + nx = (int)(parts[i].x + parts[i].vx + 0.5f); + ny = (int)(parts[i].y + parts[i].vy + 0.5f); + if(try_move(i, x, y, nx, ny)) { + parts[i].x = (float)nx; + parts[i].y = (float)ny; + } else { + kill_part(i); + continue; + } + } else { + kill_part(i); + continue; + } + } + else + { + if(nx>x+ISTP) nx=x+ISTP; + if(nxy+ISTP) ny=y+ISTP; + if(ny=XRES-CELL || ny=YRES-CELL) Binary files powder-42.3/powder.def and powder-42.4/powder.def differ