Jump to content
  • Advertisement
Sign in to follow this  
Nokturnal

Clipping Demo Crash Problem *Updated*

This topic is 4776 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 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]

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
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 for



lpddclipper->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);
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)
{
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);

}




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!