Sign in to follow this  
AngleWyrm

App intermittantly fails to quit

Recommended Posts

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;
}



Share this post


Link to post
Share on other sites
From fullscreen mode, I'm hitting escape, as there are no menus or buttons available yet. It fails to close quite often at that time.

From windowed mode, hitting either escape or clicking the close box on the menu shuts it down every time.

Share this post


Link to post
Share on other sites
Hmmm...have you used the debugger to see if there's any particular function you're getting "stuck" inside of? You may want to trace through your app after you post that quit message, see what's taking it so long.

Share this post


Link to post
Share on other sites
I ran into exactly the same problem at one time and can't remember the exact fix. However, try changing WM_DESTROY to WM_CLOSE and see if that resolves the problem.

Add a DestroyWindow(hwnd) for your app window in the app's destructor.


[Edited by - Buckeye on March 7, 2008 7:35:24 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this