I've borked my app, and don't know where to start looking. The app closes from windowed mode every time, but from fullscreen it sometimes does a...partial shutdown. The screen goes black, and I have to hit the escape key several times to get it to shut down. (escape being assigned in the message handler).
It happened some time when I created a Painter class to handle windows and DirectX functions.
Anyone run into this kind of problem before?
//--------------------------------------------------------------------------------------------------
// Painter class implementation
//--------------------------------------------------------------------------------------------------
#include "painter.hpp"
#include <debug.hpp>
#include <stdio.h> // sprintf
/* TODO: New problem--end program intermittantly fails */
void painter_class::reset_screen(){
DBG_MSG("Attempting to reset screen");
// release resources
my_font->Release(); /* TODO: might move to a gui object d'tor/asset manager */
// do screen reset
screen->Reset(&screen_parameters);
// recreate released resources
D3DXCreateFont( screen, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &my_font );
};
HRESULT painter_class::render(const float elapsed_seconds)
{
if(screen == NULL){
DBG_MSG("No screen available");
return 1;
} // else have screen
//----------------------------------------------------------------------------------------------
// Handle alt-tab/lost device
//----------------------------------------------------------------------------------------------
static HRESULT result;
result = screen->TestCooperativeLevel();
switch(result){
case D3D_OK:
DBG_MSG("device OK");
break;
case D3DERR_DEVICELOST:
DBG_MSG("device lost"); // alt-tabbed out
Sleep(100);
return 1;
case D3DERR_DEVICENOTRESET: // just returned from alt-tab
DBG_MSG("device not reset");
Sleep(1);
reset_screen();
return 1;
case D3DERR_DRIVERINTERNALERROR:
DBG_MSG("device driver error");
return 1;
default:
DBG_MSG("unknown DirectX error: " << result);
return 1;
}
//----------------------------------------------------------------------------------------------
// Render the scene
//----------------------------------------------------------------------------------------------
DBG_MSG("Begin rendering scene");
screen->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 8, 16), 1.0f, 0);
// Begin the scene
screen->BeginScene();
/* TODO: These resources should belong in a resource manager */
// Create a colour for the text - in this case blue
static D3DCOLOR fontColor = D3DCOLOR_ARGB(255,0,0,255);
// Create a rectangle to indicate where on the screen it should be drawn
static RECT rct = {100, 100, 700, 150}; // left,top,right,bottom
// Draw some text
static char test[150];
sprintf(test,"%1.3f mSec/frame; %2.1f frames/sec", 1000 * elapsed_seconds, 1/elapsed_seconds);
my_font->DrawText(NULL, test, -1, &rct, 0, fontColor );
DBG_MSG("End rendering, present scene");
screen->EndScene();
return screen->Present(NULL, NULL, NULL, NULL); /* TODO: use swapchains to allow NOWAIT/STILLDRAWING */
};
painter_class::painter_class(HINSTANCE instance, const char* app_name, int display_mode, lua_script& settings)
{
//----------------------------------------------------------------------------------------------
// Create DirectX interface
//----------------------------------------------------------------------------------------------
dx = Direct3DCreate9(D3D_SDK_VERSION);
if( dx == NULL){
DBG_MSG("DirectX failed to initialize");
error = -1;
return;
}
else{
DBG_MSG("DirectX initialized");
}
//----------------------------------------------------------------------------------------------
// Create main window
//----------------------------------------------------------------------------------------------
fullscreen = settings.get_bool("video","fullscreen"); // get initial state from settings file
dx->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &desktop_display_settings );
main_window = CreateWindowEx(0, app_name, "Dad Gum Borked App",
(fullscreen? WS_POPUP|WS_EX_TOPMOST : WS_OVERLAPPEDWINDOW) | WS_VISIBLE,
0,0,
(fullscreen? desktop_display_settings.Width : settings.get_value("video","width") ),
(fullscreen? desktop_display_settings.Height : settings.get_value("video","height") ),
HWND_DESKTOP,
NULL, /* TODO: Menu */
instance,
NULL );
if(main_window == 0){
DBG_MSG( "CreateWindowEx() failed" );
error = -1;
return;
}
else{
DBG_MSG("Main Window created");
}
//----------------------------------------------------------------------------------------------
// Create DirectX screen for main window
//----------------------------------------------------------------------------------------------
ZeroMemory( &screen_parameters, sizeof(screen_parameters) );
screen_parameters.BackBufferWidth = desktop_display_settings.Width;
screen_parameters.BackBufferHeight = desktop_display_settings.Height;
screen_parameters.BackBufferFormat = desktop_display_settings.Format;
screen_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
//screen_parameters.FullScreen_RefreshRateInHz = settings.get_value("video", "fps");
//screen_parameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
screen_parameters.Windowed = !fullscreen;
screen_parameters.hDeviceWindow = main_window;
dx->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, main_window,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &screen_parameters, &screen );
if(screen == NULL){
DBG_MSG("DirectX failed to create screen");
error = -1;
return;
}
else{
DBG_MSG("DirectX screen created");
}
// Create other resources
/* TODO: Move to a Fragile-Resources manager */
D3DXCreateFont( screen, 30, 15, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &my_font );
error = 0;
ShowWindow(main_window, display_mode);
};
painter_class::~painter_class()
{
if(my_font != NULL) my_font->Release();
if(screen != NULL) screen->Release();
if(dx != NULL) dx->Release();
DBG_MSG("painter resources released");
};
The message handler is very dull, and hasn't changed.
//--------------------------------------------------------------------------------------------------
// Message handler
//--------------------------------------------------------------------------------------------------
LRESULT CALLBACK message_handler( HWND current_window, UINT message_id,
WPARAM wParam, LPARAM lParam)
{
switch (message_id)
{
case WM_DESTROY:
PostQuitMessage(0); // send WM_QUIT to message queue with wParam=0
break;
case WM_KEYUP:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0); // Escape key pressed -> exit
break;
}
break;
default:
return DefWindowProc(current_window, message_id, wParam, lParam);
}
return 0;
}
--"I'm not at home right now, but" = lights on, but no ones home