[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]