113 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			113 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | from .Utils import data_path | ||
|  | 
 | ||
|  | # TODO | ||
|  | # Move the tunic to the generalized system | ||
|  | 
 | ||
|  | # Function for adding hue to a greyscaled icon | ||
|  | def add_hue(image, color, tiff=False): | ||
|  |     start = 154 if tiff else 0 | ||
|  |     for i in range(start, len(image), 4): | ||
|  |         try: | ||
|  |             for x in range(3): | ||
|  |                 image[i+x] = int(((image[i+x]/255) * (color[x]/255)) * 255) | ||
|  |         except:  | ||
|  |             pass | ||
|  |     return image | ||
|  | 
 | ||
|  | 
 | ||
|  | # Function for adding belt to tunic | ||
|  | def add_belt(tunic, belt, tiff=False): | ||
|  |     start = 154 if tiff else 0 | ||
|  |     for i in range(start, len(tunic), 4): | ||
|  |         try: | ||
|  |             if belt[i+3] != 0: | ||
|  |                 alpha = belt[i+3] / 255 | ||
|  |                 for x in range(3): | ||
|  |                     tunic[i+x] = int((belt[i+x] * alpha) + (tunic[i+x] * (1 - alpha))) | ||
|  |         except: | ||
|  |             pass | ||
|  |     return tunic | ||
|  | 
 | ||
|  | 
 | ||
|  | # Function for putting tunic colors together | ||
|  | def generate_tunic_icon(color): | ||
|  |     with open(data_path('icons/grey.tiff'), 'rb') as grey_fil, open(data_path('icons/belt.tiff'), 'rb') as belt_fil: | ||
|  |         grey = list(grey_fil.read()) | ||
|  |         belt = list(belt_fil.read()) | ||
|  |         return add_belt(add_hue(grey, color, True), belt, True)[154:] | ||
|  | 
 | ||
|  | # END TODO | ||
|  | 
 | ||
|  | # Function to add extra data on top of icon | ||
|  | def add_extra_data(rgbValues, fileName, intensity = 0.5): | ||
|  |     fileRGB = [] | ||
|  |     with open(fileName, "rb") as fil: | ||
|  |         data = fil.read() | ||
|  |         for i in range(0, len(data), 4): | ||
|  |             fileRGB.append([data[i+0], data[i+1], data[i+2], data[i+3]]) | ||
|  |     for i in range(len(rgbValues)): | ||
|  |         alpha = fileRGB[i][3] / 255 | ||
|  |         for x in range(3): | ||
|  |             rgbValues[i][x] = int((fileRGB[i][x] * alpha + intensity) + (rgbValues[i][x] * (1 - alpha - intensity))) | ||
|  | 
 | ||
|  | # Function for desaturating RGB values | ||
|  | def greyscaleRGB(rgbValues, intensity: int = 2): | ||
|  |     for rgb in rgbValues: | ||
|  |         rgb[0] = rgb[1] = rgb[2] = int((rgb[0] * 0.2126 + rgb[1] * 0.7152 + rgb[2] * 0.0722) * intensity) | ||
|  |     return rgbValues | ||
|  | 
 | ||
|  | # Converts rgb5a1 values to RGBA lists | ||
|  | def rgb5a1ToRGB(rgb5a1Bytes): | ||
|  |     pixels = [] | ||
|  |     for i in range(0, len(rgb5a1Bytes), 2): | ||
|  |         bits = format(rgb5a1Bytes[i], '#010b')[2:] + format(rgb5a1Bytes[i+1], '#010b')[2:] | ||
|  |         r = int(int(bits[0:5], 2) * (255/31)) | ||
|  |         g = int(int(bits[5:10], 2) * (255/31)) | ||
|  |         b = int(int(bits[10:15], 2) * (255/31)) | ||
|  |         a = int(bits[15], 2) * 255 | ||
|  |         pixels.append([r,g,b,a]) | ||
|  |     return pixels | ||
|  | 
 | ||
|  | # Adds a hue to RGB values | ||
|  | def addHueToRGB(rgbValues, color): | ||
|  |     for rgb in rgbValues: | ||
|  |         for i in range(3): | ||
|  |             rgb[i] = int(((rgb[i]/255) * (color[i]/255)) * 255) | ||
|  |     return rgbValues | ||
|  | 
 | ||
|  | # Convert RGB to RGB5a1 format | ||
|  | def rgbToRGB5a1(rgbValues): | ||
|  |     rgb5a1 = [] | ||
|  |     for rgb in rgbValues: | ||
|  |         r = int(rgb[0] / (255/31)) | ||
|  |         r = r if r <= 31 else 31 | ||
|  |         r = r if r >= 0 else 0 | ||
|  |         g = int(rgb[1] / (255/31)) | ||
|  |         g = g if g <= 31 else 31 | ||
|  |         g = g if g >= 0 else 0 | ||
|  |         b = int(rgb[2] / (255/31)) | ||
|  |         b = b if b <= 31 else 31 | ||
|  |         b = b if b >= 0 else 0 | ||
|  |         a = int(rgb[3] / 255) | ||
|  |         bits = format(r, '#07b')[2:] + format(g, '#07b')[2:] + format(b, '#07b')[2:] + format(a, '#03b')[2:] | ||
|  |         rgb5a1.append(int(bits[:8], 2)) | ||
|  |         rgb5a1.append(int(bits[8:], 2)) | ||
|  |     for i in rgb5a1: | ||
|  |         assert i <= 255, i | ||
|  |     return bytes(rgb5a1) | ||
|  | 
 | ||
|  | # Patch overworld icons | ||
|  | def patch_overworld_icon(rom, color, address, fileName = None): | ||
|  |     original = rom.original.read_bytes(address, 0x800) | ||
|  | 
 | ||
|  |     if color is None: | ||
|  |         rom.write_bytes(address, original) | ||
|  |         return | ||
|  | 
 | ||
|  |     rgbBytes = rgb5a1ToRGB(original) | ||
|  |     greyscaled = greyscaleRGB(rgbBytes) | ||
|  |     rgbBytes = addHueToRGB(greyscaled, color) | ||
|  |     if fileName != None: | ||
|  |         add_extra_data(rgbBytes, fileName) | ||
|  |     rom.write_bytes(address, rgbToRGB5a1(rgbBytes)) |