What happens during Alt-tab?

BlitzPlus Forums/BlitzPlus Programming/What happens during Alt-tab?

APE(Posted 2003) [#1]
Does the program still get input and go about its way, but just not draw anything to the screen? Does it stop in one posistion and wait their until it regains focus? If its waiting.. is it in a do nothing loop, or is it actually getting 0 cpu time, and truly stalled in one place?


coffeedotbean(Posted 2003) [#2]
Keeps going as far as i know.


Warren(Posted 2003) [#3]
Yeah, it keeps going. Just check your task manager window and look at the CPU cycles your game is taking. It doesn't decrease if the game doesn't have the focus.


Mark Tiffany(Posted 2003) [#4]
It keeps going, but with BlitzPlus, you get an event that let's you know that you've lost or gained focus (i.e. alt-Tabbed out or in to the game / app). Which is very handy to auto-pause a 2d game when some hits alt-tab.


sswift(Posted 2003) [#5]
I just tested my Tank game in Blitz 3D, and the game pauses when I alt-tab out of it from fullscreen, but not from windowed mode.

Maybe Millisecs() just doesn't increment? That seems like it would crash some people's code though if they had FPS counters and didn't check for divide by 0. So it must stop completely.


sswift(Posted 2003) [#6]
Actually I was mistaken. I'm getting weird behavior. The game does seem to continue in the background, but not in a normal manner.

For example, if I fire a bullet, alt tab out of the app for a moment, and then return to it, the bullet's direction is often reversed, as if it bounced off a wall and came straight back at me. But when bullets bounce off the walls in my game, they don't come straight back at you, they ricochet off at an angle like a pool ball.

So something funky is going on.

Maybe the gameplay stops but the timer continues, and this causes weird glitches in my physics code. Though I don't see how a frame time of over a second would cause a glitch like this.

I guess it's back to using my own custom alt-tab code. I just removed it yesterday because I thought Blitz had gotten it's act together on alt-tab. The game should stop completely when you alt-tab out of it in full screen. That includes the timer incrementing.

If (KeyDown(KEY_LEFTALT) Or KeyDown(KEY_RIGHTALT)) And KeyDown(KEY_TAB) Then Stop

The above code doesn't stop the timer from incrementing, but it does stop everything else. The timer is internal to windows, and special code would need to handle storing and restoring the value when the game is alt tabbed out of. Or you would need to skip a frame when you return to the game.

Actually perhaps if I just moved the alt tab code to another part of my main loop between the end of the last frame, and the storing of the time the last frame finished rendering at... Hm.

Argh. I just did another test. It seems like my own custom code won't be called at all if I alt-tab out of the game! So I can't do this to solve the problem:

			If (KeyDown(KEY_LEFTALT) Or KeyDown(KEY_RIGHTALT)) And KeyDown(KEY_TAB) 
			
				; Stop app.
				Stop
			
				; Reset timer.  Do nothing for first frame after returning from alt-tab.
				Current_Time    = MilliSecs()
				Time_Delta      = 0
				Time_Old		= Current_Time
				Time_Delta_Sec# = 0
			 
			EndIf



The code will never get executed. Blitz steals the alt-tab input from me. Ugh. Well this is stupid. I would rather Blitz force me to write my own alt-tab code than behave like this. If it behaves this way EVERY game will break. At least if Mark did nothing then properly coded games won't break on return from alt-tab. Is Mark considering alt-tabbing out as more important than the game working when you return to the game?


(tu) ENAY(Posted 2003) [#7]
ALT+TAB is a truly evil command after running full screen. Who knows what will or is happening to your window once you go back to it.

I'd recommend:-

If (KeyDown(KEY_LEFTALT) Or KeyDown(KEY_RIGHTALT)) And KeyDown(KEY_TAB) Then End

in your main game loop


Mark Tiffany(Posted 2003) [#8]
By timer, do you mean a Blitz timer, or MilliSecs()? The latter should NEVER stop, as it is the number of milliseconds your system has been up (or was it from midnight? One of the two). The idea of Blitz timers stopping when an alt-tab occurs, while nice, sounds like it could be very difficult to implement.

In terms of funny behaviour with the bullets, I think that when in fullscreen mode, flips may not wait for a vertical blank (Vwait may not either) as the screen is not being displayed. That's what I decided problems I had in my game were down to anyway. Which is why I migrated to BlitzPlus, as an event driven system is the only way you can really hope to deal with this (which doesn't help B3ders of course!)


sswift(Posted 2003) [#9]
"The latter should NEVER stop, as it is the number of milliseconds your system has been up"

I don't care about the number of milliseconds since my system has been up. I only care about the number of milliseconds my game has been running for. As the game should stop when you alt-tab out of it, so too should millisecs().

However, I can see how some people may desire that the game continue running when alt-tabbed out of. So that may not be the best solution.

I suppose a better solution would be for mark to create a special function which is called on return from an alt-tab event. That would allow us to put specialized code in there to handle the stuff ourselves. We can then create our own version of millisecs() which stops when our game stops and starts up again when it returns.


Mark Tiffany(Posted 2003) [#10]
You mean, cause an event to occur that your event handling code can detect and use as you see fit? That's exactly what BlitzPlus does. If you're writing a 2d only game (which I think it's fair to assume you are by the forum this post is in) in BlitzBASIC, maybe now is the time to upgrade to BlitzPlus.

Of course, as I said before, that doesn't help for any 3Ders...


WolRon(Posted 2003) [#11]
Why CAN'T Blitz3D be event driven (at least for the ALT-TAB command)??

I don't see why it can't be done.


cyberseth(Posted 2003) [#12]
The reason the funny behaviour happens (if your frame-limiting uses Millisecs()) is because Millisecs() is a global constant value, and doesn't pause when your computer does. (I'm getting weird deja vu posting this, and I feel like I did the last time I posted it... anyway...)

Millisecs() is the total number of millisecs since you last turned your computer on, so it's not going to stop for your program.

When your program has an event loop, a timer with Millisecs() finds out the difference between the last time it checked the millisecs. By doing this it finds out how many millisecs have passed since the last loop, and converts this into frames according to the FPS speed you specified.

The thing is, if you've ALT+TABBED out of your game for 10 seconds, and then return, then a game running at 60FPS has 600 frames to catch up with. The frame-limiter calculates this and calls 600 frames in order to catch up. Not only does your game jerk to a halt for a few seconds, but depending on how it's set up, especially with commands like UpdateWorld, some really weird stuff can happen!!

To combat this, I usually implement a simple thing which goes like this:


; Calculate number of frames depending on difference
; between the system timer, and the last time we updated
; our code to catch up with it. ie the number of millisecs passed

milli# = Millisecs()-Timer
frames = milli/(1000/FPS)   ; convert to frames

If Millisecs()-Timer>3000
    ; If more than 3 seconds have passed since the last
    ; time round, then we must have ALT+TABBed, coz
    ; the game should not have run that slowly.

    ; Set timer = Millisecs() to catch up with the system clock
    Timer = Millisecs()

    ; Set number of frames to 1 instead of what it was.
    Frames =1
End If

For k=1 to frames
    ; Update game code
    Timer=Timer+(1000/FPS)
    .
    .
Next



sswift(Posted 2003) [#13]
"I don't see why it can't be done."

I'm sure it can be. Mark just hasn't either because it would be hard to code, or he doesn't think it's the right thing, or he's too busy and doesn't think it's important enough to most users to bother with yet, or ever.


Foppy(Posted 2003) [#14]
Certain non-blitz games have a warning in the manual that says "do not use Alt-Tab with this game". Look I found an example in Delta Force 2:
Delta Force 2 does not support task switching, "Alt-Tabbing". Alt-Tab should NOT be used to switch to other tasks when running Delta Force 2.
So I guess when I complete a game and write a manual for it I would include a similar message! :)


Mark Tiffany(Posted 2003) [#15]
I doubt the Blitz3d product will ever get improved alt-tabbing behaviour, purely because it would (more or less) require half of BlitzPlus to be plugged into Blitz3d.

However, a certain other, oft mentioned product, bearing a similar name to that not so popular soft drink Pepsi Max, will be BlitzPlus with 3d plugged in, and would support it. So for now, go update yer manuals! ;-)


cyberseth(Posted 2003) [#16]
You don't want your game to continue while you've alt-tabbed to the desktop, though, do you? You want it to pause. And the method I posted above lets you do that, right? :O


Mark Tiffany(Posted 2003) [#17]
Absolutely you want to pause the game when alt-tab occurs. All I was saying was that with BlitzPlus you'll get instant notification via windows events of when someone alt-tabs in and out of your game. So rather than guessing that they've alt-tabbed AFTER 3 seconds, and potentially having Blitz go strange on you (which I've heard of happening on some PCs during Alt-Tab), you can handle it 'properly' in BlitzPlus.