home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_PAS
/
XLIB_TP5.ZIP
/
UNITS
/
X_PAL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-12-13
|
25KB
|
701 lines
unit X_Pal;
(*----------------------------------------------------------------------- *)
(* MODULE X_PAL *)
(* *)
(* Palette functions all MODE X 256 Color resolutions *)
(* *)
(* *)
(* ****** XLIB - Mode X graphics library **************** *)
(* ****** **************** *)
(* ****** Written By Themie Gouthas **************** *)
(* ****** Converted by Christian Harms **************** *)
(* *)
(* egg@dstos3.dsto.gov.au or teg@bart.dsto.gov.au *)
(* harms@minnie.informatik.uni-stuttgart.de *)
(*----------------------------------------------------------------------- *)
(*
All the functions in this module operate on two variations of the
pallete buffer, the raw and annotated buffers.
All those functions ending in buff operate on the following palette
structure:
BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn
No reference to the starting colour index or number of colours stored
is contained in the structure.
All those functions ending in struc operate on the following palette
structure:
BYTE:c,BYTE:n,BYTE:r0,g0,b0,r1,g1,b1,...rn,gn,bn
where c is the starting colour and n is the number of colours stored
NOTE: previously interrupts were disabled for DAC reads/writes but
they have been left enabled in this version to allow the mouse
interrupt to be invoked.
All functions with raw-palettes can uses with the type Palette from
X_Const (for example : Dark2Pal,Pal2Dark,x_put_pal_raw ).
*)
interface
(*---------------------------------------------------------------------- *)
(* Read DAC palette into annotated type buffer with interrupts disabled *)
(* ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn *)
(* *)
(* WARNING: memory for the palette buffers must all be pre-allocated *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_get_pal_struc(Var PalBuff;NumColors,StartColor:Word);
(*---------------------------------------------------------------------- *)
(* Read DAC palette into raw buffer with interrupts disabled *)
(* ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn *)
(* *)
(* WARNING: memory for the palette buffers must all be pre-allocated *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_get_pal_raw(Var PalBuff;NumColors,StartColor:Word);
(*---------------------------------------------------------------------- *)
(* Write DAC palette from annotated type buffer with interrupts disabled *)
(* ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn *)
(* If DoWait true, VSyncWait will start. *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_put_pal_struc(Var CompPalBuff;DoWait:Boolean);
(*---------------------------------------------------------------------- *)
(* Write DAC palette from annotated type buffer with interrupts disabled *)
(* starting at a new palette index *)
(* *)
(* ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn *)
(* If DoWait true, VSyncWait will start. *)
(* *)
(* WARNING: memory for the palette buffers must all be pre-allocated *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_transpose_pal_struc(Var CompPalBuff;StartColor:Word;DoWait:Boolean);
(*---------------------------------------------------------------------- *)
(* Write DAC palette from raw buffer with interrupts disabled *)
(* ie BYTE r1,g1,b1,r1,g2,b2...rn,gn,bn *)
(* If DoWait true, VSyncWait will start. *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_put_pal_raw(Var PalBuff;NumColors,StartColor:Word;DoWait:Boolean);
(*---------------------------------------------------------------------- *)
(* Set the RGB setting of a vga color *)
(* *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_set_rgb(ColorIndex,R,G,B:Byte);
(*---------------------------------------------------------------------- *)
(* Rotate annotated palette buffer entries *)
(* *)
(* Direction : 0 = backward 1 = forward *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_rot_pal_struc(Var PalBuff;Direction:Word);
(*---------------------------------------------------------------------- *)
(* Rotate raw palette buffer *)
(* *)
(* Direcction : 0 = backward 1 = forward *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_rot_pal_raw(Var PalBuff;Direction,NumColors:Word);
(*---------------------------------------------------------------------- *)
(* Copy palette making intensity adjustment *)
(* x_cpcontrast_pal_struc(char far *src_pal, char far *dest_pal, unsigned char Intensity) *)
(* *)
(* WARNING: memory for the palette buffers must all be pre-allocated *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_cpcontrast_pal_struc(Var PalSrcBuff,PalDestBuff;Intensity:Byte);
(*---------------------------------------------------------------------- *)
(* Write DAC palette from annotated type buffer with specified intensity *)
(* ie BYTE colours to skip, BYTE colours to set, r1,g1,b1,r1,g2,b2...rn,gn,bn *)
(* *)
(* x_put_contrast_pal_struc(char far * pal, unsigned char intensity) *)
(* *)
(* Designed for fading in or out a palette without using an intermediate *)
(* working palette buffer ! (Slow but memory efficient ... OK for small *)
(* pal strucs} *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_put_contrast_pal_struc(Var CompPalBuff;Intensity:Byte);
(* This procedure set a RGB (6-7-6 Level), which are used also from some *)
(* professional Programms like Photo Styler or default pal of BEX ;-) *)
procedure x_Set_RGB_pal;
(* Simply set_pal to set all colors are (0,0,0) . *)
procedure x_set_Black_pal;
(* Soften Set_Pal in Black Screen. *)
procedure x_Dark2Pal(var Colors);
(* Soften Set_Pal from Black Screen. *)
procedure x_Pal2Dark(var Colors);
implementation
uses X_Const,My_Asm;
var Work_Pal:^Palette;
procedure x_get_pal_struc(Var PalBuff;NumColors,StartColor:Word); assembler;
asm
push di
push si
cld
les di,dword ptr [PalBuff] (* Point es:di to palette buffer *)
mov si,[StartColor] (* Store the Start Colour *)
mov ax,si
stosb
mov dx,[NumColors] (* Store the Number of Colours *)
mov al,dl
stosb
mov cx,dx (* setup regs and jump *)
cld
(* call WaitVsyncStart *)
mov ax,si
mov dx,DAC_READ_INDEX
cli
out dx,al (* Tell DAC what colour to start reading*)
mov dx,DAC_DATA
mov bx,cx (* set cx to Num Colors * 3 ( size of *)
shl bx,1 (* palette buffer) *)
add cx,bx
dw _rep_insb (* read the palette enntries *)
sti
pop si
pop di
end;
procedure x_get_pal_raw(Var PalBuff;NumColors,StartColor:Word); assembler;
asm
push di
push si
les di,dword ptr [PalBuff] (* Point es:di to palette buffer *)
mov si,[StartColor]
mov cx,[NumColors]
cld
(* call WaitVsyncStart *)
mov ax,si
mov dx,DAC_READ_INDEX
cli
out dx,al (* Tell DAC what colour to start reading*)
mov dx,DAC_DATA
mov bx,cx (* set cx to Num Colors * 3 ( size of *)
shl bx,1 (* palette buffer) *)
add cx,bx
dw _rep_insb (* read the palette enntries *)
sti
pop si
pop di
end;
(* Intern asm-procedure *)
procedure WritePalEntry; assembler;
asm
mov di,Dx
or cx,cx
jz @@Done
{ cli}
cld (* Make sure we're going the right way *)
mov ax,bx
mov bx,60 (* set the vsync check timer (Vsync *)
(* is tested for at each bx'th entry to *)
(* prevent snow 60 is otimum for 10 *)
(* MHz 286 or greater *)
@@SetLoop:
mov dx,DAC_WRITE_INDEX (* Tell DAC what colour index to start *)
out dx,al (* writing from *)
mov dx,DAC_DATA
db _outsb (* Set the red component *)
db _outsb (* Set the green component *)
db _outsb (* Set the blue component *)
inc al (* increment the colour index *)
dec bx (* decrement vsync test counter *)
js @@test_vsync (* ready to test for vsync again ? *)
loop @@SetLoop (* No! - continue loop *)
jmp @@Done (* All colours done *)
@@test_vsync:
cmp di,false (* DoWait=false ? *)
je @NoWait
mov dx,INPUT_STATUS_0
push ax (* save current colour index *)
@@Wait:
in al,dx (* wait for vsync leading edge pulse *)
test al,08h
jz @@Wait (* If DoWait=false then nop;nop *)
pop ax (* restore current colour index *)
@NoWait:mov bx,60 (* reset vsync test counter *)
loop @@SetLoop (* loop for next colour index *)
@@Done:
{ sti}
end;
procedure x_put_pal_struc(Var CompPalBuff;DoWait:Boolean); assembler;
asm
push ds
push si
cld
lds si,[CompPalBuff] (* load the source compressed colour data *)
lodsb (* get the colours to skip *)
mov ah,0
mov bx,ax (* skip colours *)
lodsb (* get the count of colours to set *)
mov ah,0
mov cx,ax (* use it as a loop counter *)
mov dx,Word(DoWait)
call WritePalEntry
pop si
pop ds
end;
procedure x_transpose_pal_struc(Var CompPalBuff;StartColor:Word;DoWait:Boolean); assembler;
asm
push ds
push si
cld
lds si,[CompPalBuff] (* load the source compressed colour data *)
mov bx,[StartColor]
mov [si],bl
inc si
lodsb (* get the count of colours to set *)
mov ah,0
mov cx,ax (* use it as a loop counter *)
mov dx,Word(DoWait)
call WritePalEntry
pop si
pop ds
end;
procedure x_put_pal_raw(Var PalBuff;
NumColors,StartColor : Word;
DoWait : Boolean); assembler;
asm
push ds
push si
mov cx,[NumColors] (* Number of colours to set *)
mov bx,[StartColor]
lds si,[PalBuff] (* ds:si -> palette buffer *)
mov dx,Word(DoWait)
call WritePalEntry
pop si
pop ds
end;
procedure x_set_rgb(ColorIndex,R,G,B:Byte); assembler;
asm
mov al,[ColorIndex]
mov dx,DAC_WRITE_INDEX (* Tell DAC what colour index to *)
out dx,al (* write to *)
mov dx,DAC_DATA
mov al,[R] (* Set the red component *)
out dx,al
mov al,[G] (* Set the green component *)
out dx,al
mov al,[B] (* Set the blue component *)
out dx,al
end;
(* Intern asm procedure *)
procedure RotatePalEntry(Direction:Word); assembler;
asm;
mov ax,ds (* copy ds to es *)
mov es,ax
dec cx
mov bx,cx (* Multiply cx by 3 *)
shl bx,1
add cx,bx
cmp [Direction],0 (* are we going forward ? *)
jne @@forward (* yes - jump (colors move one position back)*)
std (* no - set reverse direction *)
add si,cx (* set si to last byte in palette *)
add si,2
@@forward:
mov ax,si (* copy si to di *)
mov di,ax
lodsb (* load first color triplet into regs *)
mov dl,al
lodsb
mov dh,al
lodsb
mov bl,al
rep movsb (* move remaining triplets direction indicated *)
(* by direction flag *)
mov al,dl (* write color triplet from regs to last position *)
stosb
mov al,dh
stosb
mov al,bl
stosb
pop di
pop si
pop ds
end;
procedure x_rot_pal_struc(Var PalBuff;Direction:Word); assembler;
asm
push ds
push si
push di
cld
lds si,dword ptr [PalBuff] (* point ds:si to Palette buffer *)
lodsw (* al = colorst ot skip, ah = num colors *)
xor ch,ch (* Set the number of palette entries to cycle in cx *)
mov cl,ah
push [Direction]
call RotatePalEntry
end;
procedure x_rot_pal_raw(Var PalBuff;Direction,NumColors:Word); assembler;
asm
push ds
push si
push di
cld
mov cx,[NumColors] (* Set the number of palette entries to cycle *)
lds si,dword ptr [PalBuff] (* point ds:si to Palette buffer *)
push [Direction]
call RotatePalEntry
end;
procedure x_cpcontrast_pal_struc(Var PalSrcBuff,PalDestBuff;Intensity:Byte); assembler;
asm
push ds
push si
push di
cld
mov bh,0ffh
sub bh,[Intensity]
and bh,07fh (* Palettes are 7 bit *)
lds si,dword ptr [PalSrcBuff] (* point ds:si to Source Palette buffer*)
les di,dword ptr [PalDestBuff] (* point ds:si to Source Palette buffer*)
lodsw (* al = colorst ot skip, ah = num color*)
stosw
xor ch,ch (* Set the number of palette entries to adjust *)
mov cl,ah (* *)
mov dx,0 (* flag set to 0 if all output palette entries zero *)
@@MainLoop:
lodsw
sub al,bh (* adjust intensity and copy RED *)
jns @@DecrementOK_R
xor al,al
@@DecrementOK_R:
sub ah,bh (* adjust intensity and copy GREEN *)
jns @@DecrementOK_G
xor ah,ah
@@DecrementOK_G:
or dx,ax
or dl,ah
stosw
lodsb
sub al,bh (* adjust intensity and copy BLUE *)
jns @@DecrementOK_B
xor al,al
@@DecrementOK_B:
or dl,al
stosb
loop @@MainLoop
mov ax,dx
pop di
pop si
pop ds
end;
procedure x_put_contrast_pal_struc(Var CompPalBuff;Intensity:Byte); assembler;
asm
push ds
push si
push di
cld
mov bh,0ffh
sub bh,[Intensity]
and bh,07fh (* Palettes are 7 bit *)
mov di,40 (* set the vsync check timer (Vsync *)
(* is tested for at each di'th entry to *)
(* prevent snow 40 is otimum for 10 *)
(* MHz 286 or greater) *)
lds si,[CompPalBuff] (* load the source compressed colour data *)
lodsb (* get the colours to skip *)
mov bl,al
lodsb (* get the count of colours to set *)
mov ah,0
mov cx,ax (* use it as a loop counter *)
or cx,cx
jz @@Done
call WaitVsyncStart (* Wait for vert sync to start *)
@@MainLoop:
mov al,bl
mov dx,DAC_WRITE_INDEX (* Tell DAC what colour index to start *)
out dx,al (* writing from *)
inc dx (* == mov dx,DAC_DATA *)
lodsb (* Load each colour component, modify for *)
sub al,bh (* intensity and write to DAC H/Ware *)
jns @@DecrementOK_R
xor al,al
@@DecrementOK_R:
out dx,al
lodsb
sub al,bh
jns @@DecrementOK_G
xor al,al
@@DecrementOK_G:
out dx,al
lodsb
sub al,bh
jns @@DecrementOK_B
xor al,al
@@DecrementOK_B:
out dx,al
inc bl (* increment color index *)
dec di (* decrement vsync test flag *)
js @@test_vsync
loop @@MainLoop
jmp @@Done
@@test_vsync:
mov dx,INPUT_STATUS_0
push ax (* save current colour index *)
@@Wait:
in al,dx (* wait for vsync leading edge pulse *)
test al,08h
jz @@Wait
pop ax (* restore current colour index *)
mov di,40 (* reset vsync test counter *)
loop @@MainLoop (* loop for next colour index *)
@@Done:
sti
pop di
pop si
pop ds
end;
procedure x_Set_RGB_pal;
var i,j,l,w:Word;
begin;
fillchar(Work_Pal^,sizeof(Work_Pal),63);
for i:=0 to 5 do
for l:=0 to 5 do
for j:=0 to 6 do begin;
w:=i+j*6+l*42;
Work_Pal^[w,2]:=12*i+0;
Work_Pal^[w,1]:=10*j+0;
Work_Pal^[w,0]:=12*l+0;
end;
fillchar(Work_Pal^[252,0],3,12);
fillchar(Work_Pal^[253,0],3,25);
fillchar(Work_Pal^[254,0],3,50);
fillchar(Work_Pal^[255,0],3,63);
x_put_pal_raw(Work_Pal^,256,0,true);
end;
procedure x_set_Black_pal; assembler;
asm;
mov dx,$3c6
mov al,$FF
out dx,al (* Port[$3c6]:=$ff; *)
mov cx,$FF
mov dx,$3C8
@3: mov al,cl (* for i:=0 to 255 do *)
out dx,al (* begin; *)
inc dx (* Port[$3C8]:=i; *)
xor al,al
out dx,al; (* rot Port[$3c9]:=0; *)
out dx,al; (* grün Port[$3c9]:=0; *)
out dx,al; (* blau Port[$3c9]:=0; *)
dec dx
loop @3 (* end; *)
end;
procedure X_Pal2Dark(var Colors); assembler;
var Old_DS:Word;
asm;
mov ax,ds
mov Old_DS,ax
mov bx,65 (* for k=64 downto 0 do *)
@Loop:Dec bl
push bx (* AX Rechenwert BL = Faktor *)
les di,DWord [Colors] (* ES:DI Pointer to original-palette *)
lds si,dword ptr [Work_Pal](* DS:SI Pointer to Work_Pal-palette *)
mov cx,768 (* CX Loop-Wert *)
@1: xor ah,ah
mov al,es:[di]
mul bl (* for i:=0 to 255 do *)
shl ax,1 (* for j:=0 to 2 do *)
shl ax,1 (* Soft_Pal[i,j]:= *)
mov ds:[si],ah (* Word(Colors[i,j])*k div 64; *)
inc di
inc si
loop @1
mov ax,Old_DS
mov ds,ax
call WaitVsyncStart
lds si,dword ptr [Work_Pal]
mov cx,256 (* NumColor := 256 *)
xor bx,bx (* StartColor := 0 *)
xor dx,dx (* DoWait := False *)
call WritePalEntry
mov ax,Old_DS
mov ds,ax
pop bx
cmp bl,0
jnz @Loop
mov ax,Old_DS
mov ds,ax
end;
procedure X_Dark2Pal(var Colors); assembler;
var Old_DS:Word;
asm;
mov ax,ds
mov Old_DS,ax
mov bx,1 (* for k=1 to 64 do *)
@Loop:Inc bl
push bx (* AX Rechenwert BL = Faktor *)
les di,DWord [Colors] (* ES:DI Pointer to original-palette *)
lds si,dword ptr [Work_Pal](* DS:SI Pointer to Work_Pal-palette *)
mov cx,768 (* CX Loop-Wert *)
@1: xor ah,ah
mov al,es:[di]
mul bl (* for i:=0 to 255 do *)
shl ax,1 (* for j:=0 to 2 do *)
shl ax,1 (* Soft_Pal[i,j]:= *)
mov ds:[si],ah (* Word(Colors[i,j])*k div 64; *)
inc di
inc si
loop @1
mov ax,Old_DS
mov ds,ax
call WaitVsyncStart
lds si,dword ptr [Work_Pal]
mov cx,256 (* NumColor := 256 *)
xor bx,bx (* StartColor := 0 *)
xor dx,dx (* DoWait := False *)
call WritePalEntry
mov ax,Old_DS
mov ds,ax
pop bx
cmp bl,64
jne @Loop
end;
begin;
GetMem(Work_Pal,sizeof(palette)+8);
end.