QB64 Phoenix Edition
SaveTextImage & LoadTextImage - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: SMcNeill (https://qb64phoenix.com/forum/forumdisplay.php?fid=29)
+---- Thread: SaveTextImage & LoadTextImage (/showthread.php?tid=2022)



SaveTextImage & LoadTextImage - SMcNeill - 09-22-2023

A couple of quick little routines to grab a SCREEN 0 text screen and save it in extended binary format so it can be reloaded instantly with all its settings intact.  This is great for saving little splash screens for use with SCREEN 0 games, and it compresses all the relevant data down to a very trivial size for us.  

My 85 x 25 default size SCREEN 0 image here compresses down to all of 538 bytes for me -- and that's preserving all the screen data 100% perfectly.  There's no data corruption here from it confusing spaces for non-breaking spaces (chr$(255)) or null characters (chr$(0)).  It saves information for if you're using blinking values or not.  Everything which is normally in our SCREEN 0 memory is dumped to the drive with a short, descriptive header which helps set its proper sizes and such.  Run time is going to be minimal as it's just grabbing and moving a single chunk of _MEM data, saving and loading it for us.

Expect this to be expanded upon in the future, once we get some sort of _MemFont function in QB64PE, so that I can embed custom font data into these little snapshots and save them when we grab our images for loading back later.  Wink

Code: (Select All)
CLS , 4 'create a screen
FOR i = 0 TO 31
    COLOR i, 15 - (i MOD 16)
    LOCATE (i MOD 16) + 1, (i \ 16) * 40 + 1: PRINT "Hello Color"; i
NEXT
SaveTextImage 0, "TextScreen0.SAV" 'and save it to disk
SLEEP
CLS 'clear it so it's obvious what we load
SLEEP
foo = LoadTextImage("TextScreen0.SAV") 'load it back from disk
SCREEN foo
SLEEP


FUNCTION LoadTextImage& (SaveFile AS STRING) 'create and load to a new Screen 0 screen with our saved image
    DIM AS INTEGER Wide, Tall, Flag: Wide = 80: Tall = 25: Flag = 0
    DIM AS STRING ImageData
    DIM AS _MEM M
    f = FREEFILE
    OPEN SaveFile FOR BINARY AS #f
    compress$ = SPACE$(LOF(f))
    GET #f, 1, compress$
    CLOSE #f
    temp$ = _INFLATE$(compress$)
    Flag = ASC(temp$, 1): p = 2

    IF Flag AND 1 THEN Wide = CVI(MID$(temp$, p, 2)): p = p + 2
    IF Flag AND 2 THEN Tall = CVI(MID$(temp$, p, 2)): p = p + 2
    IF Flag AND 4 THEN _BLINK ON ELSE _BLINK OFF
    IF Flag AND 8 THEN _FONT ASC(temp$, p): p = p + 1
    ImageData = MID$(temp$, p)
    TempImage = _NEWIMAGE(Wide, Tall, 0)
    M = _MEMIMAGE(TempImage): _MEMPUT M, M.OFFSET, ImageData: _MEMFREE M
    LoadTextImage = TempImage
END FUNCTION

SUB SaveTextImage (ImageHandle AS LONG, SaveFile AS STRING)
    DIM AS INTEGER Wide, Tall, Flag
    DIM AS LONG ImageSize
    DIM AS STRING ImageData
    DIM AS _MEM M
    IF _PIXELSIZE(ImageHandle) <> 0 THEN ERROR 5: EXIT SUB 'only text images for this routine

    M = _MEMIMAGE(ImageHandle)
    Wide = _WIDTH(ImageHandle): Tall = _HEIGHT(ImageHandle)
    temp$ = "0" 'placeholder for our finalized image flag which holds custom information

    IF Wide <> 80 THEN Flag = Flag + 1: temp$ = temp$ + MKI$(Wide)
    IF Tall <> 25 THEN Flag = Flag + 2: temp$ = temp$ + MKI$(Tall)
    IF _BLINK THEN Flag = Flag + 4 'Set a flag saying that this image uses _Blink
    SELECT CASE _FONT(ImageHandle)
        CASE 8: Flag = Flag + 8: temp$ = temp$ + CHR$(8)
        CASE 9: Flag = Flag + 8: temp$ = temp$ + CHR$(9)
        CASE 14: Flag = Flag + 8: temp$ = temp$ + CHR$(14)
        CASE 15: Flag = Flag + 8: temp$ = temp$ + CHR$(15)
        CASE 16 '16 needs no flag as it's the default for screen 0
        CASE 17: Flag = Flag + 8: temp$ = temp$ + CHR$(17)
        CASE ELSE
            'To be added once we get a _MemFont to retrieve custom font data back from QB64PE
    END SELECT
    ImageSize = Wide * Tall * 2
    ImageData = SPACE$(ImageSize): _MEMGET M, M.OFFSET, ImageData: _MEMFREE M
    temp$ = temp$ + ImageData
    MID$(temp$, 1) = CHR$(Flag) 'replace our placeholder with the proper value of the custom flag
    compress$ = _DEFLATE$(temp$)
    f = FREEFILE
    OPEN SaveFile FOR OUTPUT AS #f: CLOSE #f
    OPEN SaveFile FOR BINARY AS #f: PUT #f, 1, compress$: CLOSE #f
END SUB

Like usual, I don't swear that it's 100% glitch free, but if you guys find an issue with these little routines, just report it and I'll fix whatever it is ASAP.


RE: SaveTextImage & LoadTextImage - vince - 09-23-2023

nice, so like a _saveimage but for SCREEN 0.  I think there was a library called QuickPak Pro for QBasic that had similar routines