|
Page flipping and window focus - strange behavior |
Locutus266
Member #7,638
August 2006
|
Hello, I have developed an Allegro game and I am testing it under Windows. Recently my game developed the behavior that it doesn't recognize any more keyboard commands or other "window messages", when I switch into the background and then back to the game again. It's not a fullscreen window, by the way. If it loses window focus once, not even the close-buttons works anymore, although the game keeps running and the screen is still being updated. After clicking on the close button, Windows keeps asking to quit the task (although the game still runs). Unfortunately I didn't now when this problem developed and I have made numerous changes to the code since. When I use double buffering, the problem doesn't exist. I have tried inserting some rest() commands because I was afraid that all the CPU load is keeping the KEYDOWN messages to reach Allegro's window loop, but that obviously isn't the problem either. Maybe someone here has some good advice for me. What can cause such strange behavior? Best Regards, |
Arthur Kalliokoski
Second in Command
February 2005
|
I only use Allegro to make a few image utilities, under Windows the last few versions gray out the close button (the "x" at top right on titlebar). What version do you have? I also have trouble with focus when using console at the same time, maybe you're not makeing it as a native Windows program? I forget what the preferred option to "-mwindows" is for mingw. They all watch too much MSNBC... they get ideas. |
orz
Member #565
August 2000
|
Arthur_Kalliokoski: try calling the allegro function set_close_button_callback to get the exit button to not be greyed out. Locutus266: |
Kris Asick
Member #1,424
July 2001
|
I have had this problem before too, and at first I seemed to be the only person to experience it. It has to do with an incompatibility in all versions of Allegro starting with v4.1.0, manual bitmap locking or page flipping, and from what I understood, Windows 98. If you're not using Windows 98, it might be important to know which OS you're using specifically and what kind of video card you have. (My video card is an ASUS branded GeForce FX 5200.) The problem is related to the input sub-system. Since and including Allegro 4.1.0, all I/O threads under Windows were merged into one, but something that was changed as a result is causing this problem, and only on very few systems. (I assumed it was a Windows 98 thing.) On my system, the problem only happens full-screen. Even CTRL-ALT-DEL stops working when it happens and I have to reboot with the reset button on my tower. To get around the problem, I had to do two things: 1: Not manually lock bitmaps or use the show_video_bitmap() command. (Limiting me to double buffering, though I can still call vsync() to at least get close to page flipping quality.) 2: Add rest(1) or Sleep(1) to my game loops to give time back to the OS to prevent the I/O from stuttering. (A potentially related problem that started at the same time as the page flipping / bitmap locking problem.) Besides that workaround I do not have the faintest idea how to solve the problem, and since the computers it happens on are very specific, I doubt anyone does. (I've brought it up three times in the past and never resolved it any of those times. All I managed to find out was when the problem began.) One other workaround would be to go back to using Allegro 4.0.3, but you'll be giving up other fixes and the "_ex" functions if you do. --- Kris Asick (Gemini) --- Kris Asick (Gemini) |
Locutus266
Member #7,638
August 2006
|
Hello and thanks for your replies. I am using Allegro version 4.2.0 under Windows XP. The graphics card is some Intel onboard crap. Haven't tried it on a different PC, yet. But I will test it on a Windows ME machine soon and let you know what comes out of it. Going back to Allegro 4.0.3 unfortunately is not an option for me, but thanks for pointing out that this might be a version-specific issue. This is a simplified version of my main game loop:
If you have questions, simply ask. orz: The exit button works fine, if the application didn't lose focus before. After having lost focus once and then switching back to it, the window simply doesn't process any Window messages anymore and then Windows thinks it's stuck, so it asks me to kill it if I hit the close button. EDIT: I have been able to look further into it by commenting out some code. If I don't load any sprites into VRAM (or don't use VRAM->screen blit operations) the problem doesn't exist. This is my function to load memory bitmpas into VRAM:
Any suggestions on it? Best regards, |
orz
Member #565
August 2000
|
I don't know much WIN32, but I will take a stab at it. My current guess is that that the event loop gets stopped during handling one of the WM messages that occurs on switch out or switch in. On my setup (winXP, MSVC 7.1, slightly modified Allegro 4.2.1), the only WM message that allegro processes on switch out is WM_ACTIVATE, and the ones it processes on switch in are WM_ACTIVATE followed by WM_PAINT. Several other WM_*s are sent, but Allegro doesn't seem to do anything with them so I don't think they can cause problems. I don't see any obvious causes of failure for WM_ACTIVATE. WM_PAINT could conceivably block waiting on _enter_gfx_critical() if the main thread screwed up unlocking it. One way to test for this would be to have your main thread check the value of gfx_crit_sect_nesting (declared in allegro/platform/aintwin.h). I think it should be zero most of the time that you don't have any bitmaps locked. What OS are you using? I have access only to win2k and winXP. |
tobing
Member #5,213
November 2004
|
I have something similar, which occurs mostly when the game is starting, but the window is not immediately active (because I opened or activated another window in the meantime, e.g. my browser). Switching back and forth usually helps, so I didn't go into any detail with this. Just wanted to report that I also have this problem. WinXP, allegro 4.2.1. |
Locutus266
Member #7,638
August 2006
|
@orz: I am using Windows XP SP2. Unfortunately I cannot use a debugger, since I am using MinGW and Dev-Cpp and somehow it's not working correctly. (Step-by-Step cursor jumps back and forth wildly in code) If I use SWITCH_BACKGROUND, the game is halted when I switch back to the window (reactivating it) the second time (the first switch works fine). If I use SWITCH_AMNESIA or SWITCH_BACKANMESIA, the game is halted instantly when the game window loses focus the first time. No switching callbacks are installed. As I said, this problem only occurs if I use VRAM bitmaps. I don't do any locking on them yet. I suspect that it has something to do with Allegro's automatic bitmap locking mechanism. However, I tried putting in some calls to acquire_screen() and acquire_bitmap() (and releasing them of course), but nothing helped. To find out, what window message the last one is that is being received, I'd have to modify Allegro code I guess. That could take me some time. But I'll try and report back if I find something out. Thanks for your comments so far. Christoph B. |
orz
Member #565
August 2000
|
tobing: Locutus266: edit: #define _exit_gfx_critical() LeaveCriticalSection(&gfx_crit_sect); \ gfx_crit_sect_nesting-- corrected code: #define _exit_gfx_critical() gfx_crit_sect_nesting--;\ LeaveCriticalSection(&gfx_crit_sect)
|
Locutus266
Member #7,638
August 2006
|
Hello orz, yesterday I tried my game on a different PC with a decent graphics card -> Same problem. I have installed MSYS and rebuilt Allegro 4.2.0 (which is actually the version I am using) and inserted your corrected code. Unfortunately, the bug still persists, (using SWITCH_BACKGROUND or SWITCH_AMNESIA). No change there. I have decided to strip down my game of any unnecessary code, only to reproduce the bug. I will put it somewhere on the net, when I have done this. Best regards, |
Kris Asick
Member #1,424
July 2001
|
You know, this is the kind of thing where it's important to check the example programs that come with Allegro and see if the problem exists there. On my system, the problem I described above happens in ALL of the example programs. (And in the triple buffering example my I/O access is lost immediately and permanently.) (Correction: All of the example programs which use page flipping.) --- Kris Asick (Gemini) --- Kris Asick (Gemini) |
Locutus266
Member #7,638
August 2006
|
@Kris: I tried it with exflip.c. I even put in a VRAM->VRAM blit and forced it to windowed mode, because I am doing this in my game and that's what forces it to crash in the first place. However, the example seems to work fine. I wasn't able to reproduce the behavior. That's why I am planning to strip my game from code until it works. :-) For anyone who's interested in my code, I have put the latest version of my game at http://locutus266.homelinux.net/pnd-2.0-beta.zip No special configuration is needed to compile. Dev-Cpp might be good, though. Regards, |
orz
Member #565
August 2000
|
Hm... it has the same broken-alt-tabbing on my computer. I'll set up a project to see what's going on. edit1: The crash happens on IDirectDrawSurface2_Restore most of the time. if ((!page1) || (!page2)) { page_flip = 0; pnd_Notice(" ...error creating video memory pages."); } clear_to_color(page1, black); clear_to_color(page2, black); screen_buffer = page2; to this: if ((!page1) || (!page2)) { page_flip = 0; pnd_Notice(" ...error creating video memory pages."); if (page1) destroy_bitmap(page1); if (page2) destroy_bitmap(page2); } else { clear_to_color(page1, black); clear_to_color(page2, black); screen_buffer = page2; return 1; } appears to fix the issue. With your existing code, the next few lines immediately after this execute, changing screen_buffer to point at a memory bitmap. Why exactly that's crashing I do not know, but it's clearly not what you intended to do, and making it do what you intended to do eliminates the crashes. |
Locutus266
Member #7,638
August 2006
|
@orz: Well, I guess you found the problem! Thanks a lot for looking in to it. It works on my computer, too after changing that error. Setting up a screen buffer in RAM obviously makes no sense if two video pages already were allocated for page-flipping. It should only happen, if setting up page-flipping threw an error. Of course that code was wrong and I didn't see it. Quote:
vol_start_ticks is exported and imported as different types. How come your compiler complains about that? I also want to know, if I did something like this wrong. Is there a command-line switch? While we're at it: How did you like my code and do you have any suggestions on improving it? (I still have the problem that animation is mostly very jaggy and not smooth. I suppose it's a timer granularity issue. Best Regards, |
Tobias Dammers
Member #2,604
August 2002
|
Quote: Unfortunately I cannot use a debugger, since I am using MinGW and Dev-Cpp and somehow it's not working correctly. (Step-by-Step cursor jumps back and forth wildly in code)
You haven't compiled with any optimizations enabled, have you? Because if you have, the compiler may have rearranged a lot of your code to make it more efficient. As a result, some of your statements may be executed somewhere you don't expect them, and other statements may not be executed at all - the program still produces the same output, but it cannot easily be linked to the original source code any more. Quote: It works on my computer, too after changing that error. Setting up a screen buffer in RAM obviously makes no sense if two video pages already were allocated for page-flipping. It should only happen, if setting up page-flipping threw an error.
If something has failed, and you try to recover gracefully, make sure you clean up the the resulting mess before doing anything else. --- |
Locutus266
Member #7,638
August 2006
|
@Tobias: Thanks! I believe optimization was the problem. Debugging works fine now. |
|