Advertisement

04.04 - DirectDraw Surfaces

Started by May 22, 2001 09:26 AM
14 comments, last by Teej 22 years, 11 months ago
Being the determined man that I am I managed to get both colorkeying and clipping to work in my game_main function. In the colorkeying example Teej uses BltFast but I was using Blt so the first thing I had to do was change the dwflags parameter from DDBLT_COLORFILL to DDBLT_KEYSRC. Along with the other changes Teej specified this allowed the colorkey to work.

As for having DirectX handle the clipping for me I had to change my code in DD_Init. I had the line -
G.lpDDSPrimary->SetClipper( lpClipper);
instead of
G.lpDDSBack->SetClipper( lpClipper);

The full changes I made are as follows:
Place the following in DD_Init.
	LPDIRECTDRAWCLIPPER lpClipper;  if (G.lpDD->CreateClipper(0, &lpClipper, NULL) !=DD_OK) return -99;    lpClipper->SetHWnd(0, G.hWnd);    G.lpDDSBack->SetClipper( lpClipper); 


My current Gaim_Main code follows, this moves the Resource.bmp across the screen flashing different colours, with colourkey and clipping as it moves off the right of the screen. A viola - no crashing and no extra checking from me.

void Game_Main(){    RECT rectDest;    DDSURFACEDESC2 ddsd2;    PALETTEENTRY Pal;    //Create a random colour    Pal.peRed=rand()%256;    Pal.peGreen=rand()%256;    Pal.peBlue=rand()%256;    //Assign this random colour to the palette index for the on-screen alpha-numeric text    G.lpDDPalette->SetEntries(0, 93, 1, &Pal);	    //Get the description for the resource surface    ZeroMemory(&ddsd2,sizeof(ddsd2));    ddsd2.dwSize = sizeof(ddsd2);    G.lpDDSRes->GetSurfaceDesc(&ddsd2);    //Clear back buffer    EraseBackground();    static int i;    //Prepare the destination rect for the entire resource surface    rectDest.left =  i;    rectDest.top = 0;    rectDest.right = ddsd2.dwWidth + i;		// ensure the image stays the desired width, without the +1 the image shrinks in width    rectDest.bottom = ddsd2.dwHeight;    i++;	//increment i    DDBLTFX ddbltfx;      ZeroMemory(&ddbltfx, sizeof(ddbltfx));      ddbltfx.dwSize = sizeof(ddbltfx);      //fill with black      ddbltfx.ddckSrcColorkey;     G.lpDDSBack->Blt(&rectDest,G.lpDDSRes,NULL, DDBLT_KEYSRC | DDBLT_WAIT,  &ddbltfx);      //Flip the surface    G.lpDDSPrimary->Flip(NULL,0);} 


Hope some of you find this useful and interesting.
Now on to playing with image transfer.

**Knowledge is Power**
**Knowledge is Power**
Hi, this is embarassing. I can''t get the pallette code
to do anything other than output a black screen. No random
colors. Code prior to palletting works fine. Any hints??

Advertisement
Looking through your anonymous code I would say you have an anonymous error.

My question would be what are you setting your pallette entries to. Some code or explanation of what code you have added would help us to help you.

A picture paints a thousand words.

**Knowledge is Power**
**Knowledge is Power**
FeverPitch - I added some code to yours for the start of a Scrolling Marquee screen saver. Whoever wants to use would have to create a "Resource.bmp" of their choice and set the screen background back to black and could make t random so that the marquee goes all over the screen instead of in increments of 100 pixels.

Here's what I added or changed:

static int t; //used to set the rectDest.top value instead of
//using 0

//rectDest.top = 0;
rectDest.top = t;

//rectDest.bottom = ddsd2.dwHeight;
rectDest.bottom = ddsd2.dwHeight + rectDest.top;

//This if statement goes right before the Blitting function
if (rectDest.left > 640)
{
i = 0;
t += 100;
}
if (rectDest.bottom > 480)
{
t = 0;
}

G.lpDDSBack->Blt(&rectDest,G.lpDDSRes,NULL, DDBLT_KEYSRC | DDBLT_WAIT, &ddbltfx);

What I need help with, is instead of starting the entire bitmap always at the left edge (0), how can I start the display of the bitmap off the left edge of the screen so that it scrolls onto the screen from left to right? I tried setting i = -640 but that didnt' work.

>>UPDATED Actually I set i back to -640 because theoretically it had to work...And it did, I just wasn't patient enough. After the BMP disappears from the right edge there is about a 3 to 5 sec pause before it starts to scroll back on to the screen at the left edge (COOL!!) I will play with numbers and see if I can get it to work seemlessly like I stated below.

>>UPDATE 2 i needs to be set the negative value of the width of the resource bmp. Change the first if statement i = line to

i = -1 * ddsd2.dwWidth;

Eventually I'd like to figure out how to scroll the right side off screen contents from the right edge to immediately show up on the left edge in a random place (like the Microsoft Scrolling Marquee screen saver).


Edited by - Joruli on June 16, 2001 11:54:35 AM

Edited by - Joruli on June 16, 2001 12:01:18 PM
I am here, you are there.Joruli
Joruli: I''ve manage to find out a way to do just that what you wanted I just created another RECT and played with it''s coords depending on the other playing RECT position.

Here goes the code for a somewhat scrolling marquee screen saver, alike Thanks to Joruli for the main code.

On GameMain.cpp
void Game_Main()
{
RECT rectDest;
RECT rectDest2;
DDSURFACEDESC2 ddsd2;
PALETTEENTRY Pal;

//Create a random colour
Pal.peRed=rand()%256;
Pal.peGreen=rand()%256;
Pal.peBlue=rand()%256;

//Assign this random colour to the palette index for the on-screen alpha-numeric text
G.lpDDPalette->SetEntries(0, 93, 1, &Pal);

//Get the description for the resource surface
ZeroMemory(&ddsd2,sizeof(ddsd2));
ddsd2.dwSize = sizeof(ddsd2);
G.lpDDSRes->GetSurfaceDesc(&ddsd2);

//Clear back buffer
EraseBackground();
static int i, j;
static int t, u;

static bool first = true;
static int playing_rect1 = true;
static int playing_rect2 = false;

if(first)
{
i = j = -1 * ddsd2.dwWidth;
t = (SCREEN_HEIGHT - ddsd2.dwHeight)/2;
first = false;
}

//Prepare the destination rect for the entire resource surface
if(playing_rect1)
{
rectDest.left = i++;
rectDest.top = t;
rectDest.right = ddsd2.dwWidth + rectDest.left;
rectDest.bottom = ddsd2.dwHeight + rectDest.top;
}

if(playing_rect2)
{
rectDest2.left = j++;
rectDest2.top = u;
rectDest2.right = ddsd2.dwWidth + rectDest2.left;
rectDest2.bottom = ddsd2.dwHeight + rectDest2.top;
}

DDBLTFX ddbltfx;
ZeroMemory(&ddbltfx, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);

if (playing_rect1 && rectDest.left > SCREEN_WIDTH)
{
i = -1 * ddsd2.dwWidth;
playing_rect1 = false;
}

if(playing_rect2 && rectDest2.left > SCREEN_WIDTH)
{
j = -1 * ddsd2.dwWidth;
playing_rect2 = false;
}

if(playing_rect1 && rectDest.right == SCREEN_WIDTH)
{
playing_rect2 = true;
u = rand()%(SCREEN_HEIGHT - ddsd2.dwHeight);
}

if(playing_rect2 && rectDest2.right == SCREEN_WIDTH)
{
playing_rect1 = true;
t = rand()%(SCREEN_HEIGHT - ddsd2.dwHeight);
}

//fill background with black
ddbltfx.ddckSrcColorkey;

if(playing_rect1)
G.lpDDSBack->Blt(&rectDest,G.lpDDSRes,NULL, DDBLT_KEYSRC | DDBLT_WAIT, &ddbltfx);

if(playing_rect2)
G.lpDDSBack->Blt(&rectDest2,G.lpDDSRes,NULL, DDBLT_KEYSRC | DDBLT_WAIT, &ddbltfx);

//Flip the surface
G.lpDDSPrimary->Flip(NULL,0);
}



On InitTerm.cpp file
Put this code at the end of DD_Init() right before ''return 0'' if you don''t have it already

// Set the color key to zero (palette index 0)
DDCOLORKEY ck;
ck.dwColorSpaceLowValue = ck.dwColorSpaceHighValue = 0;
G.lpDDSRes->SetColorKey(DDCKEY_SRCBLT, &ck);

LPDIRECTDRAWCLIPPER lpClipper;
if (G.lpDD->CreateClipper(0, &lpClipper, NULL) !=DD_OK)
return -99;

lpClipper->SetHWnd(0, G.hWnd);
G.lpDDSBack->SetClipper( lpClipper);



And don''t forget to change the SCREEN_BITDEPTH to 8 on Globals.h

If you manage to create another Resource.bmp with a message it will work much better

TomahawK
Do I really need one? :)
i cant get the LoadBitmapFile function to work i get the
"Could not create surface for bitmap" error message.
any help is appriciated
heres the code

LPDIRECTDRAWSURFACE LoadBitmapFile(LPDIRECTDRAW lpdd,LPCSTR szBitmap,int dx,int dy)
{
HBITMAP hBmp;
BITMAP Bmp;
LPDIRECTDRAWSURFACE lpddsBitmap;


if((HBITMAP)LoadImage(NULL,szBitmap,IMAGE_BITMAP,dx,dy,LR_LOADFROMFILE|LR_CREATEDIBSECTION)==NULL)
{
MessageBox(main_window_handle,"Could not load Image","Error",MB_OK);
return 0;
}

GetObject(hBmp,sizeof(Bmp),&Bmp);

memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = Bmp.bmWidth;
ddsd.dwHeight = Bmp.bmHeight;

if(lpdd->CreateSurface(&ddsd,&lpddsBitmap,NULL)!=DD_OK)
{
MessageBox(main_window_handle,"Could not create surface for bitmap","Error",MB_OK);
return 0;
}

CopyBitmapFile(lpddsBitmap,hBmp,0,0,0,0);
DeleteObject(hBmp);

return lpddsBitmap;

}

This topic is closed to new replies.

Advertisement