Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SaveScreen and RestoreScreen
#3
(10-24-2023, 08:33 AM)SMcNeill Wrote: Two of the simplest little routines in the world, though I think they'll both end up becoming something I rely on more often in the future:

Code: (Select All)
Sub SaveScreen (Image As Long, SaveTo As _MEM)
    Dim m As _MEM
    m = _MemImage(Image)
    SaveTo = _MemNew(m.SIZE)
    _MemCopy m, m.OFFSET, m.SIZE To SaveTo, SaveTo.OFFSET
    _MemFree m
End Sub

Sub RestoreScreen (FromWhich As _MEM, Image As Long)
    Dim m As _MEM
    m = _MemImage(Image)
    _MemCopy FromWhich, FromWhich.OFFSET, FromWhich.SIZE To m, m.OFFSET
    _MemFree m
End Sub


So what's these brilliant little pieces of code do for us?  The just let us save a screen and then restore that screen.

That's it.  Nothing special.  No great bells or whistles here, to see folks! 

There's already about 9000 different ways to do this, so why do we need THIS particular way, you ask??

Let's take a moment and look at this scenario:

Code: (Select All)
SUB foo
    PCOPY 0, 1
    .... do stuff
    PCOPY 1, 0
END SUB

Now the above is a simple enough way to grab a copy of the screen, do stuff (like place a pop up box on it), and then restore it and get rid of whatever temporary changes we made to it (such as when we close that pop up box).

But here's a question for you:  What happens if your main program already had a PCOPY 0, 1 to save a screen??  Didn't you just overwrite that page with the new PCOPY 0, 1 that your SUB did?  How's that gonna screw up stuff when the main routine now does a call back to the old PCOPY 1, 0 when it needs it?

So PCOPY isn't particularly a great command to make use of for SUBs or Library code...

But then there's always the old _COPYIMAGE trick!

Code: (Select All)
SUB foo
    tempImage = _COPYIMAGE(0)
    ... do stuff
    _PUTIMAGE ,tempImage
    _FREEIMAGE tempImage

Which works all fine and dandy.... BUT.... What if the _DISPLAY is a SCREEN 0 text screen?  Can't _PUTIMAGE that image back then, now can you?

So we try and get tricky:

Code: (Select All)
SUB foo
    tempImage = _COPYIMAGE(0)
    ...do stuff
    D = _DISPLAY
    SCREEN tempImage
    _FREEIMAGE D

Which works all fine and dandy....  BUT.... What if someone writes their code in the following manner:

Code: (Select All)
WorkScreen = _NEWIMAGE(1280, 720, 32)

When you did the tempImage, QB64 had to create a new image handle for that screen...  Since the main routine already had a reserved handle for the screen -- that you just freed with the _FREEIMAGE D -- none of the routines in the main program are going to work anymore as the handles don't match.

One glitch after another after another!!

Which is why I give you the two little routines above:

SaveScreen (Image As Long, SaveTo As _MEM)  <-- This takes any image handle (even _DISPLAY) and saves it to a designated memblock.
RestoreScreen (FromWhich As _MEM, Image As Long)  <-- And this does the reverse, taking a memblock and using it to restore the desired image.

Should work on ALL screen modes -- text, legacy graphics, 256 color screens, and 32-bit color screens.  Shouldn't have any problems with using _DISPLAY or 0 as imagehandles.  They're quick.  They're simple.  And they solve a lot of the issues which all the other various methods of saving and restoring a screen can have.

A simple working example is below, which shows that it works in both text screens and graphic screen modes. 

Code: (Select All)
Screen _NewImage(640, 480, 32)
$Color:32
Cls , Pink
Print "An original Pink screen"
Sleep
GreenFoo
Sleep

Screen 0
Cls , 4 'redscreen
Print "A Red TEXT Screen 0"
Sleep
WhiteFoo



Sub GreenFoo
    Dim Saver As _MEM
    SaveScreen _Display, Saver
    Cls , Green
    Print "A happy Green screen"
    Sleep
    RestoreScreen Saver, _Display
    _MemFree Saver
End Sub

Sub WhiteFoo
    Dim Saver As _MEM
    SaveScreen _Display, Saver
    Cls , 15
    Print "Replaced with white"
    Sleep
    RestoreScreen Saver, _Display
    _MemFree Saver
End Sub



Sub SaveScreen (Image As Long, SaveTo As _MEM)
    Dim m As _MEM
    m = _MemImage(Image)
    SaveTo = _MemNew(m.SIZE)
    _MemCopy m, m.OFFSET, m.SIZE To SaveTo, SaveTo.OFFSET
    _MemFree m
End Sub

Sub RestoreScreen (FromWhich As _MEM, Image As Long)
    Dim m As _MEM
    m = _MemImage(Image)
    _MemCopy FromWhich, FromWhich.OFFSET, FromWhich.SIZE To m, m.OFFSET
    _MemFree m
End Sub

Nice work. Even simple enough for ME to understand, and that's not easy!
Well done Steve!
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Please visit my Website at: http://oldendayskids.blogspot.com/
Reply


Messages In This Thread
SaveScreen and RestoreScreen - by SMcNeill - 10-24-2023, 08:33 AM
RE: SaveScreen and RestoreScreen - by PhilOfPerth - 10-25-2023, 10:59 PM
RE: SaveScreen and RestoreScreen - by bplus - 10-26-2023, 01:59 PM
RE: SaveScreen and RestoreScreen - by SMcNeill - 10-26-2023, 02:09 PM
RE: SaveScreen and RestoreScreen - by bplus - 10-26-2023, 02:28 PM
RE: SaveScreen and RestoreScreen - by SMcNeill - 10-26-2023, 05:13 PM
RE: SaveScreen and RestoreScreen - by SMcNeill - 10-26-2023, 07:52 PM
RE: SaveScreen and RestoreScreen - by bplus - 10-26-2023, 09:21 PM



Users browsing this thread: 2 Guest(s)