about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-03-16 01:04:51 -0400
committerJune McEnroe <june@causal.agency>2019-03-16 01:08:07 -0400
commit7fc5513a1fe1252c5bc27f7616bf12d3db014639 (patch)
tree581e287f8862cb22943be189dbe70df04eae5767
parentSimplify Cards constants (diff)
downloadcards-7fc5513a1fe1252c5bc27f7616bf12d3db014639.tar.gz
cards-7fc5513a1fe1252c5bc27f7616bf12d3db014639.zip
Add flags to fix up cards graphics
-rw-r--r--cards.c92
-rw-r--r--cards.h19
-rw-r--r--dump.c2
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);