about summary refs log tree commit diff
path: root/cards.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-03-28 18:53:21 -0400
committerJune McEnroe <june@causal.agency>2019-03-28 18:53:21 -0400
commitc5b75b347ecaca4f62280e04508d6362cd8fa093 (patch)
tree761dcf00b6c94120c9daa139e177cc12df55d7f6 /cards.c
parentRefactor EXE/DLL loading to be more general (diff)
downloadcards-c5b75b347ecaca4f62280e04508d6362cd8fa093.tar.gz
cards-c5b75b347ecaca4f62280e04508d6362cd8fa093.zip
Simplify (sort of) Cards API and add FreeCell loading
Diffstat (limited to 'cards.c')
-rw-r--r--cards.c220
1 files changed, 110 insertions, 110 deletions
diff --git a/cards.c b/cards.c
index b9153a5..fd108b9 100644
--- a/cards.c
+++ b/cards.c
@@ -82,69 +82,6 @@ fail:
 	return NULL;
 }
 
-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;
-}
-
 // exefmt.txt
 static int
 loadNE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 neOffset) {
@@ -322,49 +259,123 @@ static int loadEXE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw) {
 	}
 }
 
-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));
-		return NULL;
+static int setColorKey(SDL_Surface **surfaces, size_t count) {
+	size_t i = Cards_Empty;
+	if (i < count) {
+		if (SDL_SetColorKey(surfaces[i], SDL_TRUE, 1) < 0) return -1;
+	}
+	for (i = Cards_X; i <= Cards_O; ++i) {
+		if (i >= count) break;
+		if (SDL_SetColorKey(surfaces[i], SDL_TRUE, 12) < 0) return -1;
 	}
+	return 0;
+}
 
-	if (loadEXE(cards->surfaces, Cards_Count, rw) < 0) goto fail;
+static int setAlphaCorners(SDL_Surface **surfaces, size_t count) {
+	SDL_Surface *alpha = NULL;
+	for (size_t i = 0; i < count; ++i) {
+		if (!surfaces[i]) continue;
 
-	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;
+		alpha = SDL_ConvertSurfaceFormat(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_CardWidth - 2, 0, 2, 1 },
+			{ Cards_CardWidth - 1, 1, 1, 1 },
+			{ 0, Cards_CardHeight - 1, 2, 1 },
+			{ 0, Cards_CardHeight - 2, 1, 1 },
+			{ Cards_CardWidth - 2, Cards_CardHeight - 1, 2, 1 },
+			{ Cards_CardWidth - 1, Cards_CardHeight - 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(surfaces[i]);
+		surfaces[i] = alpha;
 	}
-	for (int i = Cards_Empty; i <= Cards_Back12; ++i) {
-		if (cards->surfaces[i]) continue;
-		SDL_SetError("missing resource %d", i);
-		goto fail;
+	return 0;
+
+fail:
+	SDL_FreeSurface(alpha);
+	return -1;
+}
+
+static int setBlackBorders(SDL_Surface **surfaces, size_t count) {
+	for (size_t i = Cards_Diamond + Cards_A; i <= Cards_Heart + Cards_K; ++i) {
+		if (i >= count) break;
+		if (!surfaces[i]) continue;
+		SDL_Rect rects[8] = {
+			{ 2, 0, Cards_CardWidth - 4, 1 },
+			{ 2, Cards_CardHeight - 1, Cards_CardWidth - 4, 1 },
+			{ 0, 2, 1, Cards_CardHeight - 4 },
+			{ Cards_CardWidth - 1, 2, 1, Cards_CardHeight - 4 },
+			{ 1, 1, 1, 1 },
+			{ Cards_CardWidth - 2, 1, 1, 1 },
+			{ 1, Cards_CardHeight - 2, 1, 1 },
+			{ Cards_CardWidth - 2, Cards_CardHeight - 2, 1, 1 },
+		};
+		Uint32 black = SDL_MapRGB(surfaces[i]->format, 0x00, 0x00, 0x00);
+		if (SDL_FillRects(surfaces[i], rects, 8, black) < 0) return -1;
 	}
-	for (int i = Cards_X; i <= Cards_O; ++i) {
-		if (cards->surfaces[i]) continue;
-		SDL_SetError("missing resource %d", i);
-		goto fail;
+	return 0;
+}
+
+static int
+checkRange(SDL_Surface **surfaces, size_t count, size_t a, size_t b) {
+	for (size_t i = a; i <= b; ++i) {
+		if (i >= count) break;
+		if (surfaces[i]) continue;
+		SDL_SetError("missing resource %zu", i);
+		return -1;
 	}
+	return 0;
+}
 
+int
+Cards_LoadCards(
+	SDL_Surface **surfaces, size_t count,
+	SDL_RWops *rw, enum Cards_Flag flags
+) {
+	memset(surfaces, 0, sizeof(*surfaces) * count);
+	if (loadEXE(surfaces, count, rw) < 0) return -1;
+	if (checkRange(surfaces, count, Cards_A, Cards_Back12) < 0) return -1;
+	if (checkRange(surfaces, count, Cards_X, Cards_O) < 0) return -1;
 	if (flags & Cards_ColorKey) {
-		if (setColorKey(cards) < 0) goto fail;
+		if (setColorKey(surfaces, count) < 0) return -1;
 	}
 	if (flags & Cards_AlphaCorners) {
-		if (setAlphaCorners(cards) < 0) goto fail;
+		if (setAlphaCorners(surfaces, count) < 0) return -1;
 	}
 	if (flags & Cards_BlackBorders) {
-		if (setBlackBorders(cards) < 0) goto fail;
+		if (setBlackBorders(surfaces, count) < 0) return -1;
 	}
+	return 0;
+}
 
-	return cards;
-
-fail:
-	Cards_Free(cards);
-	return NULL;
+int
+Cards_LoadFreeCell(
+	SDL_Surface **surfaces, size_t count,
+	SDL_RWops *rw, enum Cards_Flag flags
+) {
+	memset(surfaces, 0, sizeof(*surfaces) * count);
+	if (loadEXE(surfaces, count, rw) < 0) return -1;
+	if (checkRange(surfaces, count, Cards_KingRight, Cards_KingWin) < 0) {
+		return -1;
+	}
+	if (flags & Cards_ColorKey) {
+		for (size_t i = Cards_KingRight; i <= Cards_KingWin; ++i) {
+			if (i >= count) break;
+			if (SDL_SetColorKey(surfaces[i], SDL_TRUE, 2) < 0) return -1;
+		}
+	}
+	return 0;
 }
 
-int invertPalette(SDL_Surface *surface) {
+static int invertPalette(SDL_Surface *surface) {
 	const SDL_Palette *palette = surface->format->palette;
 	SDL_Palette *invert = SDL_AllocPalette(palette->ncolors);
 	if (!invert) return -1;
@@ -379,7 +390,7 @@ int invertPalette(SDL_Surface *surface) {
 	return 0;
 }
 
-int invertPixels(SDL_Surface *surface) {
+static int invertPixels(SDL_Surface *surface) {
 	if (SDL_LockSurface(surface) < 0) return -1;
 	Uint8 *pixels = surface->pixels;
 	for (int y = 0; y < surface->h; ++y) {
@@ -394,25 +405,14 @@ int invertPixels(SDL_Surface *surface) {
 	return 0;
 }
 
-int Cards_Invert(struct Cards *cards) {
-	for (int i = 0; i < Cards_Count; ++i) {
-		if (!cards->surfaces[i]) continue;
-		if (cards->surfaces[i]->format->palette) {
-			if (invertPalette(cards->surfaces[i]) < 0) return -1;
-		} else if (cards->surfaces[i]->format->BytesPerPixel == 4) {
-			if (invertPixels(cards->surfaces[i]) < 0) return -1;
-		} else {
-			SDL_SetError("unexpected surface format");
-			return -1;
-		}
+int Cards_InvertSurface(SDL_Surface *surface) {
+	if (surface->format->palette) {
+		if (invertPalette(surface) < 0) return -1;
+	} else if (surface->format->BytesPerPixel == 4) {
+		if (invertPixels(surface) < 0) return -1;
+	} else {
+		SDL_SetError("cannot invert surface format");
+		return -1;
 	}
 	return 0;
 }
-
-void Cards_Free(struct Cards *cards) {
-	for (int i = 0; i < Cards_Count; ++i) {
-		if (!cards->surfaces[i]) continue;
-		SDL_FreeSurface(cards->surfaces[i]);
-	}
-	free(cards);
-}