'=========================================================================== ' Subject: FLI-PLAYER Date: 08-26-95 (04:36) ' Author: Robert Seidel Code: PB ' Origin: seidel@ifk.uni-jena.de Packet: PB.ABC '=========================================================================== $IF 0 FLIPLAY - a FLI-Player written in PowerBASIC 3.00c Beta-Version: some known bugs, but not corrected :( :< , because I have no time Note: Robert Seidel (some changes) for PowerBASIC 3.00c, I have removed the MODEX-Libary and optimized some parts, now it works about 200% faster than the original version written by Dean using Quick BASIC ! Thanks to Dean for this great source. Robert Seidel Kefersteinstr. 14 D-07745 Jena Germany E-MAIL: seidel@ifk.uni-jena.de (my dad's adress) This player has some problems with newer FLI-files, but I have no informations about the new headers. If somebody changes this file, it would be great if you could send me the new version of FLIPLAY and you will get some things I have written in PowerBASIC ! If you are interested in changing PowerBASIC- Sources, write me too ... You can you use it in your own programms, but please send me a copy of your programm (Shareware -> REGISTERED VERSION !!!) and include my name in your credits ! This file includes a small part of XGRAF, my SCREEN 13 libary. If you want to have it, write me and send me a disc with your stuff ! Optimized: -new graphic macros -no CVI/CVL-functions -some ASM-parts -used INCR/DECR -converted PEEK to ASM -... $ENDIF '----------------------- Compiler options ------------------------- $ERROR ALL OFF 'for more speed $LIB ALL OFF $CPU 80386 'I have used some 386-commands $FLOAT EMULATE 'this programm uses no coprocessor-instructions, so the EXE 'won't be bigger ! $OPTIMIZE SPEED '----------------------- Data types ------------------------------- TYPE Fheader 'This is the format of the Header on a .FLI Size AS LONG Typ AS STRING * 2 Numf AS INTEGER Wid AS INTEGER Hei AS INTEGER Bits AS INTEGER Flag AS INTEGER Speed AS INTEGER Nex AS LONG Fri AS LONG Blank AS STRING * 102 END TYPE TYPE Frameh 'This is the header attached to each frame on a .FLI Size AS LONG Typf AS INTEGER Nchu AS INTEGER Blank AS STRING * 8 END TYPE TYPE Chunkh 'This is the header for each Chunk in a frame Size AS LONG Typec AS INTEGER END TYPE DEFINT A-Z DIM DEFSEG AS SHARED INTEGER 'the PEEK-substitute needs this DIM W AS SHARED INTEGER DIM Fhead AS SHARED Fheader DIM Chunk AS SHARED Chunkh DIM Lns AS SHARED INTEGER DIM Clr AS SHARED INTEGER DIM RS AS SHARED STRING DIM FileN AS SHARED INTEGER SHARED a$ OPTION BINARY BASE 1 RS = "FLIPLAY V1.02 Beta (320x200x256) by Robert Seidel 6-11/7-16/8-26 1995" '----------------------- Main ------------------------------------- IF COMMAND$ = "" THEN 'Access input ? RS ? "File not specified!" END END IF Nme$ = COMMAND$ IF INSTR( Nme$, "." ) = 0 THEN Nme$ = Nme$ + ".FLI" ? RS ? "(QUICK BASIC Version by Dean) ? "This was written in POWER BASIC!!! ? "Now playing: " ; Nme$ ? "Press any key to continue... WHILE INKEY$ = "" WEND ! MOV AX , &h13 ! INT &h10 ! MOV AX , 19 + 128 ;this is necessary, because I have a strange VGA-card ! INT &h10 OPEN Nme$ FOR BINARY AS #1 FileN = FILEATTR(1 , 2) DO UNTIL a$ <> "" a$ = INKEY$ ' t! = TIMER Playfli Nme$ 'Play the .FLI ' time! = TIMER - t! LOOP CLOSE #1 ! MOV AX , 3 ! INT &h10 ? RS END '----------------------- PlayFLI SUB ------------------------------ DIM STATIC Fm(0 TO 32766) AS SHARED INTEGER SUB Playfli( XName$ ) SEEK #1 , 1 GET #1 ,, Fhead 'Get the header data DIM Frame AS Frameh 'Set the Frame varible Lr = LOC( 1 ) GET #1 ,, Frame Seekn& = Frame.Size + Lr + 1 DEFSEG = VARSEG( Fm(0) ) Vl = VARPTR( Fm(0) ) Lns = Vl 'Get the whole FIRST frame into memory ! PUSH DS ! MOV AH , &h3F ! MOV BX , FileN ! DB &h66 ! MOV CX , Frame[0] ! MOV DS , DEFSEG ! MOV DX , Vl ! INT &h21 ! POP DS FOR Frms = 1 TO Fhead.Numf IF INKEY$ <> "" THEN a$ = " " EXIT SUB END IF IF Frms > 1 THEN SEEK #1 , Seekn& - 1 'PB needs the "- 1" or you get an overflow ! GET #1 ,, Frame 'Get the frame data INCR Seekn& , Frame.Size 'Store where next frame in file is 'Get the whole frame ! PUSH DS ! MOV AH , &h3F ! MOV BX , FileN ! DB &h66 ! MOV CX , Frame[0] ! MOV DS , DEFSEG ! MOV DX , Vl ! INT &h21 ! POP DS Lns = Vl END IF FOR t = 1 TO Frame.Nchu 'Chunk.Size = PEEKL( Lns ) 'Get chunk data ! MOV ES , DEFSEG ! MOV BX , Lns ! DB &h66 ! MOV AX , ES:[BX] ! DB &h66 ! MOV Chunk[0] , AX INCR Lns , 4 'Chunk.Typec ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AX , ES:[BX] ! MOV Chunk[4] , AX ! MOV AX , Lns ! INC AX ! INC AX ! MOV Lns , AX C = Chunk.Typec IF C = 11 THEN 'This is if its a PALETTE block ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AX , ES:[BX] ! MOV W , AX INCR Lns , 2 Cl = 0 FOR i = 1 TO W ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV a , AH INCR Lns INCR Cl , a ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV f , AH INCR Lns IF f = 0 THEN f = 256 FOR e = Cl TO f - 1 OUT &H3C8, e ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV g , AH INCR Lns OUT &H3C9, g ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV g , AH INCR Lns OUT &H3C9, g ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV g , AH INCR Lns OUT &H3C9, g NEXT e NEXT i END IF IF C = 15 THEN 'This is if it's a FIRST frame RLE x = 0 y = 0 DO ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV Nump , AH INCR Lns FOR r = 1 TO Nump ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV u , AH INCR Lns IF u < 128 THEN ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV Clr , AH INCR Lns ! MOV AX , 320 ! MUL y ! MOV DI , AX ; Formel : 320 * y + x ! ADD DI , x ; fr Offset ! MOV DX , &hA000 ; Segment : A000h (Videospeicher) ! MOV ES , DX ! MOV AL , Clr ; Farbe ! MOV AH , AL ! MOV CX , u ! SHR CX , 1 ! REP STOSW ! ADC CX , CX ! REP STOSB INCR x , u END IF IF u > 127 THEN 'This line uses FABS, and so I have written an integer ABS 'u = IABS( u - 255 ) + 1 ! MOV AX , u ! SUB AX , 255 ! CWD ! XOR AX , DX ! SUB AX , DX ! INC AX ! MOV u , AX FOR w = 1 TO u ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV f , AH INCR Lns ! MOV AX , 320 ! MUL y ! MOV DI , AX ; Formel : 320 * y + x ! ADD DI , x ; fr Offset ! MOV DX , &hA000 ; Segment : A000h (Videospeicher) ! MOV ES , DX ! MOV AL , f ; Farbe ! MOV ES:[DI] , AL INCR x NEXT w END IF NEXT r x = 0 INCR y LOOP UNTIL y > = 199 END IF IF C = 12 THEN 'This is if it's another frame, it skips lines but 'it's also an RLE ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AX , ES:[BX] ! MOV y , AX INCR Lns , 2 x = 0 ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AX , ES:[BX] ! MOV Clins , AX INCR Lns , 2 FOR Ncl = 1 TO Clins 'Get num of lines to skip ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV a , AH INCR Lns IF a = 0 THEN Skip FOR Npa = 1 TO a Repeat: 'Get num of pixels to skip ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV Pskip , AH INCR Lns INCR x , Pskip IF Pkskip = 255 THEN Repeat ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV Snd , AH INCR Lns IF Snd < 128 THEN FOR Rd = 1 TO Snd ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV Clr , AH INCR Lns ! MOV AX , 320 ! MUL y ! MOV DI , AX ; Formel : 320 * y + x ! ADD DI , x ; fr Offset ! MOV DX , &hA000 ; Segment : A000h (Videospeicher) ! MOV ES , DX ! MOV AL , Clr ; Farbe ! MOV ES:[DI] , AL INCR x NEXT Rd ELSE 'This line uses FABS, and so I have written an integer ABS 'Snd = IABS( Snd - 256 ) ! MOV AX , Snd ! SUB AX , 256 ! CWD ! XOR AX , DX ! SUB AX , DX ! MOV Snd , AX ! MOV ES , DEFSEG ! MOV BX , Lns ! MOV AH , ES:[BX] ! MOV Clr , AH INCR Lns ! MOV AX , 320 ! MUL y ! MOV DI , AX ; Formel : 320 * y + x ! ADD DI , x ; fr Offset ! MOV DX , &hA000 ; Segment : A000h (Videospeicher) ! MOV ES , DX ! MOV AL , Clr ; Farbe ! MOV AH , AL ! MOV CX , Snd ! SHR CX , 1 ! REP STOSW ! ADC CX , CX ! REP STOSB INCR x , Snd END IF NEXT Npa Skip: x = 0 INCR y NEXT Ncl END IF NEXT t ' FOR Wt = 1 TO Fhead.Speed ' Waitvbi 'Do delay for num set of video cycles ' NEXT Wt 'If not needed, it goes faster on fast frame rate FLIs if REMED NEXT Frms END SUB SUB Waitvbi Agin: i = INP( &H3DA ) a = i AND &H8 IF a = 1 THEN Agin Agin2: i = INP( &H3DA ) a = i AND &H8 IF a = 0 THEN Agin2 END SUB