You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bomberclone/src/gfxengine.c

210 lines
4.6 KiB

/* $Id: gfxengine.c,v 1.3 2003/12/24 02:38:15 stpohle Exp $ */
/* GFX Game Engine */
#include "bomberclone.h"
int blitdb_nr = 0, blitrects_nr = 0;
static _gfxblit blitdb[MAX_BLITRECTS]; /* unsorted list of blitdb's */
static _gfxblit *sortblitdb[MAX_BLITRECTS]; /* sorted list of blitdb's */
static SDL_Rect blitrects[MAX_BLITRECTS]; /* SDLUpdate Rects */
/* sort the list of blitting objects highest will be drawn at last */
void gfx_blitsort () {
register int i,y;
gfx_blitsortclear ();
for (i = 0; i < MAX_BLITRECTS && i < blitdb_nr; i++) {
for (y = i; (y > 0 && blitdb[i].y < sortblitdb[y-1]->y); y--)
sortblitdb[y] = sortblitdb[y-1];
sortblitdb[y] = &blitdb[i];
}
}
/* delete sorted order of gfx updates */
inline void gfx_blitsortclear () {
register int i;
for (i = 0; i < MAX_BLITRECTS; i++)
sortblitdb[i] = NULL;
};
/* delete all updaterect entrys */
inline void gfx_blitupdaterectclear () {
register int i;
for (i = 0; i < MAX_BLITRECTS; i++)
blitrects[i].x = blitrects[i].y = blitrects[i].h = blitrects[i].w = -1;
blitrects_nr = 0;
};
/* SDL Update of the rects */
void gfx_blitupdaterectdraw () {
if (blitrects_nr > 0)
SDL_UpdateRects (gfx.screen, blitrects_nr, blitrects);
blitrects_nr = 0;
gfx_blitupdaterectclear ();
};
/* add updaterect entrys and skipp unneeded or double rects */
void gfx_blitupdaterectadd (SDL_Rect *rect) {
_point p1a, p1e, p2a, p2e;
int i, done = 0;
/* search for a match or an close update rect */
p2a.x = rect->x;
p2a.y = rect->y;
p2e.x = rect->x + rect->w;
p2e.y = rect->y + rect->h;
for (i = 0; i < blitrects_nr && !done; i++) {
p1a.x = blitrects[i].x;
p1a.y = blitrects[i].y;
p1e.x = blitrects[i].x + blitrects[i].w;
p1e.y = blitrects[i].y + blitrects[i].h;
if (p2a.x >= p1a.x && p2e.x <= p1e.x &&
p2a.y >= p1a.y && p2e.y <= p1e.y) {
/* p2 is in p1 >> drop rects */
done = 1;
}
/* p1 is in p2 >> change rect */
else if (p1a.x >= p2a.x && p1e.x <= p2e.x &&
p1a.y >= p2a.y && p1e.y <= p2e.y) {
blitrects[i].x = rect->x;
blitrects[i].y = rect->y;
blitrects[i].w = rect->w;
blitrects[i].h = rect->h;
done = 1;
}
}
/* no match found, add new */
if (i == blitrects_nr && !done) {
blitrects_nr++;
blitrects[i] = *rect;
}
};
void
gfx_blitdraw ()
{
int i;
if (blitdb_nr < 0) {
blitdb_nr = 0;
return;
}
gfx_blitsort ();
for (i = 0; i < MAX_BLITRECTS && sortblitdb[i] != NULL; i++) {
SDL_BlitSurface (sortblitdb[i]->srci, &sortblitdb[i]->srcr, sortblitdb[i]->desti, &sortblitdb[i]->destr);
gfx_blitupdaterectadd (&sortblitdb[i]->destr);
}
gfx_blitupdaterectdraw ();
blitdb_nr = 0;
};
/* Add a new image to draw/blit on the screen and in thw right order.
srcr srci: source image and rect
destr desti: destination image and rect
y: deep of the image */
void
gfx_blit (SDL_Surface *srci, SDL_Rect *srcr, SDL_Surface *desti, SDL_Rect *destr, int y)
{
int i;
SDL_Rect r_src, r_dest;
if (srcr == NULL) {
srcr = &r_src;
r_src.x = 0;
r_src.y = 0;
r_src.h = srci->h;
r_src.w = srci->w;
};
if (destr == NULL) {
destr = &r_dest;
r_dest.x = 0;
r_dest.y = 0;
r_dest.h = desti->h;
r_dest.w = desti->w;
};
/* check if the rects are out of the images and drop this blitting */
if (srcr->x > srci->w || srcr->y > srci->h ||
destr->x > desti->w || destr->y > desti->h)
return;
/* clipping src */
if (srcr->x < 0) { // x < 0
srcr->w += srcr->x;
destr->w += srcr->x;
destr->x -= srcr->x;
srcr->x = 0;
}
if (srcr->x+srcr->w > srci->w) { // x+w > img.w
i = srcr->x+srcr->w - srci->w;
srcr->w -= i;
destr->w -= i;
}
if (srcr->y < 0) { // y < 0
srcr->h += srcr->y;
destr->h += srcr->h;
destr->y -= srcr->y;
srcr->y = 0;
}
if (srcr->y+srcr->h > srci->h) { // y+h > img.h
i = srcr->y+srcr->h - srci->h;
srcr->h -= i;
destr->h -= i;
}
/* clipping dest */
if (destr->x < 0) { // x < 0
destr->w += destr->x;
srcr->w += destr->x;
srcr->x -= destr->x;
destr->x = 0;
}
if (destr->x+destr->w > desti->w) { // x+w > img.w
i = destr->x+destr->w - desti->w;
srcr->w -= i;
destr->w -= i;
}
if (destr->y < 0) { // y < 0
destr->h += destr->y;
srcr->h += destr->h;
srcr->y -= destr->y;
destr->y = 0;
}
if (destr->y+destr->h > desti->h) { // y+h > img.h
i = destr->y+destr->h - desti->h;
srcr->h -= i;
destr->h -= i;
}
/* add to list */
if (blitdb_nr < 0)
blitdb_nr = 0;
else if (blitdb_nr >= MAX_BLITRECTS) {
d_fatal ("blitdb_nr > MAX_BLITRECTS\n");
return;
}
blitdb[blitdb_nr].srcr = *srcr;
blitdb[blitdb_nr].srci = srci;
blitdb[blitdb_nr].destr = *destr;
blitdb[blitdb_nr].desti = desti;
blitdb[blitdb_nr].y = y;
blitdb_nr++;
};