Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
GIFPlay
#1
This is an animated GIF player library written purely in QB64-PE.

I was kind of annoyed and frustrated with the issues in the animated GIF library implementation we have listed in the wiki. Unfortunately, InForm's GIF support is derived from the same code, and it suffers from the same limitations and issues. Basically, it does not support frame local color tables and does not correctly support all of GIF's frame disposal methods. So, I set out to write an animated GIF library that can work standalone and also with InForm-PE.

The latest version of the library will always be a part of InForm-PE. You can find the code inside InForm-PE/InForm/extensions.

I am also attaching a standalone zip file here. This zip file contains just the GIFPlay library, demo and its dependencies.

Library documentation is here: InForm-PE/InForm/docs/GIFPlay.md

You'll find some other useful (?) stuff in the InForm/extensions directory.  Smile

Cheers!

[Image: Screenshot-2023-12-01-040855.png]
[Image: Screenshot-2023-12-01-040927.png]


Attached Files
.zip   GIFPlay.zip (Size: 1.81 MB / Downloads: 33)
Reply
#2
Great improvement! Thanks for that!
Reply
#3
@a740g This is great work! Would it be possible to use only the GIFPlay components outside of inform? Or are there requirements for inform too?

I guess what I'm asking is, as I've not used InForm yet myself, how would I integrate something like this in for example a formless thing like a game?

Thanks as usual Smile
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#4
(12-01-2023, 10:39 PM)grymmjack Wrote: @a740g This is great work! Would it be possible to use only the GIFPlay components outside of inform? Or are there requirements for inform too?

I guess what I'm asking is, as I've not used InForm yet myself, how would I integrate something like this in for example a formless thing like a game?

Thanks as usual Smile
Certainly we can. That's how I designed it.

Example below. I've also include this example in the zip file and updated the first post.

Also see https://github.com/a740g/InForm-PE/blob/...GIFPlay.md for complete documentation.

I might just add FLI / FLC and aseprite support in the future. Big Grin 

Code: (Select All)
' GIFPlay Demo - Standalone
' a740g, 2023

$RESIZE:SMOOTH
DEFLNG A-Z
OPTION _EXPLICIT

'$INCLUDE:'InForm/extensions/GIFPlay.bi'

' This is a unique number that can identify the GIF (think of this like a QB file number)
' We can load multiple GIFs using different GIF Ids
CONST MY_GIF_ID = 101

DO
    DIM gifFileName AS STRING: gifFileName = _OPENFILEDIALOG$("Open GIF", , "*.gif|*.GIF|*.Gif", "GIF Files")
    IF LEN(gifFileName) = 0 THEN EXIT DO

    _TITLE gifFileName

    ' GIF_LoadFromMemory can load a GIF from a STRING buffer
    IF GIF_LoadFromFile(MY_GIF_ID, gifFileName) THEN
        ' GIF_Draw can only render to 32bpp surfaces. Hence our destination surface must be 32bpp
        ' Why 32bpp? That's because GIF animations *can* display more than 256 colors using frame local palettes
        ' See SmallFullColourGIF.gif
        DIM surface AS LONG: surface = _NEWIMAGE(GIF_GetWidth(MY_GIF_ID), GIF_GetHeight(MY_GIF_ID), 32)

        SCREEN surface ' we'll directly assign this to the window
        _ALLOWFULLSCREEN _SQUAREPIXELS , _SMOOTH

        GIF_Play MY_GIF_ID ' kickstart playback

        DO
            DIM k AS LONG: k = _KEYHIT

            IF k = 32 THEN
                IF GIF_IsPlaying(MY_GIF_ID) THEN GIF_Pause (MY_GIF_ID) ELSE GIF_Play (MY_GIF_ID)
            END IF

            ' This renders a GIF frame to the current _DEST. The _DEST must be 32bpp as noted above
            ' The whole _DEST is used. Meaning the frame will be scaled and stretched to fit if _DEST does not match the frame size
            ' We need not worry about timing as it is handled internally by the library. Hence this loop can be run at any frequency (we are using 120 below)
            ' Note: Extremely low frequency will cause frame skips and sometime artifacts (due to intra-frame dependencies)
            GIF_Draw MY_GIF_ID

            _DISPLAY

            _LIMIT 120
        LOOP UNTIL k = 27

        ' This is technically not required as a call to GIF_LoadFromFile/Memory will simply free a previously loaded GIF and re-use the Id
        ' But we'll be good citizens and do it anyway Smile
        GIF_Free MY_GIF_ID

        SCREEN 0
        _FREEIMAGE surface
    END IF
LOOP

SYSTEM

'$INCLUDE:'InForm/extensions/GIFPlay.bas'
Reply
#5
<3 Asesprite!

Ok I will check what you shared.
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#6
@a740g this is excellent! Could you possibly add a way to jump to a frame, then we could use this for a stack of animation for our sprites. E.g idle - frame 1-2, walk - frame 3-5, jump = frame 6-10 etc.

Then we could do in our code check and loop over frames, stop playing walk on first frame of idle, etc
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply
#7
(12-05-2023, 05:24 AM)grymmjack Wrote: @a740g this is excellent! Could you possibly add a way to jump to a frame, then we could use this for a stack of animation for our sprites. E.g idle - frame 1-2, walk - frame 3-5, jump = frame 6-10 etc.

Then we could do in our code check and loop over frames, stop playing walk on first frame of idle, etc

That's a good idea. I was going to add seek support. The only reason I did not do that is because of GIFs last-frame dependencies. It can cause weird artifacts with some GIFs if you seek to a random frame. The only way I can get past the frame dependency issue is if I completely pre-render every frame. That's the plan anyway. Once I have the base framework locked, I'll start adding FLI/FLC and aseprite support.

Maybe we can also do a PlaySegment(m, n) kind of routine, where it only loops from frame m to n. That way you'll not even have to check and manually loop frames. We can also do reverse loops. Big Grin
Reply
#8
(12-05-2023, 08:56 AM)a740g Wrote:
(12-05-2023, 05:24 AM)grymmjack Wrote: @a740g this is excellent! Could you possibly add a way to jump to a frame, then we could use this for a stack of animation for our sprites. E.g idle - frame 1-2, walk - frame 3-5, jump = frame 6-10 etc.

Then we could do in our code check and loop over frames, stop playing walk on first frame of idle, etc

That's a good idea. I was going to add seek support. The only reason I did not do that is because of GIFs last-frame dependencies. It can cause weird artifacts with some GIFs if you seek to a random frame. The only way I can get past the frame dependency issue is if I completely pre-render every frame. That's the plan anyway. Once I have the base framework locked, I'll start adding FLI/FLC and aseprite support.

Maybe we can also do a PlaySegment(m, n) kind of routine, where it only loops from frame m to n. That way you'll not even have to check and manually loop frames. We can also do reverse loops. Big Grin

That is awesome to hear! Yes ! I will help test! This is huge!

Opens up tons of possibilities for easy game making with just GIFs!
grymmjack (gj!)
GitHubYouTube | Soundcloud | 16colo.rs
Reply




Users browsing this thread: 1 Guest(s)