[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{
This is my unit for fast PCX 320x200 show, as its almost in ASM its really
fast. It has only a handicap: as you must load the entire file in memory
before you show it, the file size could not be greater than 64K:
Sorry if I left some spanish comment.
=== Cut === }
UNIT FASTPCX;
{$G+}
{$s-}
{$r-}
{$i-}
{$x+}
{$O+}
(* Requires 286+ *)
INTERFACE
(*
PROCEDURE UNPACKPCX(Setpal:Boolean; True if you want the palette to be set
VAR FTE,DST; FTE -> where the file is loaded
DST -> whre to put it, usually Mem[$a000:0]
VAR Paleta You got the palette here,allways );
Restricctions:
- The file must be 320x200 exactly, no bigger, no smaller.
- It must be a 256 colors PCX.
- No more than 64K.
Example:
.....
VAR P:Pointer;
F:FILE;
Paleta:ARRAY[0..767] OF Byte;
BEGIN
Assign(F,'PRUEBA.PCX');
GetMem(P,65000);
Reset(F,1);
BlockRead(F,P^,FileSize(F);
Close(F);
ASM { Cambio modo de video }
MOV AX,$13
INT $10
END;
UNPACKPCX(TRUE,P^,Mem[$a000:0],Paleta);
{ Desempaqueto PCX en P^ a RAM de video y cambio su paleta }
REPEAT UNTIL Keypressed;
FreeMem(P,65535);
....
*)
IMPLEMENTATION
PROCEDURE UNPACKPCX(PonerPaleta:Boolean;VAR FTE,DST;VAR Paleta); (*Debe ser
un 320x200x256*) assembler;ASM
PUSH DS (* preservo Data Segment *)
CLD (* borro indicador de direcci¢n *)
XOR CX,CX (* CX=0, para que en toda la rutina CH est� siempre a 0, tal
*) (* que CX sea siempre igual a CL *)
LDS SI,[FTE] (* DS:SI --> FTE *)
ADD SI,128 (* Salto cabecera *)
LES DI,[DST] (* ES:DI -- DST *)
MOV DX,64000 (* Tengo que leer 64000 bytes *)
@BUCLE:
MOV CL,DS:[SI] (* Tomo valor *)
AND CL,0C0h
CMP CL,0C0h (* >=192 *)
JZ @COMPRESSED (* si es as¡ valor comprimido *)
MOVSB (* en caso contrario copio fuente en destino *)
DEC DX (* decremento DX pues falta uno menos *)
JMP @NEXT (* salto a siguiente *)
@COMPRESSED:
MOV CL,DS:[SI] (* Recupero valor (el AND lo machac¢) *)
AND CL,03Fh (* resto 192 *)
SUB DX,CX (* quito tantos puntos como contiene CL *)
INC SI (* paso a siguiente valor *)
LODSB (* lo cargo *)
REP STOSB (* y lo vuelco CX veces *)
@NEXT:
OR DX,DX (* comparo DX con cero *)
JNZ @BUCLE (* y si no lo es paso a bucle *)
@PALET:
INC SI (* SALTO valor 12, que precede a paleta *)
MOV CX,768 (* 768= 256*3 *)
LES DI,[Paleta] (* ES:DI --> Paleta *)
REP MOVSB (* copio paleta en "Paleta" *)
MOV CX,768
LDS SI,[Paleta]
@LOOP:
MOV AL,DS:[SI]
SHR AL,2
MOV DS:[SI],AL
INC SI
LOOP @LOOP; (* La divido por 4 , en el fichero PCX los valores de
paleta est�n multiplicados por 4 *)
MOV AL,PonerPaleta (* Compruebo si he de mostrarla *)
OR AL,AL (* 0=FALSE, otro valor =TRUE *)
JZ @FIN (* En caso contario salto a FIN *)
MOV DX,3DAh (* Espero retrazado *)
@Espera1:
IN AL,DX
AND AL,08h
JNZ @Espera1
@Espera2:
IN AL,DX
AND AL,08h
JZ @Espera2
MOV DX,3C8h (* Y la muestro *)
XOR AL,AL
OUT DX,AL
INC DX
MOV CX,768
SUB SI,CX
REP OUTSB
(* Si se quiere evitar la niebla en modelos lentos como
286 o 386sx 16Mhz conviene que la paleta en lugar de
ponerse de golpe se ponga por partes, esperando un
retrazado cada parte *)
@FIN:
POP DS (* recupero DS *)
END;
END.
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]