[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
Program Spiral;
{ Spiral.pas - by Mario van den Ancker
E-Mail: mario@astro.uva.nl
WWW: http://www.astro.uva.nl/mario/
Program to display a rotating spiral on the screen in 320x200x256 MCGA
mode using colour-cycling. Please be patient. Generating the spiral image
takes a little while. Requires TP 6.0 or higher. Donated to the public
domain. }
Uses Crt;
type
RGB = Array[1..3] of Byte;
TPalette = Array[0..255] of RGB;
const
MaxX = 319; { Dimensions of MCGA screen. }
MaxY = 199;
MidX = MaxX div 2;
MidY = MaxY div 2;
Palette: TPalette = (
(0, 0, 0), (0, 0, 63), (3, 0, 60), (7, 0, 56),
(10, 0, 53), (13, 0, 50), (15, 0, 48), (17, 1, 46),
(19, 1, 44), (20, 1, 43), (21, 1, 42), (23, 1, 40),
(24, 1, 39), (25, 1, 38), (26, 1, 37), (27, 2, 36),
(28, 2, 35), (29, 2, 34), (30, 2, 33), (31, 2, 32),
(32, 2, 31), (33, 3, 30), (34, 3, 29), (34, 3, 29),
(35, 3, 28), (35, 3, 28), (36, 3, 27), (37, 4, 26),
(37, 4, 26), (38, 4, 25), (38, 4, 25), (39, 4, 24),
(40, 5, 23), (40, 5, 23), (41, 5, 22), (41, 5, 22),
(41, 5, 22), (42, 6, 21), (42, 6, 21), (43, 6, 20),
(43, 6, 20), (43, 6, 20), (44, 7, 19), (44, 7, 19),
(45, 7, 18), (45, 8, 18), (45, 8, 18), (46, 8, 17),
(46, 8, 17), (47, 9, 16), (47, 9, 16), (47, 9, 16),
(47, 9, 16), (48, 10, 15), (48, 10, 15), (48, 10, 15),
(49, 11, 14), (49, 11, 14), (49, 11, 14), (50, 12, 13),
(50, 12, 13), (50, 13, 13), (50, 13, 13), (51, 13, 12),
(51, 14, 12), (51, 14, 12), (51, 14, 12), (52, 15, 11),
(52, 15, 11), (52, 15, 11), (53, 16, 10), (53, 16, 10),
(53, 17, 10), (53, 17, 10), (54, 18, 9), (54, 18, 9),
(54, 19, 9), (54, 19, 9), (54, 20, 9), (55, 20, 8),
(55, 21, 8), (55, 21, 8), (55, 22, 8), (56, 22, 7),
(56, 23, 7), (56, 23, 7), (56, 24, 7), (56, 24, 7),
(57, 25, 6), (57, 26, 6), (57, 26, 6), (57, 27, 6),
(57, 28, 6), (57, 28, 6), (58, 29, 5), (58, 30, 5),
(58, 30, 5), (58, 31, 5), (59, 32, 4), (59, 33, 4),
(59, 33, 4), (59, 34, 4), (59, 35, 4), (59, 36, 4),
(59, 37, 4), (60, 38, 3), (60, 38, 3), (60, 39, 3),
(60, 40, 3), (60, 41, 3), (60, 42, 3), (61, 43, 2),
(61, 44, 2), (61, 45, 2), (61, 46, 2), (61, 47, 2),
(61, 48, 2), (61, 49, 2), (62, 50, 1), (62, 51, 1),
(62, 52, 1), (62, 54, 1), (62, 55, 1), (62, 56, 1),
(63, 57, 0), (63, 59, 0), (63, 60, 0), (63, 61, 0),
(63, 63, 0), (63, 61, 0), (63, 60, 0), (63, 59, 0),
(63, 57, 0), (62, 56, 1), (62, 55, 1), (62, 54, 1),
(62, 52, 1), (62, 51, 1), (62, 50, 1), (61, 49, 2),
(61, 48, 2), (61, 47, 2), (61, 46, 2), (61, 45, 2),
(61, 44, 2), (61, 43, 2), (60, 42, 3), (60, 41, 3),
(60, 40, 3), (60, 39, 3), (60, 38, 3), (60, 38, 3),
(59, 37, 4), (59, 36, 4), (59, 35, 4), (59, 34, 4),
(59, 33, 4), (59, 33, 4), (59, 32, 4), (58, 31, 5),
(58, 30, 5), (58, 30, 5), (58, 29, 5), (57, 28, 6),
(57, 28, 6), (57, 27, 6), (57, 26, 6), (57, 26, 6),
(57, 25, 6), (56, 24, 7), (56, 24, 7), (56, 23, 7),
(56, 23, 7), (56, 22, 7), (55, 22, 8), (55, 21, 8),
(55, 21, 8), (55, 20, 8), (54, 20, 9), (54, 19, 9),
(54, 19, 9), (54, 18, 9), (54, 18, 9), (53, 17, 10),
(53, 17, 10), (53, 16, 10), (53, 16, 10), (52, 15, 11),
(52, 15, 11), (52, 15, 11), (51, 14, 12), (51, 14, 12),
(51, 14, 12), (51, 13, 12), (50, 13, 13), (50, 13, 13),
(50, 12, 13), (50, 12, 13), (49, 11, 14), (49, 11, 14),
(49, 11, 14), (48, 10, 15), (48, 10, 15), (48, 10, 15),
(47, 9, 16), (47, 9, 16), (47, 9, 16), (47, 9, 16),
(46, 8, 17), (46, 8, 17), (45, 8, 18), (45, 8, 18),
(45, 7, 18), (44, 7, 19), (44, 7, 19), (43, 6, 20),
(43, 6, 20), (43, 6, 20), (42, 6, 21), (42, 6, 21),
(41, 5, 22), (41, 5, 22), (41, 5, 22), (40, 5, 23),
(40, 5, 23), (39, 4, 24), (38, 4, 25), (38, 4, 25),
(37, 4, 26), (37, 4, 26), (36, 3, 27), (35, 3, 28),
(35, 3, 28), (34, 3, 29), (34, 3, 29), (33, 3, 30),
(32, 2, 31), (31, 2, 32), (30, 2, 33), (29, 2, 34),
(28, 2, 35), (27, 2, 36), (26, 1, 37), (25, 1, 38),
(24, 1, 39), (23, 1, 40), (21, 1, 42), (20, 1, 43),
(19, 1, 44), (17, 1, 46), (15, 0, 48), (13, 0, 50),
(10, 0, 53), (7, 0, 56), (3, 0, 60), (0, 0, 63));
var
MyPal, InitPal: TPalette;
TimesRun: LongInt;
i, j: Integer;
Time: Longint Absolute $0000:$046c;
StartTime, EndTime: Longint;
{ Waits for VGA's vertical retrace. }
procedure WaitVRetrace; Assembler;
Asm
mov dx, 3DAh
@@1:
in al, dx
and al, 08h
jnz @@1
@@2:
in al, dx
and al, 08h
jz @@2
end;
{ Sets a complete palette. }
procedure SetPal(var Palet: TPalette); Assembler;
Asm
call WaitVRetrace
push ds
lds si, Palet
mov dx, 3c8h
mov al, 0
out dx, al
inc dx
mov cx, 768
rep outsb
pop ds
end;
{ Flips the screen to 320x200x256 MCGA mode and puts all palette colours to
black. }
procedure SetMCGAMode;
var
Palet: TPalette;
begin
Asm
mov ax, 0013h
int 10h
end;
FillChar(Palet, 768, 0); { Put all palette colors to black. }
SetPal(Palet);
end;
{ Flips screen back to text mode. }
procedure SetTextMode; Assembler;
Asm
mov ax, $0003
int 10h
end;
{ PutPixel in MCGA mode. }
procedure PutPixel(x, y: Word; Color: Byte); Assembler;
Asm
mov ax, y
mov bx, x
xchg ah, al
add bx, ax
shr ax, 2
add bx, ax
mov ax, $A000
mov es, ax
mov al, Color
mov es:[bx], al
end;
{ Cycles all colours in both Palettes. }
procedure CyclePalettes;
var
ColMin: RGB;
i, j, k: Byte;
begin
ColMin := MyPal[1];
for i := 1 to 254 do MyPal[i] := MyPal[i+1];
MyPal[255] := ColMin;
ColMin := InitPal[1];
for i := 1 to 254 do InitPal[i] := InitPal[i+1];
InitPal[255] := ColMin;
SetPal(MyPal);
end;
{ Draws a spiral on the screen. }
procedure DrawSpiral(Phi0: Double; Colour: Byte);
var
x, y, i: Integer;
Phase1, Phase2: Double;
begin
Phase1 := Phi0;
Phase2 := 0;
for i := 0 to 1850 do
begin
x := MidX + round(Phase2*sin(Phase1));
y := MidY + round(Phase2*cos(Phase1)/1.2); { Divide by 1.2 to correct for non-square pixels. }
if (x >= 0) and (x <= MaxX) and (y >= 0) and (y <= MaxY) then PutPixel(x, y, Colour);
Phase1 := Phase1 + 0.0035*Pi;
Phase2 := Phase2 + 0.035*Pi;
end;
end;
begin
SetMCGAMode;
MyPal := Palette;
InitPal := Palette;
StartTime := Time;
for i := 0 to 255 do { Draw spirals in 255 different colours. }
DrawSpiral(i*2*Pi/255, i);
EndTime := Time;
TimesRun := 0;
Repeat
if (TimesRun < 256) then { Start with turning colours up. }
begin
for i := 0 to 255 do
for j := 1 to 3 do
MyPal[i,j] := round(InitPal[i,j]*TimesRun/255);
end;
if (TimesRun > 3000-256) then { And end with turning colours down. }
begin
for i := 0 to 255 do
for j := 1 to 3 do
MyPal[i,j] := round(InitPal[i,j]*(3000-TimesRun)/255);
end;
CyclePalettes;
Inc(TimesRun);
Until KeyPressed or (TimesRun > 3000);
SetTextMode;
WriteLn('Time required to generate image: ', (EndTime-StartTime)/18.0:2:2, ' seconds.');
end.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]