diff options
-rw-r--r-- | cards.c | 92 | ||||
-rw-r--r-- | cards.h | 19 | ||||
-rw-r--r-- | dump.c | 2 |
3 files changed, 98 insertions, 15 deletions
diff --git a/cards.c b/cards.c index 35660ad..dac93fe 100644 --- a/cards.c +++ b/cards.c @@ -20,8 +20,8 @@ #include "cards.h" -static struct SDL_Surface * -dibSurface(struct SDL_RWops *rw, Uint32 offset, Uint32 length) { +static SDL_Surface * +dibSurface(SDL_RWops *rw, Uint32 offset, Uint32 length) { Uint32 bitmapLength = 0x0E + length; Uint8 *buffer = malloc(bitmapLength); @@ -30,7 +30,7 @@ dibSurface(struct SDL_RWops *rw, Uint32 offset, Uint32 length) { return NULL; } - struct SDL_RWops *bitmap = SDL_RWFromMem(buffer, bitmapLength); + SDL_RWops *bitmap = SDL_RWFromMem(buffer, bitmapLength); if (!bitmap) { free(buffer); return NULL; @@ -80,7 +80,70 @@ fail: return NULL; } -struct Cards *Cards_Load(struct SDL_RWops *rw) { +static int setColorKey(struct Cards *cards) { + int i = Cards_Empty; + if (SDL_SetColorKey(cards->surfaces[i], SDL_TRUE, 1) < 0) return -1; + for (i = Cards_X; i <= Cards_O; ++i) { + if (SDL_SetColorKey(cards->surfaces[i], SDL_TRUE, 12) < 0) return -1; + } + return 0; +} + +static int setAlphaCorners(struct Cards *cards) { + SDL_Surface *alpha = NULL; + for (int i = 0; i < Cards_Count; ++i) { + if (!cards->surfaces[i]) continue; + + alpha = SDL_ConvertSurfaceFormat( + cards->surfaces[i], SDL_PIXELFORMAT_RGBA32, 0 + ); + if (!alpha) return -1; + + if (SDL_SetSurfaceBlendMode(alpha, SDL_BLENDMODE_BLEND) < 0) goto fail; + + SDL_Rect rects[8] = { + { 0, 0, 2, 1 }, + { 0, 1, 1, 1 }, + { Cards_Width - 2, 0, 2, 1 }, + { Cards_Width - 1, 1, 1, 1 }, + { 0, Cards_Height - 1, 2, 1 }, + { 0, Cards_Height - 2, 1, 1 }, + { Cards_Width - 2, Cards_Height - 1, 2, 1 }, + { Cards_Width - 1, Cards_Height - 2, 1, 1 }, + }; + Uint32 trans = SDL_MapRGBA(alpha->format, 0x00, 0x00, 0x00, 0x00); + if (SDL_FillRects(alpha, rects, 8, trans) < 0) goto fail; + + SDL_FreeSurface(cards->surfaces[i]); + cards->surfaces[i] = alpha; + } + return 0; + +fail: + SDL_FreeSurface(alpha); + return -1; +} + +static int setBlackBorders(struct Cards *cards) { + for (int i = Cards_Diamond + Cards_A; i <= Cards_Heart + Cards_K; ++i) { + if (!cards->surfaces[i]) continue; + SDL_Rect rects[8] = { + { 2, 0, Cards_Width - 4, 1 }, + { 2, Cards_Height - 1, Cards_Width - 4, 1 }, + { 0, 2, 1, Cards_Height - 4 }, + { Cards_Width - 1, 2, 1, Cards_Height - 4 }, + { 1, 1, 1, 1 }, + { Cards_Width - 2, 1, 1, 1 }, + { 1, Cards_Height - 2, 1, 1 }, + { Cards_Width - 2, Cards_Height - 2, 1, 1 }, + }; + Uint32 black = SDL_MapRGB(cards->surfaces[i]->format, 0x00, 0x00, 0x00); + if (SDL_FillRects(cards->surfaces[i], rects, 8, black) < 0) return -1; + } + return 0; +} + +struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags) { struct Cards *cards = calloc(1, sizeof(*cards)); if (!cards) { SDL_SetError("calloc error: %s", strerror(errno)); @@ -146,13 +209,10 @@ struct Cards *Cards_Load(struct SDL_RWops *rw) { if (SDL_RWseek(rw, next, RW_SEEK_SET) < 0) goto fail; } - int suits[4] = { Cards_Club, Cards_Diamond, Cards_Heart, Cards_Spade }; - for (int suit = 0; suit < 4; ++suit) { - for (int rank = Cards_A; rank <= Cards_K; ++rank) { - if (cards->surfaces[suits[suit] + rank]) continue; - SDL_SetError("missing resource %d", suits[suit] + rank); - goto fail; - } + for (int i = Cards_Club + Cards_A; i <= Cards_Spade + Cards_K; ++i) { + if (cards->surfaces[i]) continue; + SDL_SetError("missing resource %d", i); + goto fail; } for (int i = Cards_Empty; i <= Cards_Back12; ++i) { if (cards->surfaces[i]) continue; @@ -165,6 +225,16 @@ struct Cards *Cards_Load(struct SDL_RWops *rw) { goto fail; } + if (flags & Cards_ColorKey) { + if (setColorKey(cards) < 0) goto fail; + } + if (flags & Cards_AlphaCorners) { + if (setAlphaCorners(cards) < 0) goto fail; + } + if (flags & Cards_BlackBorders) { + if (setBlackBorders(cards) < 0) goto fail; + } + return cards; fail: diff --git a/cards.h b/cards.h index 2ce85a9..0ed1b8f 100644 --- a/cards.h +++ b/cards.h @@ -23,12 +23,15 @@ enum { Cards_Width = 71, Cards_Height = 96, +}; - Cards_Club = 0, +enum { + Cards_Club, Cards_Diamond = 13, Cards_Heart = 26, Cards_Spade = 39, + // Add rank to suit to obtain card face index. Cards_A = 1, Cards_2, Cards_3, Cards_4, Cards_5, Cards_6, Cards_7, Cards_8, Cards_9, Cards_10, Cards_J, Cards_Q, Cards_K, @@ -44,11 +47,21 @@ enum { Cards_Count, }; +// Some pointers will be NULL since there are gaps in the indices. struct Cards { - struct SDL_Surface *surfaces[Cards_Count]; + SDL_Surface *surfaces[Cards_Count]; +}; + +enum Cards_Flags { + // Set color key for Cards_Empty, Cards_X, Cards_O. + Cards_ColorKey = 1 << 0, + // Set alpha in card corners. + Cards_AlphaCorners = 1 << 1, + // Set red card borders to black. + Cards_BlackBorders = 1 << 2, }; -struct Cards *Cards_Load(struct SDL_RWops *rw); +struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags); void Cards_Free(struct Cards *cards); #endif diff --git a/dump.c b/dump.c index f52a24c..d6e705e 100644 --- a/dump.c +++ b/dump.c @@ -35,7 +35,7 @@ int main(int argc, char *argv[]) { } if (!rw) return fail("SDL_RWFromFile"); - struct Cards *cards = Cards_Load(rw); + struct Cards *cards = Cards_Load(rw, 0); if (!cards) return fail("Cards_Load"); SDL_RWclose(rw); |