summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--freecell.c117
-rw-r--r--path.h10
2 files changed, 88 insertions, 39 deletions
diff --git a/freecell.c b/freecell.c
index f480bda..178da57 100644
--- a/freecell.c
+++ b/freecell.c
@@ -132,17 +132,23 @@ enum {
 	CardWidth = Cards_CardWidth,
 	CardHeight = Cards_CardHeight,
 
-	StackMarginX = 7,
-	StackMarginY = 10,
-
 	CellX = 0,
 	CellY = 0,
 
-	CellsMarginX = 64,
+	KingMarginX = 13,
+	KingX = CellX + 4 * CardWidth + KingMarginX,
+	KingY = 18,
+	KingPadX = 3,
+	KingPadY = 3,
+	KingWidth = Cards_KingWidth + 2 * KingPadX,
+	KingHeight = Cards_KingHeight + 2 * KingPadY,
 
-	FoundationX = CellX + 4 * CardWidth + CellsMarginX,
+	FoundationX = KingX + KingWidth + KingMarginX,
 	FoundationY = CellY,
 
+	StackMarginX = 7,
+	StackMarginY = 10,
+
 	TableauX = StackMarginX,
 	TableauY = CellY + CardHeight + StackMarginY,
 
@@ -277,28 +283,43 @@ static bool mouseButtonUp(SDL_MouseButtonEvent button) {
 
 static SDL_Renderer *render;
 
+static void renderOutline(SDL_Rect rect, bool out) {
+	int right = rect.x + rect.w - 1;
+	int bottom = rect.y + rect.h - 1;
+	SDL_Point topLeft[3] = {
+		{ rect.x, bottom - 1 },
+		{ rect.x, rect.y },
+		{ right - 1, rect.y },
+	};
+	SDL_Point bottomRight[3] = {
+		{ rect.x + 1, bottom },
+		{ right, bottom },
+		{ right, rect.y + 1 },
+	};
+	SDL_SetRenderDrawColor(render, 0x00, 0x00, 0x00, 0xFF);
+	SDL_RenderDrawLines(render, out ? bottomRight : topLeft, 3);
+	SDL_SetRenderDrawColor(render, 0x00, 0xFF, 0x00, 0xFF);
+	SDL_RenderDrawLines(render, out ? topLeft : bottomRight, 3);
+}
+
 static void renderOutlines(void) {
 	for (uint i = Foundation1; i <= Cell4; ++i) {
-		int right = stackRects[i].x + CardWidth - 1;
-		int bottom = stackRects[i].y + CardHeight - 1;
-		SDL_Point black[3] = {
-			{ stackRects[i].x, bottom - 1 },
-			{ stackRects[i].x, stackRects[i].y },
-			{ right - 1, stackRects[i].y },
-		};
-		SDL_Point green[3] = {
-			{ stackRects[i].x + 1, bottom },
-			{ right, bottom },
-			{ right, stackRects[i].y + 1 },
-		};
-		SDL_SetRenderDrawColor(render, 0x00, 0x00, 0x00, 0xFF);
-		SDL_RenderDrawLines(render, black, 3);
-		SDL_SetRenderDrawColor(render, 0x00, 0xFF, 0x00, 0xFF);
-		SDL_RenderDrawLines(render, green, 3);
+		renderOutline(stackRects[i], false);
 	}
 }
 
-static void renderList(SDL_Texture **textures, const struct List *list) {
+static void renderKing(SDL_Texture *textures[]) {
+	SDL_Rect box = { KingX, KingY, KingWidth, KingHeight };
+	renderOutline(box, true);
+	SDL_Rect king = {
+		KingX + KingPadX, KingY + KingPadY,
+		Cards_KingWidth, Cards_KingHeight,
+	};
+	// TODO: Determine king direction.
+	SDL_RenderCopy(render, textures[Cards_KingRight], NULL, &king);
+}
+
+static void renderList(SDL_Texture *textures[], const struct List *list) {
 	for (uint i = 0; i < list->len; ++i) {
 		SDL_RenderCopy(
 			render, textures[list->items[i].card],
@@ -325,17 +346,32 @@ int main(void) {
 	char *prefPath = SDL_GetPrefPath("Causal Agency", "Cards");
 	if (!prefPath) err("SDL_GetPrefPath");
 
+	bool kings = false;
+	struct {
+		SDL_Surface *cards[Cards_Empty];
+		SDL_Surface *kings[Cards_FreeCellCount];
+	} surfaces;
+
 	SDL_RWops *rw = pathCards(basePath, prefPath);
 	if (!rw) return EXIT_FAILURE;
-
-	SDL_Surface *surfaces[Cards_Empty];
 	int error = Cards_LoadCards(
-		surfaces, Cards_Empty,
+		surfaces.cards, Cards_Empty,
 		rw, Cards_AlphaCorners | Cards_BlackBorders
 	);
 	if (error) err("Cards_LoadCards");
 	SDL_RWclose(rw);
 
+	rw = pathFreeCell(basePath, prefPath);
+	if (rw) {
+		kings = true;
+		int error = Cards_LoadFreeCell(
+			surfaces.kings, Cards_FreeCellCount,
+			rw, Cards_ColorKey
+		);
+		if (error) err("Cards_LoadFreeCell");
+		SDL_RWclose(rw);
+	}
+
 	SDL_Window *window;
 	error = SDL_CreateWindowAndRenderer(
 		WindowWidth, WindowHeight, SDL_WINDOW_ALLOW_HIGHDPI,
@@ -347,21 +383,33 @@ int main(void) {
 	SDL_RenderSetIntegerScale(render, SDL_TRUE);
 	SDL_RenderSetLogicalSize(render, WindowWidth, WindowHeight);
 
-	SDL_Texture *textures[Cards_Empty];
-	SDL_Texture *inverted[Cards_Empty];
+	SDL_Texture *textures[Cards_Empty] = {0};
+	SDL_Texture *inverted[Cards_Empty] = {0};
+	SDL_Texture *kingTextures[Cards_FreeCellCount] = {0};
+
 	for (uint i = 0; i < Cards_Empty; ++i) {
-		textures[i] = NULL;
-		inverted[i] = NULL;
-		if (!surfaces[i]) continue;
+		if (!surfaces.cards[i]) continue;
 
-		textures[i] = SDL_CreateTextureFromSurface(render, surfaces[i]);
+		textures[i] = SDL_CreateTextureFromSurface(render, surfaces.cards[i]);
 		if (!textures[i]) err("SDL_CreateTextureFromSurface");
 
-		if (Cards_InvertSurface(surfaces[i]) < 0) err("Cards_InvertSurface");
-		inverted[i] = SDL_CreateTextureFromSurface(render, surfaces[i]);
+		error = Cards_InvertSurface(surfaces.cards[i]);
+		if (error) err("Cards_InvertSurface");
+
+		inverted[i] = SDL_CreateTextureFromSurface(render, surfaces.cards[i]);
 		if (!inverted[i]) err("SDL_CreateTextureFromSurface");
 
-		SDL_FreeSurface(surfaces[i]);
+		SDL_FreeSurface(surfaces.cards[i]);
+	}
+
+	if (kings) {
+		for (uint i = 0; i < Cards_FreeCellCount; ++i) {
+			if (!surfaces.kings[i]) continue;
+			kingTextures[i] =
+				SDL_CreateTextureFromSurface(render, surfaces.kings[i]);
+			if (!kingTextures[i]) err("SDL_CreateTextureFromSurface");
+			SDL_FreeSurface(surfaces.kings[i]);
+		}
 	}
 
 	srand(time(NULL));
@@ -373,6 +421,7 @@ int main(void) {
 		SDL_SetRenderDrawColor(render, 0x00, 0xAA, 0x55, 0xFF);
 		SDL_RenderClear(render);
 		renderOutlines();
+		if (kings) renderKing(kingTextures);
 		renderList(textures, &layout.main);
 		renderList(inverted, &layout.drag);
 		renderList(textures, &reveal);
diff --git a/path.h b/path.h
index 05caa62..f3832d9 100644
--- a/path.h
+++ b/path.h
@@ -36,11 +36,6 @@ pathSearch(const char *base, const char *pref, const char **names, size_t len) {
 	return NULL;
 }
 
-static inline SDL_RWops *
-pathFind(const char *base, const char *pref, const char *name) {
-	return pathSearch(base, pref, &name, 1);
-}
-
 static inline SDL_RWops *pathCards(const char *base, const char *pref) {
 	const char *names[3] = { "CARDS.DLL", "SOL.EXE", "cards.dll" };
 	SDL_RWops *rw = pathSearch(base, pref, names, 3);
@@ -54,4 +49,9 @@ static inline SDL_RWops *pathCards(const char *base, const char *pref) {
 	return NULL;
 }
 
+static inline SDL_RWops *pathFreeCell(const char *base, const char *pref) {
+	const char *names[2] = { "FREECELL.EXE", "freecell.exe" };
+	return pathSearch(base, pref, names, 2);
+}
+
 #endif