[AD] Problem with remove_mouse() and video bitmaps. |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
I've noticed that if I set the mouse to display on a bitmap created with
create_video_bitmap(), then if I destroy the video bitmap and call
remove_mouse(), I can sometimes cause a crash or get my app to pause
before restoring the desktop resolution.
Here is what happens when I run the attatched program.
If I set the graphics mode to GFX_AUTODETECT_FULLSCREEN, then on exiting
the release-build in Windows 2000 (but not the debug build), an image of
part of the desktop is shown at the resolution of the app, and then
there's a pause of a few seconds before the desktop-resolution is
restored to what it was, and the desktop-wallpaper which was once in
32-bit colour has been reduced to 8-bit colour. On Windows 98, the app
exits without problems in both the debug and release builds.
If I modify the program to use GFX_AUTODETECT_WINDOWED, then exiting
causes the debug-build to crash with an unhandled exception (both W2K
and W98). The release build exits OK on W2K (on W98, it exits with an
illegal operation error). The crash occurs in
acquire_bitmap(_mouse_screen) called from show_mouse(NULL) which is
called from remove_mouse(). _mouse_screen appears to not be a valid
bitmap when examined at the point of crash.
If I un-comment show_mouse(NULL);, then the app exits gracefully. The
docs currently do not mention that show_mouse(NULL) must be called
before remove_mouse(), although I suspect that there's something that
causes remove_mouse() to call show_mouse(NULL) where _mouse_screen is an
invalid bitmap.
On another machine (which I do not have access to), exiting a similar
app without show_mouse(NULL) can cuase the resolution not to be changed
back when exiting, but adding show_mouse(NULL) caused the resolution to
be restored.
I am using a 600MhZ Athlon with a Matrox Marvel G400TV Graphocs card.
Under Windows 2000, I am using Direct X 9.0c, and under Windows 98,
Direct X 8.1
AE.
/***************************************************************************
*
* removemousetest.c
* Test program to show the app crashing on exit when remove_mouse() is called.
*
**************************************************************************/
/****************************************************************************
Includes
*/
#include <allegro.h>
/****************************************************************************
Types
*/
typedef int TeBool;
/****************************************************************************
Global Variables (across program)
*/
BITMAP *G_bmpVideoBitmap1, *G_bmpVideoBitmap2;
void
teGetModeIDString(char *szModeIDString, int nModeID)
{
*szModeIDString = nModeID>>24;
if(!(*szModeIDString))
{
*(szModeIDString++)='a';
*(szModeIDString++)='u';
*(szModeIDString++)='t';
*(szModeIDString++)='o';
}
else
{
szModeIDString++;
*(szModeIDString++) = (nModeID>>16)&0x000000FF;
*(szModeIDString++) = (nModeID>>8)&0x000000FF;
*(szModeIDString++) = (nModeID)&0x000000FF;
}
*szModeIDString=0;
}
void
teDoTest()
{
char szModeIDString[5];
BITMAP *bmpDest = G_bmpVideoBitmap2; // The freeze/crash does not occur if bmpDest == G_bmpVideoBitmap1
if(show_video_bitmap(bmpDest))
{
textout_ex(bmpDest, font, "show_video_bitmap() failed", 0, 0, 0, 1);
}
teGetModeIDString(szModeIDString,gfx_driver->id);
textprintf_ex(bmpDest, font, 20, 20, 4, 0, "Chosen gfx driver: %s", szModeIDString);
show_mouse(bmpDest);
while(!key[KEY_ESC] && !key[KEY_SPACE])
{
}
// If bmpDest == G_bmpVideoBitmap2 and the line below is commented out, then the app momentarily freezes (or crashes) on exit.
//show_mouse(NULL);
}
TeBool
teSetupGfx()
{
set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);
//set_gfx_mode(GFX_DIRECTX, 640, 480, 0, 0);
//set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
//set_gfx_mode(GFX_DIRECTX_WIN, 640, 480, 0, 0);
//set_gfx_mode(GFX_GDI, 640, 480, 0, 0);
if(!(G_bmpVideoBitmap1 = create_video_bitmap(SCREEN_W, SCREEN_H)))
{
TRACE("Error: create_video_bitmap returned NULL.\n");
return FALSE;
}
if(!(G_bmpVideoBitmap2 = create_video_bitmap(SCREEN_W, SCREEN_H)))
{
TRACE("Error: create_video_bitmap returned NULL.\n");
return FALSE;
}
set_palette(desktop_palette);
return TRUE;
}
void
teCleanupGraphics()
{
if(G_bmpVideoBitmap1)
{
destroy_bitmap(G_bmpVideoBitmap1);
}
if(G_bmpVideoBitmap2)
{
destroy_bitmap(G_bmpVideoBitmap2);
}
}
TeBool
teSetup()
{
if(allegro_init())
{
TRACE("Error Initialising Allegro.\n");
return FALSE;
}
if(install_keyboard())
{
TRACE("Error Initialising Keyboard.\n");
return FALSE;
}
if(install_timer())
{
TRACE("Error Initialising Timer.\n");
return FALSE;
}
if(install_mouse() == -1)
{
TRACE("Error Initialising Mouse.\n");
return FALSE;
}
if(!teSetupGfx())
{
TRACE("Error setting up the graphics.\n");
return FALSE;
}
return TRUE;
}
void
teCleanUp()
{
teCleanupGraphics();
remove_mouse();
remove_timer();
remove_keyboard();
allegro_exit();
}
int main(void)
{
if(!teSetup())
{
teCleanUp();
return -1;
}
teDoTest();
teCleanUp();
return 0;
}
END_OF_MAIN();