Screen Saver

Area:    Quik_Bas
  Msg:    #322
 Date:    01-18-93 11:29 (Public) 
 From:    Matt Hart                
 To:      All                      
 Subject: Screen Saver             
Here's my latest screen saver.  It will save multiple screens to a single 
file, any type of screen supported by BASIC, does RLL 
compression and supports screens saved in one position and 
restored in another (as long as it'll fit on the screen).  
The compression and decompression is all in BASIC, so it is 
relatively slow.  I'll try to crank out assembler versions 
soon and post them.  Saving very large screens will also 
tax available memory considerably.  The program could be 
modified to save half that memory by decompressing directly 
from disk - but it would lose speed over the assembler 
version.  My system was unable to save the VGA palette, 
even though I was using standard BIOS calls to do so.  I 
haven't resolved that problem yet, but I've included the 
routines that *should* work.  Let me know of any 
suggestions or problems.  Several messages follow... 

' DEFSCRS.BAS  1-14-93  Matt Hart
'
' The definitive screen saver
' Works in any screen mode, compresses and saves
' multiple screens or screen portions per file.
' Screen portions can be restored to any part of
' the screen for window movement.
'
' Compile with /AH
'
' Storage method:
' --------------- Each Screen
'             x = Screen 1 data
'             x = Screen 2 data
'             .....
'             x = Screen (number of screens) data
'       4 bytes = Number of RLL bytes for screen
'       4 bytes = Number of actual bytes for screen
'       4 bytes = Offset into file for screen data
'       2 bytes = X1
'       2 bytes = Y1
'       2 bytes = X2
'       2 bytes = Y2
'       2 bytes = Screen mode number
'             ..... Continue for number of screens
' ---------------------------
'       Last 2 bytes is the number of screens
'
' The seemingly backward method of storing the screen info
' after the screen data is done so that offsets for screen
' data do not change, and a screen's data need not be moved
' when adding screens.
'
' RLL compression is:
'       Ascii 0 = RLL code follows
'           Ascii 0 = Just kidding - actually ascii 0
'             OR
'           Ascii 1-255 = Number of repeats
'           Ascii 0-255 = Character to repeat
'         OR
'       Ascii 1-255 = Character
'
' I use the backslash division (integer division) with rather
' than regular division to prevent linking with the floating
' point library - and it is faster anyway.
'
' Note that the compression and (especially important) the decompression
' can easily be done in assembly and would be, by some previous RLL stuff,
' about 27 times faster.
'
' All of these test screens took up only 18K in a disk file - but many
' contained repetitive colors, so actual compression will be less.
'
' MonType = 0 For MONO
' MonType = 1 For CGA
' MonType = 2 For EGA
' MonType = 3 For MCGA or VGA

    DEFINT A-Z
    TYPE RegTypeX
        AX    AS INTEGER
        BX    AS INTEGER
        CX    AS INTEGER
        DX    AS INTEGER
        BP    AS INTEGER
        SI    AS INTEGER
        DI    AS INTEGER
        Flags AS INTEGER
        DS    AS INTEGER
        ES    AS INTEGER
    END TYPE
    TYPE HSDefScrsType
        RLLBytes    AS LONG
        ActualBytes AS LONG
        Offset      AS LONG
        X1          AS INTEGER
        Y1          AS INTEGER
        X2          AS INTEGER
        Y2          AS INTEGER
        ScrMode     AS INTEGER
        MonType     AS INTEGER
    END TYPE

    MonType = 3
' ----------------------------- Sample Code
    RANDOMIZE TIMER
    ScreenFile$ = "J:\DEFSCRS.BIN" : CALL KillFile(ScreenFile$)

    CLS : PRINT "Test Screen 0"                         ' Any type
    COLOR 14,4 : PRINT "     Test Screen 0"
    COLOR 6,4 : LOCATE 25,1 : PRINT SPACE$(80);
    X1 = 1 : Y1 = 1 : X2 = 80 : Y2 = 25
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)

    CLS : C = 1 : A$ = "Second Test 0  "                ' Any type
    COLOR 7,0
    FOR Y = 1 TO 25
        COLOR C : LOCATE Y,1
        PRINT A$+A$+A$+A$+A$;Y;
        C = C + 1 : IF C = 16 THEN C = 1
    NEXT
    X1 = 1 : Y1 = 1 : X2 = 80 : Y2 = 25
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)
        
    SCREEN 1 : LINE (0,0)-(80,80),1,BF                  ' CGA +
    PRINT "Screen 1"
    X1 = 0 : Y1 = 0 : X2 = 80 : Y2 = 80
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)

    SCREEN 7 : LINE (0,0)-(100,100),10,BF               ' EGA +
    PRINT "Screen 7"
    X1 = 0 : Y1 = 0 : X2 = 100 : Y2 = 100
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)

    SCREEN 9 : LINE (0,0)-(639,349),12,BF               ' EGA +
    PRINT "Screen 9"
    X1 = 0 : Y1 = 0 : X2 = 639 : Y2 = 349
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)

    SCREEN 11 : Red& = 50 : Green& = 30 : Blue& = 10    ' VGA +
    Colr& = 65536& * Blue& + 256& * Green& + Red&
    PALETTE 1,Colr& : LINE (0,0)-(100,100),1,BF
    PRINT "Screen 11"
    X1 = 0 : Y1 = 0 : X2 = 100 : Y2 = 100
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)

    SCREEN 13 : Pal = 0                                 ' VGA +
    FOR X = 0 TO 318 STEP 20
        Red& = RND(1)*63 : Green& = RND(1)*63 : Blue& = RND(1)*63
        Colr& = 65536& * Blue& + 256& * Green& + Red&
        PALETTE Pal,Colr&
        LINE (X,0)-(X+19,75),Pal,BF
        Pal = Pal + 1
    NEXT
    FOR X = 0 TO 318 STEP 20
        Red& = RND(1)*63 : Green& = RND(1)*63 : Blue& = RND(1)*63
        Colr& = 65536& * Blue& + 256& * Green& + Red&
        PALETTE Pal,Colr&
        LINE (X,76)-(X+19,150),Pal,BF
        Pal = Pal + 1
    NEXT
    FOR X = 0 TO 318 STEP 20
        Red& = RND(1)*63 : Green& = RND(1)*63 : Blue& = RND(1)*63
        Colr& = 65536& * Blue& + 256& * Green& + Red&
        PALETTE Pal,Colr&
        LINE (X,151)-(X+19,199),Pal,BF
        Pal = Pal + 1
    NEXT
    PRINT "Screen 13"
    X1 = 0 : Y1 = 0 : X2 = 319 : Y2 = 199
    CALL HSSaveScreen(ScreenFile$,X1,Y1,X2,Y2,MonType,ScrNum)
    NumScreens = ScrNum
    CLS : SCREEN 1 : SCREEN 0 : WIDTH 80

    ScrNum = 3 : CALL HSRestoreScreen(ScreenFile$,80,80,MonType,ScrNum)
    DO : A$ = INKEY$ : LOOP UNTIL LEN(A$)
    ScrNum = 6 : CALL HSRestoreScreen(ScreenFile$,80,80,MonType,ScrNum)
    DO : A$ = INKEY$ : LOOP UNTIL LEN(A$)

    DO
        CLS
        ScrNum = INT(RND*NumScreens)+1 : X1 = 0 : Y1 = 0
        CALL HSRestoreScreen(ScreenFile$,X1,Y1,MonType,ScrNum)
        DO : A$ = INKEY$ : LOOP UNTIL LEN(A$)
    LOOP UNTIL A$ = CHR$(27)

    SCREEN 0 : WIDTH 80 : CLS : END
' -----------------------------------------
'       Continued...
--- 
 * Origin: Midnight Micro!  V.32/REL  (918)451-3306 (1:170/600)


Outer Court
Echo Basic Postings

Books at Amazon:

Back to BASIC: The History, Corruption, and Future of the Language

Hackers: Heroes of the Computer Revolution (including Tiny BASIC)

Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution

The Advent of the Algorithm: The Idea that Rules the World

Moths in the Machine: The Power and Perils of Programming

Mastering Visual Basic .NET