Sign in to follow this  
nashdal13

bitmap blt program problem

Recommended Posts

I don't know exactly what's wrong with this program. It can be compiled. But it went wrong whenever I tried to run it. Hope for your help. Thank you very much.
#define WIN32_LEAN_AND_MEAN

#define INITGUID

#include <windows.h>
#include <windowsx.h> 
#include <mmsystem.h>
#include <io.h>


#include <ddraw.h> // include directdraw

//defines
#define WINDOW_CLASS_NAME "WINCLASS1"

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define SCREEN_WIDTH    800  
#define SCREEN_HEIGHT   600
#define SCREEN_BPP      32    // bits per pixel
#define BITMAP_ID            0x4D42

#define _RGB32BIT(a,r,g,b)((b) + ((g << 8)) + ((r) << 16)) + ((a <<24 )) 

#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

//typedef
typedef struct BITMAP_FILE_TAG
{
	BITMAPFILEHEADER bitmapfileheader;
	
	BITMAPINFOHEADER bitmapinfoheader;

	UCHAR *buffer;
}BITMAP_FILE, *BITMAP_FILE_PTR;

//globals
HWND      main_window_handle = NULL;
HINSTANCE hinstance_app      = NULL;

//functions
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap,char *filename);
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap);
int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height);

//directdraw
LPDIRECTDRAW7 lpdd = NULL; 
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; 
LPDIRECTDRAWPALETTE   lpddpal      = NULL; 
DDSURFACEDESC2  ddsd; 
BITMAP_FILE           bitmap; 

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 Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
{

UCHAR *buffer; 
int index;
if (!(buffer = (UCHAR*)malloc(bytes_per_line*height)))
   return(0);
memcpy(buffer,image,bytes_per_line*height);

// flip
for (index=0; index < height; index++)
    memcpy(&image[((height-1) - index)*bytes_per_line],
           &buffer[index*bytes_per_line], bytes_per_line);

free(buffer);

return(1);

} 

int Load_Bitmap_File(BITMAP_FILE_PTR bitmap,char *filename)
{
	int file_handle; 

	OFSTRUCT file_data; 

	if((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
		return(0);

	_lread(file_handle,&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));

	if(bitmap->bitmapfileheader.bfType!=BITMAP_ID)
	{
		_lclose(file_handle);

		return(0);
	}

	_lread(file_handle,&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));

	_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);

	if(bitmap->bitmapinfoheader.biBitCount==24 || bitmap->bitmapinfoheader.biBitCount==32)
	{
		if(bitmap->buffer)
			free(bitmap->buffer);

		if(!(bitmap->buffer = (UCHAR*)malloc(bitmap->bitmapinfoheader.biSizeImage)))
		{
			_lclose(file_handle);

			return(0);
		}

		_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);

	}
    else
	{
		return(0);
	}

	_lclose(file_handle);

	//
	Flip_Bitmap(bitmap->buffer,bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),bitmap->bitmapinfoheader.biHeight);

	return(1);
}

int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
if (bitmap->buffer)
   {
   free(bitmap->buffer);

   bitmap->buffer = NULL;

   }

return(1);

}

inline void SetPixel32(int x, int y, int alpha,int red, int green, int blue, UINT *video_buffer, int lpitch32)
{
	USHORT pixel = _RGB32BIT(alpha,red,green,blue);
	video_buffer[x + y * lpitch32] = pixel;
}

int Game_Init(void *parms = NULL, int num_parms = 0)
{
	if(FAILED(DirectDrawCreateEx(NULL,(void **)&lpdd,IID_IDirectDraw7,NULL)))
	{
		return(0);
	}

	if(FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
		                                                   DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
	{
		return(0);
	}

	if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)))
	{
		return(0);
	}

	DDRAW_INIT_STRUCT(ddsd);

	ddsd.dwFlags = DDSD_CAPS;

	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

	if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)))
	{
		return(0);
	}

    if (!Load_Bitmap_File(&bitmap,"c:\1.bmp"))
    return(0);

	return(1);
}

int Game_Main(void *parms = NULL, int num_parms = 0)
{
	if(KEYDOWN(VK_ESCAPE))
		SendMessage(main_window_handle,WM_DESTROY,0,0);

	DDRAW_INIT_STRUCT(ddsd);

	if(FAILED(lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
	{
		return(0);
	}
    

	DWORD *primary_buffer = (DWORD *)ddsd.lpSurface; 

    for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
    {
    for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
        {
        UCHAR blue  = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]),
              green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]),
              red   = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]);

        DWORD pixel = _RGB32BIT(0,red,green,blue);

        primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

        }

    }

	if(FAILED(lpddsprimary->Unlock(NULL)))
	{
		return(0);
	}

	return(1);
}

int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
	if(lpddpal)
	{
		lpddpal->Release();
		lpddpal = NULL;
	}

	if(lpddsprimary)
	{
		lpddsprimary->Release();
		lpddsprimary = NULL;
	}
    
	if(lpdd)
	{
		lpdd->Release();
		lpdd = NULL;
	}

    Unload_Bitmap_File(&bitmap);
	
	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,  
						        "DirectDraw Full-Screen Demo", 
						        WS_POPUP | WS_VISIBLE,
					 	        0,0,	 
						        SCREEN_WIDTH,SCREEN_HEIGHT,  
						        NULL,	  
						        NULL,	  
						        hinstance,
						        NULL)))	
    return(0);
    
	main_window_handle = hwnd;

	Game_Init();

	while(1)
	{
		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
I can see 1 mistake...

In the LoadBitmap function:
_lread(file_handle,&bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
should be
_lread(file_handle,&bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

Share this post


Link to post
Share on other sites
Here is the source for my test. I changed the load function and it seems to be something wrong with the plotting still...

#define WIN32_LEAN_AND_MEAN

#define INITGUID

#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <io.h>


#include <ddraw.h> // include directdraw

//defines
#define WINDOW_CLASS_NAME "WINCLASS1"

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define SCREEN_BPP 32 // bits per pixel
#define BITMAP_ID 0x4D42

#define _RGB32BIT(a,r,g,b)((b) + ((g << 8)) + ((r) << 16)) + ((a <<24 ))

#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

BITMAP bitmap;

//globals
HWND main_window_handle = NULL;
HINSTANCE hinstance_app = NULL;

//functions
int Load_Bitmap_File(BITMAP* bitmap,char *filename);

//directdraw
LPDIRECTDRAW7 lpdd = NULL;
LPDIRECTDRAWSURFACE7 lpddsprimary = NULL;
LPDIRECTDRAWPALETTE lpddpal = NULL;
DDSURFACEDESC2 ddsd;

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 Load_Bitmap_File(BITMAP* bitmap,char *filename)
{
HBITMAP hBitmap = NULL;

hBitmap = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if(!hBitmap)
return 0;

GetObject(hBitmap, sizeof(*bitmap), bitmap);

return(1);
}

inline void SetPixel32(int x, int y, int alpha,int red, int green, int blue, UINT *video_buffer, int lpitch32)
{
USHORT pixel = _RGB32BIT(alpha,red,green,blue);
video_buffer[x + y * lpitch32] = pixel;
}

int Game_Init(void *parms = NULL, int num_parms = 0)
{
if(FAILED(DirectDrawCreateEx(NULL,(void **)&lpdd,IID_IDirectDraw7,NULL)))
{
return(0);
}

if(FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
return(0);
}

if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0)))
{
return(0);
}

DDRAW_INIT_STRUCT(ddsd);

ddsd.dwFlags = DDSD_CAPS;

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

if(FAILED(lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)))
{
return(0);
}

if (!Load_Bitmap_File(&bitmap,"c:/1.bmp"))
return(0);

return(1);
}

int Game_Main(void *parms = NULL, int num_parms = 0)
{
if(KEYDOWN(VK_ESCAPE))
SendMessage(main_window_handle,WM_DESTROY,0,0);

DDRAW_INIT_STRUCT(ddsd);

if(FAILED(lpddsprimary->Lock(NULL,&ddsd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
{
return(0);
}


DWORD *primary_buffer = (DWORD *)ddsd.lpSurface;
UCHAR *bmp_buffer = (UCHAR*)bitmap.bmBits;

for (int index_y = 0; index_y < bitmap.bmHeight; index_y++)
{
for (int index_x = 0; index_x < bitmap.bmWidth; index_x++)
{
//primary_buffer[index_x + index_y*(ddsd.lPitch >> 2)] =
// bmp_buffer[index_x+index_y*bitmap.bmWidth];
UCHAR blue = (bmp_buffer[index_y*bitmap.bmWidthBytes + index_x + 0]),
green = (bmp_buffer[index_y*bitmap.bmWidthBytes + index_x + 1]),
red = (bmp_buffer[index_y*bitmap.bmWidthBytes + index_x + 2]);

DWORD pixel = _RGB32BIT(0,red,green,blue);

primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;
}

}

if(FAILED(lpddsprimary->Unlock(NULL)))
{
return(0);
}

return(1);
}

int Game_Shutdown(void *parms = NULL, int num_parms = 0)
{
if(lpddpal)
{
lpddpal->Release();
lpddpal = NULL;
}

if(lpddsprimary)
{
lpddsprimary->Release();
lpddsprimary = NULL;
}

if(lpdd)
{
lpdd->Release();
lpdd = NULL;
}

//Unload_Bitmap_File(&bitmap);

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,
"DirectDraw Full-Screen Demo",
WS_POPUP | WS_VISIBLE,
0,0,
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL,
NULL,
hinstance,
NULL)))
return(0);

main_window_handle = hwnd;

if(!Game_Init())
return 1;

while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;

TranslateMessage(&msg);

DispatchMessage(&msg);
}

if(!Game_Main())
break;
}

Game_Shutdown();

return (int)(msg.wParam);
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this