Archived

This topic is now archived and is closed to further replies.

Disappearing D3D Cursor Problem

This topic is 5018 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I am in the process of updating my isometric engine from DirectDraw 6 to Direct3D 8 and was hoping someone could help me figure out how to regain my cursor''s D3D image surface upon regaining application focus. Basically, all works fine in fullscreen mode until I hit ALT-TAB. When I hit it again to return to my program, the graphics reset correctly (a background image surface is displayed properly) but my cursor does not reappear. I tried reacquiring my input devices, to no avail. I also tried calling the IDirect3DDevice8::ShowCursor method, to no avail. I see nothing in the documentation to help me out any further, and I''m out of guesses. Here''s my code:


// C L E A R   S C R E E N //////////////////////////////////////////////////

//

// Clear the screen (fullscreen mode) or window (windowed mode).

//

// return value - success or failure

//

inline estate ClearScreen ()

    {

    // Clear the screen.

    hr = g_pd3dDev->Clear (0, NULL, D3DCLEAR_TARGET, g_cd3dColorBlack, 0.0f, 0);
    if (FAILED (hr))
        {
        sReport = "ClearScreen -- Failed to clear screen: ";
        sReport += D3DError (hr);
        Log (sReport);
        return g_ceSError;
        }
    return g_eState;
    
    }


// O P E N   S C E N E //////////////////////////////////////////////////////

//

// Opens the viewport in order to begin rendering.

//

// return value - success or failure

//

inline estate OpenScene ()

    {

    // Clear the viewport.

    sr = ClearScreen ();
    if (!sr)
        {
        Log ("OpenScene -- Failed to clear the screen.");
        return g_ceSError;
        }
    
    // Begin the scene.

    g_pd3dDev->BeginScene ();

    return g_eState;

    }


// R E N D E R   S C E N E ///////////////////////////////////////////////////

//

// Renders the scene to the viewport.

//

// return value - continue or pause if focus lost.

//

inline estate RenderScene ()

    {

    // End the scene.

    g_pd3dDev->EndScene ();
    
    // Present the scene.

    hr = g_pd3dDev->Present (NULL, NULL, NULL, NULL);
    if (D3DERR_DEVICELOST == hr)
        if (g_bFocus)
            {
            Log ("RenderView -- Lost device, switching to windowed mode.");
            g_bFocus = false;
            g_ePrevState = g_eState;
            return g_ceSPause;
            }

    return g_eState;
            
    }


// T E S T   F O C U S ///////////////////////////////////////////////////////

//

// Tests to see if we have regained focus so we know when to reset graphics.

//

// return value - ready or not

//

bool TestFocus ()

    {

    hr = g_pd3dDev->TestCooperativeLevel ();
    if (D3DERR_DEVICENOTRESET == hr)
        {
        Log ("TestFocus -- Device available for reset, switching back to fullscreen.");
        return true;
        }
    return false;

    }


// G R A P H I C S   R E S E T ///////////////////////////////////////////////

//

// Reset the graphics.

//

// return value - success or failure

//

estate GraphicsReset ()

    {
    
    // Grab display mode.

    g_pd3d->EnumAdapterModes (D3DADAPTER_DEFAULT, g_uMode, &g_d3dDisplayMode);

    // Fill in back buffer information relevant to fullscreen mode...

    // Screen width and height..

    g_d3dParams.BackBufferWidth = g_d3dDisplayMode.Width;
    g_d3dParams.BackBufferHeight = g_d3dDisplayMode.Height;
    
    // Not windowed mode, use desired refresh rate.

    g_d3dParams.Windowed = false;
    g_d3dParams.FullScreen_RefreshRateInHz = g_d3dDisplayMode.RefreshRate;

    // And voila, reset it.

    hr = g_pd3dDev->Reset (&g_d3dParams);
    if (FAILED (hr))
        {
        Log ("GraphicsReset -- Failed to reset graphics.");
        return g_ceSError;
        }

    g_bFocus = true;

    return g_ePrevState;

    }


// S E T   C U R S O R ///////////////////////////////////////////////////////

inline void csurface::SetCursor (uint xPos, uint yPos)

    {

    g_pd3dDev->SetCursorPosition (xPos, yPos, D3DCURSOR_IMMEDIATE_UPDATE);

    }


// G E T   I N P U T /////////////////////////////////////////////////////////

//

// Get the current input (if any) for the keyboard and mouse.

//

// return value - success or failure

//

estate GetInput ()

    {

    static void *pvr;

    // Remember previous keyboard data, so we can check for key presses and releases.

    pvr = memcpy ((void *)g_diPrevKeyS, (void *)g_diKeyState, 256);
    if (!pvr)
        {
        Log ("GetInput -- Failed to record previous keyboard state.");
        return g_ceSError;
        }

    // Get new keyboard state.

    hr = g_pdiKeyboard->GetDeviceState (sizeof (DIKEYSTATE), (LPVOID)g_diKeyState);
    if (FAILED (hr))
        {
        sReport = "GetInput -- Failed to get keyboard input: ";
        sReport += DIError (hr);
        Log (sReport);
        return g_ceSError;
        }

    // Get any mouse input.

    pvr = memcpy ((void *)&g_diPrevMouseS, (void *)&g_diMouseState, sizeof (DIMOUSESTATE));
    if (!pvr)
        {
        Log ("GetInput -- Failed to record previous mouse state.");
        return g_ceSError;
        }
    hr = g_pdiMouse->GetDeviceState (sizeof (DIMOUSESTATE), (LPVOID)&g_diMouseState);
    if (FAILED (hr))
        {
        sReport = "GetInput -- Failed to get mouse input: ";
        sReport += DIError (hr);
        Log (sReport);
        return g_ceSError;
        }

    return g_eState;

    }


// R E D R A W ///////////////////////////////////////////////

//

// Update cursor position and redraw it.

//

// return value - none.

//

void ccursor::Redraw ()

    {
    
    // Update to new position and remember the previous one.

    xp = x;
    yp = y;
    x += g_diMouseState.lX;
    y += g_diMouseState.lY;
    xo += g_diMouseState.lX;
    yo += g_diMouseState.lY;

    // Keep it within the screen''s bounds.

    if (x > rEdge.right)
        {
        x = rEdge.right;
        xo = rEdgeO.right;
        }
    if (y > rEdge.bottom)
        {
        y = rEdge.bottom;
        yo = rEdgeO.bottom;
        }
    if (x < rEdge.left)
        {
        x = rEdge.left;
        xo = rEdgeO.left;
        }
    if (y < rEdge.top)
        {
        y = rEdge.top;
        yo = rEdgeO.top;
        }

    // Redraw the cursor at new position.

    pSurface->SetCursor (x, y);

    }

Basically, I call GetInput first, then OpenScene, then draw a background image surface, then call RenderScene, and finally Redraw the cursor. Note that ''csurface'' and ''ccursor'' are custom classes I created to mask DirectX and make my code API independent (so I can port it to Linux and Mac eventually). Thanks very much!

Share this post


Link to post
Share on other sites