Absturz beim beenden von pixel plotting
-
Hallo!
Es wäre sehr nett wenn ihr folgenden Code eben in eine Win32-Anwendung kopieren und compilieren+ausführen würdet, nicht von der Länge abschrecken lassen, ist leider zwangsweise so das der Code so lang sein muss
// dxguid.lib ddraw.lib includen #define WIN32_LEAN_AND_MEAN // MFC und selten genutzte Objekte nicht includen // Include Dateien #include <windows.h> #include <mmsystem.h> // Sound #include <stdlib.h> // Randomizefunktion #include <ddraw.h> // DirectDraw // Defines #define WINDOW_CLASS_NAME "WINCLASS1" #define WINDOW_HEIGHT 400 #define WINDOW_WIDTH 400 // Fenstereigenschaften #define SCREEN_WIDTH 1024 #define SCREEN_HEIGHT 768 #define SCREEN_BPP 8 // Funktionsprototypen int Game_Init(void),Game_Shutdown(void); void Game_Main(void),Create_Surface(void), Create_Palette(void), Plot_Pixel(void); // Global bool running = false; HWND main_window_handle = NULL; LPDIRECTDRAW7 lpdd7 = NULL; LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // Pointer auf die Oberfläche DDSURFACEDESC2 ddsd; LPDIRECTDRAWPALETTE lpddpal = NULL; PALETTEENTRY palette[256]; char buffer[100]; // Window's Procedure Funktion /////////////////////////////////////////////// LRESULT WINAPI WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { PAINTSTRUCT ps; // Wird in WM_PAINT genutzt HDC hdc; // Handle zu einem best. Fenster switch(msg) { case WM_CREATE: { return(0); }break; case WM_PAINT: { hdc = BeginPaint(hwnd,&ps); EndPaint(hwnd,&ps); return(0); }break; case WM_DESTROY: { Game_Shutdown(); return(0); }break; default:break; } // Sonstige Messages verarbeiten (Default Window Processes) return(DefWindowProc(hwnd, msg, wparam, lparam)); } // WINMAIN /////////////////////////////////////////////////////////////////// int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpcmdline, int ncmdshow) { WNDCLASSEX winclass; // Speichert die Klasse die erschaffen wird MSG msg; // Die Fensterklassenstruktur winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_WINLOGO); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = WINDOW_CLASS_NAME; winclass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Fensterklasse bei Windows regestrieren if(!RegisterClassEx(&winclass)) return(0); // Fenster erschaffen if(!(main_window_handle = CreateWindowEx( NULL, WINDOW_CLASS_NAME, "Direct Draw Initialisierung", WS_POPUP | WS_VISIBLE, 0,0, // Startposition WINDOW_HEIGHT,WINDOW_WIDTH, // Fenstergröße NULL, // Handle geht an das Desktop NULL, hinstance, NULL))) // Zusätzliche Parameter return(0); Game_Init(); // Hauptschleife while(running) { if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if(msg.message == WM_QUIT) break; TranslateMessage(&msg); // Tastenbetätigungen übersetzen DispatchMessage(&msg); // " an Window Processer senden } Game_Main(); } Game_Shutdown(); return(msg.wParam); } // Game_Init() ///////////////////////////////////////////////////////////////////// int Game_Init() { if(FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd7, IID_IDirectDraw7, NULL))) MessageBox(main_window_handle, "Fehler bei DirectDrawCreateEx in Game_Init()!", "Fehler", MB_OK | MB_ICONERROR); if(FAILED(lpdd7->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) MessageBox(main_window_handle, "Fehler bei SetCooperativeLevel in Game_Init()!", "Fehler", MB_OK | MB_ICONERROR); if(FAILED(lpdd7->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP, 0, 0))) MessageBox(main_window_handle, "Fehler bei SetDisplayMode in Game_Init()!", "Fehler", MB_OK | MB_ICONERROR); Create_Surface(); Create_Palette(); running = true; // MessageBox(main_window_handle, "Game_Init() wurde erfolgreich durchlaufen", "Hinweis", MB_OK | MB_ICONINFORMATION); return(0); } // Create_Surface() //////////////////////////////////////////////////////////////////////// void Create_Surface() { memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if(FAILED(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL))) MessageBox(main_window_handle, "Fehler bei lpdd7->CreateSurface() in Create_Surface()!", "Fehler", MB_OK | MB_ICONERROR); } // Create_Palette() ///////////////////////////////////////////////////////////////////// void Create_Palette() { for(int i=1; i<=255; ++i) { palette[i].peRed = rand()%256; palette[i].peGreen = rand()%256; palette[i].peBlue = rand()%256; palette[i].peFlags = PC_NOCOLLAPSE; } palette[0].peRed = 0; palette[0].peGreen = 0; palette[0].peBlue = 0; palette[0].peFlags = PC_NOCOLLAPSE; palette[255].peRed = 255; palette[255].peGreen = 255; palette[255].peBlue = 255; palette[255].peFlags = PC_NOCOLLAPSE; if(FAILED(lpdd7->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, palette,&lpddpal, NULL))) MessageBox(main_window_handle, "Fehler bei lpdd7->CreatePalette() in Create_Palette()!", "Fehler", MB_OK | MB_ICONERROR); if(FAILED(lpddsprimary->SetPalette(lpddpal))) MessageBox(main_window_handle, "Fehler bei lpddsprimary->SetPalette() in Create_Palette()!", "Fehler", MB_OK | MB_ICONERROR); } // Plot_Pixel ///////////////////////////////////////////////////////////////////// void Plot_Pixel() { if(FAILED(lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL))) MessageBox(main_window_handle, "Fehler bei lpddsprimary->Lock() in Create_Palette()!", "Fehler", MB_OK | MB_ICONERROR); int mempitch = (int)ddsd.lPitch; UCHAR *video_buffer = (UCHAR *)ddsd.lpSurface; for(int i=0; i<=1000; ++i) { UCHAR color = rand()%256; int x = rand()%SCREEN_WIDTH; int y = rand()%SCREEN_HEIGHT; video_buffer[x+y*mempitch] = color; } lpddsprimary->Unlock(NULL); Sleep(30); } // Game_Main() ///////////////////////////////////////////////////////////////////// void Game_Main() { Plot_Pixel(); } // Game_Shutdown() ///////////////////////////////////////////////////////////////// int Game_Shutdown() { running = false; if(lpddpal) { lpddpal->Release(); lpddpal = NULL; MessageBox(main_window_handle, "Palette freigegeben!", "Hinweis", MB_OK | MB_ICONINFORMATION); } if(lpddsprimary) { lpddsprimary->Release(); lpddsprimary = NULL; MessageBox(main_window_handle, "lpddsprimary freigegeben!", "Hinweis", MB_OK | MB_ICONINFORMATION); } if(lpdd7) { lpdd7->Release(); lpdd7 = NULL; } MessageBox(main_window_handle, "Game_Shutdown() wurde erfolgreich durchlaufen", "Hinweis", MB_OK | MB_ICONINFORMATION); PostQuitMessage(0); return(0); }
Hier die Erklärung:
Das Winapifenster wird erzeugt und game_init wird als erstes aufgerufen um ddraw zu initialisieren. Soweit so gut, nun soll game_main immer wieder aufgerufen werden, solange running == true ist, jeder der André LaMothe's Buch gelesen hat wird den Aufbau sofort wieder erkennen.
Wenn das Fenster zerstört werden soll wird game_shutdown aufgerufen und soll dafür sorgen das game_main nicht mehr ausgeführt wird da running auf false gesetzt wird. Allerdings macht die schleife anscheinden doch noch nen aufruf, denn das Programm schmiert ganz am ende nochmal ab weil ein pixel geplottet werden sollvideo_buffer[x+y*mempitch] = color;
Und dann stürzt er ab, ich meine es liegt daran das er game_main halt ein weiteres mal ausführt. Wie kann ich das unterdrücken. Ich bin echt ratlos
Ab und zu kommt auch die Meldung das er
"lpddsprimary->Lock()" nicht ausführen konnte und er stürzt wieder beim plotten ab, ist das bei euch auch so?Wäre nett wenn ihr das mal bei euch testet, ich hoffe darauf das jemand weiß worans liegt.
gruß
Delryn
-
Du solltest bevor du Lock aufrufst deine DDSURFACEDESC2 initialisieren,
sprich:memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd);
Lock prüft nämlich beim Aufruf dwSize!
Normalerweise ist dann Lock auch nicht erfolgreich, auf jeden Fall aber wird ddsd nicht mit gueltigen Daten gefüllt, also ist weder der Surface Pointer noch lpPitch gültig und du schreibst ins Niemandsland.Viele Grüße
Fischi