Funny proof of concept here.
This commit is contained in:
commit
68e9f04b4a
12 changed files with 1151 additions and 0 deletions
215
zscript/firetexture_m/ft_baseclass.zsc
Normal file
215
zscript/firetexture_m/ft_baseclass.zsc
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
// This is a very awful and hacky and gross attempt at replicating Unreal's
|
||||
// FireTexture class in ZScript using canvas drawing
|
||||
//
|
||||
// Abandon all hope ye who enter here
|
||||
|
||||
class FireSpark
|
||||
{
|
||||
int type; // see above enums
|
||||
int heat; // heat of this spark
|
||||
int x, y; // location
|
||||
|
||||
int args[4]; // arguments
|
||||
// 0: usually x speed
|
||||
// 1: usually y speed
|
||||
// 2: usually age or emitter frequency
|
||||
// 3: usually expiration time
|
||||
}
|
||||
|
||||
class FireTexture
|
||||
{
|
||||
enum EFireSpark
|
||||
{
|
||||
SPARK_Burn, // stationary spark with randomized intensity
|
||||
SPARK_Sparkle, // sparks that jitter
|
||||
SPARK_Pulse, // sparks that turn on and off
|
||||
SPARK_Signal, // akin to burn but with some tweakable behavior (?)
|
||||
SPARK_Blaze, // sparks emitted in random directions
|
||||
SPARK_OzHasSpoken, // sparks that move up and fade out
|
||||
SPARK_Cone, // akin to blaze but with gravity
|
||||
SPARK_BlazeRight, // blaze but aiming to the right
|
||||
SPARK_BlazeLeft, // blaze but aiming to the left
|
||||
SPARK_Cylinder, // sparks that ping-pong horizontally
|
||||
SPARK_Cylinder3D, // like above but sparks are invisible on their way back
|
||||
SPARK_Lissajous, // sparks that ping-pong both horizontally and vertically at different frequencies
|
||||
SPARK_Jugglers, // like cylinder but vertical
|
||||
SPARK_Emit, // sparks that move in a random straight direction and fade out
|
||||
SPARK_Fountain, // like emit but with gravity
|
||||
SPARK_Flocks, // bunch of sparks that jitter smoothly in a circular area
|
||||
SPARK_Eels, // like emit except not (?)
|
||||
SPARK_Organic, // sparks that move up with slightly randomized angles
|
||||
SPARK_WanderOrganic, // hell if I know
|
||||
SPARK_RandomCloud, // ???????
|
||||
SPARK_CustomCloud, // ???????????????
|
||||
SPARK_LocalCloud, // ????????????????????
|
||||
SPARK_Stars, // single pixels of constant intensity
|
||||
SPARK_LineLightning, // lightning bolts that zap between two spots
|
||||
SPARK_RampLightning, // like above, but the intensity fades towards the endpoint
|
||||
SPARK_SphereLightning, // like above, but the bolts spread out in all directions
|
||||
SPARK_Wheel, // sparks that move in circles
|
||||
SPARK_Gametes, // like Eels but sorta wriggly
|
||||
SPARK_Sprinkler, // what it says on the tin
|
||||
NUM_SPARK_TYPES
|
||||
};
|
||||
|
||||
enum EFireSparkInternal
|
||||
{
|
||||
// special types
|
||||
SPARK_LissajousX = NUM_SPARK_TYPES,
|
||||
SPARK_LissajousY,
|
||||
// spawned sparks (names are my own here, based on guesswork)
|
||||
SSPARK_Unused, // not used at all, may have been some form of padding?
|
||||
SSPARK_Ember, // ember from a Blaze type, constant speed, fades out
|
||||
SSPARK_EmberCustom, // like above but fades based on args[3], used by OzHasSpoken and Emit
|
||||
SSPARK_Gravity, // y speed is affected by gravity, dies after a set timeout, used by Cone and BlazeRight/Left
|
||||
SSPARK_Rising, // fading out, constant upwards speed, used by Organic types
|
||||
SSPARK_CloudY, // same but fades in instead of out, used by Random/LocalCloud
|
||||
SSPARK_CloudXY, // this one moves in all directions, used by CustomCloud
|
||||
SSPARK_Eel, // moves in a chosen direction and fades out very slowly, spawned by Eels
|
||||
SSPARK_Twirl, // horizontal and vertical speed spin in a circle, used by Flocks and Wheel
|
||||
SSPARK_Sprinkle, // rises up at constant speed, horizontal speed is sinusoidal, used by Sprinkler
|
||||
SSPARK_EmberCustom2, // identical but uses args[2] instead, seemingly unused
|
||||
SSPARK_GravityFade, // used by Fountain, has half gravity and fades out
|
||||
SSPARK_Gamete // like eels but moving erratically, spawned by Gametes
|
||||
};
|
||||
|
||||
private bool initd; // true if the texture has been initialized
|
||||
|
||||
private int sparklimit; // maximum sparks allowed to be rendered
|
||||
|
||||
private uint phase; // global timer
|
||||
private Array<FireSpark> sparks;// all the active sparks
|
||||
private bool bhasstars; // true if any sparks with type SPARK_Stars exist
|
||||
|
||||
// parses a fire texture from a file
|
||||
static FireTexture Load( string path )
|
||||
{
|
||||
static const String typetable[] =
|
||||
{
|
||||
"Burn", "Sparkle", "Pulse", "Signal", "Blaze",
|
||||
"OzHasSpoken", "Cone", "BlazeRight", "BlazeLeft",
|
||||
"Cylinder", "Cylinder3D", "Lissajous", "Jugglers",
|
||||
"Emit", "Fountain", "Flocks", "Eels", "Organic",
|
||||
"WanderOrganic", "RandomCloud", "CustomCloud",
|
||||
"LocalCloud", "Stars", "LineLighting", "RampLighting",
|
||||
"SphereLighting", "Wheel", "Gametes", "Sprinkler"
|
||||
};
|
||||
int lmp = Wads.CheckNumForFullName(path);
|
||||
if ( lmp == -1 ) ThrowAbortException("Could not find fire texture '%s'.",path);
|
||||
String dat = Wads.ReadLump(lmp);
|
||||
dat.Replace("\r","");
|
||||
Array<String> lines, line;
|
||||
dat.Split(lines,"\n",TOK_SKIPEMPTY);
|
||||
String cname;
|
||||
uint width, height;
|
||||
lines[0].Split(line," ");
|
||||
cname = line[0];
|
||||
width = line[1].ToInt();
|
||||
height = line[2].ToInt();
|
||||
FireTexture ftx = new("FireTexture");
|
||||
ftx.Init(width,height);
|
||||
ftx.cv = TexMan.GetCanvas(cname);
|
||||
if ( !ftx.cv ) ThrowAbortException("Could not find canvas '%s'",cname);
|
||||
lmp = Wads.CheckNumForFullName("palettes/"..lines[1]..".pal");
|
||||
if ( lmp == -1 ) ThrowAbortException("Could not find palette '%s'",lines[1]);
|
||||
dat = Wads.ReadLump(lmp);
|
||||
for ( uint i=0; i<256; i++ )
|
||||
{
|
||||
ftx.pal[i].a = 255;
|
||||
ftx.pal[i].r = dat.ByteAt(i*3);
|
||||
ftx.pal[i].g = dat.ByteAt(i*3+1);
|
||||
ftx.pal[i].b = dat.ByteAt(i*3+2);
|
||||
}
|
||||
line.Clear();
|
||||
lines[2].Split(line," ");
|
||||
ftx.brising = !!line[0].ToInt();
|
||||
ftx.renderheat = line[1].ToInt();
|
||||
ftx.sparklimit = line[2].ToInt();
|
||||
ftx.sparks.Clear();
|
||||
for ( int i=3; i<lines.Size(); i++ )
|
||||
{
|
||||
line.Clear();
|
||||
lines[i].Split(line," ");
|
||||
FireSpark s = new("FireSpark");
|
||||
int tfn = -1;
|
||||
for ( int j=0; j<NUM_SPARK_TYPES; j++ )
|
||||
{
|
||||
if ( !(line[0] ~== typetable[j]) ) continue;
|
||||
tfn = j;
|
||||
break;
|
||||
}
|
||||
if ( tfn == -1 ) ThrowAbortException("Invalid spark type '%s'",line[0]);
|
||||
s.type = tfn;
|
||||
s.heat = uint(line[1].ToInt())&255;
|
||||
s.x = uint(line[2].ToInt())&ftx.umask;
|
||||
s.y = uint(line[3].ToInt())&ftx.vmask;
|
||||
s.args[0] = uint(line[4].ToInt())&255;
|
||||
s.args[1] = uint(line[5].ToInt())&255;
|
||||
s.args[2] = uint(line[6].ToInt())&255;
|
||||
s.args[3] = uint(line[7].ToInt())&255;
|
||||
// simplify Lissajous
|
||||
if ( s.type == SPARK_Lissajous )
|
||||
{
|
||||
if ( !s.args[1] && !s.args[3] ) s.type = SPARK_LissajousX;
|
||||
else if ( !s.args[0] && !s.args[2] ) s.type = SPARK_LissajousY;
|
||||
}
|
||||
ftx.sparks.Push(s);
|
||||
}
|
||||
ftx.PostLoad();
|
||||
return ftx;
|
||||
}
|
||||
|
||||
void PostLoad()
|
||||
{
|
||||
PostInitTables();
|
||||
// always assume there's stars at first
|
||||
bHasStars = true;
|
||||
}
|
||||
|
||||
bool Initialized()
|
||||
{
|
||||
return initd;
|
||||
}
|
||||
|
||||
int GetWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
int GetHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
void Init( uint usize, uint vsize )
|
||||
{
|
||||
// check that texture size is in powers of two
|
||||
// and is smaller than 64KiB
|
||||
if ( usize&(usize-1) != 0 ) ThrowAbortException("Tried to init FireTexture with non power of two width.");
|
||||
if ( vsize&(vsize-1) != 0 ) ThrowAbortException("Tried to init FireTexture with non power of two height.");
|
||||
if ( usize > 256 ) ThrowAbortException("Tried to init FireTexture with width above 256.");
|
||||
if ( vsize > 256 ) ThrowAbortException("Tried to init FireTexture with height above 256.");
|
||||
width = usize;
|
||||
height = vsize;
|
||||
umask = width-1;
|
||||
vmask = height-1;
|
||||
InitTables();
|
||||
initd = true;
|
||||
}
|
||||
|
||||
void Tick()
|
||||
{
|
||||
RedrawSparks();
|
||||
if ( bRising ) CalcWrapFire();
|
||||
else CalcSlowFire();
|
||||
PostDrawSparks();
|
||||
}
|
||||
|
||||
void Render()
|
||||
{
|
||||
// blit to canvas, one pixel at a time (oof)
|
||||
for ( uint y=0; y<height; y++ )
|
||||
for ( uint x=0; x<width; x++ )
|
||||
cv.Clear(x,y,x+1,y+1,GetPixelRGB(x,y));
|
||||
}
|
||||
}
|
||||
46
zscript/firetexture_m/ft_math.zsc
Normal file
46
zscript/firetexture_m/ft_math.zsc
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// math functions and whatnot
|
||||
|
||||
extend class FireTexture
|
||||
{
|
||||
private uint randindex;
|
||||
private uint8 randtable[512]; // fast rng table
|
||||
|
||||
private uint8 phasetable[256]; // unsigned sine table
|
||||
private int8 signedtable[256]; // signed sine table
|
||||
private uint8 lighttable[256]; // sine table but with an offset
|
||||
|
||||
private uint8 firetable[1024]; // color mapping table
|
||||
// (for blending 4 pixels together)
|
||||
// (influenced by heat, also)
|
||||
// (original has 4 more bytes, probably
|
||||
// to prevent overflows, but that's not
|
||||
// needed here, we can just clamp)
|
||||
|
||||
// sets up rng and sine tables
|
||||
private void InitTables()
|
||||
{
|
||||
for ( uint i=0; i<256; i++ )
|
||||
phasetable[i] = uint(round(127.45+127.5*sin((i/256.)*360.)));
|
||||
for ( uint i=0; i<256; i++ )
|
||||
{
|
||||
lighttable[i] = clamp(phasetable[i]+32,0,255);
|
||||
signedtable[i] = -128+phasetable[i];
|
||||
}
|
||||
for ( uint i=0; i<512; i++ )
|
||||
randtable[i] = Random[FireTexture](0,255);
|
||||
}
|
||||
|
||||
// sets up fire table
|
||||
private void PostInitTables()
|
||||
{
|
||||
for ( uint i=0; i<1024; i++ )
|
||||
firetable[i] = uint(clamp(i/4.+1.-(255-renderheat)/16.,0.,255.));
|
||||
}
|
||||
|
||||
// PRNG
|
||||
private uint FastRand()
|
||||
{
|
||||
randindex = (randindex+1)&63;
|
||||
return (randtable[(randindex+31)&63] ^= randtable[randindex]);
|
||||
}
|
||||
}
|
||||
79
zscript/firetexture_m/ft_pixel.zsc
Normal file
79
zscript/firetexture_m/ft_pixel.zsc
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
// 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
|
||||
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;
|
||||
}
|
||||
private Color GetPixelRGB( uint x, uint y )
|
||||
{
|
||||
// ensure coords are wrapped
|
||||
x &= umask;
|
||||
y &= vmask;
|
||||
return pal[pixels[x+y*width]];
|
||||
}
|
||||
|
||||
private uint LookupFiretable( uint a, uint b, uint c, uint d )
|
||||
{
|
||||
return firetable[min(a+b+c+d,1023)];
|
||||
}
|
||||
|
||||
// heat propagation with bRising (triangle shifted two pixels down)
|
||||
private void CalcWrapFire()
|
||||
{
|
||||
uint mid, left, right, up;
|
||||
for ( uint y=0; y<height; y++ )
|
||||
{
|
||||
for ( uint x=0; x<width; x++ )
|
||||
{
|
||||
mid = GetPixel(x,y+1);
|
||||
left = GetPixel(x-1,y+1);
|
||||
right = GetPixel(x+1,y+1);
|
||||
up = GetPixel(x,y+2);
|
||||
PutPixel(x,y,LookupFiretable(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;
|
||||
for ( uint y=0; y<height; y++ )
|
||||
{
|
||||
for ( uint x=0; x<width; x++ )
|
||||
{
|
||||
mid = GetPixel(x,y);
|
||||
left = GetPixel(x-1,y);
|
||||
right = GetPixel(x+1,y);
|
||||
up = (y==height-1)?temp[x&255]:GetPixel(x,y+1);
|
||||
PutPixel(x,y,LookupFiretable(mid,left,right,up));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
692
zscript/firetexture_m/ft_spark.zsc
Normal file
692
zscript/firetexture_m/ft_spark.zsc
Normal file
|
|
@ -0,0 +1,692 @@
|
|||
// spark handling
|
||||
// perhaps one of the most blatantly reverse-engineered parts here
|
||||
|
||||
extend class FireTexture
|
||||
{
|
||||
// movement according to specified speed
|
||||
private void MoveSparkXY( FireSpark s, int xspeed, int yspeed )
|
||||
{
|
||||
if ( xspeed < 0 )
|
||||
{
|
||||
if ( (FastRand()&127) < uint(-xspeed) )
|
||||
s.x = umask&(s.x-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (FastRand()&127) < uint(xspeed) )
|
||||
s.x = umask&(s.x+1);
|
||||
}
|
||||
if ( yspeed < 0 )
|
||||
{
|
||||
if ( (FastRand()&127) < uint(-yspeed) )
|
||||
s.y = vmask&(s.y-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (FastRand()&127) < uint(yspeed) )
|
||||
s.y = vmask&(s.y+1);
|
||||
}
|
||||
}
|
||||
// movement according to spark speed
|
||||
private void MoveSpark( FireSpark s )
|
||||
{
|
||||
MoveSparkXY(s,s.args[0],s.args[1]);
|
||||
}
|
||||
// ???
|
||||
private void MoveSparkTwo( FireSpark s )
|
||||
{
|
||||
if ( s.args[0] < 0 )
|
||||
{
|
||||
if ( (FastRand()&127) < uint(-s.args[0]) )
|
||||
s.x = umask&(s.x-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (FastRand()&127) < uint(s.args[0]) )
|
||||
s.x = umask&(s.x+1);
|
||||
}
|
||||
s.y = vmask&(s.y-2);
|
||||
}
|
||||
// random movement according to specified angle
|
||||
private void MoveSparkAngle( FireSpark s, int angle )
|
||||
{
|
||||
int xdir = -127+phasetable[angle&255];
|
||||
int ydir = -127+phasetable[(angle+64)&255];
|
||||
MoveSparkXY(s,xdir,ydir);
|
||||
}
|
||||
|
||||
// draws a lightning bolt with a set origin and dimensions, fading from two palette indices
|
||||
private void DrawBolt( int x, int y, int w, int h, uint fromcol, uint tocol )
|
||||
{
|
||||
uint flasharray[256];
|
||||
int xstep, ystep, ylen, xlen;
|
||||
// is this cache-friendly hack needed? idk
|
||||
if ( ((h&1) && ((h*2) >= w)) || ((w&1) && ((h*2) < w)) )
|
||||
{
|
||||
x += (w&1)?-w:w;
|
||||
y += (h&1)?-h:h;
|
||||
w ^= 1;
|
||||
h ^= 1;
|
||||
uint tmp = fromcol;
|
||||
fromcol = tocol;
|
||||
tocol = tmp;
|
||||
}
|
||||
int longest = 1|((w>=h)?w:h);
|
||||
uint fpos = 0;
|
||||
for ( int f=0; f<longest; f++ )
|
||||
fpos += (flasharray[f]=FastRand());
|
||||
if ( h&1 )
|
||||
{
|
||||
ystep = -1;
|
||||
ylen = -h;
|
||||
}
|
||||
else
|
||||
{
|
||||
ystep = 1;
|
||||
ylen = h;
|
||||
}
|
||||
if ( w&1 )
|
||||
{
|
||||
xstep = -1;
|
||||
xlen = -w;
|
||||
}
|
||||
else
|
||||
{
|
||||
xstep = 1;
|
||||
xlen = w;
|
||||
}
|
||||
int rcol = fromcol<<23;
|
||||
int cslope = ((tocol-fromcol)<<23)/longest;
|
||||
if ( w >= h )
|
||||
{
|
||||
int yz = (y<<6);
|
||||
int bias = ((ylen<<6)-fpos)/longest;
|
||||
for ( int f=0; f<w; f++ )
|
||||
{
|
||||
yz += flasharray[f]+bias;
|
||||
PutPixel(x,yz>>6,(rcol+=cslope)>>23);
|
||||
x += xstep;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int xz = (x<<6);
|
||||
int bias = ((xlen<<6)-fpos)/longest;
|
||||
for ( int f=0; f<h; f++ )
|
||||
{
|
||||
xz += flasharray[f]+bias;
|
||||
PutPixel(xz>>6,y,(rcol+=cslope)>>23);
|
||||
y += ystep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle all sparks (big heckin' function here)
|
||||
private void RedrawSparks()
|
||||
{
|
||||
uint newx, newy, newh;
|
||||
uint ns;
|
||||
phase++;
|
||||
for ( int i=0; i<sparks.Size(); i++ )
|
||||
{
|
||||
FireSpark s = sparks[i];
|
||||
switch ( s.type )
|
||||
{
|
||||
// normal sparks
|
||||
case SPARK_Burn:
|
||||
{
|
||||
PutPixel(s.x,s.y,FastRand());
|
||||
break;
|
||||
}
|
||||
case SPARK_Sparkle:
|
||||
{
|
||||
newx = s.x+((FastRand()*s.args[0])>>8);
|
||||
newy = s.y+((FastRand()*s.args[1])>>8);
|
||||
PutPixel(newx,newy,s.heat);
|
||||
break;
|
||||
}
|
||||
case SPARK_Pulse:
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
s.heat = (s.heat+s.args[3])&255;
|
||||
break;
|
||||
}
|
||||
case SPARK_Signal:
|
||||
{
|
||||
if ( s.heat > s.args[2] )
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
s.heat = (s.heat+s.args[3])&255;
|
||||
if ( s.heat < s.args[3] )
|
||||
s.heat = FastRand();
|
||||
break;
|
||||
}
|
||||
case SPARK_Cylinder:
|
||||
{
|
||||
newh = min(phasetable[(s.args[0]+64)&255]+s.heat,255);
|
||||
newx = s.x+((phasetable[s.args[0]]*s.args[1])>>8);
|
||||
PutPixel(newx,s.y,newh);
|
||||
s.args[0] = (s.args[0]+s.args[3])&255;
|
||||
break;
|
||||
}
|
||||
case SPARK_Cylinder3D:
|
||||
{
|
||||
if ( ((s.args[0]+64)&255) < 128 )
|
||||
{
|
||||
newh = min(phasetable[(s.args[0]+64)&255]+s.heat,255);
|
||||
newx = s.x+((phasetable[s.args[0]]*s.args[1])>>8);
|
||||
PutPixel(newx,s.y,newh);
|
||||
}
|
||||
s.args[0] = (s.args[0]+s.args[3])&255;
|
||||
break;
|
||||
}
|
||||
case SPARK_Jugglers:
|
||||
{
|
||||
newh = min(phasetable[(s.args[0]+64)&255]+s.heat,255);
|
||||
newy = s.y+((phasetable[s.args[0]]*s.args[1])>>8);
|
||||
PutPixel(s.x,newy,newh);
|
||||
s.args[0] = (s.args[0]+s.args[3])&255;
|
||||
break;
|
||||
}
|
||||
case SPARK_Lissajous:
|
||||
{
|
||||
newh = lighttable[(s.args[0]+64)&255];
|
||||
newx = s.x+((phasetable[s.args[0]]*s.heat)>>8);
|
||||
newy = s.y+((phasetable[s.args[1]]*s.heat)>>8);
|
||||
PutPixel(newx,newy,newh);
|
||||
s.args[0] = (s.args[0]+s.args[2])&255;
|
||||
s.args[1] = (s.args[1]+s.args[3])&255;
|
||||
break;
|
||||
}
|
||||
case SPARK_LissajousX:
|
||||
{
|
||||
newh = lighttable[(s.args[0]+64)&255];
|
||||
newx = s.x+((phasetable[s.args[0]]*s.heat)>>8);
|
||||
PutPixel(newx,s.y,newh);
|
||||
s.args[0] = (s.args[0]+s.args[2])&255;
|
||||
break;
|
||||
}
|
||||
case SPARK_LissajousY:
|
||||
{
|
||||
newh = lighttable[(s.args[0]+64)&255];
|
||||
newy = s.y+((phasetable[s.args[1]]*s.heat)>>8);
|
||||
PutPixel(s.x,newy,newh);
|
||||
s.args[1] = (s.args[1]+s.args[3])&255;
|
||||
break;
|
||||
}
|
||||
// emitter types
|
||||
case SPARK_Blaze:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 128) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Ember;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = FastRand()-128;
|
||||
ns.args[1] = FastRand()-128;
|
||||
ns.args[2] = s.args[2];
|
||||
ns.args[3] = s.args[3];
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_OzHasSpoken:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 128) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_EmberCustom;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = (FastRand()&127)-63;
|
||||
ns.args[1] = -127;
|
||||
ns.args[3] = 2;
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_Cone:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 64) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Gravity;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = (FastRand()&127)-63;
|
||||
ns.args[1] = 0;
|
||||
ns.args[2] = 50;
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_BlazeRight:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 128) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Gravity;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = (FastRand()&63)+63;
|
||||
ns.args[1] = -29;
|
||||
ns.args[2] = s.args[2];
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_BlazeLeft:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 128) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Gravity;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = (FastRand()&63)-128;
|
||||
ns.args[1] = -29;
|
||||
ns.args[2] = s.args[2];
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_Emit:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 64) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_EmberCustom;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = s.args[0];
|
||||
ns.args[1] = s.args[1];
|
||||
ns.args[2] = s.args[2];
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_Fountain:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 64) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_GravityFade;
|
||||
ns.heat = s.heat;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = s.args[0];
|
||||
ns.args[1] = s.args[1];
|
||||
ns.args[2] = s.args[2];
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_Organic:
|
||||
{
|
||||
if ( (sparks.Size() >= sparklimit) || (FastRand() >= 128) )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Rising;
|
||||
ns.x = (s.x+((FastRand()*s.args[2])>>8))&umask;
|
||||
ns.y = (s.y+((FastRand()*s.args[2])>>8))&vmask;
|
||||
ns.args[0] = FastRand()-128;
|
||||
ns.args[1] = -1;
|
||||
ns.args[2] = 255;
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_WanderOrganic:
|
||||
{
|
||||
if ( sparks.Size() < sparklimit )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Rising;
|
||||
ns.x = (s.x+(FastRand()&31))&umask;
|
||||
ns.y = (s.y+(FastRand()&31))&vmask;
|
||||
ns.args[0] = FastRand()-128;
|
||||
ns.args[1] = -1;
|
||||
ns.args[2] = 255;
|
||||
sparks.Push(ns);
|
||||
}
|
||||
if ( FastRand()&15 == 15 ) s.x = (s.x+(FastRand()&15)-7)&umask;
|
||||
if ( FastRand()&15 == 15 ) s.y = (s.y+(FastRand()&15)-7)&vmask;
|
||||
break;
|
||||
}
|
||||
case SPARK_RandomCloud:
|
||||
{
|
||||
if ( sparks.Size() < sparklimit )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_CloudY;
|
||||
ns.x = (s.x+(FastRand()&31))&umask;
|
||||
ns.y = (s.y+(FastRand()&31))&vmask;
|
||||
ns.args[0] = (FastRand()&31)-15;
|
||||
ns.args[1] = -1;
|
||||
ns.args[2] = 0;
|
||||
sparks.Push(ns);
|
||||
}
|
||||
if ( FastRand()&15 == 15 ) s.x = (s.x+(FastRand()&15)-7)&umask;
|
||||
if ( FastRand()&15 == 15 ) s.y = (s.y+(FastRand()&15)-7)&vmask;
|
||||
break;
|
||||
}
|
||||
case SPARK_Eels:
|
||||
{
|
||||
if ( (sparks.Size() < sparklimit) && (FastRand() < 20) )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Eel;
|
||||
ns.heat = s.heat;
|
||||
ns.x = (s.x+(FastRand()&31))&umask;
|
||||
ns.y = (s.y+(FastRand()&31))&vmask;
|
||||
ns.args[0] = FastRand();
|
||||
ns.args[1] = FastRand();
|
||||
ns.args[2] = s.args[2];
|
||||
sparks.Push(ns);
|
||||
}
|
||||
if ( FastRand()&15 == 15 ) s.x = (s.x+(FastRand()&15)-7)&umask;
|
||||
if ( FastRand()&15 == 15 ) s.y = (s.y+(FastRand()&15)-7)&vmask;
|
||||
break;
|
||||
}
|
||||
case SPARK_Gametes:
|
||||
{
|
||||
if ( (sparks.Size() < sparklimit) && (FastRand() < 20) )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Gamete;
|
||||
ns.heat = s.heat;
|
||||
ns.x = (s.x+(FastRand()&31))&umask;
|
||||
ns.y = (s.y+(FastRand()&31))&vmask;
|
||||
ns.args[0] = FastRand();
|
||||
ns.args[2] = s.args[2];
|
||||
ns.args[3] = FastRand();
|
||||
sparks.Push(ns);
|
||||
}
|
||||
if ( FastRand()&15 == 15 ) s.x = (s.x+(FastRand()&15)-7)&umask;
|
||||
if ( FastRand()&15 == 15 ) s.y = (s.y+(FastRand()&15)-7)&vmask;
|
||||
break;
|
||||
}
|
||||
case SPARK_CustomCloud:
|
||||
{
|
||||
if ( sparks.Size() < sparklimit )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_CloudXY;
|
||||
ns.x = (s.x+(FastRand()&31))&umask;
|
||||
ns.y = (s.y+(FastRand()&31))&vmask;
|
||||
ns.args[0] = s.args[0];
|
||||
ns.args[1] = s.args[1];
|
||||
ns.args[2] = s.args[3];
|
||||
sparks.Push(ns);
|
||||
}
|
||||
// dunno why the wandering math was done like this here
|
||||
s.x = (s.x+(FastRand()&7)-(FastRand()&7))&umask;
|
||||
s.y = (s.y+(FastRand()&7)-(FastRand()&7))&vmask;
|
||||
break;
|
||||
}
|
||||
case SPARK_LocalCloud:
|
||||
{
|
||||
if ( sparks.Size() < sparklimit )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_CloudXY;
|
||||
ns.x = (s.x+((FastRand()*s.args[2])>>8))&umask;
|
||||
ns.y = (s.y+((FastRand()*s.args[2])>>8))&vmask;
|
||||
ns.args[0] = s.args[0];
|
||||
ns.args[1] = s.args[1];
|
||||
ns.args[2] = s.args[3];
|
||||
sparks.Push(ns);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPARK_Flocks:
|
||||
{
|
||||
if ( sparks.Size() < sparklimit )
|
||||
{
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Twirl;
|
||||
ns.x = (s.x+(FastRand()&31))&umask;
|
||||
ns.y = (s.y+(FastRand()&31))&vmask;
|
||||
ns.args[0] = 0;
|
||||
ns.args[1] = s.args[0];
|
||||
ns.args[2] = s.args[1];
|
||||
ns.args[3] = s.args[3];
|
||||
ns.heat = s.heat;
|
||||
s.args[0] = (s.args[0]+s.args[2])&255;
|
||||
sparks.Push(ns);
|
||||
}
|
||||
// dunno why the wandering math was done like this here
|
||||
s.x = (s.x+(FastRand()&7)-(FastRand()&7))&umask;
|
||||
s.y = (s.y+(FastRand()&7)-(FastRand()&7))&vmask;
|
||||
break;
|
||||
}
|
||||
case SPARK_Wheel:
|
||||
{
|
||||
if ( sparks.Size() >= sparklimit )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Twirl;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.args[0] = 0;
|
||||
ns.args[1] = s.args[0];
|
||||
ns.args[2] = s.args[1];
|
||||
ns.args[3] = s.args[3];
|
||||
ns.heat = s.heat;
|
||||
s.args[0] = (s.args[0]+s.args[2])&255;
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
case SPARK_Sprinkler:
|
||||
{
|
||||
if ( sparks.Size() >= sparklimit )
|
||||
break;
|
||||
FireSpark ns = new("FireSpark");
|
||||
ns.type = SSPARK_Sprinkle;
|
||||
ns.x = s.x;
|
||||
ns.y = s.y;
|
||||
ns.heat = s.heat;
|
||||
ns.args[0] = s.args[0];
|
||||
ns.args[1] = s.args[1];
|
||||
ns.args[2] = s.args[2];
|
||||
ns.args[3] = 2;
|
||||
ns.heat = s.heat;
|
||||
s.args[0] = (s.args[0]+s.args[3])&255;
|
||||
sparks.Push(ns);
|
||||
break;
|
||||
}
|
||||
// stars are their own thing
|
||||
case SPARK_Stars:
|
||||
{
|
||||
PutPixel(s.x,s.y,s.args[1]);
|
||||
break;
|
||||
}
|
||||
// bolt types
|
||||
case SPARK_LineLightning:
|
||||
{
|
||||
if ( !s.heat ) break;
|
||||
if ( s.args[2] > 0 )
|
||||
{
|
||||
s.args[2]--;
|
||||
DrawBolt(s.x,s.y,s.args[0],s.args[1],s.heat,s.heat);
|
||||
}
|
||||
else if ( FastRand() >= uint(s.args[3]) )
|
||||
s.args[2] = 1+FastRand()&5;
|
||||
break;
|
||||
}
|
||||
case SPARK_RampLightning:
|
||||
{
|
||||
if ( !s.heat ) break;
|
||||
if ( s.args[2] > 0 )
|
||||
{
|
||||
s.args[2]--;
|
||||
DrawBolt(s.x,s.y,s.args[0],s.args[1],s.heat,s.heat>>3);
|
||||
}
|
||||
else if ( FastRand() >= uint(s.args[3]) )
|
||||
s.args[2] = 1+FastRand()&5;
|
||||
break;
|
||||
}
|
||||
case SPARK_SphereLightning:
|
||||
{
|
||||
if ( FastRand() < uint(s.args[3]) ) break;
|
||||
uint ang = FastRand();
|
||||
uint rad = s.args[2];
|
||||
uint sdispx = (rad*phasetable[ang])>>8;
|
||||
uint sdispy = (rad*phasetable[(ang+64)&255])>>8;
|
||||
DrawBolt(s.x,s.y,sdispx-rad/2,sdispy-rad/2,s.heat,s.heat>>2);
|
||||
break;
|
||||
}
|
||||
// and now the spawned ones
|
||||
case SSPARK_Ember:
|
||||
{
|
||||
if ( (s.heat -= 5) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
MoveSpark(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_EmberCustom:
|
||||
{
|
||||
if ( (s.heat -= s.args[3]) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
MoveSpark(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_EmberCustom2: // unused
|
||||
{
|
||||
if ( (s.heat -= s.args[2]) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
MoveSpark(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_Gravity:
|
||||
{
|
||||
if ( (s.args[2] -= 1) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
MoveSpark(s);
|
||||
s.args[1] = min(s.args[1]+3,127);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_GravityFade:
|
||||
{
|
||||
if ( (s.heat -= s.args[3]) > 50 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
MoveSpark(s);
|
||||
if ( phase&1 ) s.args[1] = min(s.args[1]+3,127);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_Rising:
|
||||
{
|
||||
if ( (s.args[2] -= 3) > 190 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.args[2]);
|
||||
MoveSparkTwo(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_CloudY:
|
||||
{
|
||||
if ( (s.args[2] += 4) < 250 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.args[2]);
|
||||
MoveSparkTwo(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_CloudXY:
|
||||
{
|
||||
if ( (s.args[2] += 4) < 250 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.args[2]);
|
||||
MoveSpark(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_Eel:
|
||||
{
|
||||
if ( (s.args[2] -= 1) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
MoveSpark(s);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_Gamete:
|
||||
{
|
||||
if ( (s.args[2] -= 1) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
uint sawtooth = 127&(s.args[0]+=7);
|
||||
if ( sawtooth>63 ) sawtooth = 127-sawtooth;
|
||||
MoveSparkAngle(s,255&(sawtooth+s.args[3]));
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_Twirl:
|
||||
{
|
||||
if ( (s.args[2] -= 1) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
int tempspeedx = signedtable[(s.args[1]+64)&255];
|
||||
int tempspeedy = signedtable[s.args[1]];
|
||||
// fixed point fuckery happening here
|
||||
uint wtf = s.args[0]+(s.args[1]<<8)+(s.args[3]<<4);
|
||||
s.args[0] = wtf&255;
|
||||
s.args[1] = (wtf>>8)&255;
|
||||
MoveSparkXY(s,tempspeedx,tempspeedy);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
case SSPARK_Sprinkle:
|
||||
{
|
||||
if ( (s.args[2] -= 1) > 0 )
|
||||
{
|
||||
PutPixel(s.x,s.y,s.heat);
|
||||
int tempspeedx = -128+phasetable[(s.args[1]+64)&255];
|
||||
int tempspeedy = s.args[1];
|
||||
s.args[0] = (s.args[0]+s.args[3])&255;
|
||||
MoveSparkXY(s,tempspeedx,tempspeedy);
|
||||
}
|
||||
else sparks.Delete(i--);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle stars
|
||||
private void PostDrawSparks()
|
||||
{
|
||||
uint sparkdest;
|
||||
if ( !bHasStars ) return;
|
||||
bool bFoundStar = false;
|
||||
for ( int i=0; i<sparks.Size(); i++ )
|
||||
{
|
||||
if ( sparks[i].type != SPARK_Stars ) continue;
|
||||
bFoundStar = true;
|
||||
uint dimstar = GetPixel(sparks[i].x,sparks[i].y);
|
||||
sparks[i].args[1] = dimstar;
|
||||
if ( dimstar < 38 )
|
||||
PutPixel(sparks[i].x,sparks[i].y,sparks[i].args[0]);
|
||||
}
|
||||
if ( !bFoundStar ) bHasStars = false;
|
||||
}
|
||||
}
|
||||
31
zscript/firetexture_m/include.zsc
Normal file
31
zscript/firetexture_m/include.zsc
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
FireTexture reverse engineering project
|
||||
Lots of disassembly and reverse engineering work all to make some fancy
|
||||
procedural textures show up in GZDoom. I'm just that insane.
|
||||
|
||||
Copyright (c)2023 Marisa the Magician, UnSX Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// include this file in your projects
|
||||
#include "./ft_baseclass.zsc"
|
||||
#include "./ft_math.zsc"
|
||||
#include "./ft_pixel.zsc"
|
||||
#include "./ft_spark.zsc"
|
||||
19
zscript/firetexture_m/license.txt
Normal file
19
zscript/firetexture_m/license.txt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2023 Marisa the Magician, UnSX Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
34
zscript/ft_testhandler.zsc
Normal file
34
zscript/ft_testhandler.zsc
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// let's test that this madness works, then
|
||||
Class FireTextureTestHandler : StaticEventHandler
|
||||
{
|
||||
ui FireTexture testme;
|
||||
ui TextureID testtex;
|
||||
ui double timers[3];
|
||||
|
||||
override void UiTick()
|
||||
{
|
||||
if ( testme && testme.Initialized() )
|
||||
{
|
||||
timers[0] = MSTimeF();
|
||||
testme.Tick();
|
||||
timers[1] = MSTimeF();
|
||||
testme.Render();
|
||||
timers[2] = MSTimeF();
|
||||
}
|
||||
}
|
||||
|
||||
override void RenderOverlay( RenderEvent e )
|
||||
{
|
||||
if ( !testme ) testme = FireTexture.Load("Pad_FX.ftx");
|
||||
if ( !testme.Initialized() ) return;
|
||||
if ( !testtex.IsValid() ) testtex = TexMan.CheckForTexture("Pad_FX");
|
||||
Screen.DrawTexture(testtex,false,8,8,
|
||||
DTA_ScaleX,CleanXFac_1,DTA_ScaleY,CleanYFac_1);
|
||||
Screen.DrawText(NewSmallFont,Font.CR_RED,16+testme.GetWidth()*CleanXFac_1,16,
|
||||
"← procedural texture running in real time\n no japes here",
|
||||
DTA_ScaleX,CleanXFac_1,DTA_ScaleY,CleanYFac_1);
|
||||
Screen.DrawText(NewSmallFont,Font.CR_RED,16,16+testme.GetHeight()*CleanYFac_1,
|
||||
"tick: "..(timers[1]-timers[0]).."ms\nrender: "..(timers[2]-timers[1]).."ms",
|
||||
DTA_ScaleX,CleanXFac_1,DTA_ScaleY,CleanYFac_1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue