This topic is 4975 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello! I've had a problem for the past few days trying on my own to load a bitmap in a C++ class i've made up from the informations gathered on MSDN. I had also read a bit of the Windows Games Programming Gurus and I have some code from that book that can get me to load a bitmap without any problems but I don't want to just copy&paste and then move on because I want to understand the "How and Why" of doing it so that I can get a better understanding of what i'm doing wrong etc... At the moment I am able to load all the proper info in BITFILEHEADER and BITMAPV5HEADER structures but it starts to bug on me with the color palettes and the actual bitmap data matrix. Also the whole procedures are made in order to load up uncompressed 16-bits BMP only at the moment. Once this will be done and I understand what's wrong then I will adapt it for 8,24 and 32 bits loading.
//paddles.h
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include <ddraw.h>

#define WIN32_LEAN_AND_MEAN  // just say no to MFC

/////////////////////////Classes Definitions/////////////

class BitmapFile
{
public:
USHORT*			 pBmpData;
};

//////////////////////////Window Objects/////////////////
HWND hwndWindow             = NULL;
HDC  hdc					= NULL;
//////////////////////////DDRAW Objects//////////////////
LPDIRECTDRAW7 lpdd7         = NULL;

LPDIRECTDRAWSURFACE7 lpdds7_OffScreen = NULL;
LPDIRECTDRAWSURFACE7 lpdds7 = NULL;
DDSURFACEDESC2 ddsd2;

HRESULT ddrval              = NULL;

//////////////////////////Misc Variables/////////////////
char buffer[80];
bool window_closed= 0;
BitmapFile image;
RECT ImageRect;
//////////////////////////Function Definitions///////////

void Error(LPCTSTR message);
USHORT _RGB16(BYTE R,BYTE G,BYTE B);
UINT _RGB32(BYTE A, BYTE R, BYTE G, BYTE B);
#define KeyDown() (GetAsyncKeyState(VK_ESCAPE) & 0x8000 ? 1:0)
bool SendImageToSurface(BitmapFile* Bmp);

LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMSG,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;

switch(uMSG)
{
case WM_CREATE:
{

return 0;
}break;

case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);

EndPaint(hwnd,&ps);
return 0;
}break;

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

}
return DefWindowProc(hwnd,uMSG,wParam,lParam);
}

int GameInit()
{
SetRect(&ImageRect,0,0,320,200);
if(!(DirectDrawCreateEx(NULL,(LPVOID*)&lpdd7,IID_IDirectDraw7,NULL))==DD_OK)
return(0);

if(!(lpdd7->SetDisplayMode(320,200,16,NULL,NULL)) == DD_OK)
return(0);

if(!(lpdd7->SetCooperativeLevel(hwndWindow,DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN))==DD_OK)
return(0);

ZeroMemory(&ddsd2,sizeof(ddsd2));

ddsd2.dwSize = sizeof(ddsd2);

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

if(!(ddrval = lpdd7->CreateSurface(&ddsd2,&lpdds7,NULL)) == DD_OK)
return(0);

ZeroMemory(&ddsd2,sizeof(ddsd2));

ddsd2.dwSize = sizeof(ddsd2);
ddsd2.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
ddsd2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
ddsd2.dwHeight = 200;
ddsd2.dwWidth  = 320;

if(!(ddrval = lpdd7->CreateSurface(&ddsd2,&lpdds7_OffScreen,NULL))== DD_OK)
return(0);

{
return(0);
}

if(!(SendImageToSurface(&image)))
{
Error("Cannot Send Image to Surface");
return(0);
}

return(1);
}

int GameMain()
{
if(KeyDown())
{
window_closed = 1;
SendMessage(hwndWindow,WM_CLOSE,NULL,NULL);
}

if(window_closed)
return(0);

lpdds7->Blt(NULL,lpdds7_OffScreen,NULL,NULL,NULL);
/*lpdds7->Lock(NULL,&ddsd2,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);
USHORT* vid_mem = (USHORT*)ddsd2.lpSurface;

for(int x = 0 ;x < 640;x++)
{
for(int y = 0; y<480; y++)
{
vid_mem[(x + y * (ddsd2.lPitch >> 1))] = _RGB16(255,0,0);
}
}
lpdds7->Unlock(NULL);*/
lpdds7->Flip(NULL,DDFLIP_WAIT);
return(1);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;

wndclass.cbSize        = sizeof(WNDCLASSEX);
wndclass.style         = CS_VREDRAW|CS_HREDRAW;
wndclass.lpfnWndProc   = WindowProc;
wndclass.cbClsExtra    = NULL;
wndclass.cbWndExtra    = NULL;
wndclass.hInstance     = hInstance;
wndclass.hIcon         = NULL;
wndclass.hCursor       = NULL;
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpszClassName = "RPG";
wndclass.hIconSm       = NULL;

if(!(RegisterClassEx(&wndclass)))
{
MessageBox(NULL,"Error Registering class", "Error", MB_OK);
return 0;
}

hwnd = CreateWindow("RPG","TEST",WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,640,480,NULL,NULL,hInstance,NULL);

hwndWindow = hwnd;

if(!(GameInit()))
return(0);

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

TranslateMessage(&msg);

DispatchMessage(&msg);
}

GameMain();
}

return msg.wParam;
}

void Error(LPCTSTR message)
{
MessageBox(NULL,message,ERROR,MB_OK);
}

USHORT _RGB16(BYTE R, BYTE G, BYTE B)
{
return ((B & 31) + ((G & 63)<<5) + ((R & 31)<<11));
}

{
HANDLE hFile      = NULL;

{
Error("INVALID_HANDLE_VALUE");
return(0);
}

{
return(0);
}

{
Error("Not a Bitmap");
return(0);

}

{
return(0);
}

{
Error("BitCount is not 16bits");
return(0);
}

// Read File with number of bytes equal to the size of RGBQUAD multiplied by the number of ColorUsed in the bitmap

{
return(0);
}*/

{
}

if(!(Bmp->pBmpData))
free(Bmp->pBmpData);

{
Error("Cannot allocate memory");
return(0);
}

{
return(0);
}

//Error(buffer);

CloseHandle(hFile);

return(1);
}

bool SendImageToSurface(BitmapFile* Bmp)
{
lpdds7_OffScreen->Lock(NULL,&ddsd2,DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT,NULL);

USHORT* vid_mem = NULL;
vid_mem = (USHORT*)ddsd2.lpSurface;

for(int x = 0; x < Bmp->BmpV5Header.bV5Width;x++)
{
for(int y = 0; y < Bmp->BmpV5Header.bV5Height; y++)
{
}
}

lpdds7_OffScreen->Unlock(NULL);

return(1);
}


So the problem with my application is that when I blit from the offscreen surface to the current display I get a black RECT from the size of the image and I assume the problem is with the BMP loading or the other function since I can lay pixels on the surface manually and blit without problems. Thank you for your help ! ; ) [Edited by - Avenyr on July 7, 2004 12:16:22 PM]