UnderwareDESIGN

PlayBASIC => Resources => Source Codes => Topic started by: kevin on January 24, 2007, 08:56:34 AM

Title: Restoring after System interruptions (like Alt Tab).
Post by: kevin on January 24, 2007, 08:56:34 AM
  This example shows a simple method that could be used for building PB app's that can survive breaks in service from the OS.   Unfortunately the OS likes to dump your gfx surfaces when a suspend occurs, this means your images (the pixel data) are _lost_ so when the program is restored, your image will no doubt be corrupted.  Lovely.

 Anyway, an easy way to detect a suspend, is by monitoring the time between syncs (since there's no native command ATM).   So, If a frame is long, and by long I mean takes over 500 etc  milliseconds (1/2 a second)  We then assume the game was halted by some external force.  It doesn't really matter what.    So If this situation occurs, we reload/recreate our GFX content, before rendering the next frame.



Cheesy Example :)   (PB1.63 and bellow)

[pbcode]
   OpenScreen 800,600,32,1      ; Windowed Mode
;   OpenScreen 800,600,32,2      ; Full Screen Mode


   ; set a max frame rate
   Setfps 60

   ; Set a Variable to Hold the num,ber of times the image content has been
   ; rebuit
   Global RebuildCount


 ; Create Images      
   BuildImages(False)
   


; Get Time of Last Sync   
   TimeOfLastSync=Timer()   
   Sync

; ---------------------------------------------------------------------
;                          >> MAIN LOOP <<
; ---------------------------------------------------------------------
      
   Do

         ; Get CurrentTime
         CurrentTime=Timer()   


         ; Check if there's been any lost of service    for a long period of time
         IF (TimeOFLastSync+500)<CurrentTime
            BuildImages(true)
            ImagesRebuildRequired$="Images Last Restored @"+str$(CurrentTime)
         EndIF


         ; Update the GAME
         UpdateGame()


         ; display how many times the media has been reloaded/created
         print "Rebuild Media Count:"+str$(RebuildCount)
         Print ImagesRebuildRequired$
         

         ; Get the
         TimeOFLastSync=GetSyncTime()

      Sync   
   loop






Function GetSyncTime()
            ; Check if the Srcreen is in a Window formatGet the TIME OF THE LAST SYNC.
   
   Select GetScreenType()

      ; --------------------------------            
      case 1   ; Screen Is Windowed
      ; --------------------------------            

            ; Check if the Windowed Screen has focus.
            if GetScreenFocus()=true

               ; Poll the timer
               LastSync=Timer()   

            else

               // Copy the BAck buffer toa  NEw FX image
               TempIMage=NewFXimage(GetScreenWidth(),GetScreenHeight())
               CopyRect 0,0,0,GetScreenWidth(),GetScreenHeight(),tempImage,0,0
               oldSurface=GetSurface()
            
                  ; if we've lost focus, wait until it's restored
                  Repeat
                     ; suspend app for a 1/5 of a second
                     wait 200
                     ; render to image to back buffer
                     drawimage TempImage,0,0,false

                     ; flip buffers/refresh window messages
                     sync
                  ; check if it's still in focus yet
                  until GetScreenFocus()=true

               deleteimage Tempimage
               rendertoimage OldSurface
            endif         

      ; --------------------------------            
      case 2   ;FULL SCREEN EXCLUSIVE
      ; --------------------------------            
             ; APP  is in FULL SCREEN MODE, so poll the timer
               LastSync=Timer()   
   endSelect
   
EndFunction LastSync

   
   
   
; ---------------------------------------------------------------------
;                          >> Example Game  <<
; ---------------------------------------------------------------------


Function UpdateGame()
   static Angle#

   Cls rgb(30,100,60)

   sw=GetScreenWidth()
   sh=GetScreenHeight()
   
   iw=GetImageWidth(1)
   ih=GetImageHeight(1)
   
   ; draw some images to siulate our game   
   Xpos#=CosNewValue(sw/2,angle#,200)
   Ypos#=SinNewValue(sh/2,angle#,200)
   Drawimage 1,Xpos#-(iw/2),Ypos#-(ih/2),true

   Xpos#=CosNewValue(sw/2,angle#+180,200)
   Ypos#=SinNewValue(sh/2,angle#+180,200)
   Drawimage 1,Xpos#-(iw/2),Ypos#-(ih/2),true

   Angle#=wrapangle(Angle#,1)

   centertext sw/2,sh/2,"Game Is Running"

EndFunction




; ---------------------------------------------------------------------
;                          >> Image CReation <<
; ---------------------------------------------------------------------

Function BuildImages(RebuildFlag)
   OldSurface=getSurface()

   if RebuldFlag=True
      rendertoscreen
      ;
      Cls 0
      Sync
      Cls 0
      Sync   
   endif

   ; Load Images  (Althis exampe will get create one)
   CreateImage 1,100,100
   RenderToImage 1
  Circlec 50,50,50,true,$00ff00    
  Circlec 20,20,10,true,$000000    
  Circlec 80,20,10,true,$000000    
  Circlec 80,80,10,true,$000000    
  Circlec 20,80,10,true,$000000    
   rendertoscreen   


  ; Load maps

   ; Load / Prepare fonts
   
   ; Sound FX
   
   ; etc etc etc


   ; bump the rebuild counter
   inc RebuildCount
   rendertoimage oldsurface   
EndFUnction

[/pbcode]



Related Topics

   * Safe Image example. (http://www.underwaredesign.com/forums/index.php?topic=2388.0)