about summary refs log tree commit diff
path: root/cards.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cards.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/cards.c b/cards.c
index 174b081..29aa7a4 100644
--- a/cards.c
+++ b/cards.c
@@ -358,6 +358,51 @@ fail:
 	return NULL;
 }
 
+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;
+}
+
+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_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;
+		}
+	}
+	return 0;
+}
+
 void Cards_Free(struct Cards *cards) {
 	for (int i = 0; i < Cards_Count; ++i) {
 		if (!cards->surfaces[i]) continue;