The Game LoopYou may think that the only real difference in the game loop is that you blit the back buffer to the primary surface when you're in windowed mode instead of flipping… We'll start with that part though. Split your rendering function into two sections, separated by an if statement:
Where did that g_bExclusive flag come from? It's that global variable that we use to keep track of the mode we're working in. Put your old exclusive mode rendering code in the exclusive code section, then add a call to Blt in the windowed code section. Use the primary surface as the destination, and the back buffer as the source, like this:
That's about as simple as you can get! But wait, that code draws to the whole primary surface, not just our window! How do we get DirectDraw to copy the entire back buffer to our main window's client area? Well, we obtain the client area of the window, then convert the two points of the rectangle into points that are relative to the upper left corner of the screen. Pass that rect as the first parameter of the Blt call and you're set! Here's some code to do that:
There's one more part to your game loop: you can't hog the system like you could in exclusive mode. Whenever Windows (or another app) wants resources, you must give it to them. This is because the user has made the choice, not just the OS. A good Windows app lets the user switch between windows, using other apps at the same time. That's why it's called Windows! So, how do we do that? Well, what consumes most of the computer's power? The game loop, of course! So, we "pause" the game automatically when the user switches to something else, and "resume" it automatically when the user switches back to our app. (In games like massive online multiplayer games, this is not plausible; you'll have to think of something else. Tip: you could at least pause the rendering, or slow it down a little.) Anyway, to pause the game loop, we add a variable to keep track of whether the game is running or not:
Then, we handle a certain Windows message in our main WndProc: WM_ACTIVATE. Whenever our main window receives the focus, we get one of these messages. We get another one of those messages when our main window loses the focus (which happens when another window gains the focus). Checking the value of wParam tells us if we're gaining or losing the focus. Set the bRunGame flag like this:
To use this variable we have just set up, check it before you continue the game loop. Replace your program's main message loop (probably in WinMain) with this; you'll note that the game loop is embedded in the message loop (near the end): Then place your game code inside that if statement we just added, where it says: // game code here. This completes the game loop section. Whew! We need to now look at changing modes while running the program. Trust me, it'll be the easiest section in this article!!
|
||||||||||||||||||||