diff --git a/src/display/scaledtexture.h b/src/display/scaledtexture.h
new file mode 100644
index 00000000..dd0224e3
--- /dev/null
+++ b/src/display/scaledtexture.h
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#pragma once
+#include "../libs.h"
+#include "texture.h"
+
+#define MANAGED_TEXTURE_SCALE_MAX 4
+
+typedef struct {
+  int16_t width;
+  int16_t height;
+  uint8_t scale;
+} scaledtexturescale_t;
+
+typedef struct {
+  uint8_t channels;
+  char *file;
+  char *path;
+  int16_t baseWidth;
+  int16_t baseHeight;
+
+  scaledtexturescale_t scales[MANAGED_TEXTURE_SCALE_MAX];
+  uint8_t scaleCount;
+} scaledtexture_t;
\ No newline at end of file
diff --git a/src/file/asset.c b/src/file/asset.c
index d4140b05..a413cf4c 100644
--- a/src/file/asset.c
+++ b/src/file/asset.c
@@ -7,52 +7,54 @@
 
 #include "asset.h"
 
-char * assetStringLoad(char *assetName) {
+size_t assetRawLoad(char *assetName, uint8_t *buffer) {
+  assetbuffer_t *asset;
+  size_t length, read;
+
   // Open a buffer.
-  assetbuffer_t *fptr = assetBufferOpen(assetName);
-  if(fptr == NULL) return NULL;
+  asset = assetBufferOpen(assetName);
+  if(asset == NULL) return 0;
 
   // Read the count of bytes in the file
-  fseek(fptr, 0, SEEK_END);// Seek to the end
-  size_t length = ftell(fptr);// Get our current position (the end)
-  fseek(fptr, 0, SEEK_SET);// Reset the seek 
+  assetBufferEnd(asset);
+  length = assetBufferGetCurrentPosition(asset);// Get our current position (the end)
 
-  // Create the string buffer
-  char *str = malloc(length + 1);// Add 1 for the null terminator.
-  if(str == NULL) {
-    assetBufferClose(fptr);
-    return NULL;
+  // Are we only reading the size?
+  if(buffer == NULL) {
+    assetBufferClose(asset);
+    return length;
   }
 
-  // Read and seal the string.
-  fread(str, 1, length, fptr);// Read all the bytes
-  str[length] = '\0';// Null terminate.
-  assetBufferClose(fptr); // Close the buffer.
+  // Reset to start
+  assetBufferStart(asset);
 
-  return str;
+  // Read and seal the string.
+  read = assetBufferRead(asset, buffer, length);
+  assetBufferClose(asset); // Close the buffer.
+
+  // Did we read successfully?
+  if(read < length) return 0;
+  return read;
 }
 
-uint8_t * assetRawLoad(char *assetName) {
-  // Open a buffer.
-  assetbuffer_t *fptr = assetBufferOpen(assetName);
-  if(fptr == NULL) return NULL;
+char * assetStringLoad(char *assetName) {
+  size_t length;
+  char *string;
 
-  // Read the count of bytes in the file
-  fseek(fptr, 0, SEEK_END);// Seek to the end
-  size_t length = ftell(fptr);// Get our current position (the end)
-  fseek(fptr, 0, SEEK_SET);// Reset the seek 
+  length = assetRawLoad(assetName, NULL);
+  if(length == 0) return NULL;
 
-  // Create the string buffer
-  uint8_t *str = malloc(length);
-  if(str == NULL) {
-    assetBufferClose(fptr);
+  string = malloc(length + 1);// +1 for null terminator
+  if(string == NULL) return NULL;
+
+  length = assetRawLoad(assetName, string);
+  if(length == 0) {
+    free(string);
     return NULL;
   }
 
-  // Read and seal the string.
-  fread(str, 1, length, fptr);// Read all the bytes
-  assetBufferClose(fptr); // Close the buffer.
-  return str;
+  string[length] = '\0';// Null terminate
+  return string;
 }
 
 assetbuffer_t * assetBufferOpen(char *assetName) {
@@ -82,7 +84,7 @@ bool assetBufferClose(assetbuffer_t *buffer) {
   return fclose((FILE *)buffer);
 }
 
-int32_t assetBufferRead(assetbuffer_t *buffer, char *data, int32_t size) {
+int32_t assetBufferRead(assetbuffer_t *buffer, char *data, size_t size) {
   return (int32_t)fread(data, 1, size, (FILE *)buffer);
 }
 
@@ -94,72 +96,12 @@ int32_t assetBufferStart(assetbuffer_t *buffer) {
   return fseek((FILE *)buffer, 0, SEEK_SET);
 }
 
-int32_t assetBufferSkip(assetbuffer_t *buffer, int32_t n) {
+int32_t assetBufferSkip(assetbuffer_t *buffer, size_t n) {
   return fseek((FILE *)buffer, n, SEEK_CUR);
 }
 
-
-void assetShaderLoad(shader_t *shader, char *fileVertex, char *fileFragment) {
-  // Load the vertex shader into memory
-  char *vertexShader = assetStringLoad(fileVertex);
-  if(vertexShader == NULL) return;
-
-  // Load the fragment shader into memory
-  char *fragmentShader = assetStringLoad(fileFragment);
-  if(fragmentShader == NULL) {
-    free(vertexShader);
-    return;
-  }
-
-  // Now attempt to load the shader
-  shaderInit(shader, vertexShader, fragmentShader);
-  
-  //Cleanup
-  free(vertexShader);
-  free(fragmentShader);
-}
-
-void assetTextureLoad(texture_t *texture, char *fileName) {
-  assetbuffer_t *buffer;
-  int channels, width, height;
-  pixel_t *data;
-  stbi_io_callbacks OPENGL_STBI_CALLBACKS;
-
-  buffer = assetBufferOpen(fileName);
-  if(buffer == NULL) return;
-  
-  // Setup the interface for STBI
-  OPENGL_STBI_CALLBACKS.read = &assetBufferRead;
-  OPENGL_STBI_CALLBACKS.skip = &assetBufferSkip;
-  OPENGL_STBI_CALLBACKS.eof = &assetBufferEnd; 
-
-  // Buffer the image
-  channels = 0;
-  data = (pixel_t *)stbi_load_from_callbacks(
-    &OPENGL_STBI_CALLBACKS, buffer,
-    &width, &height,
-    &channels, STBI_rgb_alpha
-  );
-
-  // Close the buffer
-  assetBufferClose(buffer);
-  if(data == NULL) return;
-
-  // Turn into a texture.
-  textureInit(texture, width, height, data);
-  stbi_image_free(data);
-}
-
-void assetFontLoad(font_t *font, char *assetName) {
-  char *data = assetStringLoad(assetName);
-  fontInit(font, data);
-  free(data);
-}
-
-void assetXmlLoad(xml_t *xml, char *assetName) {
-  char *data = assetStringLoad(assetName);
-  xmlLoad(xml, data);
-  free(data);
+size_t assetBufferGetCurrentPosition(assetbuffer_t *buffer) {
+  return ftell((FILE *)buffer);
 }
 
 void assetScripterAppend(scripter_t *scripter, char *fileName) {
diff --git a/src/file/asset.h b/src/file/asset.h
index e696b32e..2c9fabce 100644
--- a/src/file/asset.h
+++ b/src/file/asset.h
@@ -21,14 +21,22 @@
 typedef FILE assetbuffer_t;
 
 /**
- * Method to load an asset into memory as a raw string.
- * @param assetName Path leading to the asset within the root asset directory.
- * @return Pointer to char array of data from asset, NULL if unsuccesful.
+ * Buffer an asset from the file system into memory.
+ * 
+ * @param assetName Path to the asset to buffer.
+ * @param buffer Place to buffer the data in to, or NULL to simply read the size
+ * @return The length (in bytes) of the file.
+ */
+size_t assetRawLoad(char *assetName, uint8_t *buffer);
+
+/**
+ * Load a string from an asset into memory.
+ * 
+ * @param assetName Asset to load
+ * @return A newly loaded string (malloced into existance.)
  */
 char * assetStringLoad(char *assetName);
 
-uint8_t * assetRawLoad(char *assetName);
-
 /**
  * Platform-centric method to open a file buffer to an asset.
  * @param assetName The asset name to open a buffer for.
@@ -50,7 +58,7 @@ bool assetBufferClose(assetbuffer_t *buffer);
  * @param size Length of the data buffer. Represents how many bytes can be read.
  * @return The count of bytes read. Complete when less than data array size.
  */
-int32_t assetBufferRead(assetbuffer_t *buffer, char *data, int32_t size);
+int32_t assetBufferRead(assetbuffer_t *buffer, char *data, size_t size);
 
 /**
  * Skip to the end of the buffer, useful to find the length of the buffer.
@@ -73,31 +81,15 @@ int32_t assetBufferStart(assetbuffer_t *buffer);
  * @param n Count of bytes to skip.
  * @return 0 if successful, otherwise unsuccessful.
  */
-int32_t assetBufferSkip(assetbuffer_t *buffer, int32_t n);
+int32_t assetBufferSkip(assetbuffer_t *buffer, size_t n);
 
 /**
- * Load a shader program from a vertex and fragment shader file.
- * @param shader Shader to load into.
- * @param fileVertex The file path of the vertex shader
- * @param fileFragment The file path of the fragment shader
+ * Retreive the current byte position within the asset that the head is at.
+ * 
+ * @param buffer Buffer to get the position of.
+ * @return Position (in bytes) that the current seek is at.
  */
-void assetShaderLoad(shader_t *shader, char *fileVertex, char *fileFragment);
-
-/**
- * Load a texture from a PNG file.
- * @param texture Texture to load the file into.
- * @param fileName The file path of the PNG image.
- */
-void assetTextureLoad(texture_t *texture, char *fileName);
-
-/**
- * Load a font from a TTF file.
- * @param font Font to load into.
- * @param assetName Asset name for the TTF font.
- * @param size Size of the font.
- */
-void assetFontLoad(font_t *font, char *assetName);
-
-
+size_t assetBufferGetCurrentPosition(assetbuffer_t *buffer);
 
+/** @deprecated */
 void assetScripterAppend(scripter_t *scripter, char *fileName);
\ No newline at end of file
diff --git a/src/file/assetmanager.c b/src/file/assetmanager.c
index fb21d39d..d4f8ebdc 100644
--- a/src/file/assetmanager.c
+++ b/src/file/assetmanager.c
@@ -19,6 +19,14 @@ assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[] = {
   {
     &_assetManagerLoaderShaderAsync,
     &_assetManagerLoaderShaderSync
+  },
+  {
+    &_assetManagerLoaderScaledTextureAsync,
+    NULL
+  },
+  {
+    &_assetManagerLoaderTextureScaleAsync,
+    &_assetManagerLoaderTextureScaleSync
   }
 };
 
@@ -111,7 +119,9 @@ void assetManagerUpdate(assetmanager_t *manager) {
       if(item->state != ASSET_MANAGER_STATE_ASYNC_DONE) continue;
     } else if(item->state != ASSET_MANAGER_STATE_PENDING) {
       continue;
-    } else if(definition->loadSync == NULL) {
+    }
+    
+    if(definition->loadSync == NULL) {
       continue;
     }
     
@@ -218,7 +228,7 @@ bool _assetManagerLoaderFontSync(assetmanageritem_t *item) {
 
 
 // Shader
-assetmanageritem_t * assetManagerShaderLoad(
+assetmanageritem_t * assetManagerLoadShader(
   assetmanager_t *manager, shader_t *shader, char *fileVert, char *fileFrag
 ) {
   assetmanageritem_t *item = assetManagerItemAdd(manager);
@@ -253,4 +263,109 @@ bool _assetManagerLoaderShaderSync(assetmanageritem_t *item) {
   free(item->data.shader.dataFrag);
   free(item->data.shader.dataVert);
   return true;
+}
+
+
+// Scaled Texture
+assetmanageritem_t * assetManagerLoadScaledTexture(
+  assetmanager_t *manager, scaledtexture_t *st, char *path, char *file
+) {
+  assetmanageritem_t *item = assetManagerItemAdd(manager);
+
+  item->type = ASSET_MANAGER_TYPE_SCALED_TEXTURE;
+  item->data.scaledTexture.scaledTexture = st;
+
+  // Unlike most other loaded things, here I actually use the MT itself for the
+  // storage of many variables.
+  st->scaleCount = 0;
+  st->baseWidth = 0;
+  st->baseHeight = 0;
+  st->path = path;
+  st->file = file;
+
+  return item;
+}
+
+bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item) {
+  char buffer[128];
+  char *xmlData;
+  xml_t xml;
+  xml_t *child;
+  int16_t i, j;
+  scaledtexture_t *st;
+  st = item->data.scaledTexture.scaledTexture;
+
+  // Begin loading texture XML
+  sprintf(buffer, "%s/%s.xml", st->path, st->file);
+
+  xmlData = assetStringLoad(buffer);
+  if(xmlData == NULL) return false;
+  xmlLoad(&xml, xmlData);
+  free(xmlData);
+
+  // Parse root texture info
+  i = xmlGetAttributeByName(&xml, "channels");
+  st->channels = (uint8_t)atoi(xml.attributeDatas[i]);
+  i = xmlGetAttributeByName(&xml, "width");
+  st->baseWidth = (int16_t)atoi(xml.attributeDatas[i]);
+  i = xmlGetAttributeByName(&xml, "height");
+  st->baseHeight = (int16_t)atoi(xml.attributeDatas[i]);
+
+  for(j = 0; j < xml.childrenCount; j++) {
+    child = xml.children + j;
+    i = xmlGetAttributeByName(child, "scale");
+    st->scales[st->scaleCount].scale = (uint8_t)atoi(child->attributeDatas[i]);
+    i = xmlGetAttributeByName(child, "width");
+    st->scales[st->scaleCount].width = (int16_t)atoi(child->attributeDatas[i]);
+    i = xmlGetAttributeByName(child, "height");
+    st->scales[st->scaleCount].height = (int16_t)atoi(child->attributeDatas[i]);
+    st->scaleCount++;
+  }
+
+  // Cleanup XML
+  xmlDispose(&xml);
+  return true;
+}
+
+
+// Texture Scale
+assetmanageritem_t * assetManagerLoadTextureScale(
+  assetmanager_t *manager, scaledtexture_t *st, texture_t *text, uint8_t scale
+) {
+  assetmanageritem_t *item = assetManagerItemAdd(manager);
+
+  item->type = ASSET_MANAGER_TYPE_SCALE_TEXTURE;
+  item->data.scaleTexture.scale = scale;
+  item->data.scaleTexture.texture = text;
+  item->data.scaleTexture.scaledTexture = st;
+
+  return item;
+}
+
+bool _assetManagerLoaderTextureScaleAsync(assetmanageritem_t *item) {
+  char buffer[128];
+  scaledtexture_t *st;
+  scaledtexturescale_t *sts;
+  st = item->data.scaleTexture.scaledTexture;
+  sts = st->scales + item->data.scaleTexture.scale;
+
+  sprintf(buffer, "%s/%s_%i.texture", st->path, st->file, sts->scale);
+  item->data.scaleTexture.data = (pixel_t *)assetRawLoad(buffer);
+  return true;
+}
+
+bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item) {
+  scaledtexture_t *st;
+  scaledtexturescale_t *sts;
+  st = item->data.scaleTexture.scaledTexture;
+  sts = st->scales + item->data.scaleTexture.scale;
+
+  textureInit(
+    item->data.scaleTexture.texture,
+    sts->width, sts->height,
+    item->data.scaleTexture.data
+  );
+
+  free(item->data.scaleTexture.data);
+  return true;
 }
\ No newline at end of file
diff --git a/src/file/assetmanager.h b/src/file/assetmanager.h
index 9a7c6354..f39f7007 100644
--- a/src/file/assetmanager.h
+++ b/src/file/assetmanager.h
@@ -11,6 +11,7 @@
 #include "../engine/thread.h"
 #include "../display/shader.h"
 #include "../display/texture.h"
+#include "../display/scaledtexture.h"
 #include "../display/font.h"
 #include "../script/scripter.h"
 #include "xml.h"
@@ -28,6 +29,8 @@
 #define ASSET_MANAGER_TYPE_TEXTURE 0x00
 #define ASSET_MANAGER_TYPE_FONT 0x01
 #define ASSET_MANAGER_TYPE_SHADER 0x02
+#define ASSET_MANAGER_TYPE_SCALED_TEXTURE 0x03
+#define ASSET_MANAGER_TYPE_SCALE_TEXTURE 0x04
 
 // Types
 typedef struct {
@@ -51,11 +54,25 @@ typedef struct {
   char *data;
 } assetmanagerfont_t;
 
+typedef struct {
+  scaledtexture_t *scaledTexture;
+} assetmanagerscaledtexture_t;
+
+typedef struct {
+  scaledtexture_t *scaledTexture;
+  texture_t *texture;
+  uint8_t scale;
+  pixel_t *data;
+} assetmanagerscaletexture_t;
+
+
 // Item
 typedef union {
   assetmanagertexture_t texture;
   assetmanagershader_t shader;
   assetmanagerfont_t font;
+  assetmanagerscaledtexture_t scaledTexture;
+  assetmanagerscaletexture_t scaleTexture;
 } assetmanagerassetdata_t;
 
 typedef struct {
@@ -64,6 +81,7 @@ typedef struct {
   assetmanagerassetdata_t data;
 } assetmanageritem_t;
 
+
 // Loader
 typedef bool assetmanagerloader_t(assetmanageritem_t *item);
 
@@ -72,6 +90,7 @@ typedef struct {
   assetmanagerloader_t *loadSync;
 } assetmanagerloaderdefinition_t;
 
+
 // Manager
 typedef struct {
   thread_t thread;
@@ -82,6 +101,7 @@ typedef struct {
 
 extern assetmanagerloaderdefinition_t ASSET_MANAGER_LOADERS[];
 
+
 /**
  * Initialize the asset manager
  * 
@@ -172,9 +192,26 @@ bool _assetManagerLoaderFontSync(assetmanageritem_t *item);
  * @param fileFrag Fragment file in question to load.
  * @return A pointer to the asset manager item for tracking.
  */
-assetmanageritem_t * assetManagerShaderLoad(
+assetmanageritem_t * assetManagerLoadShader(
   assetmanager_t *manager, shader_t *shader, char *fileVert, char *fileFrag
 );
 
 bool _assetManagerLoaderShaderAsync(assetmanageritem_t *item);
-bool _assetManagerLoaderShaderSync(assetmanageritem_t *item);
\ No newline at end of file
+bool _assetManagerLoaderShaderSync(assetmanageritem_t *item);
+
+
+assetmanageritem_t * assetManagerLoadScaledTexture(
+  assetmanager_t *manager, scaledtexture_t *mt, char *path, char *file
+);
+
+bool _assetManagerLoaderScaledTextureAsync(assetmanageritem_t *item);
+
+
+
+
+assetmanageritem_t * assetManagerLoadTextureScale(
+  assetmanager_t *manager, scaledtexture_t *st, texture_t *text, uint8_t scale
+);
+
+bool _assetManagerLoaderTextureScaleAsync(assetmanageritem_t *item);
+bool _assetManagerLoaderTextureScaleSync(assetmanageritem_t *item);
\ No newline at end of file
diff --git a/src/file/xml.c b/src/file/xml.c
index 56bdca0f..8c6c43ed 100644
--- a/src/file/xml.c
+++ b/src/file/xml.c
@@ -38,7 +38,7 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
           continue;
         }
 
-        if(c == ' ' || c == '\n' || c == '\r') continue;
+        if(xmlIsWhitespace(c)) continue;
         doing = XML_PARSING_VALUE;
         buffer[bufferLength++] = c;
         break;
@@ -46,7 +46,7 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
       case XML_PARSING_TAG_NAME:
         // Just keep reading until we either hit a space (end of the tag name)
         // or a closing tag value, either / or >
-        if(c == ' ' || c == '\n' || c == '\r' || c == '>' || c == '/') {
+        if(xmlIsWhitespace(c) || c == '>' || c == '/') {
           buffer[bufferLength] = '\0';
           xml->node = buffer;
           buffer = malloc(sizeof(char) * XML_TEXT_BUFFER_MAX);
@@ -54,8 +54,10 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
           if(c == '/') {
             level--;
             insideTag = false;
+            doing = XML_PARSING_CLOSE;
+          } else {
+            doing = c == '>' ? XML_DOING_NOTHING : XML_LOOKING_FOR_ATTRIBUTE;
           }
-          doing = c == '>' ? XML_DOING_NOTHING : XML_LOOKING_FOR_ATTRIBUTE;
           continue;
         }
         buffer[bufferLength++] = c;
@@ -63,12 +65,13 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
       
       case XML_LOOKING_FOR_ATTRIBUTE:
         // Look until we hit either the end of a tag, or the attribute itself
-        if(c == ' '||c == '\n'||c == '\r'||c == '>'||c == '/'||c == '=') {
+        if(xmlIsWhitespace(c) || c == '>' || c == '/' || c == '=') {
           if(c == '>' || c == '/') {
             doing = XML_DOING_NOTHING;
             if(c == '/') {
               level--;
               insideTag = false;
+              doing = XML_PARSING_CLOSE;
             }
           } else if(c == '=') {
             doing = XML_LOOKING_FOR_ATTRIBUTE_VALUE;
@@ -91,7 +94,7 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
 
       case XML_LOOKING_FOR_ATTRIBUTE_VALUE:
         // Keep looking until we find a quote mark
-        if(c == ' ' || c == '\n' || c == '\r') continue;
+        if(xmlIsWhitespace(c)) continue;
         if(c == '>' || c == '/') {
           doing = XML_DOING_NOTHING;
           insideTag = false;
@@ -143,13 +146,10 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
           i = xmlLoadChild(xml->children + xml->childrenCount++, data, i-1);
         }
 
-        if(c == '\n' || c == '\r' || c == ' ') {
-          continue;
-        }
+        if(xmlIsWhitespace(c)) continue;
 
         // In HTML Spec there's a chance for there to be a value here, but not
         // in the XML spec.
-
         break;
 
       case XML_PARSING_CLOSE:
@@ -161,8 +161,6 @@ int32_t xmlLoadChild(xml_t *xml, char *data, int32_t i) {
         free(buffer);
         return i;
 
-        break;
-
       default:
         break;
     }
@@ -189,12 +187,24 @@ void xmlDispose(xml_t *xml) {
 
   // Dispose attributes
   for(i = 0; i < xml->attributeCount; i++) {
-    free(xml->attributeNames + i);
+    free(xml->attributeNames[i]);
     if((xml->attributeDatas + i) != NULL) {
-      free(xml->attributeDatas + i);
+      free(xml->attributeDatas[i]);
     }
   }
   
   free(xml->node);
   if(xml-> value != NULL) free(xml->value);
+}
+
+int16_t xmlGetAttributeByName(xml_t *xml, char *name) {
+  int16_t i;
+  for(i = 0; i < xml->attributeCount; i++) {
+    if(strcmp(xml->attributeNames[i], name) == 0) return i;
+  }
+  return -1;
+}
+
+bool xmlIsWhitespace(char c) {
+  return c == ' ' || c == '\r' || c == '\n' || c == '\t';
 }
\ No newline at end of file
diff --git a/src/file/xml.h b/src/file/xml.h
index 8a4ec919..77fdea4c 100644
--- a/src/file/xml.h
+++ b/src/file/xml.h
@@ -36,7 +36,6 @@ typedef struct _xml_t {
   uint8_t childrenCount;
 } xml_t;
 
-
 /**
  * Load an XML child from a string buffer.
  * 
@@ -60,4 +59,8 @@ void xmlLoad(xml_t *xml, char *data);
  * 
  * @param xml XML to dispose.
  */
-void xmlDispose(xml_t *xml);
\ No newline at end of file
+void xmlDispose(xml_t *xml);
+
+int16_t xmlGetAttributeByName(xml_t *xml, char *name);
+
+bool xmlIsWhitespace(char c);
\ No newline at end of file
diff --git a/src/file/xml2.c b/src/file/xml2.c
deleted file mode 100644
index a6ae2254..00000000
--- a/src/file/xml2.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * Copyright (c) 2021 Dominic Masters
- * 
- * This software is released under the MIT License.
- * https://opensource.org/licenses/MIT
- */
-
-#include "xml2.h"
-
-void xmlParseElement(xmlnode_t *node, char *string) {
-  char c;
-  int32_t i, j;
-  uint8_t state;
-
-  node->attributeCount = 0;
-
-  i = 0;
-  state = XML_STATE_NOTHING;
-  while(c = string[i++]) {
-    switch(state) {
-      case XML_STATE_NOTHING:
-        if(c != '<') continue;
-        node->start = string + (i - 1);
-        state = XML_STATE_PARSING_NAME;
-        break;
-
-      case XML_STATE_PARSING_NAME:
-        if(c == ' ' || c == '\n' || c == '\r') continue;
-
-        j = i - 1;
-        while(c = string[j++]) {
-          if(c == ' ' || c == '\n' || c == '\r' || c == '>') break;
-          node->name[j - i] = c;
-        }
-        node->name[j-i] = '\0';
-        i = j - 1;
-        state = XML_STATE_PARSING_ATTRIBUTES;
-        break;
-
-      case XML_STATE_PARSING_ATTRIBUTES:
-        if(c == ' ' || c == '\n' || c == '\r') continue;
-        if(c == '>') {
-          node->internalStart = string + i;
-          state = XML_STATE_DONE;
-          break;
-        }
-
-        // Parse Name
-        node->attributeNames[node->attributeCount] = string + (i - 1);
-        node->attributeNameLengths[node->attributeCount] = 0;
-        while(c != ' ' && c != '\n' && c != '\r' && c != '>' && c != '=' && c != '\0') {
-          c = string[i++];
-          node->attributeNameLengths[node->attributeCount]++;
-        }
-
-        if(c == '>') {
-          i--;
-          node->attributeValues[node->attributeCount] = NULL;
-          node->attributeValueLengths[node->attributeCount] = 0;
-          node->attributeCount++;
-          continue;
-        }
-
-        // Wait for = sign
-        while(c == ' ' || c == '\n' || c == '\r') c = string[i++];
-
-        // Handle booleans
-        if(c != '=') {
-          node->attributeValues[node->attributeCount] = NULL;
-          node->attributeValueLengths[node->attributeCount] = 0;
-          node->attributeCount++;
-          continue;
-        }
-
-        // Skip the "
-        i++;
-
-        node->attributeValues[node->attributeCount] = string + i;
-        node->attributeValueLengths[node->attributeCount] = 0;
-        do {
-          c = string[i++];
-          if(c == '\0' || c == '"') break;
-          if(c == '\\') {
-            i++;
-            node->attributeValueLengths[node->attributeCount]++;
-          }
-          node->attributeValueLengths[node->attributeCount]++;
-        } while(c);
-        
-        node->attributeCount++;
-        break;
-
-      default:
-        break;
-    }
-  }
-}
-
-void xmlGetAttributeName(xmlnode_t *xml, uint8_t attribute, char *buffer) {
-  int32_t i;
-  buffer[0] = '\0';
-  for(i = 0; i < xml->attributeNameLengths[attribute]; i++) {
-    buffer[i] = xml->attributeNames[attribute][i];
-  }
-  buffer[xml->attributeNameLengths[attribute]] = '\0';
-}
-
-void xmlGetAttributeValue(xmlnode_t *xml, uint8_t attribute, char *buffer) {
-  int32_t i;
-  buffer[0] = '\0';
-  for(i = 0; i < xml->attributeValueLengths[attribute]; i++) {
-    buffer[i] = xml->attributeValues[attribute][i];
-  }
-  buffer[xml->attributeValueLengths[attribute]] = '\0';
-}
-
-uint8_t xmlGetAttributeByName(xmlnode_t *xml, char *name) {
-  uint8_t i;
-  int32_t len = strlen(name);
-
-  for(i = 0; i < xml->attributeCount; i++) {
-    if(xml->attributeNameLengths[i] != len) continue;
-    if(memcmp(name, xml->attributeNames[i], len) == 0) return i;
-  }
-  return 0xFF;
-}
-
-void xmlFindChildNode(xmlnode_t *node, char** start, char** end) {
-  char c;
-  int32_t i;
-
-  i = 0;
-  while(c = node->internalStart[i++]) {
-    if(c == '<') break;
-  }
-  
-  *start = node->internalStart + i - 1;
-
-  // Now the part I am dreading.
-}
\ No newline at end of file
diff --git a/src/file/xml2.h b/src/file/xml2.h
deleted file mode 100644
index df3ff4ff..00000000
--- a/src/file/xml2.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2021 Dominic Masters
- * 
- * This software is released under the MIT License.
- * https://opensource.org/licenses/MIT
- */
-
-#pragma once
-#include "../libs.h"
-
-#define XML_NODE_CHILD_MAX 32
-#define XML_NODE_NAME_MAX 32
-#define XML_NODE_ATTRIBUTES_MAX 32
-
-#define XML_STATE_NOTHING 0x00
-#define XML_STATE_PARSING_NAME 0x01
-#define XML_STATE_PARSING_ATTRIBUTES 0x02
-#define XML_STATE_DONE 0x03
-
-typedef struct {
-  char *start;
-  char *internalStart;
-  char name[XML_NODE_NAME_MAX];
-
-  char *attributeNames[XML_NODE_ATTRIBUTES_MAX];
-  uint8_t attributeNameLengths[XML_NODE_ATTRIBUTES_MAX];
-
-  char *attributeValues[XML_NODE_ATTRIBUTES_MAX];
-  uint8_t attributeValueLengths[XML_NODE_ATTRIBUTES_MAX];
-
-  uint8_t attributeCount;
-} xmlnode_t;
-
-
-void xmlParseElement(xmlnode_t *node, char *string);
-
-void xmlGetAttributeName(xmlnode_t *xml, uint8_t attribute, char *buffer);
-void xmlGetAttributeValue(xmlnode_t *xml, uint8_t attribute, char *buffer);
-
-uint8_t xmlGetAttributeByName(xmlnode_t *xml, char *name);
-
-void xmlFindChildNode(xmlnode_t *node, char** start, char** end);
\ No newline at end of file
diff --git a/src/game/poker/pokergameassets.c b/src/game/poker/pokergameassets.c
index 5e5b96d8..9248954c 100644
--- a/src/game/poker/pokergameassets.c
+++ b/src/game/poker/pokergameassets.c
@@ -14,7 +14,7 @@ bool pokerGameAssetsInit(pokergameassets_t *assets) {
   languageInit(&assets->language, "locale/language/en-US.csv");
 
   
-  assetManagerShaderLoad(&assets->manager, &assets->shader,
+  assetManagerLoadShader(&assets->manager, &assets->shader,
     "shaders/textured.vert", "shaders/textured.frag"
   );
 
diff --git a/src/game/sandbox/game.c b/src/game/sandbox/game.c
index 0c556528..9f4fd32b 100644
--- a/src/game/sandbox/game.c
+++ b/src/game/sandbox/game.c
@@ -7,45 +7,34 @@
 
 #include "game.h"
 
-
-
 bool sandboxGameInit(sandboxgame_t *game) {
-  xmlnode_t node;
-  char *string = "<xml attribute=\"value\" something=\"else\"><child>Hello World</child></xml>";
-
-  char bufferTest[64];
-
-  xmlParseElement(&node, string;
-  xmlGetAttributeValue(&node, xmlGetAttributeByName(&node, "something"), bufferTest);
-
-  char *start = xmlFindChildNode(&node);
-
   quadInit(&game->quad, 0, 0,0,0,0, 500,500,1,1);
 
   assetManagerInit(&game->manager);
   assetManagerLoadFont(&game->manager, &game->font,
     "fonts/opensans/OpenSans-Regular.ttf"
   );
-  assetManagerShaderLoad(&game->manager, &game->shader, 
+  assetManagerLoadShader(&game->manager, &game->shader, 
     "shaders/textured.vert",
     "shaders/textured.frag"
   );
+  assetManagerLoadScaledTexture(&game->manager, &game->st,
+    "poker/characters/penny", "sprite"
+  );
+  assetManagerLoadTextureScale(&game->manager, &game->st, &game->texture, 0);
   
   assetManagerStart(&game->manager);
 
-  pixel_t *data = (pixel_t *)assetRawLoad("out/test.texture");
-  textureInit(&game->texture, 4360/2, 1920/2, (pixel_t *)data);
-  free(data);
-
   return true;
 }
 
 void sandboxGameUpdate(sandboxgame_t *game) {
   camera_t camera;
   float n = assetManagerProgressGet(&game->manager);
+  printf("Loading %.2f\n", n);
+
   if(n < 1.0f) {
     assetManagerUpdate(&game->manager);
-    printf("Loading %.2f\n", n);
     return;
   }
 
diff --git a/src/game/sandbox/game.h b/src/game/sandbox/game.h
index ebcab7fe..dc03b05e 100644
--- a/src/game/sandbox/game.h
+++ b/src/game/sandbox/game.h
@@ -12,12 +12,13 @@
 #include "../../display/shader.h"
 #include "../../display/primitive.h"
 #include "../../display/primitives/quad.h"
+#include "../../display/scaledtexture.h"
 #include "../../file/asset.h"
 #include "../../ui/label.h"
 #include "../../ui/breakpoint.h"
 #include "../../file/assetmanager.h"
 
-#include "../../file/xml2.h"
+#include "../../file/xml.h"
 
 typedef struct {
   engine_t engine;
@@ -26,6 +27,8 @@ typedef struct {
   texture_t texture;
   primitive_t quad;
   assetmanager_t manager;
+
+  scaledtexture_t st;
 } sandboxgame_t;
 
 /**
diff --git a/tools/display/texture_generation.c b/tools/display/texture_generation.c
index ee5ec8c4..b8c94649 100644
--- a/tools/display/texture_generation.c
+++ b/tools/display/texture_generation.c
@@ -99,8 +99,8 @@ int main(int argc, char *argv[]) {
 
     // Buffer XML info.
     sprintf(xml,
-      "%s\n  <texture-scale scale=\"%i\" width=\"%i\" height=\"%i\" asset=\"%s_%i.texture\" />",
-      xml, scale, rw, rh, out, scale
+      "%s\n  <texture-scale scale=\"%i\" width=\"%i\" height=\"%i\" />",
+      xml, scale, rw, rh
     );
   }