home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
ALIAS.ZIP
/
ALIASPAS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-03-26
|
11KB
|
586 lines
Program AntiAliasPrototyper;
{
This is an scaling/rotation/antialiasing prototyping program
by Lewis A. Sellers, ie Minimalist of The Minimalist Group
(http://www.1stresource.com/l/lsellers/),
and the MOSOCI Grail Project (http://www.dwc.edu/grail).
Written 1995-1996 A.D.
You can use it and the code involved if you wish as long as
you include the standard greetings to me somewhere in your
program, say in the credits.
It was originally a Turbo Borland C/ASM DOS 16-bit program,
but I recoded it into Pascal 7.0.
My first pascal program ever on the IBM platform actually. :-)
Frankly, it is a lot cleaner looking than the original. Hmmm...
The Keys:
'1' is no antialiasing.
'2' is bilinear.
'3' is trilinear.
'4' is... something I was playing with.
The left/right arrows change rotation.
The - + [ and ] keys zoom.
Press any key to stop zooming.
ESC and Space stop the program.
You must supply a BMP filename as an argument such as:
C:> ALIAS DEATH.BMP
The BMP it uses must be a 320x200 256 color grayscale image.
This is by no means fast. If I want something fast I do it in pure
assembly.
GREETS:
Thanks to __Elendil and Lumpy (and Hugh and Bimba) for the impromptu
Pascal hints. :)
And JMX/Opiate for the incentive to learn pascal.
}
{$R-}
{$X+} { use FPU }
{$M 16384,196608,196608} {probably too much... but tired of crashes while experimenting }
USES
Crt, DOS;
const
{screen constants}
WIDTH = 320;
HEIGHT = 200;
SCREENSIZE = WIDTH*HEIGHT;
PALETTESIZE = 256*3;
VGA : Word = $a000;
FAILURE = 0;
SUCCESS = 1;
PI = 3.14159;
type
pScreen = ^pScreenType;
pScreenType = array[0..SCREENSIZE] of byte;
VAR
texture : pScreen;
composite :pScreen;
y320 : array[0..HEIGHT] of word;
{ switch to 320x200 256 straight VGA }
Procedure SetGraphicsMode; assembler;
Asm
mov ax,13h
int 10h
mov dx,3c2h
mov al,0e3h
out dx,al
End;
{ back to 80x25 text mode }
Procedure SetTextMode; assembler;
Asm
mov ax,03h
int 10h
End;
{ load the 320x200 grayscale bitmap into memory }
Function LoadImage(filename : string) : byte;
type
pPalette = ^PaletteType;
PaletteType = array[0..PALETTESIZE] of byte;
Var
pFileMem : pScreen;
FileHandle : file;
thrash : pScreen;
palette : pPalette;
result : word;
Begin
Assign(FileHandle, filename);
Reset(FileHandle, 1);
GetMem(thrash, 320*200);
GetMem(palette, 1024);
Seek(FileHandle, 54);
BlockRead(FileHandle, palette^, 1024, result);
BlockRead(FileHandle, thrash^, 320*200, result);
Close(FileHandle);
{ fake thrash for testing }
{ Asm
les di, thrash
mov cx,320*200
sub al,al
@xyloop:
mov es:[di],al
inc al
inc di
dec cx
cmp cx,0
jne @xyloop
End; }
{ MS uses funky file formats.
Change from b-g-r-unused dword format to proper RGB 3byte and write
it to the video card as we do so. }
port[$3c6]:=$0ff;
port[$3c8]:=0;
Asm
les si,palette
mov cx,256
cld
mov dx,$3c9
@ploop:
mov al,es:[si+2]
shr al,2
out dx,al
mov al,es:[si+1]
shr al,2
out dx,al
mov al,es:[si]
shr al,2
out dx,al
add si,4
dec cx
jne @ploop
End;
{ Thrash the dumb MS format... The image is stored uncompressed
UPSIDE-DOWN, each line being on a 32-bit DWORD boundry. Hmm. }
Begin
Asm
push ds
cld
mov cx, HEIGHT
les di, texture
lds si, thrash
add di, (HEIGHT-1)*WIDTH
@tloop:
push cx
push si
push di
mov cx, WIDTH/2
rep movsw
pop di
pop si
pop cx
add si, WIDTH
sub di, WIDTH
dec cx
cmp cx,0
jne @tloop
pop ds
End;
End;
FreeMem(palette, 1024);
FreeMem(thrash, 320*200);
LoadImage:=SUCCESS;
End;
{ This is it. This rotates and scales the image into a 200x200 window. }
Procedure FastRotate(scale, ang : Real);
VAR
xscale,
yscale,
xc,
yc : Longint;
scanline : word;
x, y : Integer;
tempx, tempy : word;
xlong, ylong : Longint;
tseg, toff : word;
hseg, hoff : word;
texel : byte;
Begin
xscale := round ( (sin(ang)*65536.0)*scale);
yscale := round ( (cos(ang)*65536.0)*scale);
xc := 160*65536 - (100*(yscale+xscale));
yc := 100*65536 - (100*(yscale-xscale));
scanline:=0;
tseg:=seg(texture^);
toff:=ofs(texture^);
hseg:=seg(composite^);
hoff:=ofs(composite^);
for y:=0 to 199 do
Begin
xlong:=xc;
ylong:=yc; { init x/ylong to topleft of square }
for x:=60 to 60+200 do
Begin { normally from 0 to 319 }
tempx:=xlong SHR 16;
tempy:=ylong SHR 16;
if (tempx<0) OR (tempx>=WIDTH) OR (tempy<0) OR (tempy>=HEIGHT) then
Begin
Mem[hseg:hoff+scanline+x]:=0;
End
else
Begin
texel:=Mem[tseg:toff+y320[tempy]+tempx];
Mem[hseg:hoff+scanline+x]:=texel;
End;
inc(xlong,yscale);
dec(ylong,xscale);
End;
inc(scanline,WIDTH);
inc(xc,xscale);
inc(yc,yscale);
End;
End;
{ The bilinear antialiasing is post rotation/scaling here.
We perform the operation on the HOLDing texture which is then blitted
to video memory elsewhere in the program. }
Procedure Bilinear; assembler;
Asm
push ds
lds di, composite
add di, (WIDTH+1) + 60
mov cx, 198
@yloop:
push cx
push di
mov cx, (WIDTH-2) - 120
@xloop:
sub ax,ax
sub bx,bx
mov al,[di-1]
add bx,ax
mov al,[di+1]
add bx,ax
mov al,[di-WIDTH]
add bx,ax
mov al,[di+WIDTH]
add bx,ax
shr bx,2
mov al,[di]
add bx,ax
shr bx,1
mov [di],bl
inc di
dec cx
cmp cx,0
jne @xloop
pop di
pop cx
add di,WIDTH
dec cx
cmp cx,0
jne @yloop
pop ds
End;
{ The trilinear antialiasing is post rotation/scaling here. }
Procedure Trilinear; assembler;
Asm
push ds
lds di, composite
add di, (WIDTH+1) + 60
mov cx, (HEIGHT-2)
@yloop:
push cx
push di
mov cx, (WIDTH-2) - 120
@xloop:
mov ax,0
mov bx,0
mov al,[di-1]
add bx,ax
mov al,[di+1]
add bx,ax
mov al,[di-WIDTH]
add bx,ax
mov al,[di+WIDTH]
add bx,ax
mov al,[di-(WIDTH-1)]
add bx,ax
mov al,[di-(WIDTH-1)]
add bx,ax
mov al,[di+(WIDTH+1)]
add bx,ax
mov al,[di+(WIDTH-1)]
add bx,ax
shr bx,3
mov al,[di]
add bx,ax
shr bx,1
mov [di],bl
inc di
dec cx
cmp cx,0
jne @xloop
pop di
pop cx
add di,WIDTH
dec cx
cmp cx,0
jne @yloop
pop ds
End;
{ The hyper-linear? antialiasing is post rotation/scaling here.
If you're playing with antialiasing, do it here. This is the most
interesting of effects I ran across while playing with antialiasing.
Produces a short of fuzzy-ghosting afterimage. }
Procedure Hyperlinear; assembler;
Asm
push ds
lds di, composite
add di, (WIDTH+1)+60
mov cx, (HEIGHT-2)
@yloop:
push cx
push di
mov cx, (WIDTH-1) - 60*2
@xloop:
sub ax,ax
sub dx,dx
mov al,[di-1]
add dx,ax
mov al,[di+1]
add dx,ax
mov al,[di-WIDTH]
add dx,ax
mov al,[di+WIDTH]
add dx,ax
mov al,[di-(WIDTH+1)]
add dx,ax
mov al,[di-(WIDTH-1)]
add dx,ax
mov al,[di+(WIDTH+1)]
add dx,ax
mov al,[di+(WIDTH-1)]
add dx,ax
shr dx,3
mov al,[di]
add dx,ax
shr dx,1
mov [di-(WIDTH+1)],dl
mov [di+(WIDTH+1)],dl
mov [di-(WIDTH-1)],dl
mov [di+(WIDTH-1)],dl
inc di
dec cx
cmp cx,0
jg @xloop
pop di
pop cx
add di, WIDTH
dec cx
cmp cx,0
jg @yloop
pop ds
End;
{ copy the composition texture to the VGA screen memory. }
Procedure Copycomposite; assembler;
Asm
push ds
mov di, VGA
mov es,di
sub di,di
lds si,composite
mov cx,320*200/2
cld
rep movsw
pop ds
End;
{ clear the composition texture }
Procedure Clearcomposite; assembler;
Asm
les di, composite
mov cx,320*200/2
sub ax,ax
cld
rep stosw
End;
{ the main }
VAR
angle,
angle_v,
scale : Real;
n,
alias: Integer;
key : Char;
Begin
ClrScr;
Writeln('Antialiasing Prototyper by Minimalist 1995-1996.');
Writeln;
if ParamCount=0 then
Begin
writeln('Use: ALIAS filename.bmp');
halt(1);
End;
Writeln('This is the PASCAL version of the original C prototyper written the week of');
Writeln('March 13-14th in preparation for NAID 96. It is also the very first PASCAL');
Writeln('program I have written for the IBM PC.');
Writeln('The BMP must be 320x200 256 grayscale.');
Writeln;
Writeln('You may use any of the following keys:');
Writeln(' ESC will exit the program.');
Writeln(' 1 no antialiasing');
Writeln(' 2 post Bilinear antialising');
Writeln(' 3 post Trilinear antialiasing');
Writeln(' 4 post um... hyperlinear antialiasing? :-)');
Writeln(' Use left/right arrows to change rotation.');
Writeln(' Zoom with the - + [ and ] keys. Press any other to stop.');
{ Writeln;
Writeln('=texture=');
Writeln('memory ',MaxAvail);
}
if MaxAvail < 64000 then
Begin
Writeln('Low Memory ',MaxAvail);
Halt(1);
End;
GetMem(texture, 64000);
{
Writeln('texture ',seg(texture),':',ofs(texture));
Writeln('texture^ ',seg(texture^),':',ofs(texture^));
Writeln('texture^ seg ',seg(texture^), ' texture^ off', ofs(texture^));
Writeln;
Writeln('=composite=');
Writeln('memory ',MaxAvail);
}
if MaxAvail < 64000 then
Begin
Writeln('Low Memory ',MaxAvail);
Halt(1);
End;
GetMem(composite, 64000);
{
Writeln('composite ',seg(composite),':',ofs(composite));
Writeln('composite^ ',seg(composite^),':',ofs(composite^));
Writeln('composite^ seg ',seg(composite^), ' composite^ off', ofs(composite^));
}
Writeln;
Writeln('Press any key to begin....');
Readkey;
for n:=0 to 199 do y320[n]:=n*320;
SetGraphicsMode;
if LoadImage(ParamStr(1)) = FAILURE then
Begin
SetTextMode;
writeln('The file ', ParamStr(1),' does not exist.');
halt(2);
End;
clearcomposite;
angle:=PI/256;
angle_v:=-PI/128;
scale:=1.05;
alias:=0;
key:=#1;
while key<>#27 do
Begin
if keyPressed then key:=ReadKey;
case key of
'1': alias:=1;
'2': alias:=2;
'3': alias:=3;
'4': alias:=4;
'5': alias:=5;
'-': scale:=scale-0.05;
'=': scale:=scale+0.05;
'[': scale:=scale-0.5;
']': scale:=scale+0.5;
End;
if key=#0 then
Begin
key:=ReadKey;
case key of
#75: angle_v:=angle_v-PI/128;
#77: angle_v:=angle_v+PI/128;
End;
End;
Begin
Gotoxy(1,1);
Write('Scale:=',scale,' ');
Gotoxy(1,2);
Write('Angle:=',angle,' ');
FastRotate(scale,angle);
case alias of
2: bilinear;
3: trilinear;
4: hyperlinear;
End;
End;
copycomposite;
angle:=angle+angle_v;
End;
SetTextMode;
Writeln('By Minimalist (Lewis A. Sellers) 1996. Part of the C/Pascal/Asm package.');
Writeln('To contact, email: lsellers@1stresource.com (shortly to be lsellers@usit.net).');
Writeln('or drop by http://www.dwc.edu/grail, site of the Grail Operating System Project.');
FreeMem(composite,64000);
FreeMem(texture,64000);
End.