Clipping Demo Crash Problem *Updated*

Started by
3 comments, last by Nokturnal 18 years, 10 months ago
Hi another one from Tricks book , there is a demo which demostrates clipping , well i re-wrote the entire thing , but i am unable to trace where i am making a mistake , the demo crashes when i exit the demo using escape. I do have the original source , but i cant figure out where i am making a mistake.


#define WIN32_LEAN_AND_MEAN  
#define INITGUID

#include <windows.h>   
#include <windowsx.h> 
#include <mmsystem.h>
#include <iostream.h> 
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h> 
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <ddraw.h>


#define WINDOW_CLASS_NAME "WINCLASS1"
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

typedef struct HAP_FACE
{
	int x,y;
	int xv,yv;
}HAPPY_FACE;


LPDIRECTDRAW7 lpdd=NULL;
LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;
LPDIRECTDRAWSURFACE7 lpddsback   =NULL;  
LPDIRECTDRAWPALETTE  lpddpal=NULL;
DDSURFACEDESC2 ddsd;


HWND      main_window_handle = NULL; 
HINSTANCE hinstance_app      = NULL;
PALETTEENTRY pal[256];


static int window_closed=0;

UCHAR happy_face[64] = {0,0,0,0,0,0,0,0,
                          0,0,1,1,1,1,0,0,
                          0,1,0,1,1,0,1,0,
                          0,1,1,1,1,1,1,0,
                          0,1,0,1,1,0,1,0,
                          0,1,1,0,0,1,1,0,
                          0,0,1,1,1,1,0,0,
                          0,0,0,0,0,0,0,0};

UCHAR sad_face[64] = {0,0,0,0,0,0,0,0,
                        0,0,1,1,1,1,0,0,
                        0,1,0,1,1,0,1,0,
                        0,1,1,1,1,1,1,0,
                        0,1,1,0,0,1,1,0,
                        0,1,0,1,1,0,1,0,
                        0,0,1,1,1,1,0,0,
                        0,0,0,0,0,0,0,0};

HAPPY_FACE faces[100];


LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam)
{
PAINTSTRUCT		ps;		
HDC				hdc;	

switch(msg)
	{	
	case WM_CREATE: 
        {
		return(0);
		} break;
   
	case WM_PAINT: 
		{
   	    hdc = BeginPaint(hwnd,&ps);	 
        EndPaint(hwnd,&ps);
		return(0);
   		} break;

	case WM_DESTROY: 
		{
		PostQuitMessage(0);
		return(0);
		} break;

	default:break;

    }

return (DefWindowProc(hwnd, msg, wparam, lparam));

} 


int Game_Init(void *parms = NULL, int num_parms = 0)
{
DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL);
lpdd->SetCooperativeLevel(main_window_handle,DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE);
lpdd->SetDisplayMode(640,480,8,0,0);

memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);

ddsd.dwFlags=DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
ddsd.dwBackBufferCount=1;

lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);

ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback);

for(int in=1;in<255;in++)
{
	pal[in].peRed=rand()%256;
	pal[in].peGreen=rand()%256;
	pal[in].peBlue=rand()%256;	
	pal[in].peFlags=PC_NOCOLLAPSE;
}

	pal[0].peRed=0;
	pal[0].peGreen=0;
	pal[0].peBlue=0;	
	pal[0].peFlags=PC_NOCOLLAPSE;

	pal[0].peRed=0;
	pal[0].peGreen=255;
	pal[0].peBlue=255;	
	pal[0].peFlags=PC_NOCOLLAPSE;

	
	pal[255].peRed=255;
	pal[255].peGreen=255;
	pal[255].peBlue=255;	
	pal[255].peFlags=PC_NOCOLLAPSE;

	
	lpdd->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE | DDPCAPS_8BIT,pal,&lpddpal,NULL);
	lpddsprimary->SetPalette(lpddpal);

	for(in=0;in<100;in++)
	{
		faces[in].x=rand()%640;
		faces[in].y=rand()%480;
		faces[in].xv=-2+rand()%10;
		faces[in].yv=-2+rand()%10;
	}
	

	
return(1);

} 

void BlitClipped(int x,int y,int width,int height,UCHAR * bitmap,UCHAR *video_buffer,int pitch)
{

	if ((x+width<=0)||(x>=640)||(y+height <=0) ||(y>=480))
		return ;
	
	int x1=x;
	int y1=y;
	int x2=x+width-1;
	int y2=y+width-1;

	if(x1<0)
		x1=0;
	if(y1<0)
		y1=0;
	if(x2>640)
		x2=640;
	if(y2>480)
		y2=480;


	int x_off=x1-x;
	int y_off=y1-y;

	int dx=x2-x1+1;
	int dy=y2-y1+1;

	video_buffer+=(x1+y1*pitch);
	bitmap+=(x_off+y_off*width);
	
	UCHAR pixel;

	for(int index_y=0;index_y<dy;index_y++)
	{
		for(int index_x=0;index_x<dx;index_x++)
		{
			if(pixel=bitmap[index_x])
				video_buffer[index_x]=pixel;
		}
		bitmap+=width;
		video_buffer+=pitch;
	}
	 		

}

int Game_Main(void *parms = NULL, int num_parms = 0)
{

DDBLTFX ddblt;
static int happy        =1;
static int feeling      =0;

	if(window_closed)
		return 0;

if (KEYDOWN(VK_ESCAPE))
{
   SendMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed=1;
}




memset(&ddblt,0,sizeof(ddblt));
ddblt.dwSize=sizeof(ddblt);

ddblt.dwFillColor=0;
lpddsback->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddblt);

memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
lpddsback->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

if(++feeling>200)
{
	happy=-happy;
	feeling=0;
}

for(int in=0;in<100;in++)
{
if(happy==1)
BlitClipped(faces[in].x,faces[in].y,8,8,happy_face,(UCHAR *)ddsd.lpSurface,ddsd.lPitch);
else
BlitClipped(faces[in].x,faces[in].y,8,8,sad_face,(UCHAR *)ddsd.lpSurface,ddsd.lPitch);
}

for(in=0;in<100;in++)
{
	faces[in].x+=faces[in].xv;
	faces[in].y+=faces[in].yv;
	
	if(faces[in].x < -8)
		faces[in].x=640;
	else
	if(faces[in].x >640)
		faces[in].x=-8;

	if(faces[in].y <-8)
		faces[in].y=480;
	else
	if(faces[in].y>480)
		faces[in].y=-8;

}
lpddsback->Unlock(NULL);


lpddsprimary->Flip(NULL,DDFLIP_WAIT);
Sleep(20);

return(1);
} 


int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
lpddpal->Release();
lpddpal=NULL;
lpddsback->Release();
lpddsback=NULL;
lpddsprimary->Release();
lpdd->Release();
lpdd=NULL;
return(1);

} 

int WINAPI WinMain(	HINSTANCE hinstance,
					HINSTANCE hprevinstance,
					LPSTR lpcmdline,
					int ncmdshow)
{

WNDCLASSEX winclass; 
HWND	   hwnd;	 
MSG		   msg;		 

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_APPLICATION);
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_APPLICATION);

hinstance_app = hinstance;

if (!RegisterClassEx(&winclass))
	return(0);

if (!(hwnd = CreateWindowEx(NULL,                  
                            WINDOW_CLASS_NAME,     
						    "T3D Game Console Version 1.0", 
						    WS_POPUP | WS_VISIBLE,
					 	    0,0,	  
						    400,300,  
						    NULL,	  
						    NULL,	  
						    hinstance,
						    NULL)))	
return(0);
main_window_handle = hwnd;
Game_Init();
while(TRUE)
	{
	if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
	   { 
       if (msg.message == WM_QUIT)
           break;
	   TranslateMessage(&msg);
	   DispatchMessage(&msg);
	   }
       Game_Main();
       
	} 
Game_Shutdown();
return(msg.wParam);

}




[Edited by - Nokturnal on June 18, 2005 8:15:39 AM]
"I think there is a world market for maybe five computers." -- Thomas Watson, Chairman of IBM, 1943
Advertisement
After a quick scan of your code I believe the problem is with this snippet of code:

if(window_closed)	return 0;if (KEYDOWN(VK_ESCAPE)){	SendMessage(main_window_handle,WM_CLOSE,0,0);	window_closed=1;}


In the above code snippet from Game_Main() you check if the escape key is pressed and if so you use SendMessage(...WM_CLOSE...) and set window_closed to 1.

The SendMessage() function sends a message straight to your window procedure (whereas PostMessage() posts a message to your applications message queue). So you're closing the window and then continuing with the function - and your calls to draw stuff to the now non-existant window.

To solve this simply return immediately after the line above - "window_closed=1;".

Hope this helps :)
Progress is born from the opportunity to make mistakes.

My prize winning Connect 4 AI looks one move ahead, can you beat it? @nickstadb
You might try putting a return after setting window_closed to 1.

edit - too slow.
thanks guys , sloved :)
"I think there is a world market for maybe five computers." -- Thomas Watson, Chairman of IBM, 1943
Well the above demo is working perfectly , so i decided to attach a clipper to the same demo , such that only at particular rectangles the movement of the bitmaps would be show up., but i am unable to achive this.I am also using flipping along with this. here's what i tried , i created and attached the clipper to the primary surface & ran the demo , but it showed up as normal , then i thought since i am flipping the pages , the clipper needs to be attached to the back surface ,so i attached the clipper to the back surface, now the window's show up , but the back ground gets all messed up. Even though i know that the writing is always done in the back buffer & hardware shifts pointers , i tried attaching the same clipper to both the primary and back surface , but no luck.

Any suggestions ??
thanks.


#define WIN32_LEAN_AND_MEAN  #define INITGUID#include <windows.h>   #include <windowsx.h> #include <mmsystem.h>#include <iostream.h> #include <conio.h>#include <stdlib.h>#include <malloc.h>#include <memory.h>#include <string.h>#include <stdarg.h>#include <stdio.h> #include <math.h>#include <io.h>#include <fcntl.h>#include <ddraw.h>#define WINDOW_CLASS_NAME "WINCLASS1"#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)typedef struct HAP_FACE{	int x,y;	int xv,yv;}HAPPY_FACE;LPDIRECTDRAW7		 lpdd=NULL;LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;LPDIRECTDRAWSURFACE7 lpddsback   =NULL;  LPDIRECTDRAWPALETTE  lpddpal=NULL;LPDIRECTDRAWCLIPPER  lpddclipper= NULL;DDSURFACEDESC2 ddsd;HWND      main_window_handle = NULL; HINSTANCE hinstance_app      = NULL;PALETTEENTRY pal[256];static int window_closed=0;UCHAR happy_face[64] = {0,0,0,0,0,0,0,0,                          0,0,1,1,1,1,0,0,                          0,1,0,1,1,0,1,0,                          0,1,1,1,1,1,1,0,                          0,1,0,1,1,0,1,0,                          0,1,1,0,0,1,1,0,                          0,0,1,1,1,1,0,0,                          0,0,0,0,0,0,0,0};UCHAR sad_face[64] = {0,0,0,0,0,0,0,0,                        0,0,1,1,1,1,0,0,                        0,1,0,1,1,0,1,0,                        0,1,1,1,1,1,1,0,                        0,1,1,0,0,1,1,0,                        0,1,0,1,1,0,1,0,                        0,0,1,1,1,1,0,0,                        0,0,0,0,0,0,0,0};HAPPY_FACE faces[100];void AttachClipper(LPRECT rect_list,int num);LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam,LPARAM lparam){PAINTSTRUCT		ps;		HDC				hdc;	switch(msg)	{		case WM_CREATE:         {		return(0);		} break;   	case WM_PAINT: 		{   	    hdc = BeginPaint(hwnd,&ps);	         EndPaint(hwnd,&ps);		return(0);   		} break;	case WM_DESTROY: 		{		PostQuitMessage(0);		return(0);		} break;	default:break;    }return (DefWindowProc(hwnd, msg, wparam, lparam));} int Game_Init(void *parms = NULL, int num_parms = 0){DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL);lpdd->SetCooperativeLevel(main_window_handle,DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE);lpdd->SetDisplayMode(640,480,8,0,0);memset(&ddsd,0,sizeof(ddsd));ddsd.dwSize=sizeof(ddsd);ddsd.dwFlags=DDSD_CAPS | DDSD_BACKBUFFERCOUNT;ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;ddsd.dwBackBufferCount=1;lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback);for(int in=1;in<255;in++){	pal[in].peRed=rand()%256;	pal[in].peGreen=rand()%256;	pal[in].peBlue=rand()%256;		pal[in].peFlags=PC_NOCOLLAPSE;}	pal[0].peRed=0;	pal[0].peGreen=0;	pal[0].peBlue=0;		pal[0].peFlags=PC_NOCOLLAPSE;	pal[0].peRed=0;	pal[0].peGreen=255;	pal[0].peBlue=255;		pal[0].peFlags=PC_NOCOLLAPSE;		pal[255].peRed=255;	pal[255].peGreen=255;	pal[255].peBlue=255;		pal[255].peFlags=PC_NOCOLLAPSE;		lpdd->CreatePalette(DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE | DDPCAPS_8BIT,pal,&lpddpal,NULL);	lpddsprimary->SetPalette(lpddpal);	for(in=0;in<100;in++)	{		faces[in].x=rand()%640;		faces[in].y=rand()%480;		faces[in].xv=-2+rand()%10;		faces[in].yv=-2+rand()%10;	}		RECT rect[3] = {{10,10,50,50},{100,100,200,200},{300,300, 500, 450}};	AttachClipper(rect,3);	return(1);} void BlitClipped(int x,int y,int width,int height,UCHAR * bitmap,UCHAR *video_buffer,int pitch){	if ((x+width<=0)||(x>=640)||(y+height <=0) ||(y>=480))		return ;		int x1=x;	int y1=y;	int x2=x+width-1;	int y2=y+width-1;	if(x1<0)		x1=0;	if(y1<0)		y1=0;	if(x2>640)		x2=640;	if(y2>480)		y2=480;	int x_off=x1-x;	int y_off=y1-y;	int dx=x2-x1+1;	int dy=y2-y1+1;	video_buffer+=(x1+y1*pitch);	bitmap+=(x_off+y_off*width);		UCHAR pixel;	for(int index_y=0;index_y<dy;index_y++)	{		for(int index_x=0;index_x<dx;index_x++)		{			if(pixel=bitmap[index_x])				video_buffer[index_x]=pixel;		}		bitmap+=width;		video_buffer+=pitch;	}	 	}void AttachClipper(LPRECT rect_list,int num){LPRGNDATA region_data;int index;lpdd->CreateClipper(0,&lpddclipper,NULL);region_data=(LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num*sizeof(RECT));memcpy(region_data->Buffer,rect_list,num*sizeof(RECT));region_data->rdh.dwSize=sizeof(RGNDATAHEADER);region_data->rdh.iType =RDH_RECTANGLES;region_data->rdh.nCount=num;region_data->rdh.nRgnSize=num*sizeof(RECT);region_data->rdh.rcBound.top  =64000;region_data->rdh.rcBound.left =64000;region_data->rdh.rcBound.right=-64000;region_data->rdh.rcBound.bottom=-64000;for(index=0;index<num;index++){	if(region_data->rdh.rcBound.top > rect_list[index].top)		region_data->rdh.rcBound.top=rect_list[index].top;	if(region_data->rdh.rcBound.left > rect_list[index].left)		region_data->rdh.rcBound.left=rect_list[index].left;	if(region_data->rdh.rcBound.bottom < rect_list[index].bottom)		region_data->rdh.rcBound.bottom=rect_list[index].bottom;		if(region_data->rdh.rcBound.right < rect_list[index].right)		region_data->rdh.rcBound.right=rect_list[index].right;}//ends forlpddclipper->SetClipList(region_data,0);lpddsback->SetClipper(lpddclipper);free(region_data);}int Game_Main(void *parms = NULL, int num_parms = 0){DDBLTFX ddblt;static int happy        =1;static int feeling      =0;	if(window_closed)		return 0;if (KEYDOWN(VK_ESCAPE)){   SendMessage(main_window_handle,WM_CLOSE,0,0);   window_closed=1;   return 0;}memset(&ddblt,0,sizeof(ddblt));ddblt.dwSize=sizeof(ddblt);ddblt.dwFillColor=0;lpddsback->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddblt);memset(&ddsd,0,sizeof(ddsd));ddsd.dwSize=sizeof(ddsd);lpddsback->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);if(++feeling>200){	happy=-happy;	feeling=0;}for(int in=0;in<100;in++){if(happy==1)BlitClipped(faces[in].x,faces[in].y,8,8,happy_face,(UCHAR *)ddsd.lpSurface,ddsd.lPitch);elseBlitClipped(faces[in].x,faces[in].y,8,8,sad_face,(UCHAR *)ddsd.lpSurface,ddsd.lPitch);}for(in=0;in<100;in++){	faces[in].x+=faces[in].xv;	faces[in].y+=faces[in].yv;		if(faces[in].x < -8)		faces[in].x=640;	else	if(faces[in].x >640)		faces[in].x=-8;	if(faces[in].y <-8)		faces[in].y=480;	else	if(faces[in].y>480)		faces[in].y=-8;}lpddsback->Unlock(NULL);lpddsprimary->Flip(NULL,DDFLIP_WAIT);Sleep(20);return(1);} int Game_Shutdown(void *parms = NULL, int num_parms = 0){lpddclipper->Release();lpddclipper=NULL;lpddpal->Release();lpddpal=NULL;lpddsback->Release();lpddsback=NULL;lpddsprimary->Release();lpdd->Release();lpdd=NULL;return(1);} int WINAPI WinMain(	HINSTANCE hinstance,					HINSTANCE hprevinstance,					LPSTR lpcmdline,					int ncmdshow){WNDCLASSEX winclass; HWND	   hwnd;	 MSG		   msg;		 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_APPLICATION);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_APPLICATION);hinstance_app = hinstance;if (!RegisterClassEx(&winclass))	return(0);if (!(hwnd = CreateWindowEx(NULL,                                              WINDOW_CLASS_NAME,     						    "T3D Game Console Version 1.0", 						    WS_POPUP | WS_VISIBLE,					 	    0,0,	  						    400,300,  						    NULL,	  						    NULL,	  						    hinstance,						    NULL)))	return(0);main_window_handle = hwnd;Game_Init();while(TRUE)	{	if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	   {        if (msg.message == WM_QUIT)           break;	   TranslateMessage(&msg);	   DispatchMessage(&msg);	   }       Game_Main();       	} Game_Shutdown();return(msg.wParam);}
"I think there is a world market for maybe five computers." -- Thomas Watson, Chairman of IBM, 1943

This topic is closed to new replies.

Advertisement