Blit Help

Hello SDL users!

I’ve been using SDL for about two weeks. I’ve just started to make a fairly
complex space game (which also uses the “SGE” and a few other libraries),
but as I have a background in C this isn’t much of a problem. My problem is
thus:

The gaming engine uses a simple task scheduler I wrote. This executes the
task “MeleeTASK_Refresh(void)” every 5ms. The refresh task code is:
void MeleeTASK_Refresh(void)

{

SDL_FillRect(MeleeArea, &SpaceBounds, SDL_MapRGB(MeleeArea->format, 0, 0,
0)); // Draw black game background

for (char Player=0; Player <= 1; Player++) Melee_DrawPlayer(Player);

Images_DrawImage(MeleeArea, screen, 0, 0, 255, 1, 255); // Draw the melee
area to the screen

CheckEvents(); // Process pending system events

Screen_Refresh(); // Refresh the screen

}

This is simple. The task first redraws black over the entire MeleeArea
surface, before drawing both players onto it (via the "Melee_DrawPlayer"
routine) and then blitting that onto the screen. The DrawPlayer routine is
thus:
void Melee_DrawPlayer(char Player)

{

int CenterX = (Players[Player].MeleeShipPic->w / 2);

int CenterY = (Players[Player].MeleeShipPic->h / 2);

sge_FilledRect(Players[Player].MeleeShipPicRot, 0, 0,
Players[Player].MeleeShipPicRot->w, Players[Player].MeleeShipPicRot->h, 0);

sge_transform(Players[Player].MeleeShipPic, Players[Player].MeleeShipPicRot,
(float)Players[Player].sr, (float)Melee_Zoom, (float)Melee_Zoom, CenterX,
CenterY, (Players[Player].MeleeShipPicRot->w / 2),
(Players[Player].MeleeShipPicRot->h / 2), 0);

Images_DrawImage(Players[Player].MeleeShipPicRot, MeleeArea,
(int)(Players[Player].sx - CenterX), (int)(Players[Player].sy - CenterY),
255, 0, 255);

}

This routine will rotate the each player’s ship picture and blit it onto the
MeleeArea surface. In case you’re wondering, i’ve initialised the screen
thus:
char Init_Screen(void) // Initialise the SDL screen routines

{

screen = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE|SDL_DOUBLEBUF); //
Setup default 640x480 screen

if (screen == NULL) // Initalisation error

{

printf(“Unable to set 800x600 16 bit video: %s\n”, SDL_GetError()); // Show
error

return 1; // Return error flag to calling routine

}

// Set the screenbounds rect to the dimensions of the screen

SETRECT(screenbounds, 0, 0, screen->w, screen->h)

#if SDL_BYTEORDER == SDL_BIG_ENDIAN

screenmasks.RMask = 0xff000000;

screenmasks.GMask = 0x00ff0000;

screenmasks.BMask = 0x0000ff00;

screenmasks.AMask = 0x000000ff;

#else

screenmasks.RMask = 0x000000ff;

screenmasks.GMask = 0x0000ff00;

screenmasks.BMask = 0x00ff0000;

screenmasks.AMask = 0xff000000;

#endif

return 0; // Return no error to the calling routine

}

The blit routine is thus:
void Images_DrawImage(SDL_Surface *image, SDL_Surface *dest, int x, int y,
unsigned char MaskR, unsigned char MaskB, unsigned char MaskG)

{

SDL_Rect destbounds; // New rect structure

if (image == NULL) // Check for invalid source pointer

{

printf(“Invalid DrawImage image pointer!\n”);

return;

}

if (dest == NULL) // Check for invalid destination pointer

{

printf(“Invalid DrawImage dest pointer!\n”);

return;

}

// Fill the rect structure:

SETRECT(destbounds, x, y, image->w, image->h)

SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, MaskR,
MaskB, MaskG)); // Set transparency colour

SDL_BlitSurface(image, NULL, screen, &destbounds); // Blit the image onto
the screen

}

And the “MeleeArea” surface is initialised thus:

MeleeArea = SDL_CreateRGBSurface(SDL_SWSURFACE, SpaceBounds.w,
SpaceBounds.h, 32, screenmasks.RMask, screenmasks.BMask, screenmasks.GMask,
screenmasks.AMask); // Set up the Melee Area surface

Now, the problem. I can’t see anything on the Melee part of the screen. All
works fine if I skip the MeleeArea surface and draw directly onto my
"screen" surface. I can use the SGE blit, which semi works (transparency is
dodgy) but that’s too slow and I want to figure this out. I tested that the
surface is being drawn correctly by using SDL and SGE line/box/circle
routines. It seems that the surface only shows graphics if they are draw
from the SDL/SGE libraries, but not blitted from another surface. This is a
mystery to me. I’ve tried every combination I can think of and all the other
routines work correctly in every other situation. I can email directly my
entire source code thus far if anyone requires it.

For those playing at home, my stats are:
Windows XP @ 700MHz
Visual C++.net
Latest SDL and SGE libraries

Can anyone shed some light on this mystery?

  • Dean> ----- Original Message -----

From: sdl-request@libsdl.org ()
To: <@Dean_Camera>
Sent: Friday, July 15, 2005 10:46 PM
Subject: Welcome to the “SDL” mailing list (Digest mode)

Welcome to the SDL at libsdl.org mailing list!

To post to this list, send your email to:

sdl at libsdl.org

General information about the mailing list is at:

http://www.libsdl.org/mailman/listinfo/sdl

If you ever want to unsubscribe or change your options (eg, switch to
or from digest mode, change your password, etc.), visit your
subscription page at:

http://www.libsdl.org/mailman/options/sdl/dean_camera%40hotmail.com

You can also make such adjustments via email by sending a message to:

SDL-request at libsdl.org

with the word `help’ in the subject or body (don’t include the
quotes), and you will get back a message with instructions.

You must know your password to change your options (including changing
the password, itself) or to unsubscribe. It is:

oracle

Normally, Mailman will remind you of your libsdl.org mailing list
passwords once every month, although you can disable this if you
prefer. This reminder will also include instructions on how to
unsubscribe or change your account options. There is also a button on
your options page that will email your current password to you.

Thanks to all that reminded me I accidentally included my password with my
previous message. I’ve since changed it - I can’t BELIEVE I did that! Oh
well, chalk that up to fatigue - it’s 1AM here.

Feel free to answer my problem, anybody ;).

  • Dean