leave FullScreen with Alt-Tab is not functional?

Advanced game related topics
rudd68
User
User
Posts: 29
Joined: Wed Jun 09, 2010 2:55 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by rudd68 »

Hello,

I use PB 4.41 on Windows XP SP 3.

djes fast working example works well without debugger, but not correctly.
Alt+Tab for tabbing out works well, but it is no matter which task I select in the taskbar, the fullscreen application opens again 2 seconds after a click on a task in the taskbar. This isn't correct.

dobro's code works perfectly.

Thanks to everyone who tries to help.
Krisko
User
User
Posts: 22
Joined: Tue Jun 08, 2010 11:03 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by Krisko »

Hi all I search alot in the form but can't find what i seek. Sorry if this is the wrong place to ask. I want to ask you do you know how to disable keyboard combinations. I mean for example: ALT+TAB, ALT+F4, CTRL+ALT+TAB ... etc. I'll be very grateful if someone can help me. Thank you :)
AndyMK
Enthusiast
Enthusiast
Posts: 582
Joined: Wed Jul 12, 2006 4:38 pm
Location: UK

Re: leave FullScreen with Alt-Tab is not functional?

Post by AndyMK »

I just posted this in the Tips section. Works with debugger and closes from taskbar. :mrgreen:

http://www.purebasic.fr/english/viewtop ... 12&t=43632
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by Mistrel »

This is due to the D3D device being lost:

http://msdn.microsoft.com/en-us/library ... 85%29.aspx
The owner of the device can switch to another device at any time by calling ResetDevice, typically because the original device was lost. Device loss can occur for various reasons, including changes in the monitor resolution, power management actions, locking and unlocking the computer, and so forth. For more information, see the Direct3D documentation.
Depending on where the engine stores information in video memory and how it handles the lost device, it may be necessary to reload some or all of your game assets:

http://msdn.microsoft.com/en-us/library ... 85%29.aspx
Resources can consume video memory. Because a lost device is disconnected from the video memory owned by the adapter, it is not possible to guarantee allocation of video memory when the device is lost. As a result, all resource creation methods are implemented to succeed by returning D3D_OK, but do in fact allocate only dummy system memory. Because any video-memory resource must be destroyed before the device is resized, there is no issue of over-allocating video memory. These dummy surfaces allow lock and copy operations to appear to function normally until the application calls IDirect3DDevice9::Present and discovers that the device has been lost.

All video memory must be released before a device can be reset from a lost state to an operational state. This means that the application should release any swap chains created with IDirect3DDevice9::CreateAdditionalSwapChain and any resources placed in the D3DPOOL_DEFAULT memory class. The application need not release resources in the D3DPOOL_MANAGED or D3DPOOL_SYSTEMMEM memory classes. Other state data is automatically destroyed by the transition to an operational state.
Think of it this way. You have one game/application that uses up 90% of your video memory. Then you switch to another one or minimize the one hogging all of the memory. The system releases that memory because the program is no longer is focus and it can't guess when you'll be wanting it back again. So it prioritizes for you. This is a good thing as far as multi-tasking and preemptive resource management by the operating system.

What if your full screen application uses "all" of the video memory and you alt-tab back to the operating system. Where is it going to get its video memory from?

This behavior is completely normal. You however, as the programmer, get the arduous job to work around it. :wink:
jerico2day
User
User
Posts: 37
Joined: Mon Jul 13, 2009 5:41 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by jerico2day »

What? That seems crazy. I play games all the time that handle alt-tabbing just fine, they don't have to reload assets or anything like that. Is this a directx version thing, are the games I'm playing playing Russian roulette with the video card (as in, it could fail at coming back?), or are the developers just insanely good at hiding the fact that they reloaded all the graphical assets and game state?
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: leave FullScreen with Alt-Tab is not functional?

Post by blueznl »

Probably the latter, OR the one that wrote the library they use did the hard work for them...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by Mistrel »

jerico2day wrote:What? That seems crazy. I play games all the time that handle alt-tabbing just fine, they don't have to reload assets or anything like that.
I just quoted you the DirectX9 documentation form MSDN..
jerico2day
User
User
Posts: 37
Joined: Mon Jul 13, 2009 5:41 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by jerico2day »

Yes, but I wonder how other developers do it. You know, from reading, it looks like it normally won't become lost, but there's a possibility it may become lost when doing an event like alt-tabbing out. So it seems we should only check to make sure it wasn't lost periodically, and reload or whatever when that event occurs.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by Mistrel »

Either the developers do it themselves or the engine does it for them. :|

If by "how" you mean when and where:

http://msdn.microsoft.com/en-us/library ... 85%29.aspx
The application can determine what to do on encountering a lost device by querying the return value of the IDirect3DDevice9::TestCooperativeLevel method.
mpz
Enthusiast
Enthusiast
Posts: 497
Joined: Sat Oct 11, 2008 9:07 pm
Location: Germany, Berlin > member German forum

Re: leave FullScreen with Alt-Tab is not functional?

Post by mpz »

Hi,

if you use Alt-Tab with a DX9 engine and you restart the Dx9 screen again you must reset the DX9 IDIRECT3DDEVICE9, Alle lights, Textures, Meshes etc etc. This is not a easy thing and i think this is not implemented for now. In my dx9 Engine i need over 100 lines of code to make the "Alt Tab Reset" possible...

best regards Michael
Working on - MP3D Library - PB 5.73 version ready for download
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: leave FullScreen with Alt-Tab is not functional?

Post by Mistrel »

I don't know about PureBasic's dx9 engine, but PureGDK supports this behavior by providing callbacks for lost/reset device notifications. Reloading assets is trivial with proper implementation.
Zach
Addict
Addict
Posts: 1675
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: leave FullScreen with Alt-Tab is not functional?

Post by Zach »

Maybe someone should just email all the major development studios who license out their engines, and see if they'll tell us how to do it :mrgreen:

Like has been stated, I am very sure they are reloading assets upon return to the Full Screen Game. I don't think its necessarily a matter of how great their kung-fu is to make the process transparent, but more up to the users system and how up to date their hardware is.

I've been building my personal PC's since I was about 12 years old, and one observation (granted this is anecdotal) I've made is, that the better your system, the faster your game recovers from an ALT-TAB operation. Some older engines from the 90's can still be a bit slow about it, but there is clearly a corolation between machine speed and recovery time.

So while it may not appear that the game is re-init'ing, you can be sure it really is just to be on the safe side. We'd probably see these issues a lot more often if not for the fact that Companies who are known for their Engine development, pretty much make a killing on monopolizing the market. I would guess that most A-List commercial games run at most, on 1 out of 5 or 6 different engines.
User avatar
Blue Steel
Enthusiast
Enthusiast
Posts: 132
Joined: Wed Aug 31, 2005 4:49 pm
Contact:

Re: leave FullScreen with Alt-Tab is not functional?

Post by Blue Steel »

I'm sure i've posted this code in here before but here goes again ;)

Here is how I'm handling it so far . This is still a work in progress ..

Let me know what you think. any hints,tips,corrections,advice, helpfull critisisms are more than welcome


Handles loosing focus, Alt Tab , alt enter , minimising window or full screen and re-opening via task bar, in all modes that i can think of.. window , fullscreen , fake fullscreen borderless window etc...

Graphic screen is same resolution no matter if in fullscreen or window

Note: Transparent mode works on Xp and Win7 but only in basic not aero mode :( still working out how to get that to work

Code: Select all

;{  Set up Variables
Global AltTab = 0
Global ScrMode = 1
Global WinState = 0
Global WinH = 0
Global WinId = 0
Global Quit = 0
Global WinX = 0
Global WinY = 0
Global WinWidth = 800
Global WinHeight = 600
Global Transparent = RGBA(255,0,255,0)
Global Background =  Transparent; #Black ; #Blue RGB(r,g,b) RGBA(r,g,b,a)
Global WinFlags = #PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
Global Title.s = "test"
Global ScrMode = 0
Global ScrX = 0
Global ScrY = 0
Global ScrWidth = 640
Global ScrHeight = 480
Global ScrDepth = 32
;}

Procedure SwitchScreen()
  ScrMode = ScrMode ! 1
  If WinState
    CloseScreen()
  Else
    WinState=1
  EndIf
  If ScrMode = 0 ; Windowed
    WinH = OpenWindow(WinId, WinX, WinY, WinWidth, WinHeight, Title.s, WinFlags)
    If AltTab
    SetWindowState(WinId,#PB_Window_Minimize) 
    Else     
      SetWindowLong_(WinH,#GWL_EXSTYLE,GetWindowLong_(WinH,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_COMPOSITED)
      If Background=Transparent
        SetWindowLong_(WinH,#GWL_EXSTYLE,GetWindowLong_(WinH,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_COMPOSITED)
        SetLayeredWindowAttributes_(WinH, Transparent, 0, #LWA_COLORKEY)
      EndIf 
    EndIf
    OpenWindowedScreen(WinH, ScrX,ScrY, ScrWidth, ScrHeight, 1, 0, 0)
    SetFocus_(WinH)
  Else
    If WinH : CloseWindow(WinId) : WinHeight : EndIf
      If Background=Transparent
      WinH = OpenWindow(WinId, 0, 0, DesktopWidth(0),DesktopHeight(0), Title.s, #PB_Window_BorderLess)
      SetWindowLong_(WinH,#GWL_EXSTYLE,GetWindowLong_(WinH,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_COMPOSITED)
      SetLayeredWindowAttributes_(WinH, Transparent, 0, #LWA_COLORKEY)
      OpenWindowedScreen(WinH, ScrX,ScrY, ScrWidth, ScrHeight, 1, 0, 0)
   Else
      OpenScreen(ScrWidth, ScrHeight, ScrDepth, Title.s)
   EndIf
  EndIf
EndProcedure

Procedure RenderScreen()     
  ClearScreen(Background)
    StartDrawing(ScreenOutput())
      DrawingMode(4)
      Box(0, 0, ScrWidth, ScrHeight , #Red)
      LineXY(0, 0, ScrWidth, ScrHeight , #Red)
      LineXY(0, ScrHeight, ScrWidth, 0 , #Red)
      Circle((ScrWidth-1)/2, (ScrHeight-1)/2, (ScrHeight-1)/2, #Red)
      DrawingMode(1)
      FrontColor (RGB(255,128,0))
      If ScrMode=0
        DrawText(10,14,"Screen Size : "+Str(ScrWidth)+","+Str(ScrHeight))
        DrawText(10,28,"Window Size : "+Str(WinWidth)+","+Str(WinHeight))
      Else
        DrawText(10,10,"Screen Size : "+Str(ScrWidth)+","+Str(ScrHeight))
        If Background=Transparent
                  WinWidth = WindowWidth(WinId)
        WinHeight = WindowHeight(WinId)
          DrawText(10,28,"Full Screen/Window Size : "+Str(WinWidth)+","+Str(WinHeight))
        EndIf
      EndIf
      DrawText(10,42,"Press T to Toggle Transparent mode")
      StopDrawing()
    FlipBuffers()   
EndProcedure
 
Procedure HandleEvents()
  ExamineKeyboard() 
  ;  Toggle_Screen_Mode
  If ((KeyboardPushed(#PB_Key_LeftAlt) Or 0) Or (KeyboardPushed(#PB_Key_RightAlt) Or 0)) And ((KeyboardPushed(#PB_Key_Return) Or 0) Or (KeyboardPushed(#PB_Key_PadEnter) Or 0))
    SwitchScreen()
  EndIf
  
  If ((KeyboardReleased(#PB_Key_T) Or 0)) 
    If Background=Transparent
      Background=#Black
    Else
      Background=Transparent
    EndIf
  ScrMode = ScrMode ! 1
    SwitchScreen()
  EndIf
  If KeyboardPushed(#PB_Key_Escape)
    Quit=1
  EndIf
  
  ; Handle if fullscreen looses focus eg: alt-Tab
  If IsScreenActive() <> 1
    If ScrMode=1 And Background <> Transparent
      AltTab=1
      SwitchScreen()
      Repeat
        Select WindowEvent()
          Case #PB_Event_CloseWindow
            Quit=1
          Default
            ;do nothing
        EndSelect  
        Delay(1)  
      Until IsScreenActive() <>0 Or Quit =1
      SwitchScreen()
      AltTab=0     
    EndIf
  EndIf
  
;  If ScrMode=0 Or Background=Transparent
    Select WindowEvent()
      Case #WM_SIZE
        WinWidth = WindowWidth(WinId)
        WinHeight = WindowHeight(WinId)
      Case #PB_Event_CloseWindow
        Quit=1
      Default
        ; do nothing .. just here to clear the queue   
    EndSelect
;  EndIf
EndProcedure

Procedure Initialize()
  If InitSprite()=0 Or InitKeyboard()=0 Or InitMouse()=0 Or ExamineDesktops()=0
    MessageRequester("ERROR","Can't initialize!",#MB_ICONERROR):End
  EndIf
  ; sneaky way of opening window or screen
  SwitchScreen()
EndProcedure

Procedure QuitProgram()
  CloseScreen()
  CloseWindow(WinId)
EndProcedure

;{ Main Program  
Initialize()

Repeat
  RenderScreen()
  HandleEvents()
  Delay(1)
Until Quit=1

QuitProgram()
;}
Currently using PureBasic 4.51(x86)

Image http://www.codingmonkeys.com
Covers many languages including PureBasic
User avatar
dobro
Enthusiast
Enthusiast
Posts: 766
Joined: Sun Oct 31, 2004 10:54 am
Location: France
Contact:

Re: leave FullScreen with Alt-Tab is not functional?

Post by dobro »

Another version of my code

guard (required) resolution, so change it, and especially now reduces the screen instead of closing and reopening :)



Code: Select all


; Purebasic 4.41
;By Dobro
; exemple de l'utilisation de IsScreenActive()

; quittez le pseudo jeux avec Alt+TAB
; on retourne dans le jeux d'un clique sur la fenetre en barre des taches


Declare  SetResolution(RezX, RezY, NbCoul, Frequence, Memoriser) ; si SetResolution=2 la résolution est identique à l'actuelle, si 1 erreur lors de la recherche des infos, sinon regarder #DISP_CHANG_...


initsprite ()
initmouse ()
initkeyboard ()
Enumeration
	#sprite
EndEnumeration
Structure sprite
	x.i
	y.i
	pas_x.i
	pas_y.i
EndStructure
Dim sprite.sprite(1)
examinedesktops ()
x_screen= desktopwidth (0) ; je recup la rez de l'ecran ;)
y_screen= desktopheight (0)
flag=0




; FlipBuffers(0) 

openscreen (x_screen, y_screen, 32, "Fullscreen + ALT-TAB démo" )

releasemouse (0)
createsprite ( #sprite , 64, 64)
startdrawing ( spriteoutput ( #sprite ))
	box (0,0,64,64, rgb (255,13,40))
stopdrawing ()

debut: ; le label qui permet le retour dans le jeux !!
;********* initialisation du sprite **********
If flag=0 ; le joueur n'est jamais sorti du jeu , s'il est sorti on ne fais pas ce bloc de code !!
	sprite(1)\x=x_screen/2 ; on place le sprite au centre
	sprite(1)\y=y_screen/2 ; on place le sprite au centre
	sprite(1)\pas_x=2 ; on donne une vitesse de deplacement a notre sprite
	sprite(1)\pas_y=2 ; on donne une vitesse de deplacement a notre sprite
	Else
	;-nouveau
	ShowWindow_(ScreenID(),#SW_SHOW) ; reaffiche l'ecran ;o)
EndIf





Repeat
	examinekeyboard () ; ne sert que pour quitter le prg avec la touche esc
	
	; ************* gere le deplacement du sprite ***************
	sprite(1)\x=sprite(1)\x+sprite(1)\pas_x
	sprite(1)\y=sprite(1)\y+sprite(1)\pas_y
	; ----------------------------------------------------------------------------
	If sprite(1)\x+64>=x_screen:sprite(1)\pas_x=-sprite(1)\pas_x: EndIf
	If sprite(1)\y+64>=y_screen:sprite(1)\pas_y=-sprite(1)\pas_y: EndIf
	; ----------------------------------------------------------------------------
	If sprite(1)\x<=0:sprite(1)\pas_x=-sprite(1)\pas_x: EndIf
	If sprite(1)\y<=0:sprite(1)\pas_y=-sprite(1)\pas_y: EndIf
	; *******************************************************
	
	
	; ********** affichage du sprite *********************
	displaytransparentsprite ( #sprite , sprite(1)\x, sprite(1)\y)
	
	flipbuffers ()
	clearscreen (0)
	
	; *************** attention toute l'astuce est la !! *******************
	x_screen2= desktopwidth (0) ; je recup la rez de l'ecran  .. encore;)
	y_screen2= desktopheight (0)
	If isscreenactive () = 0  or (x_screen2<>x_screen and y_screen2<>y_screen) ; le joueur a quitter le jeu (Alt-tab)  ou on a changé la resolution !!!
		releasemouse (1) ; je libere la souris ... inutile ici mais bon
		flag=1 ; on note que l'utilisateur est sorti du jeux
		;-nouveau
		ShowWindow_(ScreenID(),#SW_HIDE) ; reduit l'ecran le temps du redessin  ( avant je fermais )
		
		
		; ******* la ruse de guerre !! ****************************
		openwindow (1,1,1,1,1, "toto le jeu " , #PB_Window_Minimize ) ; j'ouvre une fenetre que je minimise en bar des taches
		Repeat :Event= waitwindowevent (2): Until Event= #PB_Event_ActivateWindow ; j'attend qu'on clique sur la fenetre
			closewindow (1) ; je ferme la fenetre
			; je remet la resolution du jeux :
			;-nouveau
			SetResolution(x_screen,y_screen,32,60,1)  ; on remet notre resolution
			Goto debut ; je retourne dans le jeux sans réinitialiser les variables de déplacement (on reprends ou on en etait! !!! )
		EndIf
	Until keyboardpushed ( #PB_Key_Escape ) ; là , on veux vraiment quitter le jeux LOL
	End
	
	
	
	Procedure SetResolution(RezX, RezY, NbCoul, Frequence, Memoriser)  ; Force la resolution 
		; si SetResolution=2 la résolution est identique à l'actuelle, si 1 erreur lors de la recherche des infos, sinon regarder #DISP_CHANG_...
		
		dm.DEVMODE
		If EnumDisplaySettings_ (0, -1, @dm)
			If RezX = dm\dmPelsWidth And RezY = dm\dmPelsHeight And NbCoul = dm\dmBitsPerPel And Frequence=dm\dmDisplayFrequency : ProcedureReturn 2 : EndIf
			dmEcran.DEVMODE
			dmEcran\dmSize = SizeOf (dmEcran)
			dmEcran\dmFields = #DM_PELSWIDTH|#DM_PELSHEIGHT|#DM_BITSPERPEL|#DM_DISPLAYFREQUENCY
			dmEcran\dmPelsWidth = RezX
			dmEcran\dmPelsHeight = RezY
			dmEcran\dmBitsPerPel = NbCoul
			dmEcran\dmDisplayFrequency = Frequence
			If Memoriser=1 : Memoriser= #CDS_UPDATEREGISTRY Or #CDS_NORESET : Else : Memoriser= #CDS_FULLSCREEN : EndIf
			dmx = ChangeDisplaySettings_ (@dmEcran,Memoriser)
			ProcedureReturn dmx
			Else
			ProcedureReturn 1
		EndIf
	EndProcedure
	; 
	
	; EPB


Image
Windows 98/7/10 - PB 5.42
■ sites : http://michel.dobro.free.fr/
Post Reply