1
Fork 0
firetexture_m/zscript/firetexture_m/ft_pixel.zsc

153 lines
4.4 KiB
Text

// raw pixel data handling
extend class FireTexture
{
private Canvas cv; // where to blit the data to
private uint width, height; // the expected width and height of this texture
// (can't be greater than 256x256)
private uint umask, vmask; // used for wrapping texture coordinates
private Color pal[256]; // loaded palette
private uint8 pixels[65536]; // internal texture data
private bool brising; // heat is propagated upwards
private int renderheat; // overall intensity
// direct pixel access wrapper functions
// not used by the Calc code, would reduce performance
private uint GetPixel( uint x, uint y )
{
// ensure coords are wrapped
x &= umask;
y &= vmask;
return pixels[x+y*width];
}
private void PutPixel( uint x, uint y, uint c )
{
// ensure coords are wrapped
x &= umask;
y &= vmask;
pixels[x+y*width] = c;
}
// heat propagation with bRising (triangle shifted two pixels down)
private void CalcWrapFire()
{
uint mid, left, right, up;
uint y;
for ( y=0; y<height-2; y++ )
{
mid = pixels[(y+1)*width];
left = pixels[(width-1)+(y+1)*width];
right = pixels[1+(y+1)*width];
up = pixels[(y+2)*width];
pixels[y*width] = firetable[mid+left+right+up];
for ( uint x=1; x<width-1; x++ )
{
mid = pixels[x+(y+1)*width];
left = pixels[(x-1)+(y+1)*width];
right = pixels[(x+1)+(y+1)*width];
up = pixels[x+(y+2)*width];
pixels[x+y*width] = firetable[mid+left+right+up];
}
mid = pixels[(width-1)+(y+1)*width];
left = pixels[(width-2)+(y+1)*width];
right = pixels[(y+1)*width];
up = pixels[(width-1)+(y+2)*width];
pixels[(width-1)+y*width] = firetable[mid+left+right+up];
}
y = height-2;
{
mid = pixels[(y+1)*width];
left = pixels[(width-1)+(y+1)*width];
right = pixels[1+(y+1)*width];
up = pixels[0];
pixels[y*width] = firetable[mid+left+right+up];
for ( uint x=1; x<width-1; x++ )
{
mid = pixels[x+(y+1)*width];
left = pixels[(x-1)+(y+1)*width];
right = pixels[(x+1)+(y+1)*width];
up = pixels[x];
pixels[x+y*width] = firetable[mid+left+right+up];
}
mid = pixels[(width-1)+(y+1)*width];
left = pixels[(width-2)+(y+1)*width];
right = pixels[(y+1)*width];
up = pixels[(width-1)];
pixels[(width-1)+y*width] = firetable[mid+left+right+up];
}
y = height-1;
{
mid = pixels[width];
left = pixels[(width-1)];
right = pixels[1];
up = pixels[2*width];
pixels[y*width] = firetable[mid+left+right+up];
for ( uint x=1; x<width-1; x++ )
{
mid = pixels[x+width];
left = pixels[(x-1)+width];
right = pixels[(x+1)+width];
up = pixels[x+2*width];
pixels[x+y*width] = firetable[mid+left+right+up];
}
mid = pixels[(width-1)+width];
left = pixels[(width-2)+width];
right = pixels[width];
up = pixels[(width-1)+2*width];
pixels[(width-1)+y*width] = firetable[mid+left+right+up];
}
}
// ... without bRising (triangle shifted one pixel down)
// on last row, we must sample from a copy of the zeroth row, otherwise
// we would be sampling from an already modified pixel
private void CalcSlowFire()
{
uint temp[256];
for ( uint i=0; i<width; i++ ) temp[i] = pixels[i];
uint mid, left, right, up;
uint y;
for ( y=0; y<height-1; y++ )
{
mid = pixels[y*width];
left = pixels[(width-1)+y*width];
right = pixels[1+y*width];
up = pixels[(y+1)*width];
pixels[y*width] = firetable[mid+left+right+up];
for ( uint x=1; x<width-1; x++ )
{
mid = pixels[x+y*width];
left = pixels[(x-1)+y*width];
right = pixels[(x+1)+y*width];
up = pixels[x+(y+1)*width];
pixels[x+y*width] = firetable[mid+left+right+up];
}
mid = pixels[(width-1)+y*width];
left = pixels[(width-2)+y*width];
right = pixels[y*width];
up = pixels[(width-1)+(y+1)*width];
pixels[(width-1)+y*width] = firetable[mid+left+right+up];
}
y = height-1;
{
mid = pixels[y*width];
left = pixels[(width-1)+y*width];
right = pixels[1+y*width];
up = temp[0];
pixels[y*width] = firetable[mid+left+right+up];
for ( uint x=1; x<width-1; x++ )
{
mid = pixels[x+y*width];
left = pixels[(x-1)+y*width];
right = pixels[(x+1)+y*width];
up = temp[x];
pixels[x+y*width] = firetable[mid+left+right+up];
}
mid = pixels[(width-1)+y*width];
left = pixels[(width-2)+y*width];
right = pixels[y*width];
up = temp[width-1];
pixels[(width-1)+y*width] = firetable[mid+left+right+up];
}
}
}