mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-08 14:58:14 +03:00
Implement simple DrawGraph.Fill* functions
DrawGraph.Fill - fill solid color DrawGraph.FillAlphaColor - blend solid color DrawGraph.FillAMap - fill alpha channel
This commit is contained in:
+3
-3
@@ -64,11 +64,11 @@ hll_unimplemented(DrawGraph, BlendMultiply);
|
||||
//void BlendScreenAlpha(int nDest, int nDx, int nDy, int nSrc, int nSx, int nSy, int nWidth, int nHeight, int nAlpha)
|
||||
hll_unimplemented(DrawGraph, BlendScreenAlpha);
|
||||
//void Fill(int nDest, int nX, int nY, int nWidth, int nHeight, int nR, int nG, int nB)
|
||||
hll_unimplemented(DrawGraph, Fill);
|
||||
hll_defun_inline(Fill, (DrawGraph_Fill(a[0].i, a[1].i, a[2].i, a[3].i, a[4].i, a[5].i, a[6].i, a[7].i), 0));
|
||||
//void FillAlphaColor(int nDest, int nX, int nY, int nWidth, int nHeight, int nR, int nG, int nB, int nRate)
|
||||
hll_unimplemented(DrawGraph, FillAlphaColor);
|
||||
hll_defun_inline(FillAlphaColor, (DrawGraph_FillAlphaColor(a[0].i, a[1].i, a[2].i, a[3].i, a[4].i, a[5].i, a[6].i, a[7].i, a[8].i), 0));
|
||||
//void FillAMap(int nDest, int nX, int nY, int nWidth, int nHeight, int nAlpha)
|
||||
hll_unimplemented(DrawGraph, FillAMap);
|
||||
hll_defun_inline(FillAMap, (DrawGraph_FillAMap(a[0].i, a[1].i, a[2].i, a[3].i, a[4].i, a[5].i), 0));
|
||||
//void FillAMapOverBorder(int nDest, int nX, int nY, int nWidth, int nHeight, int nAlpha, int nBorder)
|
||||
hll_unimplemented(DrawGraph, FillAMapOverBorder);
|
||||
//void FillAMapUnderBorder(int nDest, int nX, int nY, int nWidth, int nHeight, int nAlpha, int nBorder)
|
||||
|
||||
@@ -65,4 +65,8 @@ void DrawGraph_CopyUseAMapBorder(int dno, int dx, int dy, int sno, int sx, int s
|
||||
void DrawGraph_CopyAMapMax(int dno, int dx, int dy, int sno, int sx, int sy, int w, int h);
|
||||
void DrawGraph_CopyAMapMin(int dno, int dx, int dy, int sno, int sx, int sy, int w, int h);
|
||||
|
||||
void DrawGraph_Fill(int sp_no, int x, int y, int w, int h, int r, int g, int b);
|
||||
void DrawGraph_FillAMap(int sp_no, int x, int y, int w, int h, int a);
|
||||
void DrawGraph_FillAlphaColor(int sp_no, int x, int y, int w, int h, int r, int g, int b, int a);
|
||||
|
||||
#endif /* SYSTEM4_SACT_H */
|
||||
|
||||
+64
-3
@@ -125,11 +125,12 @@ int sact_SP_SetCG(int sp_no, int cg_no)
|
||||
|
||||
int sact_SP_Create(int sp_no, int width, int height, int r, int g, int b, int a)
|
||||
{
|
||||
struct sact_sprite *sp = sact_get_sprite(sp_no);
|
||||
struct sact_sprite *sp;
|
||||
|
||||
if (!sp) {
|
||||
if (sp_no < 0)
|
||||
VM_ERROR("Invalid sprite number: %d", sp_no);
|
||||
if (!(sp = sact_get_sprite(sp_no)))
|
||||
sp = alloc_sprite(sp_no);
|
||||
}
|
||||
|
||||
sp->color = (SDL_Color) { .r = r, .g = g, .b = b, .a = a };
|
||||
sp->rect.w = width;
|
||||
@@ -344,6 +345,17 @@ static inline void next_pixel(SDL_Surface *s, uint32_t **p)
|
||||
SDL_UnlockSurface(ds); \
|
||||
} while (0)
|
||||
|
||||
#define fill_for_each_pixel(s, x, y, w, h, p, expr) \
|
||||
do { \
|
||||
SDL_LockSurface(s); \
|
||||
for (int _row = 0; _row < h; _row++) { \
|
||||
uint32_t *p = get_pixel(s, x, _row+y); \
|
||||
for (int _col = 0; _col < w; _col++, next_pixel(s, &p)) \
|
||||
expr; \
|
||||
} \
|
||||
SDL_UnlockSurface(s); \
|
||||
} while(0);
|
||||
|
||||
void DrawGraph_CopyAMap(int dno, int dx, int dy, int sno, int sx, int sy, int w, int h)
|
||||
{
|
||||
SDL_Surface *ds = DrawGraph_get_sprite(dno)->cg->s;
|
||||
@@ -450,3 +462,52 @@ void DrawGraph_CopyAMapMin(int dno, int dx, int dy, int sno, int sx, int sy, int
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void blend_pixels(SDL_Color *dst, SDL_Color src)
|
||||
{
|
||||
uint32_t alpha = src.a + 1;
|
||||
uint32_t inv_alpha = 256 - src.a;
|
||||
dst->r = (uint8_t)((alpha * src.r + inv_alpha * dst->r) >> 8);
|
||||
dst->g = (uint8_t)((alpha * src.g + inv_alpha * dst->g) >> 8);
|
||||
dst->b = (uint8_t)((alpha * src.b + inv_alpha * dst->b) >> 8);
|
||||
}
|
||||
|
||||
void DrawGraph_Fill(int sp_no, int x, int y, int w, int h, int r, int g, int b)
|
||||
{
|
||||
SDL_Surface *s = DrawGraph_get_sprite(sp_no)->cg->s;
|
||||
|
||||
fill_for_each_pixel(s, x, y, w, h, p, {
|
||||
*p &= ~(s->format->Rmask | s->format->Gmask | s->format->Bmask);
|
||||
*p |= (uint32_t)r << s->format->Rshift;
|
||||
*p |= (uint32_t)g << s->format->Gshift;
|
||||
*p |= (uint32_t)b << s->format->Bshift;
|
||||
});
|
||||
}
|
||||
|
||||
// XXX: Despite being called a fill operation, this function actually performs blending.
|
||||
void DrawGraph_FillAlphaColor(int sp_no, int x, int y, int w, int h, int r, int g, int b, int a)
|
||||
{
|
||||
SDL_Surface *s = DrawGraph_get_sprite(sp_no)->cg->s;
|
||||
|
||||
SDL_Color dst;
|
||||
SDL_Color src = { .r = r, .g = g, .b = b, .a = a };
|
||||
fill_for_each_pixel(s, x, y, w, h, p, {
|
||||
SDL_GetRGBA(*p, s->format, &dst.r, &dst.g, &dst.b, &dst.a);
|
||||
blend_pixels(&dst, src);
|
||||
*p &= ~(s->format->Rmask | s->format->Gmask | s->format->Bmask | s->format->Amask);
|
||||
*p |= (uint32_t)dst.r << s->format->Rshift;
|
||||
*p |= (uint32_t)dst.g << s->format->Gshift;
|
||||
*p |= (uint32_t)dst.b << s->format->Bshift;
|
||||
*p |= (uint32_t)dst.a << s->format->Ashift;
|
||||
});
|
||||
}
|
||||
|
||||
void DrawGraph_FillAMap(int sp_no, int x, int y, int w, int h, int a)
|
||||
{
|
||||
SDL_Surface *s = DrawGraph_get_sprite(sp_no)->cg->s;
|
||||
|
||||
fill_for_each_pixel(s, x, y, w, h, p, {
|
||||
*p &= ~s->format->Amask;
|
||||
*p |= (uint32_t)a << s->format->Ashift;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user