diff --git a/programs/media/fliplayer/ASPAPI.INC b/programs/media/fliplayer/ASPAPI.INC new file mode 100644 index 0000000000..5e3f583eea --- /dev/null +++ b/programs/media/fliplayer/ASPAPI.INC @@ -0,0 +1,119 @@ +macro start_draw_window x,y,xsize,ysize,areacolor,caption +{ + mov eax, 12 ; function 12:tell os about windowdraw + mov ebx, 1 ; 1, start of draw + int 0x40 + ; DRAW WINDOW + mov eax, 0 ; function 0 : define and draw window + mov ebx, x*65536+xsize ; [x start] *65536 + [x size] + mov ecx, y*65536+ysize ; [y start] *65536 + [y size] + mov edx,areacolor ; color of work area RRGGBB + mov edi,caption ; window title + int 0x40 +} + +macro end_draw_window +{ + mov eax, 12 ; end of redraw + mov ebx, 2 + int 0x40 +} + +macro draw_button x,y,xsize,ysize,id,butcolor,text,textlen,textcolor +{ + mov eax, 8 ; function 8 : define and draw button + mov ebx, (x)*65536+xsize ; [x start] *65536 + [x size] + mov ecx, (y)*65536+ysize ; [y start] *65536 + [y size] + mov edx, id ; button id + mov esi, butcolor ; button color RRGGBB + int 0x40 + + mov ebx, (x+5)*65536+y+(ysize-5)/2 ; Draw button text + mov ecx, textcolor + mov edx, text + xor eax, eax + mov al, textlen + mov esi, eax + mov eax, 4 + int 0x40 +} + +macro outtextxy x,y,prompt,prompt_len,color +{ + mov ebx, x*65536+y ; draw info text with function 4 + mov ecx, color + mov edx, prompt + xor eax, eax + mov al, prompt_len + mov esi, eax + mov eax, 4 + int 0x40 +} + +macro bar x,y,xsize,ysize,color +{ + mov eax, 13 + mov ebx, x*65536+xsize + mov ecx, y*65536+ysize + mov edx, color + int 0x40 +} + +macro line x1,y1,x2,y2,color +{ + mov eax, 38 + mov ebx, x1*65536+x2 + mov ecx, y1*65536+y2 + mov edx, color + int 0x40 +} + +macro rectangle x,y,xsize,ysize,color +{ + x2=x+xsize + y2=y+ysize + line x,y,x2,y,color + line x,y,x,y2,color + line x,y2,x2,y2,color + line x2,y,x2,y2,color +} + +macro putpixel x,y,color +{ + mov eax, 1 + mov ebx, x + mov ecx, y + mov edx, color + int 0x40 +} + +macro lights_on cns +{ + mov ax, cns + test ax, 0x40 + jz @f + push ax + bar 532, 53, 10, 11, 0x0000FF00 + pop ax + @@: + test ax, 0x80 + jz @f + push ax + bar 500, 53, 10, 11, 0x0000FF00 + pop ax + @@: + test ax, 0x100 + jz @f + bar 565, 53, 10, 11, 0x0000FF00 + @@: +} + +out_symbol: + ;mov ebx, x*65536+y ; draw info text with function 4 + ;mov ecx, color + ;mov edx, prompt + mov esi, 1 + mov eax, 4 + int 0x40 + ret + diff --git a/programs/media/fliplayer/FLI_format.TXT b/programs/media/fliplayer/FLI_format.TXT new file mode 100644 index 0000000000..f456e98ec8 --- /dev/null +++ b/programs/media/fliplayer/FLI_format.TXT @@ -0,0 +1,244 @@ + +Flic Files (.FLI) Format description: + + The details of a FLI file are moderately complex, but the +idea behind it is simple: don't bother storing the parts of a +frame that are the same as the last frame. Not only does this +save space, but it's very quick. It's faster to leave a pixel +alone than to set it. + + A FLI file has a 128-byte header followed by a sequence of +frames. The first frame is compressed using a bytewise run-length +compression scheme. Subsequent frames are stored as the +difference from the previous frame. (Occasionally the first +frame and/or subsequent frames are uncompressed.) There is one +extra frame at the end of a FLI which contains the difference +between the last frame and the first frame. + + The FLI header: + + byte size name meaning + offset + + 0 4 size Length of file, for programs that want + to read the FLI all at once if possible. + 4 2 magic Set to hex AF11. Please use another + value here if you change format (even to + a different resolution) so Autodesk + Animator won't crash trying to read it. + 6 2 frames Number of frames in FLI. FLI files have + a maxium length of 4000 frames. + 8 2 width Screen width (320). + 10 2 height Screen height (200). + 12 2 depth Depth of a pixel (8). + 14 4 flags Must be 0. + 18 2 speed Number of video ticks between frames. + 20 4 next Set to 0. + 24 4 frit Set to 0. + 28 100 expand All zeroes -- for future enhancement. + + Next are the frames, each of which has a header: + + byte size name meaning + offset + 0 4 size Bytes in this frame. Autodesk Animator + demands that this be less than 64K. + 4 2 magic Always hexadecimal F1FA + 6 2 chunks Number of 'chunks' in frame. + 8 8 expand Space for future enhancements. All + zeros. + + After the frame header come the chunks that make up the +frame. First comes a color chunk if the color map has changed +from the last frame. Then comes a pixel chunk if the pixels have +changed. If the frame is absolutely identical to the last frame +there will be no chunks at all. + + A chunk itself has a header, followed by the data. The +chunk header is: + + byte size name meaning + offset + 0 4 size Bytes in this chunk. + 4 2 type Type of chunk (see below). + + There are currently five types of chunks you'll see in a FLI +file. + + number name meaning + 11 FLI_COLOR Compressed color map + 12 FLI_LC Line compressed -- the most common type + of compression for any but the first + frame. Describes the pixel difference + from the previous frame. + 13 FLI_BLACK Set whole screen to color 0 (only occurs + on the first frame). + 15 FLI_BRUN Bytewise run-length compression -- first + frame only + 16 FLI_COPY Indicates uncompressed 64000 bytes soon + to follow. For those times when + compression just doesn't work! + + The compression schemes are all byte-oriented. If the +compressed data ends up being an odd length a single pad byte is +inserted so that the FLI_COPY's always start at an even address +for faster DMA. + +FLI_COLOR Chunks + The first word is the number of packets in this chunk. This +is followed directly by the packets. The first byte of a packet +says how many colors to skip. The next byte says how many colors +to change. If this byte is zero it is interpreted to mean 256. +Next follows 3 bytes for each color to change (one each for red, +green and blue). + +FLI_LC Chunks + This is the most common, and alas, most complex chunk. The +first word (16 bits) is the number of lines starting from the top +of the screen that are the same as the previous frame. (For +example, if there is motion only on the bottom line of screen +you'd have a 199 here.) The next word is the number of lines +that do change. Next there is the data for the changing lines +themselves. Each line is compressed individually; among other +things this makes it much easier to play back the FLI at a +reduced size. + + The first byte of a compressed line is the number of packets +in this line. If the line is unchanged from the last frame this +is zero. The format of an individual packet is: + +skip_count +size_count +data + + The skip count is a single byte. If more than 255 pixels +are to be skipped it must be broken into 2 packets. The size +count is also a byte. If it is positive, that many bytes of data +follow and are to be copied to the screen. If it's negative a +single byte follows, and is repeated -size_count times. + + In the worst case a FLI_LC frame can be about 70K. If it +comes out to be 60000 bytes or more Autodesk Animator decides +compression isn't worthwhile and saves the frame as FLI_COPY. + +FLI_BLACK Chunks + These are very simple. There is no data associated with +them at all. In fact they are only generated for the first frame +in Autodesk Animator after the user selects NEW under the FLIC +menu. + +FLI_BRUN Chunks + These are much like FLI_LC chunks without the skips. They +start immediately with the data for the first line, and go line- +by-line from there. The first byte contains the number of +packets in that line. The format for a packet is: + +size_count +data + + If size_count is positive the data consists of a single byte +which is repeated size_count times. If size_count is negative +there are -size_count bytes of data which are copied to the +screen. In Autodesk Animator if the "compressed" data shows signs +of exceeding 60000 bytes the frame is stored as FLI_COPY instead. + +FLI_COPY Chunks + These are 64000 bytes of data for direct reading onto the +screen. + +----------------------------------------------------------------------- +And here's the PRO extensions: +----------------------------------------------------------------------- + +This is supplemental info on the AutoDesk Animator FLI and FLC formats. + +The following is an attempt at describing the newer chunks and frames +that are not described in the Turbo C FLI library documentation. + + Chunk type Chunk ID + ---------- ----------- + FLI_DELTA 7 (decimal) + + First WORD (16 bits) is the number of compressed lines to follow. Next + is the data for the changing lines themselves, always starting with the + first line. Each line is compressed individually. + + The first WORD (16 bits) of a compressed line is the number of packets in + the line. If the number of packets is a negative skip -packets lines. + If the number of packets is positive, decode the packets. The format of + an individual packet is: + + skip_count + size_count + data + + The skip count is a single byte. If more than 255 pixels are to be + skipped, it must be broken into 2 packets. The size_count is also a byte. + If it is positive, that many WORDS of data follow and are to be copied to + the screen. If it is negative, a single WORDS value follows, and is to be + repeated -size_count times. + + Chunk type Chunk ID + ---------- ----------- + FLI_256_COLOR 4 (decimal) + + The first WORD is the number of packets in this chunk. This is followed + directly by the packets. The first byte of a packet is how many colors + to skip. The next byte is how many colors to change. If this number is + 0, (zero), it means 256. Next follow 3 bytes for each color to change. + (One each for red, green and blue). + + The only difference between a FLI_256_COLOR chunk (type 4 decimal) and a + FLI_COLOR chunk (type 11 decimal) is that the values in the type 4 chunk + range from 0 to 255, and the values in a type 11 chunk range from 0 to 63. + + NOTE: WORD refer to a 16 bit int in INTEL (Little Endian) format. + WORDS refer to two-bytes (16 bits) of consecutive data. (Big Endian) + + .FLC special frames and chunks + + FLC's may contain all the above chunks plus one other: + + Chunk type Chunk ID + ---------- ----------- + FLI_MINI 18 (decimal) 12 (Hex) + + From what I understand, this is a miniture 64 x 32 version of the first + frame in FLI_BRUN format, used as an button for selecting flc's from + within Animator Pro. Simply do nothing with this chunk. + + FLC New Frame + + FLC's also contains a frame with the magic bytes set to hex 00A1. This + is the first frame in the .flc file. Actually it isn't a frame at all + but to have several chunks within it that specify file location info + specific to Animator Pro. IE: filepath, font to use, and .COL file info. + This FRAME may be skipped while loading. That's right! Ignore it! The + frame header is the same length as all other frames. So you may read the + frame header, then skip past the rest of the frame. + + + NOTE: When reading the FLI header on the newer FLI and FLC files, the + FLI signature bytes are AF12 instead of AF11 used in the older FLI files. + Also, you cannot ignore the screen width and height they may not be + 320 x 200. + + Allowable screen sizes include: + + 320 x 200, 640 x 480, 800 x 600, 1280 x 1024 + + + NOTE: the delay value between frames appears to be in 1000th's of a + second instead of 70th's. + +If you have any questions or more info on the FLI or FLC formats, +please let me know. + +Mike Haaland +(corrected by P. Oliver 30 May 1997 using information supplied by Reeves Hall) + +CompuServe : 72300,1433 +Delphi : MikeHaaland +Internet : mike@htsmm1.las-vegas.nv.us +Usenet : ...!htsmm1.las-vegas.nv.us!mike + diff --git a/programs/media/fliplayer/ReadMe.txt b/programs/media/fliplayer/ReadMe.txt new file mode 100644 index 0000000000..8a891936ef --- /dev/null +++ b/programs/media/fliplayer/ReadMe.txt @@ -0,0 +1,4 @@ +Fliplayer v0.3 by Asper + +Can play Autodesk *.fli files. + diff --git a/programs/media/fliplayer/build.bat b/programs/media/fliplayer/build.bat new file mode 100644 index 0000000000..ef11dfd739 --- /dev/null +++ b/programs/media/fliplayer/build.bat @@ -0,0 +1,2 @@ +@fasm fliplayer.asm fliplayer +@pause \ No newline at end of file diff --git a/programs/media/fliplayer/fliplayer.asm b/programs/media/fliplayer/fliplayer.asm new file mode 100644 index 0000000000..b6e65f4344 --- /dev/null +++ b/programs/media/fliplayer/fliplayer.asm @@ -0,0 +1,784 @@ +use32 + org 0x0 + + db 'MENUET01' ; 8 byte id + dd 38 ; required os + dd STARTAPP ; program start + dd I_END ; program image size + dd 0x100000 ; required amount of memory + dd 0x100000 ; reserved= extended header + dd filename, 0x0 ; I_Param , I_Icon + +include "aspAPI.inc" + +;Clock_Hz equ 4608 ; Frequency of clock +;Monitor_Hz equ 70 ; Frequency of monitor +;Clock_Scale equ Clock_Hz / Monitor_Hz +CData equ 0x40 ; Port number of timer 0 +CMode equ 0x43 ; Port number of timer control word +BufSize equ 65528 ; Frame buffer size - Must be even + +struc MainHeaderRec +{ + .Padding1 dd ? ; size of the file + .ID dw ? ; magic + .Frames dw ? ; frames + .Padding2 dd ? ; width/height + .Padding3 dd ? ; depth/flags + .Speed dw ? ; speed + .Reserv dw ? ; always = 0 + ; Only for FLC + .Created dd ? ; date file attribute + .Creator dd ? ; creator serial number + .Updated dd ? ; date of the last change + .Updater dd ? ; updater serial number + .Aspectx dw ? ; scale by x + .Aspecty dw ? ; scale by Y + .Padding4 db 38 dup(?) ; Reserved. All zeroes. + .Oframe1 dd ? ; offset to the 1st frame + .Oframe2 dd ? ; offset to the 2nd frame + .Padding5 db 40 dup(?) ; Reserved. All zeroes. +} + +struc FrameHeaderRec +{ + .Size dd ? ; size + .Padding1 dw ? ; magic + .Chunks dw ? ; chunks + .Padding2 db 8 dup(?) ;Pad to 16 Bytes. All zeroes. +} + + +; in: esi = pointer to the buffer + +DrawFrame: + ; this is the routine that takes a frame and put it on the screen + @Fli_Loop: ; main loop that goes through all the chunks in a frame + cmp word [Chunks],0 ;are there any more chunks to draw? + je @Exit + dec word [Chunks] ;decrement Chunks For the chunk to process now + + mov ax, word [esi+4] ; let AX have the ChunkType + add esi, 6 ; skip the ChunkHeader + cmp ax, 0Bh ; is it a FLI_COLor chunk? + je @Fli_Color + cmp ax, 0Ch ; is it a FLI_LC chunk? + je @Fli_Lc + cmp ax, 0Dh ; is it a FLI_BLACK chunk? + je @Fli_Black + cmp ax, 0Fh ; is it a FLI_BRUN chunk? + je @Fli_Brun + cmp ax, 10h ; is it a FLI_COPY chunk? + je @Fli_Copy + jmp @Fli_Loop ; This command should not be necessary + + @Fli_Color: + mov bx, word [esi] ; number of packets in this chunk (always 1?) + add esi, 2 ; skip the NumberofPackets +;_________________________________________________________________________________________ + mov al, 0 ; start at color 0 + xor cx, cx ; reset CX + @Color_Loop: + or bx, bx ; set flags + jz @Fli_Loop ; Exit if no more packages + dec bx ; decrement NumberofPackages For the package to process now + mov cl, byte [esi] ; first Byte in packet tells how many colors to skip + add al, cl ; add the skiped colors to the start to get the new start + mov edi, pal + add di, cx + + ;push cx ;----- save how many colors to skip -----> + mov cl, byte [esi+1] ; next Byte in packet tells how many colors to change + or cl, cl ; set the flags + jnz @Jump_Over ; if NumberstoChange=0 then NumberstoChange=256 + inc ch ; CH=1 and CL=0 => CX=256 + @Jump_Over: + ;add al, cl ; update the color to start at + add esi, 2 ; skip the NumberstoSkip and NumberstoChange Bytes + .set_next_color: + lodsb ; B + shl al, 2 ; Enlight the color r*4, g*4, b*4 + push ax + + lodsb ; G + shl al, 2 ; Enlight the color r*4, g*4, b*4 + push ax + + lodsb ; R + shl al, 2 ; Enlight the color r*4, g*4, b*4 + + stosb ; R + pop ax + stosb ; G + pop ax + stosb ; B + xor al, al + stosb ; 0 + loop .set_next_color + + jmp @Color_Loop ; finish With this packet - jump back + @Fli_Lc: + mov di, word [esi] ; put LinestoSkip into DI - + mov ax, di ; - to get the offset address to this line we have to multiply With 320 - + shl ax, 8 ; - DI = old_DI shl 8 + old_DI shl 6 - + shl di, 6 ; - it is the same as DI = old_DI*256 + old_DI*64 = old_DI*320 - + add di, ax ; - but this way is faster than a plain mul + add edi, dword [image] + mov bx, word [esi+2] ; put LinestoChange into BX + add esi, 4 ; skip the LinestoSkip and LinestoChange Words + xor cx, cx ; reset cx + @Line_Loop: + or bx, bx ; set flags + jz @Fli_Loop ; Exit if no more lines to change + dec bx + mov dl, byte [esi] ; put PacketsInLine into DL + inc esi ; skip the PacketsInLine Byte + push edi ; save the offset address of this line + @Pack_Loop: + or dl, dl ; set flags + jz @Next_Line ; Exit if no more packets in this line + + dec dl + mov cl, byte [esi] ; put BytestoSkip into CL + add di, cx ; update the offset address + mov cl, byte [esi+1] ; put BytesofDatatoCome into CL + or cl, cl ; set flags + jns @Copy_Bytes ; no SIGN means that CL number of data is to come - + ; - else the next data should be put -CL number of times + mov al, byte [esi+2] ; put the Byte to be Repeated into AL + add esi, 3 ; skip the packet + neg cl ; Repeat -CL times + rep stosb + jmp @Pack_Loop ; finish With this packet + @Copy_Bytes: + add esi, 2 ; skip the two count Bytes at the start of the packet + rep movsb + jmp @Pack_Loop ; finish With this packet + @Next_Line: + pop edi ; restore the old offset address of the current line + add edi, 320 ; offset address to the next line + jmp @Line_Loop + @Fli_Black: + mov edi, dword [image] + mov cx, 32000 ; number of Words in a screen + xor ax, ax ; color 0 is to be put on the screen + rep stosw + jmp @Fli_Loop ; jump back to main loop + @Fli_Brun: + mov edi, dword [image] + mov bx, 200 ; numbers of lines in a screen + xor cx, cx + @Line_Loop2: + mov dl, byte [esi] ; put PacketsInLine into DL + inc esi ; skip the PacketsInLine Byte + push edi ; save the offset address of this line + @Pack_Loop2: + or dl, dl ; set flags + jz @Next_Line2 ; Exit if no more packets in this line + dec dl + mov cl, byte [esi] ; put BytesofDatatoCome into CL + or cl, cl ; set flags + js @Copy_Bytes2 ; SIGN meens that CL number of data is to come - + ; - else the next data should be put -CL number of times + mov al, byte [esi+1] ; put the Byte to be Repeated into AL + add esi, 2 ; skip the packet + rep stosb + jmp @Pack_Loop2 ; finish With this packet + @Copy_Bytes2: + inc esi ; skip the count Byte at the start of the packet + neg cl ; Repeat -CL times + rep movsb + jmp @Pack_Loop2 ; finish With this packet + @Next_Line2: + pop edi ; restore the old offset address of the current line + add edi, 320 ; offset address to the next line + dec bx ; any more lines to draw? + jnz @Line_Loop2 + jmp @Fli_Loop ; jump back to main loop + @Fli_Copy: + mov edi, dword [image] + mov cx, 32000 ; number of Words in a screen + rep movsw + jmp @Fli_Loop ; jump back to main loop + @Exit: + + mov eax, 65 + mov ebx, dword [image] + mov ecx, 320*65536+200 + mov edx, 10*65536+100 + mov esi, 8 + mov edi, pal + xor ebp, ebp + int 0x40 + + ret ; DrawFrame end. + +TFliPlayer_Init: + mov eax, 68 ; Init process memory + mov ebx, 11 + int 0x40 + cmp eax, BufSize + jl .fail + .ok: + ;GetMem(Buffer,BufSize); + mov eax, 68 + mov ebx, 12 + mov ecx, BufSize + int 0x40 + mov dword [Buffer], eax + + ;GetMem(image,32000); + mov eax, 68 + mov ebx, 12 + mov ecx, 320*200*4 ;32000 + int 0x40 + mov dword [image], eax + + + mov word [Interval], -1 ; ClearSpeed + mov ax, 1 + ret + .fail: + xor ax, ax + ret ; TFliPlayer_Init end. + +TFliPlayer_Done: + ;FreeMem(Buffer,BufSize); + mov eax, 68 + mov ebx, 13 + mov ecx, dword [Buffer] + int 0x40 + + ;FreeMem(image,32000); + mov eax, 68 + mov ebx, 13 + mov ecx, dword [image] + int 0x40 + + ret ; TFliPlayer_Done end. + +; in: ax = Speed +;TFliPlayer_SetSpeed: +; mov bl, byte Clock_Scale +; mul bl +; mov word [Interval], ax ;= Speed * Clock_Scale; +; ret ; TFliPlayer_SetSpeed end. + + + +ReadHeader: ;Boolean; + ;BlockRead(FliFile,MainHeader,SizeOf(MainHeader)) ; Read header record + mov eax, dword [filepos] + mov dword [InfoStructure+4], eax + mov dword [InfoStructure+12], 128 + mov dword [InfoStructure+16], MainHeader + mov eax, 70 + mov ebx, InfoStructure + + int 0x40 + + mov eax, 128 + mov dword [filepos], eax + + mov ax, word [MainHeader.ID] + cmp ax, 0xAF11 ; FLI ? + je .fli + + cmp ax, 0xAF12 ; FLC ? + je .flc + + xor ax, ax ; Not a .FLI File + ret + .fli: + mov byte [filetype], 1 + jmp .ok + .flc: + mov byte [filetype], 2 + .ok: +; cmp word [Interval], -1 +; jne @f +; ; Read speed from header +; mov ax, word [MainHeader.Speed] +; mov bl, byte Clock_Scale +; mul bl +; mov word [Interval], ax ;= Speed * Clock_Scale; + mov ax, 1 +; @@: + ret ; ReadHeader end. + +ReadFrame: + ;BlockRead(FliFile,FrameHeader,SizeOf(FrameHeader)); + mov eax, dword [filepos] + mov dword [InfoStructure+4], eax + mov dword [InfoStructure+12], 16 + mov dword [InfoStructure+16], FrameHeader + mov eax, 70 + mov ebx, InfoStructure + + int 0x40 + + add dword [filepos], 16 + ;FrameSize := FrameHeader.Size - SizeOf(FrameHeader); + mov eax, dword [FrameHeader.Size] + sub eax, 16 + mov dword [FrameSize], eax + xor ecx, ecx + + ret ; ReadFrame end. + +ProcessFrame: + ;BlockRead(FliFile,Buffer^,FrameSize); + mov eax, dword [filepos] + mov dword [InfoStructure+4], eax + mov eax, dword [FrameSize] + mov dword [InfoStructure+12], eax + mov eax, dword [Buffer] + mov dword [InfoStructure+16], eax + mov eax, 70 + mov ebx, InfoStructure + + int 0x40 + + mov eax, dword [FrameSize] + add dword [filepos], eax + mov esi, dword [Buffer] + mov dx, word [FrameHeader.Chunks] + mov word [Chunks], dx + call DrawFrame + + ret ; ProcessFrame end. + + +; in: esi = pointer to the filename +TFliPlayer_Play: + mov eax, 70 + mov ebx, InfoStructure + mov dword [InfoStructure+12], 1 + mov dword [InfoStructure+16], FrameHeader + int 0x40 + test ax, ax + jnz .err + + call ReadHeader + test ax, ax + jz .err + + call ReadFrame + + mov eax, dword [FrameSize] + add eax, 128+16 + mov dword [RestartPos], eax + call ProcessFrame + + + .play_again: + mov word [Frame], 1 + .show_next_frame: + + call ReadFrame + cmp dword [FrameSize], 0 + je @f + call ProcessFrame + @@: + + ;REPEAT UNTIL GetClock > Timeout; + mov eax, 5 + mov ebx, 2 + int 0x40 + + push edi + call process_events + pop edi + + mov al, byte [stop] + cmp al, 1 + je .end + + mov ax, word [Frame] + inc ax + mov word [Frame], ax + + cmp ax, word [MainHeader.Frames] + jng .show_next_frame + mov eax, dword [RestartPos] + mov dword [InfoStructure+4], eax + mov eax, 128 + mov dword [filepos], eax + + jmp .play_again + .end: + mov dword [filepos], 0 + xor ax, ax + .err: + + ret ; TFliPlayer_Play end. + + +; in: esi = pointer to filename +AAPlay: + mov byte [pausetime], 0 + mov byte [stop], 0 + cmp byte [playtime], 1 + je .end + call unprint_error + + mov byte [playtime], 1 + call TFliPlayer_Play + test ax, ax + jz .end + call print_error + .end: + mov byte [playtime], 0 + ret ; AAPlay end. + + + +N_KEYCOLOR equ 0x00444444 ; Normal button color +TEXTCOLOR equ 0x80FFFFFF ; Text color +BUTCAPCOLOR equ 0x0000FF00 ; Button caption color + + +unprint_error: + mov eax, 13 + mov ebx, 10*65536+320 + mov ecx, 50*65536+15 + mov edx, 0 ; color + int 0x40 +ret + +print_error: + ;call unprint_error + + mov ebx, 15*65536+54 + mov edx, error_text + mov ecx, TEXTCOLOR - 0x0000FFFF + mov eax, 4 + int 0x40 + +ret + +print_filename: + mov eax, 13 + mov ebx, 10*65536+320 + mov ecx, 30*65536+15 + mov edx, 0 ; color + int 0x40 + + mov ebx, 15*65536+34 + mov edx, filename + mov ecx, TEXTCOLOR - 0x00FF00FF + mov eax, 4 + int 0x40 + +ret + +;********************************** +;* input: ecx = type of map * +;********************************** +get_keyboard_map: + mov eax, 26 + mov ebx, 2 + mov edx, keymap + int 0x40 +ret + +;********************************** +;* input: ecx = type of mode * +;********************************** +set_keyboard_mode: + mov eax, 66 + mov ebx, 1 ; Set keyboard mode + int 0x40 +ret + +get_control_keys_state: + mov eax, 66 + mov ebx, 3 + int 0x40 +ret + +reload_ascii_keymap: + pusha + call get_control_keys_state + mov ecx, 1 + + test ax, 1 ; Left Shift pressed ? + jnz @f + test ax, 2 ; Right Shift pressed ? + jnz @f + test ax, 0x40 ; Caps Lock on ? + jz .load_ascii_keymap + @@: + mov ecx, 2 + .load_ascii_keymap: + call get_keyboard_map + popa + ret + + +STARTAPP: + + call TFliPlayer_Init + test ax, ax + jz close_app + + mov ecx, 1 ; to send scancodes. + call set_keyboard_mode + call reload_ascii_keymap + call draw_window + call print_filename + + cmp [filename], byte 0 + je .noparam + call AAPlay + .noparam: + jmp still + + +draw_window: + start_draw_window 20,170,340,310,0x14224466,labelt + draw_button 15,70,20,20,2,N_KEYCOLOR,keyText,1,BUTCAPCOLOR ; Play + + mov ecx, BUTCAPCOLOR + + mov edx, keyText + mov ebx, 21*65536+77 ; | + call out_symbol + + mov edx, keyText+1 + mov ebx, 22*65536+75 ; - + call out_symbol + + mov ebx, 24*65536+76 ; - + @@: + call out_symbol + inc ebx + cmp ebx, 24*65536+79 + jl @b + + mov ebx, 22*65536+79 ; - + call out_symbol + + mov ebx, 26*65536+77 ; - + call out_symbol + + draw_button 45,70,20,20,3,N_KEYCOLOR,keyText,1,BUTCAPCOLOR ; Pause + + mov ecx, BUTCAPCOLOR + + mov edx, keyText + mov ebx, 49*65536+77 ; | + call out_symbol + + mov ebx, 51*65536+77 ; | + call out_symbol + + mov ebx, 54*65536+77 ; | + call out_symbol + + mov ebx, 55*65536+77 ; | + call out_symbol + + mov ebx, 56*65536+77 ; | + call out_symbol + + draw_button 75,70,20,20,4,N_KEYCOLOR,keyText,1,BUTCAPCOLOR ; Stop + + bar 81,77,8,7,BUTCAPCOLOR + + end_draw_window + ret + +process_events: + mov eax, 11 ; Test if there is an event in the queue. + int 0x40 + + cmp eax,1 ; redraw request ? + jnz @f + call red + ret + @@: + cmp eax,3 ; button in buffer ? + jnz @f + call button + ret + @@: + cmp eax,2 ; key in buffer ? + jnz @f + + call key + @@: + ;jz key + ; cmp eax, 2 + ; jnz @f + ; + ; cmp byte [playtime], 0 + ; je @f + ;int 0x40 + ;@@: + + ret + +still: + call process_events + jmp still + +red: + call draw_window + ret ;jmp still + +key: + mov eax, 2 + int 0x40 + + test al, al + jnz .end + + cmp ah, 1 ; Esc + jne @f + jmp close_app + @@: + cmp ah, 28 ; Enter + jne @f + call AAPlay + jmp .end + @@: + cmp ah, 15 ; Tab + je .end + cmp ah, 29 ; Left Control + je .end + cmp ah, 42 ; Left Shift + je .end + + cmp ah, 14 ; BackSpace + jne @f + + ; strlen(filename) + mov edi, filename + xor al, al ; search for the end of the filename + repne scasb + cmp edi, filename+2 + jl .end + + cmp edi, filename+2 + jl .end + mov byte [edi-2], 0 + + call print_filename + jmp .end + + @@: + cmp ah, 57 ; Space + je .input_symbol + cmp ah, 2 + jl .end + cmp ah, 54 + jg .end + + .input_symbol: + mov byte [stop], 1 + call reload_ascii_keymap + ; strlen(filename) + mov edi, filename + xor al, al ; search for the end of the filename + repne scasb + cmp edi, filename+52 + jg .end + + shr ax, 8 + and eax, 0x7F + mov al, byte [keymap+eax] ; Read ASCII from the keymap table. + mov byte [edi-1], al + mov byte [edi], 0 + + call print_filename + .end: + ret + +button: + mov eax, 17 ; Get pressed button code + int 0x40 + + cmp ah, 1 ; Test x button + je close_app + + cmp ah, 2 ; Test "Play" button + jne @f + call AAPlay + jmp .end + @@: + + cmp ah, 3 ; Test "Pause" button + jne @f + cmp byte [playtime], 1 + jne @f + + not byte [pausetime] + .pause: + call process_events + cmp byte [pausetime], 0 + jne .pause + + @@: + cmp ah, 4 ; Test "Stop" button + jne @f + mov byte [stop], 1 + jne @f + @@: + + .end: + ret +close_app: + + cmp dword [image], 0 + je @f + call TFliPlayer_Done + @@: + mov eax,-1 ; close this program + int 0x40 + + +; DATA +; Application Title +labelt db 'FLI Player v0.31',0 +keyText db '|-_' + + +error_text db "Can't load file.",0 +filepos dd 0x0 +filetype db 0 ; 0 - unsupported, 1 - fli, 2 - flc + +playtime db 0 +pausetime db 0 +stop db 0 + +pal rb 256*4 +image dd 0 +InfoStructure: + dd 0x0 ; subfunction number + dd filepos ; position in the file in bytes + dd 0x0 ; upper part of the position address + dd 0x0 ; number of bytes to read + dd 0x0 ; pointer to the buffer to write data + db 0 + dd filename + +keymap rb 128 + +I_END: + +Buffer dd ? +Interval dw ? + +Chunks dw ? + +FrameSize dd ? +RestartPos dd ? +Frame dw ? + +MainHeader MainHeaderRec +FrameHeader FrameHeaderRec + +filename db '/hd0/2/',0 + rb 46 +