diff options
| author | Simon <simon@hardwired.org.uk> | 2010-10-03 13:56:30 (GMT) |
|---|---|---|
| committer | Simon <simon@hardwired.org.uk> | 2010-10-03 13:56:30 (GMT) |
| commit | 5591a7346cd11b2d45cb80e37526714741be5842 (patch) | |
| tree | c48e9e66afcacbb174139ea664fa1749349c03f7 /src | |
| parent | d80f3e346b493c46855442609f1c3962af13be3a (diff) | |
| download | powder-5591a7346cd11b2d45cb80e37526714741be5842.zip powder-5591a7346cd11b2d45cb80e37526714741be5842.tar.gz | |
Firework improvements and Fire changes
Diffstat (limited to 'src')
| -rw-r--r-- | src/graphics.c | 69 | ||||
| -rw-r--r-- | src/powder.c | 178 |
2 files changed, 200 insertions, 47 deletions
diff --git a/src/graphics.c b/src/graphics.c index 08798dc..2c9a686 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1417,10 +1417,23 @@ void draw_parts(pixel *vid) { if(cmode == 3||cmode==4 || cmode==6) { - vid[ny*(XRES+BARSIZE)+nx] = ptypes[t].pcolors; - cg = 12; - cb = 12; - cr = 12; + cg = 0; + cb = 0; + cr = 0; + for(x=0; x<12; x++) { + cr += (parts[i].ctype >> (x+18)) & 1; + cb += (parts[i].ctype >> x) & 1; + } + for(x=0; x<14; x++) + cg += (parts[i].ctype >> (x+9)) & 1; + x = 624/(cr+cg+cb+1); + cr *= x; + cg *= x; + cb *= x; + vid[ny*(XRES+BARSIZE)+nx] = PIXRGB(cr>255?255:cr,cg>255?255:cg,cb>255?255:cb); + cr >>= 4; + cg >>= 4; + cb >>= 4; x = nx/CELL; y = ny/CELL; cg += fire_g[y][x]; @@ -1828,9 +1841,9 @@ void draw_parts(pixel *vid) blendpixel(vid, nx+1, ny+1, cr, cg, cb, 32); blendpixel(vid, nx-1, ny-1, cr, cg, cb, 32); } - } else if(t==PT_FIRW&&parts[i].tmp==3) + } else if(t==PT_FIRW&&parts[i].tmp>=3) { - float ttemp = (float)parts[i].life; + float ttemp = (float)parts[i].tmp-4; int caddress = restrict_flt(restrict_flt(ttemp, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); uint8 R = firw_data[caddress]; uint8 G = firw_data[caddress+1]; @@ -1870,7 +1883,45 @@ void draw_parts(pixel *vid) } else if(t==PT_FIRE && parts[i].life) { - if(cmode == 3||cmode==4 || cmode==6) + float ttemp = (float)parts[i].life; + int caddress = restrict_flt(restrict_flt(ttemp, 0.0f, 200.0f)*3, 0.0f, (200.0f*3)-3); + uint8 R = flm_data[caddress]; + uint8 G = flm_data[caddress+1]; + uint8 B = flm_data[caddress+2]; + if(cmode == 3||cmode==4 || cmode==6) + { + cr = R/8; + cg = G/8; + cb = B/8; + x = nx/CELL; + y = ny/CELL; + cg += fire_g[y][x]; + if(cg > 255) cg = 255; + fire_g[y][x] = cg; + cb += fire_b[y][x]; + if(cb > 255) cb = 255; + fire_b[y][x] = cb; + cr += fire_r[y][x]; + if(cr > 255) cr = 255; + fire_r[y][x] = cr; + } + else + { + cr = R; + cg = G; + cb = B; + blendpixel(vid, nx, ny, cr, cg, cb, 192); + blendpixel(vid, nx+1, ny, cr, cg, cb, 96); + blendpixel(vid, nx-1, ny, cr, cg, cb, 96); + blendpixel(vid, nx, ny+1, cr, cg, cb, 96); + blendpixel(vid, nx, ny-1, cr, cg, cb, 96); + blendpixel(vid, nx+1, ny-1, cr, cg, cb, 32); + blendpixel(vid, nx-1, ny+1, cr, cg, cb, 32); + blendpixel(vid, nx+1, ny+1, cr, cg, cb, 32); + blendpixel(vid, nx-1, ny-1, cr, cg, cb, 32); + } + // Older Code + /*if(cmode == 3||cmode==4 || cmode==6) { cr = parts[i].life / 4; cg = parts[i].life / 16; @@ -1907,7 +1958,7 @@ void draw_parts(pixel *vid) blendpixel(vid, nx-1, ny+1, cr, cg, cb, 32); blendpixel(vid, nx+1, ny+1, cr, cg, cb, 32); blendpixel(vid, nx-1, ny-1, cr, cg, cb, 32); - } + }*/ } else if(t==PT_LAVA && parts[i].life) { @@ -1976,7 +2027,7 @@ void draw_parts(pixel *vid) else { float ttemp = parts[i].temp+(-MIN_TEMP); - int caddress = restrict_flt((int)( restrict_flt(ttemp, 0.0f, MAX_TEMP+(-MIN_TEMP)) / ((MAX_TEMP+(-MIN_TEMP))/512) ) *3, 0.0f, (512.0f*3)-3); + int caddress = restrict_flt((int)( restrict_flt(ttemp, 0.0f, MAX_TEMP+(-MIN_TEMP)) / ((MAX_TEMP+(-MIN_TEMP))/1024) ) *3, 0.0f, (1024.0f*3)-3); uint8 R = color_data[caddress]; uint8 G = color_data[caddress+1]; uint8 B = color_data[caddress+2]; diff --git a/src/powder.c b/src/powder.c index cdad9b0..0bccf8f 100644 --- a/src/powder.c +++ b/src/powder.c @@ -35,6 +35,13 @@ static int eval_move(int pt, int nx, int ny, unsigned *rr) r = (r&~0xFF) | parts[r>>8].type; if(rr) *rr = r; + + if((r&0xFF)==PT_VOID || (r&0xFF)==PT_BHOL) + return 1; + + if(pt==PT_NEUT && (r&0xFF)==PT_GLAS) + return 2; + if(pt==PT_PHOT&&( (r&0xFF)==PT_GLAS || (r&0xFF)==PT_PHOT || (r&0xFF)==PT_CLNE || (r&0xFF)==PT_PCLN || @@ -65,6 +72,9 @@ static int eval_move(int pt, int nx, int ny, unsigned *rr) return 2; return 1; } + +static void create_cherenkov_photon(int pp); + int try_move(int i, int x, int y, int nx, int ny) { unsigned r, e; @@ -81,16 +91,13 @@ int try_move(int i, int x, int y, int nx, int ny) } return 0; } - if(e == 2) + if(e == 2) { + if(parts[i].type == PT_NEUT && (r&0xFF)==PT_GLAS) { + if(rand() < RAND_MAX/10) + create_cherenkov_photon(i); + } return 1; - - if(bmap[ny/CELL][nx/CELL]==12 && !emap[y/CELL][x/CELL]) - return 1; - 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(r && (r>>8)<NPART && ptypes[r&0xFF].falldown!=2 && bmap[y/CELL][x/CELL]==3) - return 0; + } if((r&0xFF)==PT_VOID) { @@ -110,6 +117,14 @@ int try_move(int i, int x, int y, int nx, int ny) if(parts[i].type==PT_CNCT && y<ny && (pmap[y+1][x]&0xFF)==PT_CNCT) return 0; + if(bmap[ny/CELL][nx/CELL]==12 && !emap[y/CELL][x/CELL]) + return 1; + 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(r && (r>>8)<NPART && ptypes[r&0xFF].falldown!=2 && bmap[y/CELL][x/CELL]==3) + return 0; + pmap[ny][nx] = (i<<8)|parts[i].type; pmap[y][x] = r; @@ -436,27 +451,14 @@ inline int create_part(int p, int x, int y, int t) } if(t==PT_PHOT) { - float r = (rand()%3-1)*3; - float a = (rand()%3-1)*3; + float a = (rand()%8) * 0.78540f; parts[i].life = 680; - if(a==0.0f&&r==0.0f) - { - parts[i].life = 0; - parts[i].type = PT_NONE; - return -1; - } - else - { - parts[i].vx = a; - parts[i].vy = r; - } - //} else { - // parts[i].life = 0; - // parts[i].type = PT_NONE; - //}/ + parts[i].ctype = 0x3FFFFFFF; + parts[i].vx = 3.0f*cosf(a); + parts[i].vy = 3.0f*sinf(a); } - if(t!=PT_STKM && t!=PT_PHOT) + if(t!=PT_STKM && t!=PT_PHOT && t!=PT_NEUT) pmap[y][x] = t|(i<<8); else if(t==PT_STKM) { @@ -500,6 +502,49 @@ inline int create_part(int p, int x, int y, int t) return i; } +static void create_cherenkov_photon(int pp) +{ + int i, lr, nx, ny; + float r; + + if(pfree == -1) + return; + i = pfree; + + nx = (int)(parts[pp].x + 0.5f); + ny = (int)(parts[pp].y + 0.5f); + if((pmap[ny][nx] & 0xFF) != PT_GLAS) + return; + + if(hypotf(parts[pp].vx, parts[pp].vy) < 1.44f) + return; + + pfree = parts[i].life; + + lr = rand() % 2; + + parts[i].type = PT_PHOT; + parts[i].ctype = 0x00000F80; + parts[i].life = 680; + parts[i].x = parts[pp].x; + parts[i].y = parts[pp].y; + parts[i].temp = parts[pp].temp; + parts[i].tmp = 0; + + if(lr) { + parts[i].vx = parts[pp].vx - 2.5f*parts[pp].vy; + parts[i].vy = parts[pp].vy + 2.5f*parts[pp].vx; + } else { + parts[i].vx = parts[pp].vx + 2.5f*parts[pp].vy; + parts[i].vy = parts[pp].vy - 2.5f*parts[pp].vx; + } + + /* photons have speed of light. no discussion. */ + r = 1.44f / hypotf(parts[i].vx, parts[i].vy); + parts[i].vx *= r; + parts[i].vy *= r; +} + #ifdef WIN32 _inline void delete_part(int x, int y) #else @@ -536,6 +581,31 @@ inline int is_wire_off(int x, int y) return (bmap[y][x]==6 || bmap[y][x]==7 || bmap[y][x]==3 || bmap[y][x]==8 || bmap[y][x]==11 || bmap[y][x]==12) && emap[y][x]<8; } +int get_wavelength_bin(int *wm) +{ + int i, w0=30, wM=0; + + if(!*wm) + return -1; + + for(i=0; i<30; i++) + if(*wm & (1<<i)) { + if(i < w0) + w0 = i; + if(i > wM) + wM = i; + } + + if(wM-w0 < 5) + return (wM+w0)/2; + + i = rand() % (wM-w0-3); + i += w0; + + *wm &= 0x1F << i; + return i + 2; +} + void set_emap(int x, int y) { int x1, x2; @@ -1692,7 +1762,7 @@ void update_particles_i(pixel *vid, int start, int inc) if(rt==PT_FIRE||rt==PT_PLSM||rt==PT_THDR) { parts[i].tmp = 1; - parts[i].life = rand()%50+120; + parts[i].life = rand()%50+60; } } } @@ -1700,7 +1770,7 @@ void update_particles_i(pixel *vid, int start, int inc) if(parts[i].life==0) { parts[i].tmp=2; } else { - float newVel = parts[i].life/50; + float newVel = parts[i].life/25; parts[i].flags = parts[i].flags&0xFFFFFFFE; if((pmap[(int)(ly-newVel)][(int)lx]&0xFF)==PT_NONE) { parts[i].vy = -newVel; @@ -1710,6 +1780,7 @@ void update_particles_i(pixel *vid, int start, int inc) } } else if(parts[i].tmp==2) { + int col = rand()%200+4; for(nx=-2; nx<3; nx++) { for(ny=-2; ny<3; ny++) { if(x+nx>=0 && y+ny>0 && x+nx<XRES && y+ny<YRES && (nx || ny)) @@ -1722,7 +1793,7 @@ void update_particles_i(pixel *vid, int start, int inc) if(parts[r>>8].type==PT_FIRW) { parts[r>>8].vx = (rand()%3-1)*tmul; parts[r>>8].vy = (rand()%3-1)*tmul; - parts[r>>8].tmp = 3; + parts[r>>8].tmp = col; parts[r>>8].life = rand()%100+100; parts[r>>8].temp = 6000.0f; } @@ -1731,7 +1802,7 @@ void update_particles_i(pixel *vid, int start, int inc) } pv[y/CELL][x/CELL] += 20; kill_part(i); - } else if(parts[i].tmp==3) { + } else if(parts[i].tmp>=3) { if(parts[i].life<=0) { kill_part(i); } @@ -2444,17 +2515,25 @@ killed: lt = pmap[y][x] & 0xFF; - if((rt==PT_GLAS && lt!=PT_GLAS) || (rt!=PT_GLAS && lt==PT_GLAS)) { + r = eval_move(PT_PHOT, nx, ny, NULL); + + if(((rt==PT_GLAS && lt!=PT_GLAS) || (rt!=PT_GLAS && lt==PT_GLAS)) && r) { if(!get_normal_interp(REFRACT|parts[i].type, x, y, parts[i].vx, parts[i].vy, &nrx, &nry)) { kill_part(i); continue; } + + r = get_wavelength_bin(&parts[i].ctype); + if(r == -1) { + kill_part(i); + continue; + } + nn = 2.3f - 0.02f*r; + nrx = -nrx; nry = -nry; - if(rt!=PT_GLAS && lt==PT_GLAS) - nn = 2.0; - else - nn = 0.5; + if(rt==PT_GLAS && lt!=PT_GLAS) + nn = 1.0f/nn; ct1 = parts[i].vx*nrx + parts[i].vy*nry; ct2 = 1.0f - (nn*nn)*(1.0f-(ct1*ct1)); if(ct2 < 0.0f) { @@ -2589,6 +2668,27 @@ killed: } else if(t==PT_NEUT || t==PT_PHOT) { + r = pmap[ny][nx]; + + /* this should be replaced with a particle type attribute ("photwl" or something) */ + if((r & 0xFF) == PT_COAL) parts[i].ctype = 0x00000000; + if((r & 0xFF) == PT_PLEX) parts[i].ctype &= 0x1F00003E; + if((r & 0xFF) == PT_NITR) parts[i].ctype &= 0x0007C000; + if((r & 0xFF) == PT_NBLE) parts[i].ctype &= 0x3FFF8000; + if((r & 0xFF) == PT_LAVA) parts[i].ctype &= 0x3FF00000; + if((r & 0xFF) == PT_ACID) parts[i].ctype &= 0x1FE001FE; + if((r & 0xFF) == PT_DUST) parts[i].ctype &= 0x3FFFFFC0; + if((r & 0xFF) == PT_SNOW) parts[i].ctype &= 0x03FFFFFF; + if((r & 0xFF) == PT_GOO) parts[i].ctype &= 0x3FFAAA00; + if((r & 0xFF) == PT_PLNT) parts[i].ctype &= 0x0007C000; + if((r & 0xFF) == PT_PLUT) parts[i].ctype &= 0x001FCE00; + if((r & 0xFF) == PT_URAN) parts[i].ctype &= 0x003FC000; + + if(!parts[i].ctype) { + kill_part(i); + continue; + } + 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; @@ -2666,8 +2766,10 @@ void update_particles(pixel *vid) t = parts[i].type; x = (int)(parts[i].x+0.5f); y = (int)(parts[i].y+0.5f); - if(x>=0 && y>=0 && x<XRES && y<YRES && parts[i].type!=PT_PHOT) - pmap[y][x] = t|(i<<8); + if(x>=0 && y>=0 && x<XRES && y<YRES && parts[i].type!=PT_PHOT) { + if(parts[i].type!=PT_NEUT || (pmap[y][x]&0xFF)!=PT_GLAS) + pmap[y][x] = t|(i<<8); + } } else { |
