Merge pull request #269 from Daft-Freak/user-only

Don't include the firmware in every app
diff --git a/32blit/engine/tweening.cpp b/32blit/engine/tweening.cpp
index aa2ec42..1e4fc46 100644
--- a/32blit/engine/tweening.cpp
+++ b/32blit/engine/tweening.cpp
@@ -50,24 +50,24 @@
   }
 
   float tween_linear(uint32_t t, float b, float c, uint32_t d) {
-    return c * t / d + b;
+    return (c - b) * t / d + b;
   }
 
   float tween_ease_in_quad(uint32_t t, float b, float c, uint32_t d) {
     float ft = float(t) / float(d);
-    return -c * ft * (ft - 2) + b;
+    return -(c - b) * ft * (ft - 2) + b;
   }
 
   float tween_ease_out_quad(uint32_t t, float b, float c, uint32_t d) {
     float ft = float(t) / float(d);
-    return c * ft * ft + b;
+    return (c - b) * ft * ft + b;
   }
 
   float tween_ease_in_out_quad(uint32_t t, float b, float c, uint32_t d) {
-    float ft = (float)t / d / 2.0f;
-    if (ft < 1) return c / 2 * ft * ft + b;
+    float ft = (float)t / d * 2.0f;
+    if (ft < 1) return (c - b) / 2 * ft * ft + b;
     ft--;
-    return -c / 2 * (ft*(ft - 2) - 1) + b;
+    return -(c - b) / 2 * (ft*(ft - 2) - 1) + b;
   }
 
   /**
diff --git a/docs/32Blit-Firmware.md b/docs/32Blit-Firmware.md
index 4f1276c..9c3d1ec 100644
--- a/docs/32Blit-Firmware.md
+++ b/docs/32Blit-Firmware.md
@@ -1,8 +1,20 @@
-# 32Blit Firmware

+# 32Blit Firmware <!-- omit in toc -->

 

 This repository includes firmware for the 32Blit that lets you manage games on SD card, and copy or flash games via USB serial.

 

-In order to use it, you will need to:

+- [Prerequisites](#prerequisites)

+- [Building & Flashing The 32Blit Firmware](#building--flashing-the-32blit-firmware)

+  - [Building The Firmware](#building-the-firmware)

+  - [Flashing The Firmware To Your 32Blit](#flashing-the-firmware-to-your-32blit)

+    - [Prepare the device](#prepare-the-device)

+    - [Linux and macOS](#linux-and-macos)

+    - [Windows](#windows)

+- [Troubleshooting](#troubleshooting)

+  - [Finding The Right DFU Device](#finding-the-right-dfu-device)

+

+# Prerequisites

+

+In order to use the 32blit firmware, you will need to:

 

 1. Build and install the 32Blit firmware (if you don't have it already)

 2. [Build the flash loader](32Blit-Loader.md) tool in `tools/src`

@@ -65,8 +77,8 @@
 

 In the "Upload Action" section hit "Choose" and select the `firmware.dfu` file you built earlier. (It should be in `build.stm32/firmware/firmware.dfu`) and finally hit "Upgrade" to flash the file.

 

-## Troubleshooting

+# Troubleshooting

 

-### Finding The Right DFU Device

+## Finding The Right DFU Device

 

 If you have more than one device in DFU mode connected to your computer then find the 32blit using `lsusb` and add `-d vid:pid` to the dfu-util command. Replace `vid:pid` with the 4 character ID strings to target the correct device.

diff --git a/docs/32Blit-Loader.md b/docs/32Blit-Loader.md
index 274d907..66b8167 100644
--- a/docs/32Blit-Loader.md
+++ b/docs/32Blit-Loader.md
@@ -1,7 +1,13 @@
-# 32Blit Loader Tool

+# 32Blit Loader Tool <!-- omit in toc -->

 

 The 32Blit loader is a tool for saving 32Blit games to your SD card over USB, or flashing them directly to the 32Blit's external flash for quick and easy testing.

 

+- [Building The 32Blit Loader Tool](#building-the-32blit-loader-tool)

+  - [macOS & Linux](#macos--linux)

+  - [Windows - Visual Studio](#windows---visual-studio)

+  - [Windows - WSL](#windows---wsl)

+- [Usage](#usage)

+

 ## Building The 32Blit Loader Tool

 

 ### macOS & Linux

diff --git a/docs/32blit.md b/docs/32blit.md
index c40a040..27b2d74 100644
--- a/docs/32blit.md
+++ b/docs/32blit.md
@@ -1,7 +1,18 @@
-# Building & Running On 32Blit
+# Building & Running On 32Blit <!-- omit in toc -->
 
 These instructions assume a basic familiarity with the Linux command-line and with compiling software from source.
 
+- [Prerequisites](#prerequisites)
+  - [Examples](#examples)
+    - [Building An Example](#building-an-example)
+    - [Uploading An Example](#uploading-an-example)
+  - [Your Own Projects](#your-own-projects)
+- [Troubleshooting](#troubleshooting)
+    - [Flasher Can't Find 32Blit Port](#flasher-cant-find-32blit-port)
+    - [CMake Errors](#cmake-errors)
+
+# Prerequisites
+
 Make sure you've prepared your 32Blit by following the instructions in:
 
 * [Building & Flashing The 32Blit Firmware](32Blit-Firmware.md#building--flashing-the-32blit-firmware)
@@ -71,6 +82,6 @@
 
 Port-detection does not work if your device is in DFU mode. Either reset it to get it out, or it it's stuck in DFU mode (or just boots into a black screen), you may need to reflash the firmware.
 
-### Cmake Errors
+### CMake Errors
 
 If you see `cannot create target because another target with the same name already exists` you've probably run `cmake ..` in the wrong directory (the project directory rather than the build directory), you should remove all but your project files and `cmake ..` again from the build directory.
diff --git a/docs/ChromeOS.md b/docs/ChromeOS.md
index 491c5db..d286859 100644
--- a/docs/ChromeOS.md
+++ b/docs/ChromeOS.md
@@ -1,5 +1,13 @@
+# Chrome OS <!-- omit in toc -->
+
+These instructions cover building 32blit on a Chrome OS Linux VM.
+
 Chrome OS (Chromebook) uses a Linux virtual machine to run Linux software. Once the virtual machine is set up you can follow the the [General Readme](../README.md) and the [Linux](Linux.md) instructions.
 
+- [Installing the Linux Beta](#installing-the-linux-beta)
+- [Sharing folders with the Linux virtual machine](#sharing-folders-with-the-linux-virtual-machine)
+- [Flashing the firmware (DFU mode) and USB access](#flashing-the-firmware-dfu-mode-and-usb-access)
+
 # Installing the Linux Beta
 
 Go to settings find Linux (Beta) and switch it on. This will install a Debian Linux virtual machine on your system.
diff --git a/docs/Linux.md b/docs/Linux.md
index aa340ac..de38b66 100644
--- a/docs/Linux.md
+++ b/docs/Linux.md
@@ -1,6 +1,16 @@
-# Building & Running on Linux
+# Building & Running on Linux <!-- omit in toc -->
+
+These instructions cover building 32blit on Linux.
+
+- [Prerequisites](#prerequisites)
+  - [Building & Running on 32Blit](#building--running-on-32blit)
+  - [Building & Running Locally](#building--running-locally)
+    - [Build Everything](#build-everything)
+
+# Prerequisites
 
 First install the required tools:
+
 ```
 sudo apt install git gcc g++ gcc-arm-none-eabi cmake make python3 python3-pip libsdl2-dev libsdl2-image-dev
 
@@ -8,6 +18,7 @@
 ```
 
 Optionally, for building the firmware as a .DFU file (usually not needed on Linux):
+
 ```
 pip3 install construct bitstring
 ```
diff --git a/docs/Tools.md b/docs/Tools.md
index 83da941..74f1dfa 100644
--- a/docs/Tools.md
+++ b/docs/Tools.md
@@ -1,14 +1,24 @@
-# Tools
+# Tools <!-- omit in toc -->
 
 The individual asset tools have been deprecated in favour of https://github.com/pimoroni/32blit-tools which installs `32blit` or `32blit.exe` command on Linux/Mac or Windows respectively.
 
 You can install these tools with `pip`:
+
 ```
 pip3 install 32blit
 ```
 
 Head on over to https://github.com/pimoroni/32blit-tools for further documentation covering the installation of the new tools.
 
+- [Asset Pipeline](#asset-pipeline)
+- [Visual Studio](#visual-studio)
+- [Old Tools](#old-tools)
+  - [Sprite Builder](#sprite-builder)
+    - [Prerequisites](#prerequisites)
+    - [Usage](#usage)
+      - [Packed](#packed)
+      - [Raw](#raw)
+
 # Asset Pipeline
 
 The new `32blit` tool has been integrated into CMake so that you can turn your raw images and assets into packed data at compile time.
@@ -93,13 +103,13 @@
 
 Have a look into the script for further details regarding the formats.
 
-### Prerequisites:
+### Prerequisites
 
 ``` shell
 python3 -m pip install construct bitarray bitstring pillow
 ```
 
-### Usage:
+### Usage
 
 Currently `sprite-builder` knows two types of conversion:
 
diff --git a/docs/VSCode.md b/docs/VSCode.md
index a537151..cbfbbb2 100644
--- a/docs/VSCode.md
+++ b/docs/VSCode.md
@@ -1,7 +1,22 @@
-# Setting up Visual Studio Code
+# Setting up Visual Studio Code <!-- omit in toc -->
+
+These instructions cover setting up Visual Studio Code to build the CMake project.
+
+A working knowledge of using and configuring Visual Studio Code is assumed.
+
+- [Requirements](#requirements)
+- [Windows specific setup](#windows-specific-setup)
+- [Mac specific setup](#mac-specific-setup)
+- [Initial setup for local builds](#initial-setup-for-local-builds)
+- [IntelliSense](#intellisense)
+- [CMake Arguments](#cmake-arguments)
+- [Debugger configuration](#debugger-configuration)
+- [Building for 32Blit](#building-for-32blit)
 
 ## Requirements
+
 You'll need to install:
+
  - [Visual Studio Code](https://code.visualstudio.com/)
  - The [C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
  - The [CMake Tools extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools)
diff --git a/docs/Windows-VisualStudio.md b/docs/Windows-VisualStudio.md
index b3206b0..88a1c65 100644
--- a/docs/Windows-VisualStudio.md
+++ b/docs/Windows-VisualStudio.md
@@ -1,9 +1,15 @@
-# Visual Studio 2019
+# Visual Studio 2019 <!-- omit in toc -->
 
 You can use Visual Studio 2019 to examine the samples (compile them and run them in an SDL window) or to build your own apps for the 32blit API.
 
 See [Building & Running On 32Blit](32blit.md) if you want to compile examples/projects to run on 32Blit.
 
+- [Requirements](#requirements)
+- [Option 1: Use the solution file](#option-1-use-the-solution-file)
+  - [Get started with your own game](#get-started-with-your-own-game)
+- [Option 2: Use Visual Studio's built-in CMake support](#option-2-use-visual-studios-built-in-cmake-support)
+- [Troubleshooting](#troubleshooting)
+
 ## Requirements
 
 You will need Visual Studio 2019 (preferably version 16.4). 
diff --git a/docs/Windows-WSL.md b/docs/Windows-WSL.md
index 9c7e5d8..4bd4c5d 100644
--- a/docs/Windows-WSL.md
+++ b/docs/Windows-WSL.md
@@ -1,11 +1,24 @@
-# Building & Running on Win32 (WSL and MinGW)
+# Building & Running on Win32 (WSL and MinGW) <!-- omit in toc -->
 
-These instructions cover setting up Windows Subsystem for Linux so that you can cross-compile Windows-compatible binaries with MinGW.
+These instructions cover setting up Windows Subsystem for Linux so that you can cross-compile Windows-compatible binaries with MinGW. This approach is included for completeness but not recommended, since MinGW binaries are statically linked and much larger than the Visual Studio output.
 
-They assume a basic knowledge of the Linux command-line, installing tools and compiling code from source.
+A basic knowledge of the Linux command-line, installing tools and compiling code from source is assumed.
 
 If you're more familiar with Visual Studio then you should [follow the instructions in Windows-VisualStudio.md](Windows-VisualStudio.md)
 
+- [Setting Up](#setting-up)
+  - [Windows Subsystem for Linux (WSL)](#windows-subsystem-for-linux-wsl)
+  - [Installing requirements inside WSL](#installing-requirements-inside-wsl)
+- [Building & Running on 32Blit](#building--running-on-32blit)
+- [Building & Running Locally](#building--running-locally)
+  - [Installing SDL2 & SDL2_image](#installing-sdl2--sdl2_image)
+    - [SDL2](#sdl2)
+    - [SDL2_image](#sdl2_image)
+  - [Building](#building)
+    - [Single Example](#single-example)
+    - [Build Everything](#build-everything)
+  - [Troubleshooting](#troubleshooting)
+
 ## Setting Up
 
 ### Windows Subsystem for Linux (WSL)
@@ -35,27 +48,41 @@
 
 You can use WSL on Windows to cross-compile your project (or any 32Blit example) into a Windows .exe for testing locally.
 
-First you'll need to cross-compile SDL2 for MinGW and install it.
+You will need to cross-compile SDL2 for MinGW and install both it, and SDL2-image.
 
-Grab the SDL2 source code and unzip it with the following commands:
+### Installing SDL2 & SDL2_image
+
+This will install the SDL2 64bit mingw development headers and libraries into `/opt/local/x86_64-w64-mingw32/`.
+
+Note: the `lib/cmake/SDL2/sdl2-config.cmake` shipped with these libraries expects them to be in `/opt/local`, if you change the install path you will have to modify this file.
+
+First, make sure the `/opt/local/` directory exists:
 
 ```shell
-wget https://www.libsdl.org/release/SDL2-2.0.10.zip
-unzip SDL2-2.0.10.zip
-cd SDL2-2.0.10
+sudo mkdir -p /opt/local/
 ```
 
-Then build and install it:
+#### SDL2
+
+Grab and install the SDL2 mingw development package:
 
 ```shell
-mkdir build.mingw
-cd build.mingw
-../configure --target=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --build=x86_64--linux --prefix=/usr/local/cross-tools/x86_64-w64-mingw32/
-make
-sudo make install
+wget https://libsdl.org/release/SDL2-devel-2.0.10-mingw.tar.gz
+tar xzf SDL2-devel-2.0.10-mingw.tar.gz
+sudo cp -r SDL2-2.0.10/x86_64-w64-mingw32 /opt/local/
 ```
 
-This will install the SDL2 development headers and libraries into `/usr/local/cross-tools/x86_64-w64-mingw32/` if you use a different directory then you will have to supply the SDL2 dir to the `cmake` command below using `-DSDL2_DIR=/usr/local/cross-tools/x86_64-w64-mingw32/lib/cmake/SDL2`
+#### SDL2_image
+
+Grab and install the SDL2_image mingw development package:
+
+```shell
+wget https://www.libsdl.org/projects/SDL_image/release/SDL2_image-devel-2.0.5-mingw.tar.gz
+tar xzf SDL2_image-devel-2.0.5-mingw.tar.gz
+sudo cp -r SDL2_image-2.0.5/x86_64-w64-mingw32 /opt/local/
+```
+
+### Building
 
 Finally, set up the 32Blit Makefile from the root of the repository with the following commands:
 
@@ -65,6 +92,8 @@
 cmake .. -DCMAKE_TOOLCHAIN_FILE=../mingw.toolchain
 ```
 
+#### Single Example
+
 Now to make any example, type:
 
 ```shell
@@ -87,7 +116,7 @@
 
 Don't forget to include `SDL2.dll` this if you want to redistribute a game/example.
 
-### Build Everything
+#### Build Everything
 
 Alternatively you can build everything by just typing:
 
diff --git a/docs/macOS.md b/docs/macOS.md
index 23547a3..08edff3 100644
--- a/docs/macOS.md
+++ b/docs/macOS.md
@@ -1,4 +1,19 @@
-# Building & Running on macOS
+# Building & Running on macOS <!-- omit in toc -->
+
+These instructions cover building 32blit on macOS.
+
+- [Prerequisites](#prerequisites)
+- [Python3](#python3)
+  - [Installing python3](#installing-python3)
+  - [Installing pip3 dependecies](#installing-pip3-dependecies)
+  - [Verifying install](#verifying-install)
+- [Installing `gcc-arm-none-eabi`](#installing-gcc-arm-none-eabi)
+- [Building & Running on 32Blit](#building--running-on-32blit)
+- [Building & Running Locally](#building--running-locally)
+  - [Build Everything](#build-everything)
+- [Troubleshooting](#troubleshooting)
+
+## Prerequisites
 
 You will need build tools and CMake. Assuming you have [homebrew](https://docs.brew.sh/Installation) installed:
 
@@ -24,6 +39,7 @@
 TODO: Document install of `construct` and `bitstring` for Python 3 (probably need a requirements.txt for the tools directory)
 
 ###  Verifying install
+
 ``` shell
 python3 --version
 ```
diff --git a/examples/sprite-test/CMakeLists.txt b/examples/sprite-test/CMakeLists.txt
index 88ae77a..ea2de68 100644
--- a/examples/sprite-test/CMakeLists.txt
+++ b/examples/sprite-test/CMakeLists.txt
@@ -2,3 +2,4 @@
 project (sprite-test)
 include (../../32blit.cmake)
 blit_executable (sprite-test sprite-test.cpp)
+blit_assets_yaml(sprite-test assets.yml)
diff --git a/examples/sprite-test/assets.yml b/examples/sprite-test/assets.yml
new file mode 100644
index 0000000..f0b7432
--- /dev/null
+++ b/examples/sprite-test/assets.yml
@@ -0,0 +1,3 @@
+assets.cpp:
+  ../../assets/s4m_ur4i-dingbads.png:
+    name: asset_dingbads
diff --git a/examples/sprite-test/sprite-test.cpp b/examples/sprite-test/sprite-test.cpp
index 6b0f7d7..6b545ee 100644
--- a/examples/sprite-test/sprite-test.cpp
+++ b/examples/sprite-test/sprite-test.cpp
@@ -4,6 +4,7 @@
 #include <cstdlib>
 
 #include "sprite-test.hpp"
+#include "assets.hpp"
 
 using namespace blit;
 
@@ -12,6 +13,9 @@
 
 /* setup */
 void init() {
+  // You gotta load those tasty sprites first
+  // "asset_dingbads" is the asset name defined in assets.yml
+  screen.sprites = SpriteSheet::load(asset_dingbads);
 }
 
 int tick_count = 0;
@@ -22,11 +26,45 @@
   screen.alpha = 255;
   screen.mask = nullptr;
 
+  // draw grid
+  screen.alpha = 255;
+  screen.pen = Pen(255, 255, 255);
+  screen.rectangle(Rect(0, 0, 320, 14));
+
+  screen.text("Apple", minimal_font, Point(5, 20));
+  screen.text("Skull", minimal_font, Point(5, 40));
+  screen.text("Flowers", minimal_font, Point(5, 60));
+
+  screen.pen = Pen(0, 0, 0);
+  screen.text("Sprite demo", minimal_font, Point(5, 4));
+
   uint32_t ms_start = now();
 
+  // Draw a sprite using its numerical index into the sprite sheet
+  // Treats the sprite sheet as a grid of 8x8 sprites numbered from 0 to 63
+  // In this case sprite number 1 is the second sprite from the top row.
+  // It should be an apple! Munch!
+  screen.sprite(1, Point(60, 20));
+
+  // Draw a sprite using its X/Y position from the sprite sheet
+  // Treats the sprite sheet as a grid of 8x8 sprites
+  // numbered 0 to 15 across and 0 to 15 down!
+  // In this case we draw the sprite from:
+  // The 10th position across (0 based, remember!)
+  // The 3rd position down.
+  // It should be a skull! Yarr!
+  screen.sprite(Point(9, 2), Point(60, 40));
+
+  // Draw a group of sprites starting from an X/Y position, with a width/height
+  // Treats the sprite sheet a grid of 8x8 sprites and selects a group of them defined by a Rect(x, y, w, h)
+  // The width and height are measured in sprites.
+  // In this case we draw three sprites from the 6th column on the 12th row.
+  // It should be a row of flowers! Awww!
+  screen.sprite(Rect(5, 11, 3, 1), Point(60, 60));
 
   uint32_t ms_end = now();
 
+
   // draw FPS meter
   screen.alpha = 255;
   screen.pen = Pen(255, 255, 255, 100);
diff --git a/mingw.toolchain b/mingw.toolchain
index ffe38e2..09fed02 100644
--- a/mingw.toolchain
+++ b/mingw.toolchain
@@ -1,5 +1,5 @@
 if(NOT DEFINED SDL2_DIR)
-	set(SDL2_DIR /usr/local/cross-tools/x86_64-w64-mingw32/lib/cmake/SDL2)
+	set(SDL2_DIR /opt/local/x86_64-w64-mingw32/lib/cmake/SDL2)
 endif()
 list(APPEND CMAKE_MODULE_PATH ${SDL2_DIR})
 include(sdl2-config REQUIRED)
@@ -13,4 +13,8 @@
 
 if(EXISTS "${SDL2_PREFIX}/bin/SDL2.dll")
 	set(SDL2_DLL "${SDL2_PREFIX}/bin/SDL2.dll")
+endif()
+
+if(EXISTS "${SDL2_PREFIX}/bin/SDL2_image.dll")
+	set(SDL2_IMAGE_DLL "${SDL2_PREFIX}/bin/SDL2_image.dll")
 endif()
\ No newline at end of file
diff --git a/vs/examples/sprite-test/sprite-test.vcxproj b/vs/examples/sprite-test/sprite-test.vcxproj
index 19adb1b..143ea97 100644
--- a/vs/examples/sprite-test/sprite-test.vcxproj
+++ b/vs/examples/sprite-test/sprite-test.vcxproj
@@ -71,15 +71,19 @@
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <LinkIncremental>true</LinkIncremental>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <LinkIncremental>true</LinkIncremental>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)</IncludePath>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <LinkIncremental>false</LinkIncremental>
+    <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)</IncludePath>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -96,6 +100,9 @@
       <AdditionalDependencies>32blit.lib;32blit-sdl.lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>$(OutputPath);$(SolutionDir)sdl\lib\$(PlatformTarget)\</AdditionalLibraryDirectories>
     </Link>
+    <PreBuildEvent>
+      <Command>python -m ttblit pack --force --config $(ProjectDir)..\..\..\examples\sprite-test\assets.yml --output $(ProjectDir)</Command>
+    </PreBuildEvent>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <ClCompile>
@@ -112,6 +119,9 @@
       <AdditionalLibraryDirectories>$(OutputPath);$(SolutionDir)sdl\lib\$(PlatformTarget)\</AdditionalLibraryDirectories>
       <AdditionalDependencies>32blit.lib;32blit-sdl.lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
+    <PreBuildEvent>
+      <Command>python -m ttblit pack --force --config $(ProjectDir)..\..\..\examples\sprite-test\assets.yml --output $(ProjectDir)</Command>
+    </PreBuildEvent>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
@@ -132,6 +142,9 @@
       <AdditionalLibraryDirectories>$(OutputPath);$(SolutionDir)sdl\lib\$(PlatformTarget)\</AdditionalLibraryDirectories>
       <AdditionalDependencies>32blit.lib;32blit-sdl.lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
+    <PreBuildEvent>
+      <Command>python -m ttblit pack --force --config $(ProjectDir)..\..\..\examples\sprite-test\assets.yml --output $(ProjectDir)</Command>
+    </PreBuildEvent>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <ClCompile>
@@ -152,12 +165,17 @@
       <AdditionalLibraryDirectories>$(OutputPath);$(SolutionDir)sdl\lib\$(PlatformTarget)\</AdditionalLibraryDirectories>
       <AdditionalDependencies>32blit.lib;32blit-sdl.lib;SDL2.lib;SDL2main.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
+    <PreBuildEvent>
+      <Command>python -m ttblit pack --force --config $(ProjectDir)..\..\..\examples\sprite-test\assets.yml --output $(ProjectDir)</Command>
+    </PreBuildEvent>
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\examples\sprite-test\sprite-test.hpp" />
+    <ClInclude Include="assets.hpp" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\examples\sprite-test\sprite-test.cpp" />
+    <ClCompile Include="assets.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">