summary refs log tree commit diff
path: root/cards.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-08-25 13:21:48 -0400
committerJune McEnroe <june@causal.agency>2019-08-25 13:21:48 -0400
commit4a54edfcd4b964a94b7c7f4fb7a8d30dd2272b7f (patch)
treeb5a8455f75f1763fa08f781272689860c2a4da4d /cards.c
parentMark card functions inline (diff)
downloadwep-4a54edfcd4b964a94b7c7f4fb7a8d30dd2272b7f.tar.gz
wep-4a54edfcd4b964a94b7c7f4fb7a8d30dd2272b7f.zip
Remove files from cards repo
Diffstat (limited to 'cards.c')
-rw-r--r--cards.c428
1 files changed, 0 insertions, 428 deletions
diff --git a/cards.c b/cards.c
deleted file mode 100644
index ddc5b86..0000000
--- a/cards.c
+++ /dev/null
@@ -1,428 +0,0 @@
-/* Copyright (C) 2019  C. McEnroe <june@causal.agency>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cards.h"
-
-static SDL_Surface *
-dibSurface(SDL_RWops *rw, Uint32 offset, Uint32 length) {
-	Uint32 bitmapLength = 0x0E + length;
-
-	Uint8 *buffer = malloc(bitmapLength);
-	if (!buffer) {
-		SDL_SetError("malloc error: %s", strerror(errno));
-		return NULL;
-	}
-
-	SDL_RWops *bitmap = SDL_RWFromMem(buffer, bitmapLength);
-	if (!bitmap) {
-		free(buffer);
-		return NULL;
-	}
-
-	if (SDL_RWseek(rw, offset, RW_SEEK_SET) < 0) goto fail;
-	Uint32 dibHeaderLength = SDL_ReadLE32(rw);
-	Uint32 bitmapDataOffset = 0x0E + dibHeaderLength;
-
-	if (dibHeaderLength == 0x0C) {
-		if (SDL_RWseek(rw, 0x06, RW_SEEK_CUR) < 0) goto fail;
-		Uint16 bitsPerPixel = SDL_ReadLE16(rw);
-		bitmapDataOffset += 3 * (1 << bitsPerPixel);
-
-	} else if (dibHeaderLength == 0x28) {
-		if (SDL_RWseek(rw, 0x0A, RW_SEEK_CUR) < 0) goto fail;
-		Uint16 bitsPerPixel = SDL_ReadLE16(rw);
-		if (SDL_RWseek(rw, 0x10, RW_SEEK_CUR) < 0) goto fail;
-		Uint32 paletteLength = SDL_ReadLE32(rw);
-
-		if (!paletteLength && bitsPerPixel < 16) {
-			paletteLength = 1 << bitsPerPixel;
-		}
-		bitmapDataOffset += 4 * paletteLength;
-
-	} else {
-		SDL_SetError("unrecognized DIB header length %u", dibHeaderLength);
-		goto fail;
-	}
-
-	SDL_WriteU8(bitmap, 'B');
-	SDL_WriteU8(bitmap, 'M');
-	SDL_WriteLE32(bitmap, bitmapLength);
-	SDL_WriteLE16(bitmap, 0); // reserved
-	SDL_WriteLE16(bitmap, 0); // reserved
-	SDL_WriteLE32(bitmap, bitmapDataOffset);
-
-	if (SDL_RWseek(rw, offset, RW_SEEK_SET) < 0) goto fail;
-	if (SDL_RWread(rw, &buffer[SDL_RWtell(bitmap)], length, 1) < 1) goto fail;
-
-	SDL_RWseek(bitmap, 0, RW_SEEK_SET);
-	SDL_Surface *surface = SDL_LoadBMP_RW(bitmap, 1);
-	free(buffer);
-	return surface;
-
-fail:
-	SDL_RWclose(bitmap);
-	free(buffer);
-	return NULL;
-}
-
-// exefmt.txt
-static int
-loadNE(
-	SDL_Surface **surfaces, size_t count,
-	SDL_RWops *rw, Uint16 neOffset, Uint32 idSkip
-) {
-	if (SDL_RWseek(rw, neOffset + 0x24, RW_SEEK_SET) < 0) return -1;
-	Uint16 resourceTableOffset = neOffset + SDL_ReadLE16(rw);
-
-	if (SDL_RWseek(rw, resourceTableOffset, RW_SEEK_SET) < 0) return -1;
-	Uint16 alignmentShift = SDL_ReadLE16(rw);
-
-	Uint16 resourceCount;
-	for (;;) {
-		Uint16 typeID = SDL_ReadLE16(rw);
-		resourceCount = SDL_ReadLE16(rw);
-		SDL_ReadLE32(rw); // reserved
-
-		if (!typeID) {
-			SDL_SetError("no bitmap resources");
-			return -1;
-		}
-		if (typeID == 0x8002) break;
-
-		if (SDL_RWseek(rw, 0x0C * resourceCount, RW_SEEK_CUR) < 0) return -1;
-	}
-
-	for (Uint16 i = 0; i < resourceCount; ++i) {
-		Uint16 dataOffset = SDL_ReadLE16(rw);
-		Uint16 dataLength = SDL_ReadLE16(rw);
-		/* Uint16 flags = */ SDL_ReadLE16(rw);
-		Uint16 resourceID = SDL_ReadLE16(rw);
-		SDL_ReadLE32(rw); // reserved
-
-		resourceID &= 0x7FFF;
-		if (resourceID >= idSkip) resourceID -= idSkip;
-		if (resourceID >= count) continue;
-
-		Sint64 nextResource = SDL_RWtell(rw);
-		if (nextResource < 0) return -1;
-
-		surfaces[resourceID] = dibSurface(
-			rw,
-			(Uint32)dataOffset << alignmentShift,
-			(Uint32)dataLength << alignmentShift
-		);
-		if (!surfaces[resourceID]) return -1;
-
-		if (SDL_RWseek(rw, nextResource, RW_SEEK_SET) < 0) return -1;
-	}
-
-	return 0;
-}
-
-// <https://docs.microsoft.com/en-us/windows/desktop/Debug/pe-format>
-static int
-loadPE(
-	SDL_Surface **surfaces, size_t count,
-	SDL_RWops *rw, Uint16 peOffset, Uint32 idSkip
-) {
-	if (SDL_RWseek(rw, peOffset + 0x04 + 0x02, RW_SEEK_SET) < 0) return -1;
-	Uint16 sectionCount = SDL_ReadLE16(rw);
-
-	if (SDL_RWseek(rw, peOffset + 0x04 + 0x10, RW_SEEK_SET) < 0) return -1;
-	Uint16 optionalHeaderLength = SDL_ReadLE16(rw);
-	Uint16 sectionTableOffset = peOffset + 0x04 + 0x14 + optionalHeaderLength;
-
-	Uint32 resourceTableOffset = 0;
-	Uint32 resourceTableVirtual = 0;
-	for (Uint16 i = 0; i < sectionCount; ++i) {
-		Uint16 headerOffset = sectionTableOffset + 0x28 * i;
-
-		if (SDL_RWseek(rw, headerOffset, RW_SEEK_SET) < 0) return -1;
-		char name[8];
-		if (!SDL_RWread(rw, name, sizeof(name), 1)) return -1;
-		if (strncmp(".rsrc", name, sizeof(name))) continue;
-
-		if (SDL_RWseek(rw, headerOffset + 0x0C, RW_SEEK_SET) < 0) return -1;
-		resourceTableVirtual = SDL_ReadLE32(rw);
-
-		if (SDL_RWseek(rw, headerOffset + 0x14, RW_SEEK_SET) < 0) return -1;
-		resourceTableOffset = SDL_ReadLE32(rw);
-
-		break;
-	}
-	if (!resourceTableOffset) {
-		SDL_SetError("no resource table");
-		return -1;
-	}
-
-	if (SDL_RWseek(rw, resourceTableOffset + 0x0C, RW_SEEK_SET) < 0) return -1;
-	Uint16 typeNameCount = SDL_ReadLE16(rw);
-	Uint16 typeIDCount = SDL_ReadLE16(rw);
-
-	if (SDL_RWseek(rw, 0x08 * typeNameCount, RW_SEEK_CUR) < 0) return -1;
-
-	Uint32 bitmapTableOffset = 0;
-	for (Uint16 i = 0; i < typeIDCount; ++i) {
-		Uint32 typeID = SDL_ReadLE32(rw);
-		Uint32 subdirOffset = SDL_ReadLE32(rw);
-		if (typeID != 0x02) continue;
-		if (!(subdirOffset & (1 << 31))) {
-			SDL_SetError("bitmap type entry does not point to table");
-			return -1;
-		}
-		bitmapTableOffset = resourceTableOffset + (subdirOffset & ~(1 << 31));
-		break;
-	}
-
-	if (SDL_RWseek(rw, bitmapTableOffset + 0x0C, RW_SEEK_SET) < 0) return -1;
-	Uint16 nameNameCount = SDL_ReadLE16(rw);
-	Uint16 nameIDCount = SDL_ReadLE16(rw);
-
-	if (SDL_RWseek(rw, 0x08 * nameNameCount, RW_SEEK_CUR) < 0) return -1;
-
-	for (Uint16 i = 0; i < nameIDCount; ++i) {
-		Uint32 nameID = SDL_ReadLE32(rw);
-		if (nameID >= idSkip) nameID -= idSkip;
-		if (nameID >= count) continue;
-
-		Uint32 subdirOffset = SDL_ReadLE32(rw);
-		if (!(subdirOffset & (1 << 31))) {
-			SDL_SetError("bitmap name entry does not point to table");
-			return -1;
-		}
-
-		Sint64 nextName = SDL_RWtell(rw);
-		if (nextName < 0) return -1;
-
-		Uint32 langTableOffset =
-			resourceTableOffset + (subdirOffset & ~(1 << 31));
-
-		if (SDL_RWseek(rw, langTableOffset + 0x0C, RW_SEEK_SET) < 0) return -1;
-		Uint16 langNameCount = SDL_ReadLE16(rw);
-		Uint16 langIDCount = SDL_ReadLE16(rw);
-		if (langNameCount != 0 || langIDCount != 1) {
-			SDL_SetError("language table contains more than one entry");
-			return -1;
-		}
-
-		/* Uint32 langID = */ SDL_ReadLE32(rw);
-		Uint32 dataEntryOffset = SDL_ReadLE32(rw);
-		if (dataEntryOffset & (1 << 31)) {
-			SDL_SetError("language entry does not point to data");
-			return -1;
-		}
-		dataEntryOffset += resourceTableOffset;
-
-		if (SDL_RWseek(rw, dataEntryOffset, RW_SEEK_SET) < 0) return -1;
-		Uint32 dataVirtual = SDL_ReadLE32(rw);
-		Uint32 dataLength = SDL_ReadLE32(rw);
-		Uint32 dataOffset =
-			dataVirtual - (resourceTableVirtual - resourceTableOffset);
-
-		surfaces[nameID] = dibSurface(rw, dataOffset, dataLength);
-		if (!surfaces[nameID]) return -1;
-
-		if (SDL_RWseek(rw, nextName, RW_SEEK_SET) < 0) return -1;
-	}
-
-	return 0;
-}
-
-static int
-loadEXE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint32 idSkip) {
-	if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0) return -1;
-	if (SDL_ReadU8(rw) != 'M' || SDL_ReadU8(rw) != 'Z') {
-		SDL_SetError("invalid MZ signature");
-		return -1;
-	}
-
-	if (SDL_RWseek(rw, 0x3C, RW_SEEK_SET) < 0) return -1;
-	Uint16 offset = SDL_ReadLE16(rw);
-
-	if (SDL_RWseek(rw, offset, RW_SEEK_SET) < 0) return -1;
-	Uint8 sig[2] = { SDL_ReadU8(rw), SDL_ReadU8(rw) };
-
-	if (sig[0] == 'N' && sig[1] == 'E') {
-		return loadNE(surfaces, count, rw, offset, idSkip);
-	} else if (sig[0] == 'P' && sig[1] == 'E') {
-		return loadPE(surfaces, count, rw, offset, idSkip);
-	} else {
-		SDL_SetError("invalid NE/PE signature");
-		return -1;
-	}
-}
-
-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;
-}
-
-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;
-
-		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;
-	}
-	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;
-	}
-	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) < 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(surfaces, count) < 0) return -1;
-	}
-	if (flags & Cards_AlphaCorners) {
-		if (setAlphaCorners(surfaces, count) < 0) return -1;
-	}
-	if (flags & Cards_BlackBorders) {
-		if (setBlackBorders(surfaces, count) < 0) return -1;
-	}
-	return 0;
-}
-
-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, 402) < 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;
-}
-
-static int invertPalette(SDL_Surface *surface) {
-	const SDL_Palette *palette = surface->format->palette;
-	SDL_Palette *invert = SDL_AllocPalette(palette->ncolors);
-	if (!invert) return -1;
-	for (int i = 0; i < invert->ncolors; ++i) {
-		invert->colors[i].r = ~palette->colors[i].r;
-		invert->colors[i].g = ~palette->colors[i].g;
-		invert->colors[i].b = ~palette->colors[i].b;
-		invert->colors[i].a =  palette->colors[i].a;
-	}
-	if (SDL_SetSurfacePalette(surface, invert) < 0) return -1;
-	SDL_FreePalette(invert);
-	return 0;
-}
-
-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) {
-		Uint32 *row = (Uint32 *)&pixels[y * surface->pitch];
-		for (int x = 0; x < surface->w; ++x) {
-			Uint32 color = ~row[x] & ~surface->format->Amask;
-			Uint32 alpha = row[x] & surface->format->Amask;
-			row[x] = color | alpha;
-		}
-	}
-	SDL_UnlockSurface(surface);
-	return 0;
-}
-
-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;
-}