Crashing on prog quit

This is a discussion on Crashing on prog quit within the Game Programming forums, part of the General Programming Boards category; Hey guys! I'm currently learning DirectX (DirectDraw to be specific), in order to recode my game (you can check out ...

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Crashing on prog quit

    Hey guys! I'm currently learning DirectX (DirectDraw to be specific), in order to recode my game (you can check out the GDI version in my sig). But this simple prog keeps giving me an illegal operation whenever I close it! No idea what's wrong, except that my init/shutdown code was working fine before... Well, this is the relevant code:
    PHP Code:
    #include <ddraw.h>
    #include "main.h" //function prototypes

    #define WINDOW_CAPTION "DirectX Pixelz"
    #define WINDOW_WIDTH 640
    #define WINDOW_HEIGHT 480
    #define WINDOW_POS_X 0
    #define WINDOW_POS_Y 0

    #define SCREEN_WIDTH 640
    #define SCREEN_HEIGHT 480

    HWND hWnd;
    bool done;
    LPDIRECTDRAW ddraw;
    LPDIRECTDRAWSURFACE surfacePrimarysurfaceSecondary;
    unsigned charvideoBuffer;
    DDSURFACEDESC desc = {0};
    DDSCAPS ddscaps;
    int xy;

    void registerWindowClass()
    {
        
    WNDCLASSEX wc = {0};

        
    wc.cbSize sizeof(wc);
        
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        
    wc.hCursor LoadCursor(NULLIDC_ARROW);
        
    wc.hInstance GetModuleHandle(NULL);
        
    wc.lpfnWndProc WndProc;
        
    wc.lpszClassName "WndClass";
        
        
    RegisterClassEx(&wc);
    }

    int WINAPI WinMain(HINSTANCE hInstHINSTANCE hPrevInstLPSTR cmdint showCmd)
    {
        
    srand((unsigned int)GetTickCount());
        
    registerWindowClass();

        
    hWnd CreateWindowEx(0"WndClass"WINDOW_CAPTIONWS_POPUPWINDOW_POS_XWINDOW_POS_YWINDOW_WIDTHWINDOW_HEIGHTNULLNULLhInstNULL);
        
    ShowWindow(hWndSW_SHOW);

        if(!
    gameInit())
            return 
    1;

        
    MSG msg;
        while(!
    done)
        {
            while(
    PeekMessage(&msgNULL00PM_REMOVE))
            {
                
    TranslateMessage(&msg);
                
    DispatchMessage(&msg);
            }

            
    gameMain();
        }

        
    gameShutdown();

        return 
    0;
    }

    LRESULT CALLBACK WndProc(HWND hWndUINT msgWPARAM wParamLPARAM lParam)
    {
        switch(
    msg)
        {
        case 
    WM_CLOSE:
            
    done true;
            
    DestroyWindow(hWnd);
            return 
    0;

        case 
    WM_KEYDOWN:
            switch((int)
    wParam)
            {
            case 
    'Q':
                
    done true;
                
    DestroyWindow(hWnd);
                break;
            }
            return 
    0;
        }

        return 
    DefWindowProc(hWndmsgwParamlParam);
    }

    bool gameInit()
    {
        
    desc.dwSize sizeof(desc);
        
    desc.dwFlags DDSD_CAPS DDSD_BACKBUFFERCOUNT;
        
    desc.dwBackBufferCount 1;
        
    desc.ddsCaps.dwCaps DDSCAPS_PRIMARYSURFACE |
            
    DDSCAPS_FLIP DDSCAPS_COMPLEX;

        if(
    DirectDrawCreate(NULL, &ddrawNULL) != DD_OK)
            return 
    false;

        if(
    ddraw->SetCooperativeLevel(hWndDDSCL_EXCLUSIVE DDSCL_FULLSCREEN DDSCL_ALLOWMODEX DDSCL_ALLOWREBOOT) != DD_OK)
            return 
    false;

        if(
    ddraw->SetDisplayMode(SCREEN_WIDTHSCREEN_HEIGHT8) != DD_OK)
            return 
    false;

        if(
    ddraw->CreateSurface(&desc, &surfacePrimaryNULL) != DD_OK)
            return 
    false;

        
    ddscaps.dwCaps DDSCAPS_BACKBUFFER;

        if(
    surfacePrimary->GetAttachedSurface(&ddscaps, &surfaceSecondary) != DD_OK)
            return 
    false;

        return 
    true;
    }

    void gameMain()
    {
        
    memset(&desc0sizeof(desc));
        
    desc.dwSize sizeof(desc);
        
    surfaceSecondary->Lock(NULL, &descDDLOCK_SURFACEMEMORYPTR DDLOCK_WAITNULL);
        
    videoBuffer = (unsigned char*)desc.lpSurface;
        
        if(
    desc.lPitch == SCREEN_WIDTH)
            
    memset(videoBuffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);
        else
        {
            
    unsigned charasdf videoBuffer;

            for(
    int i 0SCREEN_HEIGHT; ++i)
            {
                
    memset(asdf0SCREEN_WIDTH);
                
    asdf += desc.lPitch;
            }
        }
        

        for(
    int i 01000; ++i)
        {
            
    rand() % SCREEN_WIDTH;
            
    rand() % SCREEN_HEIGHT;
            
            
    videoBuffer[+ (* (desc.lPitch))] = rand() % 256;
        }
        
        
    surfaceSecondary->Unlock(videoBuffer);
        while(
    surfacePrimary->Flip(NULLDDFLIP_WAIT) != DD_OK && (!done));
    }

    void gameShutdown()
    {
        if(
    surfaceSecondary != NULL)
            
    surfaceSecondary->Release();
        if(
    surfacePrimary != NULL)
            
    surfacePrimary->Release();
        if(
    ddraw != NULL)
            
    ddraw->Release();

    Anyone have any quick pointers?
    Last edited by Hunter2; 09-04-2002 at 09:20 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    It's late and I'm pretty tired but off hand I noticed that you aren't setting your pointers to NULL/0 after you release them (surface/DD object).

    Tomorrow morning (after I've had some sleep and coffee) I'll take a closer look at it.

    ***edit*** I just noticed you're releasing your backbuffer individually. Your backbuffer (when it's an attached surface to a complex primary surface) is cleaned up by releasing it's attached-to primary surface. Check the DX docs, under the Ddraw section, it explains it.

    What's most likely happening is that you're releasing it then it's not their when it's "parent" surface is trying to release it in the next line. You can take the lines to release the backbuffer out entirely.

    The only time you'd want to release your backbuffer individually is when you're using Windowed Ddraw (which is SLOW) and your backbuffer isn't an attached surface but instead a regular off-screen surface.
    Last edited by jdinger; 09-04-2002 at 10:43 PM.

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok Well, I guess it doesn't surprise me even though I took the releasing stuff right out of a book... the book I'm using has a typo/bug every couple of pages I guess I'll try taking out the backbuffer-releasing lines though
    Last edited by Hunter2; 09-05-2002 at 05:40 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Hmm, not working I've alternatingly taken out the secondary surface's release, the primary's, and the main directdraw's (just to see what was the problem), but it crashed no matter what. Hope you've had some sleep and coffee, jdinger

    **EDIT**
    I ran it through the debugger again, and it miraculously didn't freeze! It said there was an unhandled exception, then zoomed into the file in which memset() is implemented (in assembler ). So I figure it's gotta be somewhere in gameMain(), since that's where all the memset()'s are...

    **EDIT Final**
    NVM, I think I figured it out When the window received a WM_QUIT message, it would set 'done' to true, and then call DestroyWindow(). I'm thinking that this is bad, since gameMain() gets called after, and then tries to clear the screen by memsetting videobuffer, which (by my reasoning) might be null. So I just added an if statement, and if done was true then it would skip over everything
    Last edited by Hunter2; 09-05-2002 at 05:58 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #5
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    This actual problem was discussed on the Windows board by me and ken a week or so ago. We came to the conclusion that by using PeekMessage you are unable to call DestroyWindow from the WM_CLOSE message but should instead be called from the DestroyMethod after the message loop or from your class's destructor.
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    "DestroyMethod"? You mean, just a method to destroy everything? (i.e. gameShutdown()?) And why can't it be called from the WM_CLOSE message?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    Hunter, for Windows clean-up, here is what I use (and I have no/nor have I ever had any problems with it):

    Code:
    //this is all that is at the bottom of my winmain() after the basic 
    //window's class set-up/registration/creation
    
    if(!InitGame()) return(0);
    MSG msg;
    for(;;)
    {
        if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
       {
         if(msg.message==WM_QUIT) break;
         TranslateMessage(&msg);
         DispatchMessage(&msg);
       }
       MainLoop();
    }
    CleanUp();
    return(msg.wParam);
    And in my message handler (Window proc):

    Code:
    case WM_DESTROY:
    {
      PostQuitMessage(0);
      return(0);
    }break;
    And that's it.

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok, sounds simple enough... But doesn't Windows automatically post a WM_QUIT message if the WM_DESTROY isn't handled?...

    Oh yeah, and I was just wondering why you used "for(;". Is it faster than "while(true)" or neater or something?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    Originally posted by Hunter2
    Oh yeah, and I was just wondering why you used "for(;". Is it faster than "while(true)" or neater or something?
    hehe, I honestly don't have a great answer for that. It's just the way I was originally taught and it's never failed me.

  10. #10
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Ok then
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  11. #11
    Registered User xds4lx's Avatar
    Join Date
    Nov 2001
    Posts
    630
    I dont know why you cant call it from WM_CLOSE all I know is that it wont work if your using a message pump using PeekMessage
    "only two things are infinite, the universe and human stupidity, and im not sure about the former." - albert einstein

  12. #12
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Hmm, I was looking at my code and I noticed that at the beginning of gameMain() I empty 'desc' and re-enter its size. I tried commenting out those lines, and it seemed to work fine... is there any reason why I should keep them there?

    P.s. A book I'm using had those lines, so I used them too... but the book is error/redundancy-infested, so I don't know whether or not to do the memset.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 07-05-2010, 10:43 AM
  2. BST inser method seems to be crashing my prog
    By ray_broome in forum C++ Programming
    Replies: 12
    Last Post: 04-22-2005, 12:02 PM
  3. How do I stop cin from crashing my prog
    By Panopticon in forum C++ Programming
    Replies: 10
    Last Post: 12-13-2004, 02:41 PM
  4. why is this prog crashing on delete?
    By Waldo2k2 in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 10:17 PM
  5. sprintf crashing my prog?
    By Eber Kain in forum C++ Programming
    Replies: 11
    Last Post: 11-21-2001, 03:25 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21