[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{
SEAN PALMER
I've been playing around with it as a way to make 'heat-seeking
missiles' in games. Very interesting...
What I do is have the points set up as follows:
1 : current position
2&3 : current speed + the current position
4 : destination
and update current position by indexing somewhere into the curve (like
at $100 out of $FFFF
This works very well. Problem is that I don't know of a good way to
change the speed.
Here is a simple demo that makes a dot chase the mouse cursor (needs
VGA as written) that shows what I mean.
If ANYBODY can make this work smoother or improve on it in any way I
would appreciate being told how... 8)
}
uses
mouse, crt; { you will need to change accesses to the mouse unit }
{ to use a mouse package that you provide }
type
coord = record
x, y : word;
end;
CurveDataRec = array [0..65521 div sizeof(coord)] of coord;
const
nSteps = 1 shl 8; {about 8 for smoothness (dots), 4 for speed (lines)}
var
color : byte;
src, spd,
dst, mov1,
mov2 : coord;
i : integer;
procedure plot(x, y : word);
begin
mem[$A000 : y * 320 + x] := color;
end;
function fracMul(f, f2 : word) : word;
Inline(
$58/ {pop ax}
$5B/ {pop bx}
$F7/$E3/ {mul bx}
$89/$D0); {mov ax,dx}
function mul(f, f2 : word) : longint;
inline(
$58/ {pop ax}
$5B/ {pop bx}
$F7/$E3); {mul bx}
{this is the original full BSpline routine}
procedure drawBSpline(var d0 : coord; nPoints : word);
const
nsa = $10000 div 6;
nsb = $20000 div 3;
step = $10000 div nSteps;
var
i, xx, yy : word;
t1, t2, t3 : word;
c1, c2, c3, c4 : word;
d : curveDataRec absolute d0;
begin
t1 := 0;
color := 32 + 2;
for i := 0 to nPoints - 4 do
begin
{algorithm converted from Steve Enns' original Basic subroutine}
repeat
t2 := fracMul(t1, t1);
t3 := fracMul(t2, t1);
c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);
c2 := (t3 shr 1) + nsb - t2;
c3 := ((t2 + t1 - t3) shr 1) + nsa;
c4 := fracmul(nsa, t3);
xx := (mul(c1, d[i].x) + mul(c2, d[i + 1].x) +
mul(c3, d[i + 2].x) + mul(c4, d[i + 3].x)) shr 16;
yy := (mul(c1, d[i].y) + mul(c2, d[i + 1].y) +
mul(c3, d[i + 2].y) + mul(c4, d[i + 3].y)) shr 16;
plot(xx, yy);
inc(t1, step);
until t1 = 0; {this is why nSteps must be even power of 2}
inc(color);
end;
end;
{find 1/nth point in BSpline} {this is what does the B-Spline work}
procedure moveTowards(d1, d2, d3, d4 : coord; t1 : word; var mov : coord);
const
nsa = $10000 div 6;
nsb = $20000 div 3;
var
t2, t3 : word;
c1, c2,
c3, c4 : word;
begin
t2 := fracMul(t1, t1);
t3 := fracMul(t2, t1);
c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);
c2 := (t3 shr 1) + nsb - t2;
c3 := ((t2 + t1 - t3) shr 1) + nsa;
c4 := fracmul(nsa, t3);
mov.x := (mul(c1, d1.x) + mul(c2, d2.x) + mul(c3, d3.x) + mul(c4, d4.x)) shr 16;
mov.y := (mul(c1, d1.y) + mul(c2, d2.y) + mul(c3, d3.y) + mul(c4, d4.y)) shr 16;
end;
begin
asm
mov ax, $13
int $10
end; {init vga/mcga graphics}
{mouse.init;}
mshow;
src.x := 5;
src.y := 5;
spd.x := 5;
spd.y := 5;
dst.x := 315;
dst.y := 190;
repeat
{for i:=0 to 23 do begin}
{ color:=i+32;}
{ inc(dst.x,i);}
delay(10);
{mouse.check;} {this loads Mouse.X, Mouse.Y, Mouse.Button from driver}
mhide;
color := 15;
plot(src.x, src.y);
color := 14;
plot(spd.x, spd.y);
dst.x := mousex shr 1;
dst.y := mousey;
color := 1;
plot(dst.x, dst.y);
mshow;
{the parameters in these next two lines can be changed}
{I have played with almost all possible combinations and}
{most work, but not well, so don't be afraid to play around}
{But I think an entirely different approach is needed for the}
{second moveTowards..}
moveTowards(src, src, spd, dst, $0010, mov1);
moveTowards(src, spd, dst, dst, $5000, mov2);
src := mov1;
longint(spd) := (longint(spd) * 7 + longint(mov2)) shr 3 and $1FFF1FFF;
until 1=0;
mhide;
asm
mov ax, 3
int $10
end; {text mode again}
end.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]