From 4e0501f3610f2a303c869b02533cb8f5d66e10ab Mon Sep 17 00:00:00 2001
From: divverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 27 Aug 2010 05:43:12 +0000
Subject: [PATCH] SDL: also use a non-XPM icon darkplaces-icon.tga but only if
 SDL is >= 1.3 (SDL 1.2 doesn't support smooth alpha transparency on window
 icons)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10422 d7cf8633-e32d-0410-b094-e92efae38249
---
 vid_sdl.c | 184 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 114 insertions(+), 70 deletions(-)

diff --git a/vid_sdl.c b/vid_sdl.c
index e751030d..eda8c6a0 100644
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include <stdio.h>
 
 #include "quakedef.h"
+#include "image.h"
 
 #ifdef WIN32
 #define SDL_R_RESTART
@@ -551,100 +552,143 @@ static void VID_SetIcon(void)
 	unsigned short palenc[256]; // store color id by char
 	char *xpm;
 	char **idata, *data;
+	const SDL_version *version;
 
-	xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
-	idata = NULL;
-	if(xpm)
-		idata = XPM_DecodeString(xpm);
-	if(!idata)
-		idata = ENGINE_ICON;
-	if(xpm)
-		Mem_Free(xpm);
-
-	data = idata[0];
-
-	if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4)
+	version = SDL_Linked_Version();
+	// only use non-XPM icon support in SDL v1.3 and higher
+	// SDL v1.2 does not support "smooth" transparency, and thus is better
+	// off the xpm way
+	if(version->major >= 2 || version->major == 1 && version->minor >= 3)
 	{
-		// NOTE: Only 1-char colornames are supported
-		Con_Printf("Sorry, but this does not even look similar to an XPM.\n");
-		return;
-	}
+		data = (char *) loadimagepixelsbgra("darkplaces-icon", false, false, false, NULL);
+		if(data)
+		{
+			unsigned int red = 0x00FF0000;
+			unsigned int green = 0x0000FF00;
+			unsigned int blue = 0x000000FF;
+			unsigned int alpha = 0xFF000000;
+			width = image_width;
+			height = image_height;
+
+			// reallocate with malloc, as this is in tempmempool (do not want)
+			xpm = data;
+			data = malloc(width * height * 4);
+			memcpy(data, xpm, width * height * 4);
+			Mem_Free(xpm);
+			xpm = NULL;
+
+			icon = SDL_CreateRGBSurface(SDL_SRCALPHA, width, height, 32, LittleLong(red), LittleLong(green), LittleLong(blue), LittleLong(alpha));
+
+			if(icon == NULL) {
+				Con_Printf(	"Failed to create surface for the window Icon!\n"
+						"%s\n", SDL_GetError());
+				free(data);
+				return;
+			}
 
-	if(isize != 1)
-	{
-		// NOTE: Only 1-char colornames are supported
-		Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize);
-		return;
+			icon->pixels = data;
+		}
 	}
 
-	for(i = 0; i < colors; ++i)
+	// we only get here if non-XPM icon was missing, or SDL version is not
+	// sufficient for transparent non-XPM icons
+	if(!icon)
 	{
-		unsigned int r, g, b;
-		char idx;
+		xpm = (char *) FS_LoadFile("darkplaces-icon.xpm", tempmempool, false, NULL);
+		idata = NULL;
+		if(xpm)
+			idata = XPM_DecodeString(xpm);
+		if(!idata)
+			idata = ENGINE_ICON;
+		if(xpm)
+			Mem_Free(xpm);
+
+		data = idata[0];
+
+		if(sscanf(data, "%i %i %i %i", &width, &height, &colors, &isize) != 4)
+		{
+			// NOTE: Only 1-char colornames are supported
+			Con_Printf("Sorry, but this does not even look similar to an XPM.\n");
+			return;
+		}
+
+		if(isize != 1)
+		{
+			// NOTE: Only 1-char colornames are supported
+			Con_Printf("This XPM's palette is either huge or idiotically unoptimized. It's key size is %i\n", isize);
+			return;
+		}
 
-		if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4)
+		for(i = 0; i < colors; ++i)
 		{
-			char foo[2];
-			if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0
+			unsigned int r, g, b;
+			char idx;
+
+			if(sscanf(idata[i+1], "%c c #%02x%02x%02x", &idx, &r, &g, &b) != 4)
 			{
-				Con_Printf("This XPM's palette looks odd. Can't continue.\n");
-				return;
+				char foo[2];
+				if(sscanf(idata[i+1], "%c c Non%1[e]", &idx, foo) != 2) // I take the DailyWTF credit for this. --div0
+				{
+					Con_Printf("This XPM's palette looks odd. Can't continue.\n");
+					return;
+				}
+				else
+				{
+					palette[i].r = 255; // color key
+					palette[i].g = 0;
+					palette[i].b = 255;
+					thenone = i; // weeeee
+				}
 			}
 			else
 			{
-				palette[i].r = 255; // color key
-				palette[i].g = 0;
-				palette[i].b = 255;
-				thenone = i; // weeeee
+				palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key
+				palette[i].g = g;
+				palette[i].b = b;
 			}
-		}
-		else
-		{
-			palette[i].r = r - (r == 255 && g == 0 && b == 255); // change 255/0/255 pink to 254/0/255 for color key
-			palette[i].g = g;
-			palette[i].b = b;
-		}
 
-		palenc[(unsigned char) idx] = i;
-	}
+			palenc[(unsigned char) idx] = i;
+		}
 
-	// allocate the image data
-	data = (char*) malloc(width*height);
+		// allocate the image data
+		data = (char*) malloc(width*height);
 
-	for(j = 0; j < height; ++j)
-	{
-		for(i = 0; i < width; ++i)
+		for(j = 0; j < height; ++j)
 		{
-			// casting to the safest possible datatypes ^^
-			data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]];
+			for(i = 0; i < width; ++i)
+			{
+				// casting to the safest possible datatypes ^^
+				data[j * width + i] = palenc[((unsigned char*)idata[colors+j+1])[i]];
+			}
 		}
-	}
 
-	if(icon != NULL)
-	{
-		// SDL_FreeSurface should free the data too
-		// but for completeness' sake...
-		if(icon->flags & SDL_PREALLOC)
+		if(icon != NULL)
 		{
-			free(icon->pixels);
-			icon->pixels = NULL; // safety
+			// SDL_FreeSurface should free the data too
+			// but for completeness' sake...
+			if(icon->flags & SDL_PREALLOC)
+			{
+				free(icon->pixels);
+				icon->pixels = NULL; // safety
+			}
+			SDL_FreeSurface(icon);
 		}
-		SDL_FreeSurface(icon);
-	}
 
-	icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed
-	// 8 bit surfaces get an empty palette allocated according to the docs
-	// so it's a palette image for sure :) no endian check necessary for the mask
+		icon = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, width, height, 8, 0,0,0,0);// rmask, gmask, bmask, amask); no mask needed
+		// 8 bit surfaces get an empty palette allocated according to the docs
+		// so it's a palette image for sure :) no endian check necessary for the mask
 
-	if(icon == NULL) {
-		Con_Printf(	"Failed to create surface for the window Icon!\n"
-				"%s\n", SDL_GetError());
-		free(data);
-		return;
+		if(icon == NULL) {
+			Con_Printf(	"Failed to create surface for the window Icon!\n"
+					"%s\n", SDL_GetError());
+			free(data);
+			return;
+		}
+
+		icon->pixels = data;
+		SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors);
+		SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone);
 	}
-	icon->pixels = data;
-	SDL_SetPalette(icon, SDL_PHYSPAL|SDL_LOGPAL, palette, 0, colors);
-	SDL_SetColorKey(icon, SDL_SRCCOLORKEY, thenone);
 
 	SDL_WM_SetIcon(icon, NULL);
 }
-- 
2.39.5