shithub: cstory

Download patch

ref: 8377f011cf71743289f8b1b17b685154fb477a85
parent: e40de4992f89d4301e6d12851f109b0162f38e1b
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Apr 20 20:58:20 EDT 2020

Add in-progress hardware Wii U renderer

*Very* incomplete. Right now, it can render textures and perform
colour-fills to the screen.

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -297,6 +297,8 @@
 	target_sources(CSE2 PRIVATE "src/Backends/Rendering/SDLTexture.cpp")
 elseif(BACKEND_RENDERER MATCHES "SDLSurface")
 	target_sources(CSE2 PRIVATE "src/Backends/Rendering/SDLSurface.cpp")
+elseif(BACKEND_RENDERER MATCHES "WiiU")
+	target_sources(CSE2 PRIVATE "src/Backends/Rendering/WiiU.cpp")
 elseif(BACKEND_RENDERER MATCHES "Software")
 	target_sources(CSE2 PRIVATE "src/Backends/Rendering/Software.cpp")
 else()
@@ -383,6 +385,7 @@
 	target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-OpenGLES2.cpp")
 elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "Software")
 	target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-Software.cpp")
+elseif(BACKEND_PLATFORM MATCHES "WiiU" AND BACKEND_RENDERER MATCHES "WiiU")
 elseif(BACKEND_PLATFORM MATCHES "WiiU" AND BACKEND_RENDERER MATCHES "Software")
 	target_sources(CSE2 PRIVATE "src/Backends/WiiU/Window-Software-Polygon.cpp")
 elseif(BACKEND_PLATFORM MATCHES "Null" AND BACKEND_RENDERER MATCHES "Software")
--- /dev/null
+++ b/src/Backends/Rendering/WiiU.cpp
@@ -1,0 +1,433 @@
+#include "../Rendering.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+
+#include <gx2/draw.h>
+#include <gx2/event.h>
+#include <gx2/registers.h>
+#include <gx2/sampler.h>
+#include <gx2/texture.h>
+#include <gx2r/buffer.h>
+#include <gx2r/draw.h>
+#include <gx2r/resource.h>
+#include <gx2r/surface.h>
+#include <whb/gfx.h>
+
+#include "../Misc.h"
+
+#include "../WiiU/colour_fill.gsh.h"
+#include "../WiiU/texture.gsh.h"
+#include "../WiiU/texture_colour_key.gsh.h"
+
+typedef struct RenderBackend_Surface
+{
+	bool is_screen;
+	GX2Texture texture;
+	unsigned int width;
+	unsigned int height;
+	unsigned char *lock_buffer;	// TODO - Dumb
+} RenderBackend_Surface;
+
+typedef struct RenderBackend_Glyph
+{
+} RenderBackend_Glyph;
+
+static WHBGfxShaderGroup texture_shader;
+static WHBGfxShaderGroup texture_colour_key_shader;
+static WHBGfxShaderGroup colour_fill_shader;
+
+static GX2RBuffer vertex_position_buffer;
+static GX2RBuffer texture_coordinate_buffer;
+
+static GX2Sampler sampler;
+
+RenderBackend_Surface *framebuffer;
+static unsigned int framebuffer_width;
+static unsigned int framebuffer_height;
+
+static void StartFrameDraw(void)
+{
+	WHBGfxBeginRender();
+
+	// Draw to the gamepad
+	WHBGfxBeginRenderDRC();
+	WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+}
+
+static void EndFrameDraw(void)
+{
+	WHBGfxFinishRenderDRC();
+
+	WHBGfxFinishRender();
+}
+
+RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, bool fullscreen)
+{
+	(void)window_title;
+	(void)fullscreen;
+
+	framebuffer_width = screen_width;
+	framebuffer_height = screen_height;
+
+	framebuffer = (RenderBackend_Surface*)malloc(sizeof(RenderBackend_Surface));
+
+	if (framebuffer != NULL)
+	{
+		framebuffer->is_screen = true;
+
+		WHBGfxInit();
+
+		if (WHBGfxLoadGFDShaderGroup(&texture_shader, 0, rtexture))
+		{
+			WHBGfxInitShaderAttribute(&texture_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+			WHBGfxInitShaderAttribute(&texture_shader, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+			WHBGfxInitFetchShader(&texture_shader);
+
+			if (WHBGfxLoadGFDShaderGroup(&texture_colour_key_shader, 0, rtexture_colour_key))
+			{
+				WHBGfxInitShaderAttribute(&texture_colour_key_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+				WHBGfxInitShaderAttribute(&texture_colour_key_shader, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+				WHBGfxInitFetchShader(&texture_colour_key_shader);
+
+				if (WHBGfxLoadGFDShaderGroup(&colour_fill_shader, 0, rcolour_fill))
+				{
+					WHBGfxInitShaderAttribute(&colour_fill_shader, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+					WHBGfxInitFetchShader(&colour_fill_shader);
+
+					// Initialise vertex position buffer
+					vertex_position_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
+																	   GX2R_RESOURCE_USAGE_CPU_READ |
+																	   GX2R_RESOURCE_USAGE_CPU_WRITE |
+																	   GX2R_RESOURCE_USAGE_GPU_READ);
+					vertex_position_buffer.elemSize = 2 * sizeof(float);
+					vertex_position_buffer.elemCount = 4;
+					GX2RCreateBuffer(&vertex_position_buffer);
+
+					// Initialise texture coordinate buffer
+					texture_coordinate_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
+																		  GX2R_RESOURCE_USAGE_CPU_READ |
+																		  GX2R_RESOURCE_USAGE_CPU_WRITE |
+																		  GX2R_RESOURCE_USAGE_GPU_READ);
+					texture_coordinate_buffer.elemSize = 2 * sizeof(float);
+					texture_coordinate_buffer.elemCount = 4;
+					GX2RCreateBuffer(&texture_coordinate_buffer);
+
+					// Initialise sampler
+					GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
+
+					{
+						// Disable depth-test (enabled by default for some reason)
+						GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_ALWAYS);
+
+
+
+						// Enable blending
+				//		GX2SetColorControl(GX2_LOGIC_OP_COPY, 0xFF, FALSE, TRUE);
+
+						// Set custom blending mode for pre-multiplied alpha
+		/*				GX2SetBlendControl(GX2_RENDER_TARGET_0,
+										   GX2_BLEND_MODE_ZERO,
+										   GX2_BLEND_MODE_ONE,
+										   GX2_BLEND_COMBINE_MODE_ADD,
+										   TRUE,
+										   GX2_BLEND_MODE_ZERO,
+										   GX2_BLEND_MODE_ONE,
+										   GX2_BLEND_COMBINE_MODE_ADD);
+		*/
+						// Do some binding
+
+						StartFrameDraw();
+
+						return framebuffer;
+					}
+
+					GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+					GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+					WHBGfxFreeShaderGroup(&colour_fill_shader);
+				}
+
+				WHBGfxFreeShaderGroup(&texture_colour_key_shader);
+			}
+
+			WHBGfxFreeShaderGroup(&texture_shader);
+		}
+
+		WHBGfxShutdown();
+
+		free(framebuffer);
+	}
+
+	return NULL;
+}
+
+void RenderBackend_Deinit(void)
+{
+	GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+	GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+	WHBGfxFreeShaderGroup(&colour_fill_shader);
+	WHBGfxFreeShaderGroup(&texture_colour_key_shader);
+	WHBGfxFreeShaderGroup(&texture_shader);
+
+	WHBGfxShutdown();
+
+	free(framebuffer);
+}
+
+void RenderBackend_DrawScreen(void)
+{
+	EndFrameDraw();
+
+	StartFrameDraw();
+}
+
+RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height)
+{
+	RenderBackend_Surface *surface = (RenderBackend_Surface*)malloc(sizeof(RenderBackend_Surface));
+
+	if (surface != NULL)
+	{
+		surface->is_screen = false;
+		surface->width = width;
+		surface->height = height;
+
+		// Initialise texture
+		memset(&surface->texture, 0, sizeof(surface->texture));
+		surface->texture.surface.width = width;
+		surface->texture.surface.height = height;
+		surface->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
+		surface->texture.surface.depth = 1;
+		surface->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
+		surface->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
+		surface->texture.surface.mipLevels = 1;
+		surface->texture.viewNumMips = 1;
+		surface->texture.viewNumSlices = 1;
+		surface->texture.compMap = 0x00010203;
+		GX2CalcSurfaceSizeAndAlignment(&surface->texture.surface);
+		GX2InitTextureRegs(&surface->texture);
+
+		if (GX2RCreateSurface(&surface->texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER |
+		                                                                     GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ |
+		                                                                     GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ)))
+		{
+			return surface;
+		}
+
+		free(surface);
+	}
+
+	return NULL;
+}
+
+void RenderBackend_FreeSurface(RenderBackend_Surface *surface)
+{
+	if (surface != NULL)
+	{
+		GX2RDestroySurfaceEx(&surface->texture.surface, (GX2RResourceFlags)0);
+		free(surface);
+	}
+}
+
+bool RenderBackend_IsSurfaceLost(RenderBackend_Surface *surface)
+{
+	(void)surface;
+
+	return false;
+}
+
+void RenderBackend_RestoreSurface(RenderBackend_Surface *surface)
+{
+	(void)surface;
+}
+
+unsigned char* RenderBackend_LockSurface(RenderBackend_Surface *surface, unsigned int *pitch, unsigned int width, unsigned int height)
+{
+	if (surface != NULL)
+	{
+		surface->lock_buffer = (unsigned char*)malloc(width * height * 3);
+		*pitch = width * 3;
+
+		return surface->lock_buffer;
+	}
+
+	return NULL;
+}
+
+void RenderBackend_UnlockSurface(RenderBackend_Surface *surface, unsigned int width, unsigned int height)
+{
+	if (surface != NULL)
+	{
+		if (surface->lock_buffer != NULL)
+		{
+			// Convert from RGB24 to RGBA32, and upload it to the GPU texture
+			unsigned char *framebuffer = (unsigned char*)GX2RLockSurfaceEx(&surface->texture.surface, 0, (GX2RResourceFlags)0);
+
+			const unsigned char *in_pointer = surface->lock_buffer;
+
+			for (size_t y = 0; y < height; ++y)
+			{
+				unsigned char *out_pointer = &framebuffer[surface->texture.surface.pitch * 4 * y];
+
+				for (size_t x = 0; x < width; ++x)
+				{
+					*out_pointer++ = *in_pointer++;
+					*out_pointer++ = *in_pointer++;
+					*out_pointer++ = *in_pointer++;
+					*out_pointer++ = 0xFF;
+				}
+			}
+
+			free(surface->lock_buffer);
+
+			GX2RUnlockSurfaceEx(&surface->texture.surface, 0, (GX2RResourceFlags)0);
+		}
+	}
+}
+
+void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBackend_Rect *rect, RenderBackend_Surface *destination_surface, long x, long y, bool colour_key)
+{
+	if (source_surface == NULL || destination_surface == NULL)
+		return;
+
+	if (source_surface->is_screen || !destination_surface->is_screen)
+		return;
+
+	GX2DrawDone();
+
+	const float destination_left = x;
+	const float destination_top = y;
+	const float destination_right = x + (rect->right - rect->left);
+	const float destination_bottom = y + (rect->bottom - rect->top);
+
+	float *position_pointer = (float*)GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+	position_pointer[0] = destination_left;
+	position_pointer[1] = destination_top;
+	position_pointer[2] = destination_right;
+	position_pointer[3] = destination_top;
+	position_pointer[4] = destination_right;
+	position_pointer[5] = destination_bottom;
+	position_pointer[6] = destination_left;
+	position_pointer[7] = destination_bottom;
+	for (unsigned int i = 0; i < 8; i += 2)
+	{
+		position_pointer[i + 0] /= framebuffer_width;
+		position_pointer[i + 0] *= 2.0f;
+		position_pointer[i + 0] -= 1.0f;
+
+		position_pointer[i + 1] /= framebuffer_height;
+		position_pointer[i + 1] *= -2.0f;
+		position_pointer[i + 1] += 1.0f;
+	}
+	GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+	float *texture_coordinate_pointer = (float*)GX2RLockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+	texture_coordinate_pointer[0] = rect->left / (float)source_surface->width;
+	texture_coordinate_pointer[1] = rect->top / (float)source_surface->height;
+	texture_coordinate_pointer[2] = rect->right / (float)source_surface->width;
+	texture_coordinate_pointer[3] = rect->top / (float)source_surface->height;
+	texture_coordinate_pointer[4] = rect->right / (float)source_surface->width;
+	texture_coordinate_pointer[5] = rect->bottom / (float)source_surface->height;
+	texture_coordinate_pointer[6] = rect->left / (float)source_surface->width;
+	texture_coordinate_pointer[7] = rect->bottom / (float)source_surface->height;
+	GX2RUnlockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+
+	GX2SetFetchShader(&texture_colour_key_shader.fetchShader);
+	GX2SetVertexShader(texture_colour_key_shader.vertexShader);
+	GX2SetPixelShader(texture_colour_key_shader.pixelShader);
+
+	GX2SetPixelSampler(&sampler, texture_colour_key_shader.pixelShader->samplerVars[0].location);
+	GX2SetPixelTexture(&source_surface->texture, texture_colour_key_shader.pixelShader->samplerVars[0].location);
+	GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
+	GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
+
+	GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
+}
+
+void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RenderBackend_Rect *rect, unsigned char red, unsigned char green, unsigned char blue)
+{
+	if (surface == NULL)
+		return;
+
+	if (!surface->is_screen)
+		return;
+
+	GX2DrawDone();
+
+	float *position_pointer = (float*)GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+	position_pointer[0] = rect->left;
+	position_pointer[1] = rect->top;
+	position_pointer[2] = rect->right;
+	position_pointer[3] = rect->top;
+	position_pointer[4] = rect->right;
+	position_pointer[5] = rect->bottom;
+	position_pointer[6] = rect->left;
+	position_pointer[7] = rect->bottom;
+	for (unsigned int i = 0; i < 8; i += 2)
+	{
+		position_pointer[i + 0] /= framebuffer_width;
+		position_pointer[i + 0] *= 2.0f;
+		position_pointer[i + 0] -= 1.0f;
+
+		position_pointer[i + 1] /= framebuffer_height;
+		position_pointer[i + 1] *= -2.0f;
+		position_pointer[i + 1] += 1.0f;
+	}
+	GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+	float uniform_colours[4] = {red / 255.0f, green / 255.0f, blue / 255.0f, 1.0f};
+
+	GX2SetPixelUniformReg(colour_fill_shader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&uniform_colours);
+
+	GX2SetFetchShader(&colour_fill_shader.fetchShader);
+	GX2SetVertexShader(colour_fill_shader.vertexShader);
+	GX2SetPixelShader(colour_fill_shader.pixelShader);
+
+	GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
+
+	GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
+}
+
+RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
+{
+	return NULL;
+}
+
+void RenderBackend_UnloadGlyph(RenderBackend_Glyph *glyph)
+{
+	if (glyph == NULL)
+		return;
+}
+
+void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surface, const unsigned char *colour_channels)
+{
+	if (destination_surface == NULL)
+		return;
+}
+
+void RenderBackend_DrawGlyph(RenderBackend_Glyph *glyph, long x, long y)
+{
+	if (glyph == NULL)
+		return;
+}
+
+void RenderBackend_FlushGlyphs(void)
+{
+	
+}
+
+void RenderBackend_HandleRenderTargetLoss(void)
+{
+	// No problem for us
+}
+
+void RenderBackend_HandleWindowResize(unsigned int width, unsigned int height)
+{
+	(void)width;
+	(void)height;
+
+	// No problem for us
+}
--- a/src/Backends/WiiU/Window-Software-Polygon.cpp
+++ b/src/Backends/WiiU/Window-Software-Polygon.cpp
@@ -123,9 +123,9 @@
 
 			GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
 			GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
-		}
 
-		WHBGfxFreeShaderGroup(&shader_group);
+			WHBGfxFreeShaderGroup(&shader_group);
+		}
 
 		WHBGfxShutdown();
 
--- /dev/null
+++ b/src/Backends/WiiU/colour_fill.gsh.h
@@ -1,0 +1,50 @@
+#pragma once
+
+static const unsigned char rcolour_fill[0x5AC] = {
+	71,102,120,50,0,0,0,32,0,0,0,7,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,3,0,0,1,144,0,0,0,0,0,0,0,0,
+	0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,
+	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,255,255,255,254,
+	0,0,0,1,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,0,0,0,0,14,0,0,0,16,0,0,1,8,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,1,208,96,1,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,112,1,68,0,0,0,9,0,0,0,0,
+	0,0,0,0,105,110,112,117,116,95,118,101,114,116,101,120,95,99,111,111,114,100,105,110,97,116,101,115,0,0,0,0,
+	208,96,1,8,202,112,1,52,125,66,76,75,0,0,0,40,0,0,0,0,0,0,1,96,208,96,0,0,0,0,0,28,
+	208,96,1,68,0,0,0,0,0,0,0,2,208,96,1,96,66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,
+	0,0,0,5,0,0,1,8,0,0,0,1,0,0,0,0,0,0,0,0,0,0,128,9,60,160,0,0,136,6,0,148,
+	0,64,0,0,255,15,0,148,32,0,0,0,0,0,0,160,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,13,0,0,66,76,75,123,0,0,0,32,
+	0,0,0,1,0,0,0,0,0,0,0,6,0,0,1,52,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,2,
+	20,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,0,0,0,1,32,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,232,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	202,112,0,252,0,0,0,11,0,0,0,1,0,0,0,0,255,255,255,255,99,111,108,111,117,114,0,0,208,96,0,188,
+	202,112,0,232,125,66,76,75,0,0,0,40,0,0,0,0,0,0,1,4,208,96,0,0,0,0,0,8,208,96,0,252,
+	0,0,0,0,0,0,0,2,208,96,1,4,66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,7,
+	0,0,1,32,0,0,0,3,0,0,0,0,32,0,0,0,0,0,12,160,0,0,0,0,136,6,32,148,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,144,12,0,0,0,5,0,0,144,12,0,32,0,9,0,0,
+	144,12,0,64,0,13,0,128,144,12,0,96,66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,1,
+	0,0,0,0,0,0,0,4,0,0,0,0
+};
--- a/src/Backends/WiiU/newshader.gsh.h
+++ /dev/null
@@ -1,52 +1,0 @@
-#pragma once
-
-static const unsigned char rnewshader[0x600] = {
-	71,102,120,50,0,0,0,32,0,0,0,7,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
-	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,3,0,0,1,192,0,0,0,0,0,0,0,0,
-	0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,255,255,255,252,
-	0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
-	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
-	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
-	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
-	0,0,0,255,0,0,0,0,0,0,0,14,0,0,0,16,0,0,1,24,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,2,208,96,1,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,112,1,84,0,0,0,9,0,0,0,0,
-	0,0,0,1,202,112,1,112,0,0,0,9,0,0,0,0,0,0,0,0,105,110,112,117,116,95,116,101,120,116,117,114,
-	101,95,99,111,111,114,100,105,110,97,116,101,115,0,0,0,105,110,112,117,116,95,118,101,114,116,101,120,95,99,111,111,
-	114,100,105,110,97,116,101,115,0,0,0,0,208,96,1,8,202,112,1,52,202,112,1,68,125,66,76,75,0,0,0,40,
-	0,0,0,0,0,0,1,140,208,96,0,0,0,0,0,56,208,96,1,84,0,0,0,0,0,0,0,3,208,96,1,140,
-	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,5,0,0,1,24,0,0,0,1,0,0,0,0,
-	0,0,0,0,0,0,128,9,32,0,0,0,0,0,4,160,60,32,1,0,136,6,0,148,0,192,0,0,136,4,0,20,
-	34,0,0,0,0,0,0,160,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	1,0,0,0,144,12,32,0,1,4,0,128,144,12,32,32,0,0,0,128,0,13,0,0,66,76,75,123,0,0,0,32,
-	0,0,0,1,0,0,0,0,0,0,0,6,0,0,1,88,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,2,
-	20,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,0,0,0,1,16,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,232,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	202,112,1,8,0,0,0,9,0,0,0,1,0,0,0,0,255,255,255,255,202,112,1,28,0,0,0,1,0,0,0,0,
-	116,101,120,116,117,114,101,95,99,111,111,114,100,105,110,97,116,101,115,0,116,101,120,0,208,96,0,188,208,96,0,212,
-	202,112,0,232,202,112,0,252,125,66,76,75,0,0,0,40,0,0,0,0,0,0,1,32,208,96,0,0,0,0,0,24,
-	208,96,1,8,0,0,0,0,0,0,0,4,208,96,1,32,66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,
-	0,0,0,7,0,0,1,16,0,0,0,3,0,0,0,0,32,0,0,0,0,0,192,128,0,0,0,0,136,6,32,148,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,16,13,240,0,0,128,16,0,0,0,0,
-	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,0
-};
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/colour_fill.frag
@@ -1,0 +1,7 @@
+#version 150 core
+layout(location = 0) uniform vec4 colour;
+out vec4 fragment;
+void main()
+{
+	fragment = colour;
+}
\ No newline at end of file
binary files /dev/null b/src/Backends/WiiU/shader sources/colour_fill.gsh differ
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/colour_fill.psh
@@ -1,0 +1,18 @@
+; $MODE = "UniformRegister"
+; $NUM_SPI_PS_INPUT_CNTL = 1
+; $SPI_PS_INPUT_CNTL[0].semantic = 0
+; $SPI_PS_INPUT_CNTL[0].default_val = 1
+; $UNIFORM_VARS[0].name = "colour"
+; $UNIFORM_VARS[0].type = "vec4"
+; $UNIFORM_VARS[0].count = 1
+; $UNIFORM_VARS[0].offset = 0
+; $UNIFORM_VARS[0].block = -1
+
+00 ALU: ADDR(32) CNT(4) 
+      0  x: MOV         R0.x,  C0.x      
+         y: MOV         R0.y,  C0.y      
+         z: MOV         R0.z,  C0.z      
+         w: MOV         R0.w,  C0.w      
+01 EXP_DONE: PIX0, R0
+END_OF_PROGRAM
+
--- a/src/Backends/WiiU/shader sources/fragmentshader.frag
+++ /dev/null
@@ -1,8 +1,0 @@
-#version 150 core
-layout(location = 0) uniform sampler2D tex;
-in vec2 texture_coordinates;
-out vec4 fragment;
-void main()
-{
-	fragment = texture(tex, texture_coordinates);
-}
\ No newline at end of file
--- a/src/Backends/WiiU/shader sources/fragmentshader.psh
+++ /dev/null
@@ -1,18 +1,0 @@
-; $MODE = "UniformRegister"
-; $SAMPLER_VARS[0].name= "tex"
-; $SAMPLER_VARS[0].type= "sampler2D"
-; $SAMPLER_VARS[0].location = 0
-; $NUM_SPI_PS_INPUT_CNTL = 1
-; $SPI_PS_INPUT_CNTL[0].semantic = 0
-; $SPI_PS_INPUT_CNTL[0].default_val = 1
-; $UNIFORM_VARS[0].name = "texture_coordinates"
-; $UNIFORM_VARS[0].type = "vec2"
-; $UNIFORM_VARS[0].count = 1
-; $UNIFORM_VARS[0].offset = 0
-; $UNIFORM_VARS[0].block = -1
-
-00 TEX: ADDR(32) CNT(1) VALID_PIX 
-      0  SAMPLE R0, R0.xy0x, t0, s0
-01 EXP_DONE: PIX0, R0
-END_OF_PROGRAM
-
binary files a/src/Backends/WiiU/shader sources/newshader.gsh /dev/null differ
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/plain.vert
@@ -1,0 +1,6 @@
+#version 150 core
+layout(location = 0) in vec4 input_vertex_coordinates;
+void main() 
+{ 
+	gl_Position = input_vertex_coordinates; 
+} 
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/plain.vsh
@@ -1,0 +1,20 @@
+; $MODE = "UniformRegister"
+; $ATTRIB_VARS[0].name = "input_vertex_coordinates"
+; $ATTRIB_VARS[0].type = "vec2"
+; $ATTRIB_VARS[0].location = 0
+; $NUM_SPI_VS_OUT_ID = 1
+; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0
+
+00 CALL_FS NO_BARRIER 
+01 EXP_DONE: POS0, R1
+02 EXP_DONE: PARAM0, R0.____
+03 ALU: ADDR(32) CNT(1) 
+      0  x: NOP         ____      
+04 NOP NO_BARRIER 
+END_OF_PROGRAM
+
+
+
+
+
+
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/texture.frag
@@ -1,0 +1,8 @@
+#version 150 core
+layout(location = 0) uniform sampler2D tex;
+in vec2 texture_coordinates;
+out vec4 fragment;
+void main()
+{
+	fragment = texture(tex, texture_coordinates);
+}
\ No newline at end of file
binary files /dev/null b/src/Backends/WiiU/shader sources/texture.gsh differ
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/texture.psh
@@ -1,0 +1,18 @@
+; $MODE = "UniformRegister"
+; $SAMPLER_VARS[0].name= "tex"
+; $SAMPLER_VARS[0].type= "sampler2D"
+; $SAMPLER_VARS[0].location = 0
+; $NUM_SPI_PS_INPUT_CNTL = 1
+; $SPI_PS_INPUT_CNTL[0].semantic = 0
+; $SPI_PS_INPUT_CNTL[0].default_val = 1
+; $UNIFORM_VARS[0].name = "texture_coordinates"
+; $UNIFORM_VARS[0].type = "vec2"
+; $UNIFORM_VARS[0].count = 1
+; $UNIFORM_VARS[0].offset = 0
+; $UNIFORM_VARS[0].block = -1
+
+00 TEX: ADDR(32) CNT(1) VALID_PIX 
+      0  SAMPLE R0, R0.xy0x, t0, s0
+01 EXP_DONE: PIX0, R0
+END_OF_PROGRAM
+
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/texture.vert
@@ -1,0 +1,9 @@
+#version 150 core
+layout(location = 0) in vec4 input_vertex_coordinates;
+layout(location = 1) in vec2 input_texture_coordinates;
+out vec2 texture_coordinates; 
+void main() 
+{ 
+	gl_Position = input_vertex_coordinates; 
+	texture_coordinates = input_texture_coordinates; 
+} 
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/texture.vsh
@@ -1,0 +1,27 @@
+; $MODE = "UniformRegister"
+; $ATTRIB_VARS[0].name = "input_texture_coordinates"
+; $ATTRIB_VARS[0].type = "vec2"
+; $ATTRIB_VARS[0].location = 1
+; $ATTRIB_VARS[1].name = "input_vertex_coordinates"
+; $ATTRIB_VARS[1].type = "vec2"
+; $ATTRIB_VARS[1].location = 0
+; $NUM_SPI_VS_OUT_ID = 1
+; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0
+
+00 CALL_FS NO_BARRIER 
+01 ALU: ADDR(32) CNT(2) 
+      0  x: MOV         R1.x,  R1.x      
+         y: MOV         R1.y,  R1.y      
+02 EXP_DONE: POS0, R2
+03 EXP_DONE: PARAM0, R1.xyzz  NO_BARRIER 
+04 ALU: ADDR(34) CNT(1) 
+      1  x: NOP         ____      
+05 NOP NO_BARRIER 
+END_OF_PROGRAM
+
+
+
+
+
+
+
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/texture_colour_key.frag
@@ -1,0 +1,13 @@
+#version 150 core
+layout(location = 0) uniform sampler2D tex;
+in vec2 texture_coordinates;
+out vec4 fragment;
+void main()
+{
+	vec4 colour = texture(tex, texture_coordinates);
+
+	if (colour.r + colour.g + colour. b == 0.0)
+		discard;
+
+	fragment = colour;
+}
\ No newline at end of file
binary files /dev/null b/src/Backends/WiiU/shader sources/texture_colour_key.gsh differ
--- /dev/null
+++ b/src/Backends/WiiU/shader sources/texture_colour_key.psh
@@ -1,0 +1,25 @@
+; $MODE = "UniformRegister"
+; $SAMPLER_VARS[0].name= "tex"
+; $SAMPLER_VARS[0].type= "sampler2D"
+; $SAMPLER_VARS[0].location = 0
+; $NUM_SPI_PS_INPUT_CNTL = 1
+; $SPI_PS_INPUT_CNTL[0].semantic = 0
+; $SPI_PS_INPUT_CNTL[0].default_val = 1
+; $UNIFORM_VARS[0].name = "texture_coordinates"
+; $UNIFORM_VARS[0].type = "vec2"
+; $UNIFORM_VARS[0].count = 1
+; $UNIFORM_VARS[0].offset = 0
+; $UNIFORM_VARS[0].block = -1
+
+00 TEX: ADDR(48) CNT(1) VALID_PIX 
+      0  SAMPLE R0, R0.xy0x, t0, s0
+01 ALU: ADDR(32) CNT(3) 
+      1  y: ADD         ____,  R0.x,  R0.y      
+      2  x: ADD         ____,  R0.z,  PV1.y      
+      3  x: KILLE       ____,  PV2.x,  0.0f      
+02 EXP_DONE: PIX0, R0
+END_OF_PROGRAM
+
+
+
+
--- a/src/Backends/WiiU/shader sources/vertexshader.vert
+++ /dev/null
@@ -1,9 +1,0 @@
-#version 150 core
-layout(location = 0) in vec4 input_vertex_coordinates;
-layout(location = 1) in vec2 input_texture_coordinates;
-out vec2 texture_coordinates; 
-void main() 
-{ 
-	gl_Position = input_vertex_coordinates; 
-	texture_coordinates = input_texture_coordinates; 
-} 
--- a/src/Backends/WiiU/shader sources/vertexshader.vsh
+++ /dev/null
@@ -1,27 +1,0 @@
-; $MODE = "UniformRegister"
-; $ATTRIB_VARS[0].name = "input_texture_coordinates"
-; $ATTRIB_VARS[0].type = "vec2"
-; $ATTRIB_VARS[0].location = 1
-; $ATTRIB_VARS[1].name = "input_vertex_coordinates"
-; $ATTRIB_VARS[1].type = "vec2"
-; $ATTRIB_VARS[1].location = 0
-; $NUM_SPI_VS_OUT_ID = 1
-; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0
-
-00 CALL_FS NO_BARRIER 
-01 ALU: ADDR(32) CNT(2) 
-      0  x: MOV         R1.x,  R1.x      
-         y: MOV         R1.y,  R1.y      
-02 EXP_DONE: POS0, R2
-03 EXP_DONE: PARAM0, R1.xyzz  NO_BARRIER 
-04 ALU: ADDR(34) CNT(1) 
-      1  x: NOP         ____      
-05 NOP NO_BARRIER 
-END_OF_PROGRAM
-
-
-
-
-
-
-
--- a/src/Backends/WiiU/shader sources/wtf is this.txt
+++ b/src/Backends/WiiU/shader sources/wtf is this.txt
@@ -1,3 +1,16 @@
+#######################
+# Shader combinations #
+#######################
+
+texture.vsh + texture.psh = texture.gsh
+texture.vsh + texture_colour_key.psh = texture_colour_key.gsh
+plain.vsh + colour_fill.psh = colour_fill.gsh
+
+
+##########################
+# How to compile shaders #
+##########################
+
 I'mma give it to you straight: compiling shaders for the Wii U is an absolute
 nightmare.
 
--- /dev/null
+++ b/src/Backends/WiiU/texture.gsh.h
@@ -1,0 +1,52 @@
+#pragma once
+
+static const unsigned char rtexture[0x600] = {
+	71,102,120,50,0,0,0,32,0,0,0,7,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,3,0,0,1,192,0,0,0,0,0,0,0,0,
+	0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,
+	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,255,255,255,252,
+	0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,0,0,0,0,14,0,0,0,16,0,0,1,24,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,2,208,96,1,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,112,1,84,0,0,0,9,0,0,0,0,
+	0,0,0,1,202,112,1,112,0,0,0,9,0,0,0,0,0,0,0,0,105,110,112,117,116,95,116,101,120,116,117,114,
+	101,95,99,111,111,114,100,105,110,97,116,101,115,0,0,0,105,110,112,117,116,95,118,101,114,116,101,120,95,99,111,111,
+	114,100,105,110,97,116,101,115,0,0,0,0,208,96,1,8,202,112,1,52,202,112,1,68,125,66,76,75,0,0,0,40,
+	0,0,0,0,0,0,1,140,208,96,0,0,0,0,0,56,208,96,1,84,0,0,0,0,0,0,0,3,208,96,1,140,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,5,0,0,1,24,0,0,0,1,0,0,0,0,
+	0,0,0,0,0,0,128,9,32,0,0,0,0,0,4,160,60,32,1,0,136,6,0,148,0,192,0,0,136,4,0,20,
+	34,0,0,0,0,0,0,160,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	1,0,0,0,144,12,32,0,1,4,0,128,144,12,32,32,0,0,0,128,0,13,0,0,66,76,75,123,0,0,0,32,
+	0,0,0,1,0,0,0,0,0,0,0,6,0,0,1,88,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,2,
+	20,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,0,0,0,1,16,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,232,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	202,112,1,8,0,0,0,9,0,0,0,1,0,0,0,0,255,255,255,255,202,112,1,28,0,0,0,1,0,0,0,0,
+	116,101,120,116,117,114,101,95,99,111,111,114,100,105,110,97,116,101,115,0,116,101,120,0,208,96,0,188,208,96,0,212,
+	202,112,0,232,202,112,0,252,125,66,76,75,0,0,0,40,0,0,0,0,0,0,1,32,208,96,0,0,0,0,0,24,
+	208,96,1,8,0,0,0,0,0,0,0,4,208,96,1,32,66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,
+	0,0,0,7,0,0,1,16,0,0,0,3,0,0,0,0,32,0,0,0,0,0,192,128,0,0,0,0,136,6,32,148,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,16,13,240,0,0,128,16,0,0,0,0,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,0
+};
--- /dev/null
+++ b/src/Backends/WiiU/texture_colour_key.gsh.h
@@ -1,0 +1,56 @@
+#pragma once
+
+static const unsigned char rtexture_colour_key[0x680] = {
+	71,102,120,50,0,0,0,32,0,0,0,7,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,3,0,0,1,192,0,0,0,0,0,0,0,0,
+	0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,0,255,255,255,255,255,255,255,255,255,255,255,255,
+	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,255,255,255,252,
+	0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255,
+	0,0,0,255,0,0,0,0,0,0,0,14,0,0,0,16,0,0,1,24,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,2,208,96,1,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,112,1,84,0,0,0,9,0,0,0,0,
+	0,0,0,1,202,112,1,112,0,0,0,9,0,0,0,0,0,0,0,0,105,110,112,117,116,95,116,101,120,116,117,114,
+	101,95,99,111,111,114,100,105,110,97,116,101,115,0,0,0,105,110,112,117,116,95,118,101,114,116,101,120,95,99,111,111,
+	114,100,105,110,97,116,101,115,0,0,0,0,208,96,1,8,202,112,1,52,202,112,1,68,125,66,76,75,0,0,0,40,
+	0,0,0,0,0,0,1,140,208,96,0,0,0,0,0,56,208,96,1,84,0,0,0,0,0,0,0,3,208,96,1,140,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,5,0,0,1,24,0,0,0,1,0,0,0,0,
+	0,0,0,0,0,0,128,9,32,0,0,0,0,0,4,160,60,32,1,0,136,6,0,148,0,192,0,0,136,4,0,20,
+	34,0,0,0,0,0,0,160,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	1,0,0,0,144,12,32,0,1,4,0,128,144,12,32,32,0,0,0,128,0,13,0,0,66,76,75,123,0,0,0,32,
+	0,0,0,1,0,0,0,0,0,0,0,6,0,0,1,88,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,2,
+	20,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,1,0,0,0,16,0,0,0,0,0,0,1,144,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,232,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,1,208,96,0,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	202,112,1,8,0,0,0,9,0,0,0,1,0,0,0,0,255,255,255,255,202,112,1,28,0,0,0,1,0,0,0,0,
+	116,101,120,116,117,114,101,95,99,111,111,114,100,105,110,97,116,101,115,0,116,101,120,0,208,96,0,188,208,96,0,212,
+	202,112,0,232,202,112,0,252,125,66,76,75,0,0,0,40,0,0,0,0,0,0,1,32,208,96,0,0,0,0,0,24,
+	208,96,1,8,0,0,0,0,0,0,0,4,208,96,1,32,66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,
+	0,0,0,7,0,0,1,144,0,0,0,3,0,0,0,0,48,0,0,0,0,0,192,128,32,0,0,0,0,0,8,160,
+	0,0,0,0,136,6,32,148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,0,0,0,32,0,200,159,128,0,0,0,0,
+	254,0,31,128,0,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,16,13,240,0,0,128,16,0,0,0,0,
+	66,76,75,123,0,0,0,32,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,0
+};