shithub: pokecrystal

Download patch

ref: 5cf1754b08aa6903f01b839c917169e6dc8c260f
parent: c26d758fee2bc3a3af617430378bc7649d8f7b67
author: yenatch <[email protected]>
date: Wed Jun 12 08:38:28 EDT 2013

gfx: handling for <4-color pngs when converting to 2bpp

without a .pal file as reference, palettes are sorted by luminance.
pokemon crystal reads palettes exactly 4 colors in length.
if an image used fewer than 4 colors, invalid palettes were produced.

instead, dummy colors are inserted to pad out the palette.

--- a/extras/gfx.py
+++ b/extras/gfx.py
@@ -1183,6 +1183,12 @@
 	blue = word & 0b11111
 	alpha = 255
 	return ((red<<3)+0b100, (green<<3)+0b100, (blue<<3)+0b100, alpha)
+	
+def rgb_to_dmg(color):
+	word =  (color['r'] / 8) << 10
+	word += (color['g'] / 8) <<  5
+	word += (color['b'] / 8)
+	return word
 
 
 def png_pal(filename):
@@ -1303,17 +1309,13 @@
 		greyscale = info[3]['greyscale']
 
 
-	# commented out for the moment
-
 	padding = { 'left':   0,
 	            'right':  0,
 	            'top':    0,
 	            'bottom': 0, }
-
 	#if width  % 8 != 0:
 	#	padding['left']   =    int(ceil((width / 8 + 8 - width) / 2))
 	#	padding['right']  =   int(floor((width / 8 + 8 - width) / 2))
-
 	#if height % 8 != 0:
 	#	padding['top']    =  int(ceil((height / 8 + 8 - height) / 2))
 	#	padding['bottom'] = int(floor((height / 8 + 8 - height) / 2))
@@ -1322,7 +1324,7 @@
 	# turn the flat values into something more workable
 
 	pixel_length = 4 # rgba
-	image   = []
+	image = []
 
 	# while we're at it, let's size up the palette
 
@@ -1331,18 +1333,31 @@
 	for line in rgba:
 		newline = []
 		for pixel in range(len(line)/pixel_length):
-			i = pixel*pixel_length
+			i = pixel * pixel_length
 			color = { 'r': line[i  ],
 			          'g': line[i+1],
 			          'b': line[i+2],
 			          'a': line[i+3], }
-			newline.append(color)
-			if color not in palette: palette.append(color)
+			newline += [color]
+			if color not in palette: palette += [color]
 		image.append(newline)
 
+	# pad out any small palettes
+	hues = {
+		'white': { 'r': 0xff, 'g': 0xff, 'b': 0xff, 'a': 0xff },
+		'black': { 'r': 0x00, 'g': 0x00, 'b': 0x00, 'a': 0xff },
+		'grey':  { 'r': 0x55, 'g': 0x55, 'b': 0x55, 'a': 0xff },
+		'gray':  { 'r': 0xaa, 'g': 0xaa, 'b': 0xaa, 'a': 0xff },
+	}
+	while len(palette) < 4:
+		for hue in hues.values():
+			if not any(color is hue for color in palette):
+				palette += [hue]
+				if len(palette) >= 4: break
 
-	# sort by luminance, because we can
+	assert len(palette) <= 4, 'Palette should be 4 colors, is really ' + str(len(palette))
 
+	# sort by luminance
 	def luminance(color):
 		# this is actually in reverse, thanks to dmg/cgb palette ordering
 		rough = { 'r':  4.7,
@@ -1349,35 +1364,18 @@
 		          'g':  1.4,
 		          'b': 13.8, }
 		return sum(color[key] * -rough[key] for key in rough.keys())
+	palette = sorted(palette, key=luminance)
 
-	palette = sorted(palette, key = lambda x:luminance(x))
+	# spit out new .pal file
+	#if palout != None:
+	#	output = []
+	#	for color in palette[1:3]:
+	#		word = rgb_to_dmg(color)
+	#		output += [word & 0xff]
+	#		output += [word >> 8]
+	#	to_file(palout, output)
 
-	# no palette fixing for now
-
-	assert len(palette) <= 4, 'Palette should be 4 colors, is really ' + str(len(palette))
-
-
-	# spit out new palette (disabled for now)
-
-	def rgb_to_dmg(color):
-		word =  (color['r'] / 8) << 10
-		word += (color['g'] / 8) <<  5
-		word += (color['b'] / 8)
-		return word
-
-	palout = None
-
-	if palout != None:
-		output = []
-		for color in palette[1:3]:
-			word = rgb_to_dmg(color)
-			output.append(word>>8)
-			output.append(word&0xff)
-		to_file(palout, output)
-
-
-	# create a new map consisting of quaternary color ids
-
+	# create a new map of quaternary color ids
 	map = []
 	if padding['top']: map += [0] * (width + padding['left'] + padding['right']) * padding['top']
 	for line in image:
@@ -1388,12 +1386,9 @@
 	if padding['bottom']: map += [0] * (width + padding['left'] + padding['right']) * padding['bottom']
 
 	# split it into strips of 8, and make them planar
-
 	num_columns = width / 8
 	num_rows = height / 8
-
 	tile = 8 * 8
-
 	image = []
 	for row in range(num_rows):
 		for column in range(num_columns):