Agrego transparencia a las bolsas que desparecen.
parent
2db613871d
commit
e0ab125eda
39
src/beans.c
39
src/beans.c
|
@ -379,6 +379,7 @@ void setup (void);
|
||||||
SDL_Surface * set_video_mode(unsigned flags);
|
SDL_Surface * set_video_mode(unsigned flags);
|
||||||
void setup_and_color_penguin (void);
|
void setup_and_color_penguin (void);
|
||||||
void add_bag (int tipo);
|
void add_bag (int tipo);
|
||||||
|
void delete_bag (BeanBag *p);
|
||||||
|
|
||||||
/* Variables globales */
|
/* Variables globales */
|
||||||
SDL_Surface * screen;
|
SDL_Surface * screen;
|
||||||
|
@ -526,11 +527,11 @@ int game_loop (void) {
|
||||||
Uint32 last_time, now_time;
|
Uint32 last_time, now_time;
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
int penguinx, handposx;
|
int penguinx, handposx;
|
||||||
BeanBag *thisbag;
|
BeanBag *thisbag, *nextbag;
|
||||||
|
|
||||||
int bags = 0;
|
int bags = 0;
|
||||||
int penguin_frame = 0;
|
int penguin_frame = 0;
|
||||||
int i;
|
int i, j;
|
||||||
|
|
||||||
/* Predibujar todo */
|
/* Predibujar todo */
|
||||||
/*SDL_FillRect (screen, NULL, 0);
|
/*SDL_FillRect (screen, NULL, 0);
|
||||||
|
@ -598,9 +599,17 @@ int game_loop (void) {
|
||||||
/* Procesar las bolsas */
|
/* Procesar las bolsas */
|
||||||
thisbag = first_bag;
|
thisbag = first_bag;
|
||||||
while (thisbag != NULL) {
|
while (thisbag != NULL) {
|
||||||
|
nextbag = thisbag->next;
|
||||||
|
|
||||||
thisbag->frame++;
|
thisbag->frame++;
|
||||||
|
|
||||||
thisbag = thisbag->next;
|
j = thisbag->frame - thisbag->throw_length;
|
||||||
|
if (j >= 35) {
|
||||||
|
/* Eliminar esta bolsa */
|
||||||
|
delete_bag (thisbag);
|
||||||
|
}
|
||||||
|
|
||||||
|
thisbag = nextbag;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_BlitSurface (images[IMG_BACKGROUND], NULL, screen, NULL);
|
SDL_BlitSurface (images[IMG_BACKGROUND], NULL, screen, NULL);
|
||||||
|
@ -655,12 +664,17 @@ int game_loop (void) {
|
||||||
i = IMG_BAG_4;
|
i = IMG_BAG_4;
|
||||||
rect.x = thisbag->bag_points[thisbag->throw_length][1];
|
rect.x = thisbag->bag_points[thisbag->throw_length][1];
|
||||||
rect.y = thisbag->bag_points[thisbag->throw_length][2];
|
rect.y = thisbag->bag_points[thisbag->throw_length][2];
|
||||||
|
j = thisbag->frame - thisbag->throw_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
rect.w = images[i]->w;
|
rect.w = images[i]->w;
|
||||||
rect.h = images[i]->h;
|
rect.h = images[i]->h;
|
||||||
|
|
||||||
SDL_BlitSurface (images[i], NULL, screen, &rect);
|
if (i == IMG_BAG_4 && j > 25) {
|
||||||
|
SDL_gfxBlitRGBAWithAlpha (images[i], NULL, screen, &rect, 255 - SDL_ALPHA_OPAQUE * (j - 25) / 10);
|
||||||
|
} else {
|
||||||
|
SDL_BlitSurface (images[i], NULL, screen, &rect);
|
||||||
|
}
|
||||||
|
|
||||||
thisbag = thisbag->next;
|
thisbag = thisbag->next;
|
||||||
}
|
}
|
||||||
|
@ -989,3 +1003,20 @@ void add_bag (int tipo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void delete_bag (BeanBag *p) {
|
||||||
|
if (p == NULL) return;
|
||||||
|
|
||||||
|
if (p->prev == NULL) { /* El primero de la lista */
|
||||||
|
first_bag = p->next;
|
||||||
|
} else {
|
||||||
|
p->prev->next = p->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->next == NULL) {
|
||||||
|
last_bag = p->prev;
|
||||||
|
} else {
|
||||||
|
p->next->prev = p->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,13 @@ b = ((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss; \
|
||||||
a = ((pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss; \
|
a = ((pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \
|
||||||
|
{ \
|
||||||
|
r = (((Pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss); \
|
||||||
|
g = (((Pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss); \
|
||||||
|
b = (((Pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss); \
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Disassemble buffer pointer into a pixel and separate RGBA values.
|
\brief Disassemble buffer pointer into a pixel and separate RGBA values.
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +58,34 @@ GFX_RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a); \
|
||||||
pixel &= ~fmt->Amask; \
|
pixel &= ~fmt->Amask; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define GFX_DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \
|
||||||
|
do { \
|
||||||
|
switch (bpp) { \
|
||||||
|
case 2: \
|
||||||
|
Pixel = *((Uint16 *)(buf)); \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case 3: { \
|
||||||
|
Uint8 *B = (Uint8 *)buf; \
|
||||||
|
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
|
||||||
|
Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
|
||||||
|
} else { \
|
||||||
|
Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case 4: \
|
||||||
|
Pixel = *((Uint32 *)(buf)); \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
default: \
|
||||||
|
Pixel = 0; /* prevent gcc from complaining */ \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Wrap a pixel from RGBA values using mask, shift and loss for surface.
|
\brief Wrap a pixel from RGBA values using mask, shift and loss for surface.
|
||||||
*/
|
*/
|
||||||
|
@ -67,10 +102,36 @@ pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \
|
||||||
*/
|
*/
|
||||||
#define GFX_ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
|
#define GFX_ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \
|
||||||
{ \
|
{ \
|
||||||
Uint32 pixel; \
|
switch (bpp) { \
|
||||||
\
|
case 2: { \
|
||||||
GFX_PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \
|
Uint16 Pixel; \
|
||||||
*((Uint32 *)(buf)) = pixel; \
|
\
|
||||||
|
GFX_PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
|
||||||
|
*((Uint16 *)(buf)) = Pixel; \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case 3: { /* FIXME: broken code (no alpha) */ \
|
||||||
|
if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \
|
||||||
|
*((buf)+fmt->Rshift/8) = r; \
|
||||||
|
*((buf)+fmt->Gshift/8) = g; \
|
||||||
|
*((buf)+fmt->Bshift/8) = b; \
|
||||||
|
} else { \
|
||||||
|
*((buf)+2-fmt->Rshift/8) = r; \
|
||||||
|
*((buf)+2-fmt->Gshift/8) = g; \
|
||||||
|
*((buf)+2-fmt->Bshift/8) = b; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case 4: { \
|
||||||
|
Uint32 Pixel; \
|
||||||
|
\
|
||||||
|
GFX_PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a); \
|
||||||
|
*((Uint32 *)(buf)) = Pixel; \
|
||||||
|
} \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -83,18 +144,6 @@ dG = (((sG-dG)*(A))/255)+dG; \
|
||||||
dB = (((sB-dB)*(A))/255)+dB; \
|
dB = (((sB-dB)*(A))/255)+dB; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define PERFECT_ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
|
|
||||||
do { \
|
|
||||||
dR = ((sR * sA) + (dR * dA * (255 - sA))); \
|
|
||||||
dG = ((sG * sA) + (dG * dA * (255 - sA))); \
|
|
||||||
dB = ((sB * sA) + (dB * dA * (255 - sA))); \
|
|
||||||
dA = (sA + (dA * (255 - sA))); \
|
|
||||||
dR = dR / dA; \
|
|
||||||
dG = dG / dA; \
|
|
||||||
dB = dB / dA; \
|
|
||||||
dA = (dA / 255); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief 4-times unrolled DUFFs loop.
|
\brief 4-times unrolled DUFFs loop.
|
||||||
|
|
||||||
|
@ -124,6 +173,7 @@ typedef struct {
|
||||||
SDL_PixelFormat *src;
|
SDL_PixelFormat *src;
|
||||||
Uint8 *table;
|
Uint8 *table;
|
||||||
SDL_PixelFormat *dst;
|
SDL_PixelFormat *dst;
|
||||||
|
Uint8 alpha;
|
||||||
} SDL_gfxBlitInfo;
|
} SDL_gfxBlitInfo;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -607,3 +657,206 @@ int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SD
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Funciones escritas por Gatuno para hacer Blit con superficies transparentes más un alpha general */
|
||||||
|
/* General (slow) N->N blending with per-surface alpha */
|
||||||
|
static void _SDL_gfxBlitBlitterRGBAWithAlpha(SDL_gfxBlitInfo *info)
|
||||||
|
{
|
||||||
|
int width = info->d_width;
|
||||||
|
int height = info->d_height;
|
||||||
|
Uint8 *src = info->s_pixels;
|
||||||
|
int srcskip = info->s_skip;
|
||||||
|
Uint8 *dst = info->d_pixels;
|
||||||
|
int dstskip = info->d_skip;
|
||||||
|
SDL_PixelFormat *srcfmt = info->src;
|
||||||
|
SDL_PixelFormat *dstfmt = info->dst;
|
||||||
|
int srcbpp = srcfmt->BytesPerPixel;
|
||||||
|
int dstbpp = dstfmt->BytesPerPixel;
|
||||||
|
unsigned sAlpha = info->alpha;
|
||||||
|
unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;
|
||||||
|
|
||||||
|
if(sAlpha) {
|
||||||
|
while ( height-- ) {
|
||||||
|
GFX_DUFFS_LOOP4( {
|
||||||
|
Uint32 Pixel;
|
||||||
|
unsigned sR;
|
||||||
|
unsigned sG;
|
||||||
|
unsigned sB;
|
||||||
|
unsigned dR;
|
||||||
|
unsigned dG;
|
||||||
|
unsigned dB;
|
||||||
|
unsigned sA;
|
||||||
|
|
||||||
|
GFX_DISASSEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA);
|
||||||
|
GFX_DISEMBLE_RGB(dst, dstbpp, dstfmt, Pixel, dR, dG, dB);
|
||||||
|
sA = sA * sAlpha / 255;
|
||||||
|
GFX_ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);
|
||||||
|
GFX_ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA);
|
||||||
|
src += srcbpp;
|
||||||
|
dst += dstbpp;
|
||||||
|
},
|
||||||
|
width);
|
||||||
|
src += srcskip;
|
||||||
|
dst += dstskip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int _SDL_gfxBlitRGBACallWithAlpha(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect, Uint8 alpha)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set up source and destination buffer pointers, then blit
|
||||||
|
*/
|
||||||
|
if (srcrect->w && srcrect->h) {
|
||||||
|
SDL_gfxBlitInfo info;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the blit information
|
||||||
|
*/
|
||||||
|
#if (SDL_MINOR_VERSION == 3)
|
||||||
|
info.s_pixels = (Uint8 *) src->pixels + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
|
||||||
|
#else
|
||||||
|
info.s_pixels = (Uint8 *) src->pixels + src->offset + (Uint16) srcrect->y * src->pitch + (Uint16) srcrect->x * src->format->BytesPerPixel;
|
||||||
|
#endif
|
||||||
|
info.s_width = srcrect->w;
|
||||||
|
info.s_height = srcrect->h;
|
||||||
|
info.s_skip = (int)(src->pitch - info.s_width * src->format->BytesPerPixel);
|
||||||
|
#if (SDL_MINOR_VERSION == 3)
|
||||||
|
info.d_pixels = (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
|
||||||
|
#else
|
||||||
|
info.d_pixels = (Uint8 *) dst->pixels + dst->offset + (Uint16) dstrect->y * dst->pitch + (Uint16) dstrect->x * dst->format->BytesPerPixel;
|
||||||
|
#endif
|
||||||
|
info.d_width = dstrect->w;
|
||||||
|
info.d_height = dstrect->h;
|
||||||
|
info.d_skip = (int)(dst->pitch - info.d_width * dst->format->BytesPerPixel);
|
||||||
|
info.aux_data = NULL;
|
||||||
|
info.src = src->format;
|
||||||
|
info.table = NULL;
|
||||||
|
info.dst = dst->format;
|
||||||
|
info.alpha = alpha;
|
||||||
|
/*
|
||||||
|
* Run the actual software blitter
|
||||||
|
*/
|
||||||
|
_SDL_gfxBlitBlitterRGBAWithAlpha(&info);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Blitter for RGBA->RGBA blits with alpha per surface.
|
||||||
|
|
||||||
|
Verifies the input 'src' and 'dst' surfaces and rectangles and performs blit.
|
||||||
|
The destination clip rectangle is honored.
|
||||||
|
|
||||||
|
\param src The source surface.
|
||||||
|
\param srcrect The source rectangle.
|
||||||
|
\param dst The destination surface.
|
||||||
|
\param dstrect The destination rectangle.
|
||||||
|
|
||||||
|
\returns Returns 1 if blit was performed, 0 otherwise, or -1 if an error occured.
|
||||||
|
*/
|
||||||
|
int SDL_gfxBlitRGBAWithAlpha(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect, Uint8 alpha)
|
||||||
|
{
|
||||||
|
SDL_Rect sr, dr;
|
||||||
|
int srcx, srcy, w, h;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure the surfaces aren't locked
|
||||||
|
*/
|
||||||
|
if (!src || !dst) {
|
||||||
|
SDL_SetError("SDL_UpperBlit: passed a NULL surface");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if ((src->locked) || (dst->locked)) {
|
||||||
|
SDL_SetError("Surfaces must not be locked during blit");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alpha == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If the destination rectangle is NULL, use the entire dest surface
|
||||||
|
*/
|
||||||
|
if (dstrect == NULL) {
|
||||||
|
dr.x = dr.y = 0;
|
||||||
|
dr.w = dst->w;
|
||||||
|
dr.h = dst->h;
|
||||||
|
} else {
|
||||||
|
dr = *dstrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clip the source rectangle to the source surface
|
||||||
|
*/
|
||||||
|
if (srcrect) {
|
||||||
|
int maxw, maxh;
|
||||||
|
|
||||||
|
srcx = srcrect->x;
|
||||||
|
w = srcrect->w;
|
||||||
|
if (srcx < 0) {
|
||||||
|
w += srcx;
|
||||||
|
dr.x -= srcx;
|
||||||
|
srcx = 0;
|
||||||
|
}
|
||||||
|
maxw = src->w - srcx;
|
||||||
|
if (maxw < w)
|
||||||
|
w = maxw;
|
||||||
|
|
||||||
|
srcy = srcrect->y;
|
||||||
|
h = srcrect->h;
|
||||||
|
if (srcy < 0) {
|
||||||
|
h += srcy;
|
||||||
|
dr.y -= srcy;
|
||||||
|
srcy = 0;
|
||||||
|
}
|
||||||
|
maxh = src->h - srcy;
|
||||||
|
if (maxh < h)
|
||||||
|
h = maxh;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
srcx = srcy = 0;
|
||||||
|
w = src->w;
|
||||||
|
h = src->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clip the destination rectangle against the clip rectangle
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
SDL_Rect *clip = &dst->clip_rect;
|
||||||
|
int dx, dy;
|
||||||
|
|
||||||
|
dx = clip->x - dr.x;
|
||||||
|
if (dx > 0) {
|
||||||
|
w -= dx;
|
||||||
|
dr.x += dx;
|
||||||
|
srcx += dx;
|
||||||
|
}
|
||||||
|
dx = dr.x + w - clip->x - clip->w;
|
||||||
|
if (dx > 0)
|
||||||
|
w -= dx;
|
||||||
|
|
||||||
|
dy = clip->y - dr.y;
|
||||||
|
if (dy > 0) {
|
||||||
|
h -= dy;
|
||||||
|
dr.y += dy;
|
||||||
|
srcy += dy;
|
||||||
|
}
|
||||||
|
dy = dr.y + h - clip->y - clip->h;
|
||||||
|
if (dy > 0)
|
||||||
|
h -= dy;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
|
sr.x = srcx;
|
||||||
|
sr.y = srcy;
|
||||||
|
sr.w = dr.w = w;
|
||||||
|
sr.h = dr.h = h;
|
||||||
|
return (_SDL_gfxBlitRGBACallWithAlpha(src, &sr, dst, &dr, alpha));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define __GFX_BLIT_FUNC_H__
|
#define __GFX_BLIT_FUNC_H__
|
||||||
|
|
||||||
int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect);
|
int SDL_gfxBlitRGBA(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect);
|
||||||
|
int SDL_gfxBlitRGBAWithAlpha(SDL_Surface * src, SDL_Rect * srcrect, SDL_Surface * dst, SDL_Rect * dstrect, Uint8 alpha);
|
||||||
|
|
||||||
#endif /* __GFX_BLIT_FUNC_H__ */
|
#endif /* __GFX_BLIT_FUNC_H__ */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue