From 4d0439ca11cbf7f14f9487d62bdc7ce08c718329 Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Tue, 14 Mar 2023 00:20:43 -0700
Subject: [PATCH] Added PS Vita support

---
 cmake/targets/CMakeLists.txt                  |   8 +-
 .../CMakeLists.txt                            |   9 +
 .../target-helloworld-vita/CMakeLists.txt     |   2 +-
 lib/CMakeLists.txt                            |   2 +-
 src/CMakeLists.txt                            |   8 +-
 src/dawn/game/_DawnGame.hpp                   |   1 -
 .../scene/components/display/CMakeLists.txt   |  11 +-
 .../scene/components/example/CMakeLists.txt   |   4 +-
 .../components/physics/3d/CMakeLists.txt      |   5 +-
 .../scene/components/scene/CMakeLists.txt     |   5 +-
 .../visualnovel/components/CMakeLists.txt     |   5 +-
 src/dawnglfw/CMakeLists.txt                   |  48 ++--
 src/dawnhelloworld/CMakeLists.txt             |   6 +-
 src/dawnhelloworld/game/CMakeLists.txt        |  10 +
 src/dawnhelloworld/game/DawnGame.cpp          |  43 ++++
 src/dawnhelloworld/game/DawnGame.hpp          |  28 +++
 src/dawnhelloworld/input/InputBinds.hpp       |  19 ++
 src/dawnhelloworld/save/CMakeLists.txt        |  10 +
 .../save/DawnGameSaveManager.cpp              |  28 +++
 .../save/DawnGameSaveManager.hpp              |  22 ++
 src/dawnhelloworld/scenes/HelloWorldScene.hpp |  33 +++
 src/dawnlinux64/CMakeLists.txt                |  48 ++--
 src/dawnlinux64/debug/debug.hpp               |  14 ++
 src/dawnopengl/CMakeLists.txt                 |  54 ++---
 .../display/shader/ShaderProgram.cpp          | 208 +++++++++---------
 .../display/shader/ShaderProgram.hpp          | 127 +++++------
 .../shader/SimpleTexturedShaderProgram.hpp    |  91 +++++---
 src/dawntools/tools/CMakeLists.txt            |  21 +-
 src/dawnvita/CMakeLists.txt                   |  43 +++-
 .../dawnopengl.hpp}                           |  13 +-
 src/dawnvita/debug/debug.hpp                  |  44 ++++
 src/dawnvita/host/DawnHostVita.cpp            | 200 +++++++++++++++--
 src/dawnvita/host/DawnHostVita.hpp            |  17 +-
 src/dawnvita/input/CMakeLists.txt             |  10 +
 src/dawnvita/input/InputManager.cpp           |  20 ++
 src/dawnvita/input/InputManager.hpp           |  19 ++
 src/dawnvita/time/CMakeLists.txt              |  10 +
 src/dawnvita/time/TimeManager.cpp             |  16 ++
 src/dawnvita/time/TimeManager.hpp             |  15 ++
 39 files changed, 937 insertions(+), 340 deletions(-)
 create mode 100644 cmake/targets/target-helloworld-linux64-glfw/CMakeLists.txt
 create mode 100644 src/dawnhelloworld/game/CMakeLists.txt
 create mode 100644 src/dawnhelloworld/game/DawnGame.cpp
 create mode 100644 src/dawnhelloworld/game/DawnGame.hpp
 create mode 100644 src/dawnhelloworld/input/InputBinds.hpp
 create mode 100644 src/dawnhelloworld/save/CMakeLists.txt
 create mode 100644 src/dawnhelloworld/save/DawnGameSaveManager.cpp
 create mode 100644 src/dawnhelloworld/save/DawnGameSaveManager.hpp
 create mode 100644 src/dawnhelloworld/scenes/HelloWorldScene.hpp
 create mode 100644 src/dawnlinux64/debug/debug.hpp
 rename src/{dawnhelloworld/HelloWorld.cpp => dawnvita/dawnopengl.hpp} (85%)
 create mode 100644 src/dawnvita/debug/debug.hpp
 create mode 100644 src/dawnvita/input/CMakeLists.txt
 create mode 100644 src/dawnvita/input/InputManager.cpp
 create mode 100644 src/dawnvita/input/InputManager.hpp
 create mode 100644 src/dawnvita/time/CMakeLists.txt
 create mode 100644 src/dawnvita/time/TimeManager.cpp
 create mode 100644 src/dawnvita/time/TimeManager.hpp

diff --git a/cmake/targets/CMakeLists.txt b/cmake/targets/CMakeLists.txt
index 6646e984..a5df8102 100644
--- a/cmake/targets/CMakeLists.txt
+++ b/cmake/targets/CMakeLists.txt
@@ -6,18 +6,20 @@
 # Check for build target, or default. This is pretty much not guaranteed.
 if(NOT DEFINED DAWN_BUILD_TARGET)
   if(WIN32)
-    set(DAWN_BUILD_TARGET "target-pokergame-win32-glfw")
+    set(DAWN_BUILD_TARGET "target-helloworld-win32-glfw")
   elseif(UNIX AND NOT APPLE)
-    set(DAWN_BUILD_TARGET "target-tictactoe-linux64-glfw")
+    set(DAWN_BUILD_TARGET "target-helloworld-linux64-glfw")
   endif()
 endif()
 
-set(DAWN_BUILD_TARGET "target-helloworld-vita")
+# set(DAWN_BUILD_TARGET "target-helloworld-vita")
 
 # Now validate we have a build target for real
 if(NOT DEFINED DAWN_BUILD_TARGET)
   message(FATAL_ERROR "You need to define a DAWN_BUILD_TARGET")
 endif()
 
+message("Building target ${DAWN_BUILD_TARGET}")
+
 # Include the build target
 add_subdirectory(${DAWN_BUILD_TARGET})
\ No newline at end of file
diff --git a/cmake/targets/target-helloworld-linux64-glfw/CMakeLists.txt b/cmake/targets/target-helloworld-linux64-glfw/CMakeLists.txt
new file mode 100644
index 00000000..fd42abe0
--- /dev/null
+++ b/cmake/targets/target-helloworld-linux64-glfw/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+set(DAWN_BUILDING dawnhelloworld CACHE INTERNAL ${DAWN_CACHE_TARGET})
+set(DAWN_TARGET_LINUX64 true CACHE INTERNAL ${DAWN_CACHE_TARGET})
+set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
+set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
\ No newline at end of file
diff --git a/cmake/targets/target-helloworld-vita/CMakeLists.txt b/cmake/targets/target-helloworld-vita/CMakeLists.txt
index 8fb2231f..e7cb57b6 100644
--- a/cmake/targets/target-helloworld-vita/CMakeLists.txt
+++ b/cmake/targets/target-helloworld-vita/CMakeLists.txt
@@ -17,5 +17,5 @@ set(DAWN_VITA_VERSION  "01.00" CACHE INTERNAL ${DAWN_CACHE_TARGET})
 if(DEFINED ENV{VITASDK})
   set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE INTERNAL ${DAWN_CACHE_TARGET})
 else()
-  message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
+  message(FATAL_ERROR "VITASDK Environment variable is missing! Either you do not have the VITASDK installed, or it is not set up with the env vars correctly.")
 endif()
\ No newline at end of file
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 455c1816..6ce1a1b4 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -23,7 +23,7 @@ add_library(stb INTERFACE)
 target_include_directories(stb INTERFACE stb)
 
 # OpenAL
-if(DANW_TARGET_OPENAL)
+if(DAWN_TARGET_OPENAL)
   set(LIBTYPE "STATIC")
   add_subdirectory(openal-soft)
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 42438c00..5e105248 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -24,7 +24,7 @@ if(NOT DEFINED DAWN_TARGET_NAME)
 endif()
 
 # Add in base library
-# add_subdirectory(dawn)
+add_subdirectory(dawn)
 
 # Compile entry targets
 if(DAWN_TARGET_WIN32)
@@ -54,7 +54,11 @@ if(DAWN_TARGET_SDL2)
   add_subdirectory(dawnopengl)
 endif()
 
-if(false)
+if(DAWN_TARGET_VITA)
+  add_subdirectory(dawnopengl)
+endif()
+
+if(DAWN_TARGET_OPENAL)
   add_subdirectory(dawnopenal)
 endif()
 
diff --git a/src/dawn/game/_DawnGame.hpp b/src/dawn/game/_DawnGame.hpp
index d13da5ae..c9672ae2 100644
--- a/src/dawn/game/_DawnGame.hpp
+++ b/src/dawn/game/_DawnGame.hpp
@@ -13,7 +13,6 @@
 #include "input/InputBinds.hpp"
 #include "locale/LocaleManager.hpp"
 #include "save/SaveManager.hpp"
-#include "audio/AudioManager.hpp"
 // #include "scene/SceneItemComponentList.hpp"
 
 #define DAWN_GAME_INIT_RESULT_SUCCESS 0
diff --git a/src/dawn/scene/components/display/CMakeLists.txt b/src/dawn/scene/components/display/CMakeLists.txt
index 43dec7cc..661db97b 100644
--- a/src/dawn/scene/components/display/CMakeLists.txt
+++ b/src/dawn/scene/components/display/CMakeLists.txt
@@ -14,13 +14,4 @@ target_sources(${DAWN_TARGET_NAME}
     PixelPerfectCamera.cpp
     TiledSprite.cpp
     SimpleRenderTargetQuad.cpp
-)
-
-tool_scenecomponent(AnimationController scene/components/display/AnimationController.hpp)
-tool_scenecomponent(Camera scene/components/display/Camera.hpp)
-tool_scenecomponent(Material scene/components/display/Material.hpp)
-tool_scenecomponent(MeshHost scene/components/display/MeshHost.hpp)
-tool_scenecomponent(MeshRenderer scene/components/display/MeshRenderer.hpp)
-tool_scenecomponent(PixelPerfectCamera scene/components/display/PixelPerfectCamera.hpp)
-tool_scenecomponent(TiledSprite scene/components/display/TiledSprite.hpp)
-tool_scenecomponent(SimpleRenderTargetQuad scene/components/display/SimpleRenderTargetQuad.hpp)
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/src/dawn/scene/components/example/CMakeLists.txt b/src/dawn/scene/components/example/CMakeLists.txt
index 6f502946..13a039b4 100644
--- a/src/dawn/scene/components/example/CMakeLists.txt
+++ b/src/dawn/scene/components/example/CMakeLists.txt
@@ -7,6 +7,4 @@
 target_sources(${DAWN_TARGET_NAME}
   PRIVATE
     ExampleSpin.cpp
-)
-
-tool_scenecomponent(ExampleSpin scene/components/example/ExampleSpin.hpp)
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/src/dawn/scene/components/physics/3d/CMakeLists.txt b/src/dawn/scene/components/physics/3d/CMakeLists.txt
index b2f59941..d61702b9 100644
--- a/src/dawn/scene/components/physics/3d/CMakeLists.txt
+++ b/src/dawn/scene/components/physics/3d/CMakeLists.txt
@@ -8,7 +8,4 @@ target_sources(${DAWN_TARGET_NAME}
   PRIVATE
     Collider3D.cpp
     CubeCollider.cpp
-)
-
-tool_scenecomponent(Collider3D scene/components/physics/3d/Collider3D.hpp)
-tool_scenecomponent(CubeCollider scene/components/physics/3d/CubeCollider.hpp)
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/src/dawn/scene/components/scene/CMakeLists.txt b/src/dawn/scene/components/scene/CMakeLists.txt
index d153df89..b0ccded6 100644
--- a/src/dawn/scene/components/scene/CMakeLists.txt
+++ b/src/dawn/scene/components/scene/CMakeLists.txt
@@ -8,7 +8,4 @@ target_sources(${DAWN_TARGET_NAME}
   PRIVATE
     SubSceneCameraAlign.cpp
     SubSceneController.cpp
-)
-
-tool_scenecomponent(SubSceneCameraAlign scene/components/scene/SubSceneCameraAlign.hpp)
-tool_scenecomponent(SubSceneController scene/components/scene/SubSceneController.hpp)
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/src/dawn/visualnovel/components/CMakeLists.txt b/src/dawn/visualnovel/components/CMakeLists.txt
index a2ce30ac..f029bf35 100644
--- a/src/dawn/visualnovel/components/CMakeLists.txt
+++ b/src/dawn/visualnovel/components/CMakeLists.txt
@@ -8,7 +8,4 @@ target_sources(${DAWN_TARGET_NAME}
   PRIVATE
     SimpleVisualNovelBackground.cpp
     VisualNovelCharacter.cpp
-)
-
-tool_scenecomponent(SimpleVisualNovelBackground visualnovel/components/SimpleVisualNovelBackground.hpp)
-tool_scenecomponent(VisualNovelCharacter visualnovel/components/VisualNovelCharacter.hpp)
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/src/dawnglfw/CMakeLists.txt b/src/dawnglfw/CMakeLists.txt
index 6185b931..3d49ba4c 100644
--- a/src/dawnglfw/CMakeLists.txt
+++ b/src/dawnglfw/CMakeLists.txt
@@ -1,22 +1,28 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Libs
-target_link_libraries(${DAWN_TARGET_NAME}
-  PUBLIC
-    glfw
-    glad
-)
-
-# Includes
-target_include_directories(${DAWN_TARGET_NAME}
-  PUBLIC
-    ${CMAKE_CURRENT_LIST_DIR}
-)
-
-# Subdirs
-add_subdirectory(host)
-add_subdirectory(input)
+# Copyright (c) 2022 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Libs
+target_link_libraries(${DAWN_TARGET_NAME}
+  PUBLIC
+    glfw
+    glad
+)
+
+# Platform variables
+target_compile_definitions(${DAWN_TARGET_NAME}
+  PUBLIC
+    DAWN_OPENGL_GLSL=true
+)
+
+# Includes
+target_include_directories(${DAWN_TARGET_NAME}
+  PUBLIC
+    ${CMAKE_CURRENT_LIST_DIR}
+)
+
+# Subdirs
+add_subdirectory(host)
+add_subdirectory(input)
 add_subdirectory(time)
\ No newline at end of file
diff --git a/src/dawnhelloworld/CMakeLists.txt b/src/dawnhelloworld/CMakeLists.txt
index 0ffcd48a..8de667f3 100644
--- a/src/dawnhelloworld/CMakeLists.txt
+++ b/src/dawnhelloworld/CMakeLists.txt
@@ -3,9 +3,6 @@
 # This software is released under the MIT License.
 # https://opensource.org/licenses/MIT
 
-# Add Common Engine Parts
-set(DAWN_VISUAL_NOVEL true CACHE INTERNAL ${DAWN_CACHE_TARGET})
-
 # Build Project
 add_executable(${DAWN_TARGET_NAME})
 
@@ -16,4 +13,5 @@ target_include_directories(${DAWN_TARGET_NAME}
 )
 
 # Subdirs
-# add_subdirectory(game)
\ No newline at end of file
+add_subdirectory(game)
+add_subdirectory(save)
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/CMakeLists.txt b/src/dawnhelloworld/game/CMakeLists.txt
new file mode 100644
index 00000000..8ca94ca8
--- /dev/null
+++ b/src/dawnhelloworld/game/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    DawnGame.cpp
+)
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/DawnGame.cpp b/src/dawnhelloworld/game/DawnGame.cpp
new file mode 100644
index 00000000..149e66e7
--- /dev/null
+++ b/src/dawnhelloworld/game/DawnGame.cpp
@@ -0,0 +1,43 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "DawnGame.hpp"
+#include "scenes/HelloWorldScene.hpp"
+
+using namespace Dawn;
+
+DawnGame::DawnGame(DawnHost *host) :
+  host(host),
+  renderManager(this),
+  inputManager(this),
+  saveManager(this)
+{
+}
+
+int32_t DawnGame::init() {
+  this->assetManager.init();
+  this->renderManager.init();
+
+  this->scene = new HelloWorldScene(this);
+  
+  return DAWN_GAME_INIT_RESULT_SUCCESS;
+}
+
+int32_t DawnGame::update(float_t delta) {
+  this->assetManager.update();
+  this->inputManager.update();
+  this->timeManager.update(delta);
+
+  if(this->scene != nullptr) this->scene->update();
+  
+  this->renderManager.update();
+
+  return DAWN_GAME_UPDATE_RESULT_SUCCESS;
+}
+
+void DawnGame::sceneCutover(Scene *scene) {
+  if(scene == nullptr) scene = this->scene;
+  this->sceneToCutTo = scene;
+}
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/DawnGame.hpp b/src/dawnhelloworld/game/DawnGame.hpp
new file mode 100644
index 00000000..eb00eced
--- /dev/null
+++ b/src/dawnhelloworld/game/DawnGame.hpp
@@ -0,0 +1,28 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "game/_DawnGame.hpp"
+#include "save/DawnGameSaveManager.hpp"
+
+namespace Dawn {
+  class DawnGame : public IDawnGame {
+    private:
+      Scene *sceneToCutTo = nullptr;
+      
+    public:
+      DawnHost *host;
+      RenderManager renderManager;
+      AssetManager assetManager;
+      InputManager inputManager;
+      TimeManager timeManager;
+      DawnGameSaveManager saveManager;
+      
+      DawnGame(DawnHost *host);
+      int32_t init() override;
+      int32_t update(float_t delta) override;
+      void sceneCutover(Scene *scene) override;
+  };
+}
\ No newline at end of file
diff --git a/src/dawnhelloworld/input/InputBinds.hpp b/src/dawnhelloworld/input/InputBinds.hpp
new file mode 100644
index 00000000..32fc1016
--- /dev/null
+++ b/src/dawnhelloworld/input/InputBinds.hpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "input/InputManager.hpp"
+
+#define INPUT_BIND(n) ((inputbind_t)n)
+
+#define INPUT_BIND_ACCEPT INPUT_BIND(1)
+#define INPUT_BIND_NEGATIVE_X INPUT_BIND(2)
+#define INPUT_BIND_POSITIVE_X INPUT_BIND(3)
+#define INPUT_BIND_NEGATIVE_Y INPUT_BIND(4)
+#define INPUT_BIND_POSITIVE_Y INPUT_BIND(5)
+#define INPUT_BIND_MOUSE_X INPUT_BIND(6)
+#define INPUT_BIND_MOUSE_Y INPUT_BIND(7)
+#define INPUT_BIND_MOUSE_CLICK INPUT_BIND(8)
+#define INPUT_BIND_CANCEL INPUT_BIND(9)
\ No newline at end of file
diff --git a/src/dawnhelloworld/save/CMakeLists.txt b/src/dawnhelloworld/save/CMakeLists.txt
new file mode 100644
index 00000000..2d057169
--- /dev/null
+++ b/src/dawnhelloworld/save/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    DawnGameSaveManager.cpp
+)
\ No newline at end of file
diff --git a/src/dawnhelloworld/save/DawnGameSaveManager.cpp b/src/dawnhelloworld/save/DawnGameSaveManager.cpp
new file mode 100644
index 00000000..75a006b4
--- /dev/null
+++ b/src/dawnhelloworld/save/DawnGameSaveManager.cpp
@@ -0,0 +1,28 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "DawnGameSaveManager.hpp"
+
+using namespace Dawn;
+
+DawnGameSaveManager::DawnGameSaveManager(DawnGame *game) : SaveManager(game) {
+}
+
+bool_t DawnGameSaveManager::validateSave(struct SaveFile raw) {
+  if(!raw.has(POKER_SAVE_KEY_EXAMPLE)) return true;
+  this->currentSave.copy(raw, POKER_SAVE_KEY_EXAMPLE);
+
+  return false;
+}
+
+void DawnGameSaveManager::setExample(int32_t val) {
+  savedata_t value;
+  value.i32 = val;
+  this->currentSave.set(POKER_SAVE_KEY_EXAMPLE, value);
+}
+
+int32_t DawnGameSaveManager::getExample() {
+  return this->currentSave.get(POKER_SAVE_KEY_EXAMPLE).i32;
+}
\ No newline at end of file
diff --git a/src/dawnhelloworld/save/DawnGameSaveManager.hpp b/src/dawnhelloworld/save/DawnGameSaveManager.hpp
new file mode 100644
index 00000000..bc946262
--- /dev/null
+++ b/src/dawnhelloworld/save/DawnGameSaveManager.hpp
@@ -0,0 +1,22 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "save/SaveManager.hpp"
+
+#define POKER_SAVE_KEY_EXAMPLE "poker.example"
+
+namespace Dawn {
+  class DawnGameSaveManager : public SaveManager {
+    protected:
+      virtual bool_t validateSave(struct SaveFile raw) override;
+
+    public:
+      DawnGameSaveManager(DawnGame *game);
+
+      void setExample(int32_t value);
+      int32_t getExample();
+  };
+}
\ No newline at end of file
diff --git a/src/dawnhelloworld/scenes/HelloWorldScene.hpp b/src/dawnhelloworld/scenes/HelloWorldScene.hpp
new file mode 100644
index 00000000..3189df48
--- /dev/null
+++ b/src/dawnhelloworld/scenes/HelloWorldScene.hpp
@@ -0,0 +1,33 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "scene/Scene.hpp"
+#include "prefabs/SimpleSpinningCubePrefab.hpp"
+
+namespace Dawn {
+  class HelloWorldScene : public Scene {
+    protected:
+      Camera *camera;
+      SimpleSpinningCubePrefab *cube;
+
+      void stage() override {
+        camera = Camera::create(this);
+        camera->transform->lookAt(glm::vec3(0, 0, 8), glm::vec3(0, 0, 0));
+
+        cube = SimpleSpinningCubePrefab::create(this);
+      }
+      
+      std::vector<Asset*> getRequiredAssets() override {
+        auto assMan = &this->game->assetManager;
+        std::vector<Asset*> assets;
+        vectorAppend(&assets, SimpleSpinningCubePrefab::getRequiredAssets(assMan));
+        return assets;
+      }
+
+    public:
+      HelloWorldScene(DawnGame *game) : Scene(game) {}
+  };
+}
\ No newline at end of file
diff --git a/src/dawnlinux64/CMakeLists.txt b/src/dawnlinux64/CMakeLists.txt
index 34bbb94f..2ae0f125 100644
--- a/src/dawnlinux64/CMakeLists.txt
+++ b/src/dawnlinux64/CMakeLists.txt
@@ -1,25 +1,25 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Libraries
-target_link_libraries(${DAWN_TARGET_NAME}
-  PUBLIC
-    m
-)
-
-# Includes
-target_include_directories(${DAWN_TARGET_NAME}
-  PUBLIC
-    ${CMAKE_CURRENT_LIST_DIR}
-)
-
-# Platform variables
-target_compile_definitions(${DAWN_TARGET_NAME}
-  PUBLIC
-    DAWN_ASSET_BUILD_PREFIX="../../assets/"
-)
-
-# Subdirs
+# Copyright (c) 2022 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Libraries
+target_link_libraries(${DAWN_TARGET_NAME}
+  PUBLIC
+    m
+)
+
+# Includes
+target_include_directories(${DAWN_TARGET_NAME}
+  PUBLIC
+    ${CMAKE_CURRENT_LIST_DIR}
+)
+
+# Platform variables
+target_compile_definitions(${DAWN_TARGET_NAME}
+  PUBLIC
+    DAWN_ASSET_BUILD_PREFIX="../../assets/"
+)
+
+# Subdirs
 add_subdirectory(host)
\ No newline at end of file
diff --git a/src/dawnlinux64/debug/debug.hpp b/src/dawnlinux64/debug/debug.hpp
new file mode 100644
index 00000000..319c90be
--- /dev/null
+++ b/src/dawnlinux64/debug/debug.hpp
@@ -0,0 +1,14 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "dawnlibs.hpp"
+
+// Draws an error message on screen and force closes the app after user input
+template<typename... A>
+void debugMessage(const char *fmt, A... args) {
+  printf(fmt, args...);
+  printf("\n");
+}
\ No newline at end of file
diff --git a/src/dawnopengl/CMakeLists.txt b/src/dawnopengl/CMakeLists.txt
index 2e9101a4..90f8d807 100644
--- a/src/dawnopengl/CMakeLists.txt
+++ b/src/dawnopengl/CMakeLists.txt
@@ -1,27 +1,29 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Libraries
-find_package(OpenGL REQUIRED)
-
-target_include_directories(${DAWN_TARGET_NAME}
-  PUBLIC
-    ${OPENGL_INCLUDE_DIR}
-)
-
-target_link_libraries(${DAWN_TARGET_NAME}
-  PUBLIC
-    ${OPENGL_LIBRARIES}
-)
-
-# Includes
-target_include_directories(${DAWN_TARGET_NAME}
-  PUBLIC
-    ${CMAKE_CURRENT_LIST_DIR}
-)
-
-# Subdirs
-add_subdirectory(display)
+# Copyright (c) 2022 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+if(NOT DEFINED DAWN_OPENGL_EXCLUDE_LIBRARIES)
+  # Libraries
+  find_package(OpenGL REQUIRED)
+
+  target_include_directories(${DAWN_TARGET_NAME}
+    PUBLIC
+      ${OPENGL_INCLUDE_DIR}
+  )
+
+  target_link_libraries(${DAWN_TARGET_NAME}
+    PUBLIC
+      ${OPENGL_LIBRARIES}
+  )
+endif()
+
+# Includes
+target_include_directories(${DAWN_TARGET_NAME}
+  PUBLIC
+    ${CMAKE_CURRENT_LIST_DIR}
+)
+
+# Subdirs
+add_subdirectory(display)
 add_subdirectory(scene)
\ No newline at end of file
diff --git a/src/dawnopengl/display/shader/ShaderProgram.cpp b/src/dawnopengl/display/shader/ShaderProgram.cpp
index 7a3b8f4e..a1d4f1fd 100644
--- a/src/dawnopengl/display/shader/ShaderProgram.cpp
+++ b/src/dawnopengl/display/shader/ShaderProgram.cpp
@@ -1,101 +1,109 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "ShaderProgram.hpp"
-
-using namespace Dawn;
-
-void ShaderProgram::compileShader(
-  std::string vertexShader,
-  std::string fragmentShader
-) {
-  GLint isSuccess;
-  int32_t maxLength;
-  char error[1024];
-  
-  // Load the vertex shader first
-  this->shaderVertex = glCreateShader(GL_VERTEX_SHADER);
-  auto vertShaderC = vertexShader.c_str();
-  glShaderSource(this->shaderVertex, 1, &vertShaderC, 0);
-  glCompileShader(this->shaderVertex);
-
-  // Validate
-  glGetShaderiv(this->shaderVertex, GL_COMPILE_STATUS, &isSuccess);
-  if(!isSuccess) {
-    glGetShaderiv(this->shaderVertex, GL_INFO_LOG_LENGTH, &maxLength);
-    glGetShaderInfoLog(this->shaderVertex, maxLength, &maxLength, error);
-    throw error;
-  }
-
-  // Now load the Frag shader
-  this->shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
-  auto fragShaderC = fragmentShader.c_str();
-  glShaderSource(this->shaderFrag, 1, &fragShaderC, 0);
-  glCompileShader(this->shaderFrag);
-  glGetShaderiv(this->shaderFrag, GL_COMPILE_STATUS, &isSuccess);
-  if(!isSuccess) {
-    glGetShaderiv(this->shaderFrag, GL_INFO_LOG_LENGTH, &maxLength);
-    glGetShaderInfoLog(this->shaderFrag, maxLength, &maxLength, error);
-    glDeleteShader(this->shaderVertex);
-    throw error;
-  }
-
-  // Now create the shader program.
-  this->shaderProgram = glCreateProgram();
-  glAttachShader(this->shaderProgram, this->shaderVertex);
-  glAttachShader(this->shaderProgram, this->shaderFrag);
-
-  //Bind, Verify & Use the shader program
-  glLinkProgram(this->shaderProgram);
-  glGetProgramiv(this->shaderProgram, GL_LINK_STATUS, &isSuccess);
-  if(!isSuccess) {
-    glGetProgramiv(this->shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
-    glGetProgramInfoLog(this->shaderProgram, maxLength, &maxLength, error);
-    glDeleteShader(this->shaderVertex);
-    glDeleteShader(this->shaderFrag);
-    throw error;
-  }
-
-  // Now parse out the variables.
-}
-
-void ShaderProgram::setTexture(shaderparameter_t param, textureslot_t slot) {
-  glUniform1i(param, slot);
-}
-
-shaderparameter_t ShaderProgram::getParameterByName(std::string name) {
-  return glGetUniformLocation(this->shaderProgram, name.c_str());
-}
-
-void ShaderProgram::setMatrix(shaderparameter_t uniform, glm::mat4 matrix) {
-  glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(matrix));
-}
-
-void ShaderProgram::setBoolean(shaderparameter_t uni, bool value) {
-  glUniform1i(uni, value);
-}
-
-void ShaderProgram::setColor(shaderparameter_t uniform, struct Color color) {
-  glUniform4f(uniform, color.r, color.g, color.b, color.a);
-}
-
-void ShaderProgram::setVector3(shaderparameter_t uniform, glm::vec3 vector) {
-  glUniform3f(uniform, vector.x, vector.y, vector.z);
-}
-
-void ShaderProgram::setFloat(shaderparameter_t param, float_t value) {
-  glUniform1f(param, value);
-}
-
-void ShaderProgram::bind() {
-  if(this->shaderProgram == -1) throw "Shader has not yet been compiled";
-  glUseProgram(this->shaderProgram);
-}
-
-ShaderProgram::~ShaderProgram() {
-  if(this->shaderProgram != -1) glDeleteProgram(this->shaderProgram);
-  if(this->shaderVertex != -1) glDeleteShader(this->shaderVertex);
-  if(this->shaderFrag != -1) glDeleteShader(this->shaderFrag);
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "ShaderProgram.hpp"
+
+using namespace Dawn;
+
+void ShaderProgram::compileShader(
+  std::string vertexShader,
+  std::string fragmentShader
+) {
+  GLint isSuccess;
+  int32_t maxLength;
+  char error[1024];
+  
+  // Load the vertex shader first
+  this->shaderVertex = glCreateShader(GL_VERTEX_SHADER);
+  auto vertShaderC = vertexShader.c_str();
+  glShaderSource(this->shaderVertex, 1, &vertShaderC, 0);
+  glCompileShader(this->shaderVertex);
+
+  // Validate
+  glGetShaderiv(this->shaderVertex, GL_COMPILE_STATUS, &isSuccess);
+  if(!isSuccess) {
+    glGetShaderiv(this->shaderVertex, GL_INFO_LOG_LENGTH, &maxLength);
+    glGetShaderInfoLog(this->shaderVertex, maxLength, &maxLength, error);
+    debugMessage("Error compiling vert shader");
+    debugMessage(error);
+    throw error;
+  }
+
+  // Now load the Frag shader
+  this->shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
+  auto fragShaderC = fragmentShader.c_str();
+  glShaderSource(this->shaderFrag, 1, &fragShaderC, 0);
+  glCompileShader(this->shaderFrag);
+  glGetShaderiv(this->shaderFrag, GL_COMPILE_STATUS, &isSuccess);
+  if(!isSuccess) {
+    glGetShaderiv(this->shaderFrag, GL_INFO_LOG_LENGTH, &maxLength);
+    glGetShaderInfoLog(this->shaderFrag, maxLength, &maxLength, error);
+    glDeleteShader(this->shaderVertex);
+    debugMessage("Error compiling frag shader");
+    debugMessage(error);
+    throw error;
+  }
+
+  // Now create the shader program.
+  this->shaderProgram = glCreateProgram();
+  glAttachShader(this->shaderProgram, this->shaderVertex);
+  glAttachShader(this->shaderProgram, this->shaderFrag);
+
+  //Bind, Verify & Use the shader program
+  glLinkProgram(this->shaderProgram);
+  glGetProgramiv(this->shaderProgram, GL_LINK_STATUS, &isSuccess);
+  if(!isSuccess) {
+    glGetProgramiv(this->shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
+    glGetProgramInfoLog(this->shaderProgram, maxLength, &maxLength, error);
+    glDeleteShader(this->shaderVertex);
+    glDeleteShader(this->shaderFrag);
+    debugMessage("Error compiling shader program");
+    debugMessage(error);
+    throw error;
+  }
+
+  // Now parse out the variables.
+	glBindAttribLocation(this->shaderProgram, 0, "aPos");
+	glBindAttribLocation(this->shaderProgram, 1, "aTexCoord");
+}
+
+void ShaderProgram::setTexture(shaderparameter_t param, textureslot_t slot) {
+  glUniform1i(param, slot);
+}
+
+shaderparameter_t ShaderProgram::getParameterByName(std::string name) {
+  return glGetUniformLocation(this->shaderProgram, name.c_str());
+}
+
+void ShaderProgram::setMatrix(shaderparameter_t uniform, glm::mat4 matrix) {
+  glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(matrix));
+}
+
+void ShaderProgram::setBoolean(shaderparameter_t uni, bool value) {
+  glUniform1i(uni, value);
+}
+
+void ShaderProgram::setColor(shaderparameter_t uniform, struct Color color) {
+  glUniform4f(uniform, color.r, color.g, color.b, color.a);
+}
+
+void ShaderProgram::setVector3(shaderparameter_t uniform, glm::vec3 vector) {
+  glUniform3f(uniform, vector.x, vector.y, vector.z);
+}
+
+void ShaderProgram::setFloat(shaderparameter_t param, float_t value) {
+  glUniform1f(param, value);
+}
+
+void ShaderProgram::bind() {
+  if(this->shaderProgram == -1) throw "Shader has not yet been compiled";
+  glUseProgram(this->shaderProgram);
+}
+
+ShaderProgram::~ShaderProgram() {
+  if(this->shaderProgram != -1) glDeleteProgram(this->shaderProgram);
+  if(this->shaderVertex != -1) glDeleteShader(this->shaderVertex);
+  if(this->shaderFrag != -1) glDeleteShader(this->shaderFrag);
 }
\ No newline at end of file
diff --git a/src/dawnopengl/display/shader/ShaderProgram.hpp b/src/dawnopengl/display/shader/ShaderProgram.hpp
index 280a4a02..4dc8f504 100644
--- a/src/dawnopengl/display/shader/ShaderProgram.hpp
+++ b/src/dawnopengl/display/shader/ShaderProgram.hpp
@@ -1,64 +1,65 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "display/shader/_ShaderProgram.hpp"
-#include "dawnopengl.hpp"
-#include "display/Color.hpp"
-
-typedef GLuint shaderparameter_t;
-
-namespace Dawn {
-  class ShaderProgram : public IShaderProgram<shaderparameter_t> {
-    private:
-      /** Pointer to an uploaded vertex shader program */
-      GLuint shaderVertex = -1;
-
-      /** Pointer to an uploaded fragment shader program */
-      GLuint shaderFrag = -1;
-
-      /** Pointer to an uploaded shader program linked */
-      GLuint shaderProgram = -1;
-
-    protected:
-      /**
-       * Compiles a GLSL shader and stores it on the GPU, updates the underlying
-       * pointers for you.
-       * 
-       * @param vertexShader The string source of the vertex shader.
-       * @param fragmentShader The string source of the fragment shader.
-       */
-      void compileShader(std::string vertexShader, std::string fragmentShader);
-
-
-    public:
-      /**
-       * Locate a shader parameter by its name.
-       * 
-       * @param name Name of the parameter to get.
-       * @return The shader parameter.
-       */
-      shaderparameter_t getParameterByName(std::string name);
-
-      /**
-       * Method to request that this shader be compiled and put on the GPU. This
-       * method should call the protected compileShader method.
-       */
-      virtual void compile() = 0;
-
-      void bind() override;
-      void setMatrix(shaderparameter_t parameter, glm::mat4 matrix) override;
-      void setBoolean(shaderparameter_t parameter, bool_t value) override;
-      void setColor(shaderparameter_t parameter, struct Color color) override;
-      void setVector3(shaderparameter_t parameter, glm::vec3 vector) override;
-      void setTexture(shaderparameter_t parameter, textureslot_t texture) override;
-      void setFloat(shaderparameter_t parameter, float_t value) override;
-
-      /**
-       * Destroys and deletes the shader from the GPU.
-       */
-      virtual ~ShaderProgram();
-  };
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "display/shader/_ShaderProgram.hpp"
+#include "dawnopengl.hpp"
+#include "display/Color.hpp"
+#include "debug/debug.hpp"
+
+typedef GLuint shaderparameter_t;
+
+namespace Dawn {
+  class ShaderProgram : public IShaderProgram<shaderparameter_t> {
+    private:
+      /** Pointer to an uploaded vertex shader program */
+      GLuint shaderVertex = -1;
+
+      /** Pointer to an uploaded fragment shader program */
+      GLuint shaderFrag = -1;
+
+      /** Pointer to an uploaded shader program linked */
+      GLuint shaderProgram = -1;
+
+    protected:
+      /**
+       * Compiles a GLSL shader and stores it on the GPU, updates the underlying
+       * pointers for you.
+       * 
+       * @param vertexShader The string source of the vertex shader.
+       * @param fragmentShader The string source of the fragment shader.
+       */
+      void compileShader(std::string vertexShader, std::string fragmentShader);
+
+
+    public:
+      /**
+       * Locate a shader parameter by its name.
+       * 
+       * @param name Name of the parameter to get.
+       * @return The shader parameter.
+       */
+      shaderparameter_t getParameterByName(std::string name);
+
+      /**
+       * Method to request that this shader be compiled and put on the GPU. This
+       * method should call the protected compileShader method.
+       */
+      virtual void compile() = 0;
+
+      void bind() override;
+      void setMatrix(shaderparameter_t parameter, glm::mat4 matrix) override;
+      void setBoolean(shaderparameter_t parameter, bool_t value) override;
+      void setColor(shaderparameter_t parameter, struct Color color) override;
+      void setVector3(shaderparameter_t parameter, glm::vec3 vector) override;
+      void setTexture(shaderparameter_t parameter, textureslot_t texture) override;
+      void setFloat(shaderparameter_t parameter, float_t value) override;
+
+      /**
+       * Destroys and deletes the shader from the GPU.
+       */
+      virtual ~ShaderProgram();
+  };
 }
\ No newline at end of file
diff --git a/src/dawnopengl/display/shader/SimpleTexturedShaderProgram.hpp b/src/dawnopengl/display/shader/SimpleTexturedShaderProgram.hpp
index e6f99453..c81111fb 100644
--- a/src/dawnopengl/display/shader/SimpleTexturedShaderProgram.hpp
+++ b/src/dawnopengl/display/shader/SimpleTexturedShaderProgram.hpp
@@ -17,38 +17,75 @@ namespace Dawn {
       shaderparameter_t paramHasTexture;
 
       void compile() override {
-        this->compileShader(
-          // Vertex Shader
-          "#version 330 core\n"
-          "layout (location = 0) in vec3 aPos;\n"
-          "layout (location = 1) in vec2 aTexCoord;\n"
+        #if DAWN_OPENGL_GLSL
+          this->compileShader(
+            // Vertex Shader
+            "#version 330 core\n"
+            "layout (location = 0) in vec3 aPos;\n"
+            "layout (location = 1) in vec2 aTexCoord;\n"
 
-          "uniform mat4 u_Proj;\n"
-          "uniform mat4 u_View;\n"
-          "uniform mat4 u_Model;\n"
+            "uniform mat4 u_Proj;\n"
+            "uniform mat4 u_View;\n"
+            "uniform mat4 u_Model;\n"
 
-          "out vec2 o_TextCoord;\n"
-          "void main() {\n"
-            "gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n"
-            "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
-          "}",
+            "out vec2 o_TextCoord;\n"
+            "void main() {\n"
+              "gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n"
+              "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
+            "}",
 
-          // Fragment Shader
-          "#version 330 core\n"
-          "in vec2 o_TextCoord;\n"
-          "out vec4 o_Color;\n"
-          "uniform vec4 u_Color;\n"
-          "uniform bool u_HasTexture;\n"
-          "uniform sampler2D u_Text;\n"
+            // Fragment Shader
+            "#version 330 core\n"
+            "in vec2 o_TextCoord;\n"
+            "out vec4 o_Color;\n"
+            "uniform vec4 u_Color;\n"
+            "uniform bool u_HasTexture;\n"
+            "uniform sampler2D u_Text;\n"
 
-          "void main() {\n"
-            "if(u_HasTexture) {\n"
-              "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n"
-            "} else {\n"
-              "o_Color = u_Color;"
+            "void main() {\n"
+              "if(u_HasTexture) {\n"
+                "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n"
+              "} else {\n"
+                "o_Color = u_Color;"
+              "}\n"
             "}\n"
-          "}\n"
-        );
+          );
+        #elif DAWN_OPENGL_HLSL
+          this->compileShader(
+            // Vertex Shader
+            "uniform float4x4 u_Proj;\n"
+            "uniform float4x4 u_View;\n"
+            "uniform float4x4 u_Model;\n"
+            "void main("
+              "float3 aPos,\n"
+              // "float2 aTexCoord,\n"
+              "float3 out o_TextCoord : TEXCOORD0,\n"
+              "float4 out gl_Position : POSITION\n"
+            ") {\n"
+              // "o_TextCoord = float3(aTexCoord.x, 0.0, 1.0);\n"
+              "gl_Position = mul(mul(mul(float4(aPos, 1.0), u_Model), u_View), u_Proj);\n"
+            "}",
+
+            // Fragment Shader
+            "uniform float4 u_Color;\n"
+            "uniform bool u_HasTexture;\n"
+            "uniform sampler2D u_Text;\n"
+
+            "float4 main(\n"
+              "float3 o_TextCoord : TEXCOORD0\n"
+            ") {\n"
+              "float4 o_Color;\n"
+              "if(u_HasTexture) {\n"
+                // "o_Color = mul(tex2D(u_Text, o_TextCoord), u_Color);\n"
+              "} else {\n"
+                "o_Color = u_Color;\n"
+              "}\n"
+              "return o_Color;\n"
+            "}\n"
+          );
+        #else
+          #error Shader Type must be either GLSL or HLSL
+        #endif
 
         this->paramProjection = this->getParameterByName("u_Proj");
         this->paramView = this->getParameterByName("u_View");
diff --git a/src/dawntools/tools/CMakeLists.txt b/src/dawntools/tools/CMakeLists.txt
index d862041a..07e79cd9 100644
--- a/src/dawntools/tools/CMakeLists.txt
+++ b/src/dawntools/tools/CMakeLists.txt
@@ -8,7 +8,6 @@ add_subdirectory(tilesetgen)
 add_subdirectory(truetypegen)
 add_subdirectory(uigen)
 add_subdirectory(languagegen)
-add_subdirectory(audiogen)
 add_subdirectory(generatedlanguages)
 add_subdirectory(sceneitemcomponentregister)
 
@@ -89,14 +88,18 @@ function(tool_language target in)
 endfunction()
 
 # Audio Tool
-function(tool_audio target in)
-  add_custom_target(${target}
-    COMMAND audiogen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_ASSETS_BUILD_DIR}/${target}"
-    COMMENT "Generating audio ${target} from ${in}"
-    DEPENDS audiogen
-  )
-  add_dependencies(${DAWN_TARGET_NAME} ${target})
-endfunction()
+if(DAWN_TARGET_OPENAL)
+  add_subdirectory(audiogen)
+
+  function(tool_audio target in)
+    add_custom_target(${target}
+      COMMAND audiogen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_ASSETS_BUILD_DIR}/${target}"
+      COMMENT "Generating audio ${target} from ${in}"
+      DEPENDS audiogen
+    )
+    add_dependencies(${DAWN_TARGET_NAME} ${target})
+  endfunction()
+endif()
 
 # Scene Item Component Tool
 function(tool_scenecomponent clazz hfile)
diff --git a/src/dawnvita/CMakeLists.txt b/src/dawnvita/CMakeLists.txt
index 3e89a352..16fc4f4f 100644
--- a/src/dawnvita/CMakeLists.txt
+++ b/src/dawnvita/CMakeLists.txt
@@ -3,14 +3,6 @@
 # This software is released under the MIT License.
 # https://opensource.org/licenses/MIT
 
-# Libraries
-target_link_libraries(${DAWN_TARGET_NAME}
-  SceLibKernel_stub
-  SceDisplay_stub
-  stdc++
-  pthread
-)
-
 # Includes
 target_include_directories(${DAWN_TARGET_NAME}
   PUBLIC
@@ -18,9 +10,18 @@ target_include_directories(${DAWN_TARGET_NAME}
 )
 
 # Platform variables
+target_compile_definitions(${DAWN_TARGET_NAME}
+  PUBLIC
+    DAWN_ASSET_BUILD_PREFIX="../../assets/"
+    DAWN_OPENGL_HLSL=true
+)
+
+set(DAWN_OPENGL_EXCLUDE_LIBRARIES true CACHE INTERNAL ${DAWN_CACHE_TARGET})
 
 # Subdirs
 add_subdirectory(host)
+add_subdirectory(input)
+add_subdirectory(time)
 
 # Toolchain
 include("$ENV{VITASDK}/share/vita.cmake" REQUIRED)
@@ -28,6 +29,32 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11" CACHE INTERNAL ${DAWN_CACHE_TARG
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" CACHE INTERNAL ${DAWN_CACHE_TARGET})
 set(VITA_MKSFOEX_FLAGS "${VITA_MKSFOEX_FLAGS} -d PARENTAL_LEVEL=1" CACHE INTERNAL ${DAWN_CACHE_TARGET})
 
+# Libraries
+target_link_libraries(${DAWN_TARGET_NAME}
+  PUBLIC
+    m
+    stdc++
+    vitaGL
+    mathneon
+    vitashark
+    kubridge_stub
+    SceAppMgr_stub
+    SceAudio_stub
+    SceCtrl_stub
+    SceCommonDialog_stub
+    SceDisplay_stub
+    SceKernelDmacMgr_stub
+    SceGxm_stub
+    SceShaccCg_stub
+    SceSysmodule_stub
+    ScePower_stub
+    SceTouch_stub
+    SceVshBridge_stub
+    SceIofilemgr_stub
+    SceShaccCgExt
+    libtaihen_stub.a
+)
+
 # VPK Packaging
 if(NOT DEFINED DAWN_VITA_APP_NAME)
 message(FATAL_ERROR "Please define DAWN_VITA_APP_NAME in your target.")
diff --git a/src/dawnhelloworld/HelloWorld.cpp b/src/dawnvita/dawnopengl.hpp
similarity index 85%
rename from src/dawnhelloworld/HelloWorld.cpp
rename to src/dawnvita/dawnopengl.hpp
index 55bff476..63185eda 100644
--- a/src/dawnhelloworld/HelloWorld.cpp
+++ b/src/dawnvita/dawnopengl.hpp
@@ -1,6 +1,7 @@
-// Copyright (c) 2023 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include <vitaGL.h>
\ No newline at end of file
diff --git a/src/dawnvita/debug/debug.hpp b/src/dawnvita/debug/debug.hpp
new file mode 100644
index 00000000..ecb51df6
--- /dev/null
+++ b/src/dawnvita/debug/debug.hpp
@@ -0,0 +1,44 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "debug/debug.hpp"
+#include <vitasdk.h>
+#include "dawnopengl.hpp"
+
+// Initialize sceMsgDialog widget with a given message text
+static int vitaMsgInit(const char *msg) {
+  SceMsgDialogUserMessageParam msg_param;
+  memset(&msg_param, 0, sizeof(msg_param));
+  msg_param.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_OK;
+  msg_param.msg = (SceChar8 *)msg;
+
+  SceMsgDialogParam param;
+  sceMsgDialogParamInit(&param);
+  _sceCommonDialogSetMagicNumber(&param.commonParam);
+  param.mode = SCE_MSG_DIALOG_MODE_USER_MSG;
+  param.userMsgParam = &msg_param;
+
+  return sceMsgDialogInit(&param);
+}
+
+// Gets current state for sceMsgDialog running widget
+static int vitaMsgGetResult(void) {
+  if(sceMsgDialogGetStatus() != SCE_COMMON_DIALOG_STATUS_FINISHED) return 0;
+  sceMsgDialogTerm();
+  return 1;
+}
+
+// Draws an error message on screen and force closes the app after user input
+template<typename... A>
+static void debugMessage(const char *fmt, A... args) {
+  char string[512];
+  sprintf(string, fmt, args...);
+  vitaMsgInit(string);
+  while(!vitaMsgGetResult()) {
+    glClear(GL_COLOR_BUFFER_BIT);
+    vglSwapBuffers(GL_TRUE);
+  }
+}
\ No newline at end of file
diff --git a/src/dawnvita/host/DawnHostVita.cpp b/src/dawnvita/host/DawnHostVita.cpp
index 33ef36f1..32e1c24f 100644
--- a/src/dawnvita/host/DawnHostVita.cpp
+++ b/src/dawnvita/host/DawnHostVita.cpp
@@ -4,24 +4,194 @@
 // https://opensource.org/licenses/MIT
 
 #include "DawnHostVita.hpp"
+#include "game/DawnGame.hpp"
+
+using namespace Dawn;
+
+void vitaTestCube() {
+  float colors[] = {1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0}; // Colors for a face
+  float vertices_front[] = {-0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f}; // Front Face
+  float vertices_back[] = {-0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f}; // Back Face
+  float vertices_left[] = {-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f}; // Left Face
+  float vertices_right[] = {0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f}; // Right Face
+  float vertices_top[] = {-0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f}; // Top Face
+  float vertices_bottom[] = {-0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f}; // Bottom Face
+
+  uint16_t indices[] = {
+    0, 1, 2, 1, 2, 3, // Front
+    4, 5, 6, 5, 6, 7, // Back
+    8, 9,10, 9,10,11, // Left
+    12,13,14,13,14,15, // Right
+    16,17,18,17,18,19, // Top
+    20,21,22,21,22,23  // Bottom
+  };
+
+  // Creating colors array for all faces
+  float color_array[12*6];
+  int i;
+  for (i=0;i<12*6;i++){
+  color_array[i] = colors[i % 12];
+  }
+
+  // Creating vertex array for all faces
+  float vertex_array[12*6];
+  memcpy(&vertex_array[12*0], &vertices_front[0], sizeof(float) * 12);
+  memcpy(&vertex_array[12*1], &vertices_back[0], sizeof(float) * 12);
+  memcpy(&vertex_array[12*2], &vertices_left[0], sizeof(float) * 12);
+  memcpy(&vertex_array[12*3], &vertices_right[0], sizeof(float) * 12);
+  memcpy(&vertex_array[12*4], &vertices_top[0], sizeof(float) * 12);
+  memcpy(&vertex_array[12*5], &vertices_bottom[0], sizeof(float) * 12);
+
+  // Setting clear color
+  glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
+
+  // Initializing mvp matrix with a perspective full screen matrix
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(90.0f, 960.f/544.0f, 0.01f, 100.0f);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glTranslatef(0.0f, 0.0f, -3.0f); // Centering the cube
+
+  // Enabling depth test
+  glEnable(GL_DEPTH_TEST);
+  glDepthFunc(GL_LESS);
+
+  // Main loop
+  for (;;){
+  // Clear color and depth buffers
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+  // Drawing our cube with vertex arrays
+  glEnableClientState(GL_VERTEX_ARRAY);
+  glEnableClientState(GL_COLOR_ARRAY);
+  glVertexPointer(3, GL_FLOAT, 0, vertex_array);
+  glColorPointer(3, GL_FLOAT, 0, color_array);
+  glRotatef(1.0f, 0.0f, 0.0f, 1.0f); // Rotating cube at each frame by 1 on axis x and axis w
+  glRotatef(0.5f, 0.0f, 1.0f, 0.0f); // Rotating cube at each frame by 0.5 on axis x and 1.0 on axis z
+  glDrawElements(GL_TRIANGLES, 6*6, GL_UNSIGNED_SHORT, indices);
+  glDisableClientState(GL_VERTEX_ARRAY);
+  glDisableClientState(GL_COLOR_ARRAY);
+
+  // Performing buffer swap
+  vglSwapBuffers(GL_FALSE);
+  }
+}
+
+
+DawnHost::DawnHost() {
+
+}
+
+int32_t DawnHost::init(DawnGame *game) {
+  this->game = game;
+
+  vglInit(0x800000);
+  vglWaitVblankStart(GL_TRUE);
+
+  // Override the defaults
+  game->renderManager.backBuffer.setSize(DAWN_VITA_WIDTH, DAWN_VITA_HEIGHT);
+
+  // Initialize the game
+  auto result = game->init();
+  if(result != DAWN_GAME_INIT_RESULT_SUCCESS) return result;
+
+  // Hard-Load the first scene assets.
+  if(game->scene != nullptr) {
+    auto assets = game->scene->getRequiredAssets();
+    game->assetManager.queueLoad(assets);
+    game->assetManager.syncLoad();
+    game->scene->stage();
+  }
+
+  return DAWN_HOST_INIT_RESULT_SUCCESS;
+}
+
+int32_t DawnHost::start(DawnGame *game) {
+  double_t time, newTime;
+  float_t fDelta;
+  int32_t updateResult;
+
+  // Main Render Loop 
+  time = 0.0f;
+	for(;;) {
+    // Determine the delta.
+    float_t fDelta = 1.0f / 60.0f;
+    time = newTime;
+
+    // Perform update
+    updateResult = this->update(game, fDelta);
+
+    // Did the update complete successfully?
+    if(updateResult == DAWN_HOST_UPDATE_RESULT_EXIT) {
+      break;
+    } else if(updateResult != DAWN_HOST_UPDATE_RESULT_SUCCESS) {
+      return updateResult;
+    }
+    
+		// Performing buffer swap
+		vglSwapBuffers(GL_FALSE);
+  }
+
+  return DAWN_HOST_START_RESULT_EXIT_SUCCESS;
+}
+
+int32_t DawnHost::update(DawnGame *game, float_t delta) {
+  // Tick game.
+  auto ret = game->update(delta);
+  switch(ret) {
+    case DAWN_GAME_UPDATE_RESULT_SUCCESS:
+      return DAWN_HOST_UPDATE_RESULT_SUCCESS;
+    
+    case DAWN_GAME_UPDATE_RESULT_EXIT:
+      return DAWN_HOST_UPDATE_RESULT_EXIT;
+
+    default:
+      return ret;
+  }
+}
+
+void DawnHost::unload(DawnGame *game) {
+  vglEnd();
+}
+
+DawnHost::~DawnHost() {
+}
+
 
 int main(int argc, char **args) {
-  // Success
-  std::stringstream output;
-	std::vector<std::string> hello = { "Hello" };
-	hello.push_back(",");
-	hello.push_back(" C++ ");
-	hello.push_back("world!");
-	for (auto &s : hello) {
-		// std::cout does't work ATM :(
-		output << s;
-	}
-	output << std::endl;
-	printf("%s\n", output.str().c_str());
+  int32_t result;
 
-  while(1) {
-    
+  // Create the host
+  auto host = new DawnHost();
+  auto game = new DawnGame(host);
+
+  // Initialize the host and error check
+  result = host->init(game);
+  switch(result) {
+    case DAWN_HOST_INIT_RESULT_SUCCESS:
+      break;
+    default:
+      return result;
   }
-	sceKernelExitProcess(0);
+
+  // Request the main loop to start running.
+  result = host->start(game);
+  switch(result) {
+    case DAWN_HOST_START_RESULT_SUCCESS:
+      break;
+    case DAWN_HOST_START_RESULT_EXIT_SUCCESS:
+      break;
+    default:
+      return result;
+  }
+
+  // Main loop finished without errors, cleanup
+  host->unload(game);
+
+  delete game;
+  delete host;
+
+  // Success
   return 0;
 }
\ No newline at end of file
diff --git a/src/dawnvita/host/DawnHostVita.hpp b/src/dawnvita/host/DawnHostVita.hpp
index 38de107a..2a3bb0a7 100644
--- a/src/dawnvita/host/DawnHostVita.hpp
+++ b/src/dawnvita/host/DawnHostVita.hpp
@@ -4,10 +4,19 @@
 // https://opensource.org/licenses/MIT
 
 #pragma once
-#include <sstream>
-#include <vector>
-#include <cstdio>
-#include <psp2/kernel/processmgr.h>
+#include "dawnopengl.hpp"
+#include "dawnlibs.hpp"
+#include "host/DawnHost.hpp"
+#include "debug/debug.hpp"
+
+#define DAWN_VITA_WIDTH 960
+#define DAWN_VITA_HEIGHT 540
+
+namespace Dawn {
+  class DawnHostData {
+    void *nothing;
+  };
+}
 
 /**
  * Main entry function received by parent Win32 Operating System.
diff --git a/src/dawnvita/input/CMakeLists.txt b/src/dawnvita/input/CMakeLists.txt
new file mode 100644
index 00000000..906c8ca6
--- /dev/null
+++ b/src/dawnvita/input/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2022 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    InputManager.cpp
+)
\ No newline at end of file
diff --git a/src/dawnvita/input/InputManager.cpp b/src/dawnvita/input/InputManager.cpp
new file mode 100644
index 00000000..634e32a8
--- /dev/null
+++ b/src/dawnvita/input/InputManager.cpp
@@ -0,0 +1,20 @@
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "InputManager.hpp"
+#include "game/DawnGame.hpp"
+
+using namespace Dawn;
+
+InputManager::InputManager(DawnGame *game) : IInputManager<int32_t>(game) {
+
+}
+
+float_t InputManager::getInputValue(int32_t axis) {
+  auto exist = this->rawInputValues.find(axis);
+  if(exist == this->rawInputValues.end()) return 0.0f;
+  
+  return exist->second;
+}
\ No newline at end of file
diff --git a/src/dawnvita/input/InputManager.hpp b/src/dawnvita/input/InputManager.hpp
new file mode 100644
index 00000000..cf755acf
--- /dev/null
+++ b/src/dawnvita/input/InputManager.hpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "input/_InputManager.hpp"
+
+namespace Dawn {
+  class InputManager : public IInputManager<int32_t> {
+    protected:
+      float_t getInputValue(int32_t axis) override;
+
+    public:
+      std::map<int32_t, float_t> rawInputValues;
+
+      InputManager(DawnGame *game);
+  };
+}
\ No newline at end of file
diff --git a/src/dawnvita/time/CMakeLists.txt b/src/dawnvita/time/CMakeLists.txt
new file mode 100644
index 00000000..97241518
--- /dev/null
+++ b/src/dawnvita/time/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2022 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    TimeManager.cpp
+)
\ No newline at end of file
diff --git a/src/dawnvita/time/TimeManager.cpp b/src/dawnvita/time/TimeManager.cpp
new file mode 100644
index 00000000..de9a0f01
--- /dev/null
+++ b/src/dawnvita/time/TimeManager.cpp
@@ -0,0 +1,16 @@
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "TimeManager.hpp"
+
+using namespace Dawn;
+
+TimeManager::TimeManager() : ITimeManager() {
+
+}
+
+int64_t TimeManager::getTimestamp() {
+  return (int64_t)std::time(nullptr);
+}
\ No newline at end of file
diff --git a/src/dawnvita/time/TimeManager.hpp b/src/dawnvita/time/TimeManager.hpp
new file mode 100644
index 00000000..5db481a9
--- /dev/null
+++ b/src/dawnvita/time/TimeManager.hpp
@@ -0,0 +1,15 @@
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "time/ITimeManager.hpp"
+
+namespace Dawn {
+  class TimeManager : public ITimeManager {
+    public:
+      TimeManager();
+      int64_t getTimestamp() override;
+  };
+}
\ No newline at end of file