[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();


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/