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.
218 lines
4.8 KiB
218 lines
4.8 KiB
/* $Id: gfxengine.c,v 1.5 2004/09/25 10:57:51 stpohle Exp $ */
|
|
/* GFX Game Engine */
|
|
|
|
#include "bomberclone.h"
|
|
|
|
int blitdb_nr = 0, blitrects_nr = 0;
|
|
static _gfxblit *blitdb; /* unsorted list of blitdb's */
|
|
static _gfxblit **sortblitdb; /* sorted list of blitdb's */
|
|
static SDL_Rect *blitrects; /* SDLUpdate Rects */
|
|
|
|
/* alloc all needed space */
|
|
void gfxengine_init () {
|
|
blitdb = malloc (sizeof (_gfxblit)* MAX_BLITRECTS);
|
|
sortblitdb = malloc (sizeof (_gfxblit *)* MAX_BLITRECTS);
|
|
blitrects = malloc (sizeof (SDL_Rect) * MAX_BLITRECTS);
|
|
};
|
|
|
|
|
|
/* 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++;
|
|
};
|