diff --git a/olcCodeJam2023Entry.sln b/olcCodeJam2023Entry.sln
new file mode 100644
index 0000000..779dc01
--- /dev/null
+++ b/olcCodeJam2023Entry.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33516.290
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "olcCodeJam2023Entry", "olcCodeJam2023Entry\olcCodeJam2023Entry.vcxproj", "{FA5243BE-6446-44B1-ADE6-EB26118F6B3E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x64.ActiveCfg = Debug|x64
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x64.Build.0 = Debug|x64
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x86.ActiveCfg = Debug|Win32
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Debug|x86.Build.0 = Debug|Win32
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x64.ActiveCfg = Release|x64
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x64.Build.0 = Release|x64
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x86.ActiveCfg = Release|Win32
+ {FA5243BE-6446-44B1-ADE6-EB26118F6B3E}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {59D77397-F63B-47B2-B936-7BB19452CD50}
+ EndGlobalSection
+EndGlobal
diff --git a/olcCodeJam2023Entry/VirusAttack.cpp b/olcCodeJam2023Entry/VirusAttack.cpp
new file mode 100644
index 0000000..4edb02b
--- /dev/null
+++ b/olcCodeJam2023Entry/VirusAttack.cpp
@@ -0,0 +1,32 @@
+#define OLC_PGE_APPLICATION
+#include "olcPixelGameEngine.h"
+#define OLC_SOUNDWAVE
+#include "olcSoundWaveEngine.h"
+#include "VirusAttack.h"
+
+VirusAttack::VirusAttack()
+{
+ // Name your application
+ sAppName = "olcCodeJam 2023 Entry";
+}
+
+bool VirusAttack::OnUserCreate(){
+ // Called once at the start, so create things here
+ return true;
+}
+
+bool VirusAttack::OnUserUpdate(float fElapsedTime){
+ // Called once per frame, draws random coloured pixels
+ for (int x = 0; x < ScreenWidth(); x++)
+ for (int y = 0; y < ScreenHeight(); y++)
+ Draw(x, y, olc::Pixel(rand() % 256, rand() % 256, rand() % 256));
+ return true;
+}
+
+int main()
+{
+ VirusAttack app;
+ if (app.Construct(256, 240, 4, 4))
+ app.Start();
+ return 0;
+}
\ No newline at end of file
diff --git a/olcCodeJam2023Entry/VirusAttack.h b/olcCodeJam2023Entry/VirusAttack.h
new file mode 100644
index 0000000..1aca66e
--- /dev/null
+++ b/olcCodeJam2023Entry/VirusAttack.h
@@ -0,0 +1,13 @@
+#include "olcPixelGameEngine.h"
+#include "olcSoundWaveEngine.h"
+
+class VirusAttack : public olc::PixelGameEngine
+{
+public:
+ VirusAttack();
+
+public:
+ bool OnUserCreate() override;
+
+ bool OnUserUpdate(float fElapsedTime) override;
+};
\ No newline at end of file
diff --git a/olcCodeJam2023Entry/assets/MAINICON.ico b/olcCodeJam2023Entry/assets/MAINICON.ico
new file mode 100644
index 0000000..fb37210
Binary files /dev/null and b/olcCodeJam2023Entry/assets/MAINICON.ico differ
diff --git a/olcCodeJam2023Entry/assets/Vast Horizons.wav b/olcCodeJam2023Entry/assets/Vast Horizons.wav
new file mode 100644
index 0000000..5e8e58d
Binary files /dev/null and b/olcCodeJam2023Entry/assets/Vast Horizons.wav differ
diff --git a/olcCodeJam2023Entry/emscripten_build.ps1 b/olcCodeJam2023Entry/emscripten_build.ps1
new file mode 100644
index 0000000..da29d72
--- /dev/null
+++ b/olcCodeJam2023Entry/emscripten_build.ps1
@@ -0,0 +1,2 @@
+~\Documents\emsdk\emsdk_env.ps1 activate latest
+em++ -std=c++20 -gsource-map -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1 -s USE_SDL_MIXER=2 $(Get-ChildItem *.cpp) -o pge.html --preload-file assets
\ No newline at end of file
diff --git a/olcCodeJam2023Entry/icon.png b/olcCodeJam2023Entry/icon.png
new file mode 100644
index 0000000..d9c3b3e
Binary files /dev/null and b/olcCodeJam2023Entry/icon.png differ
diff --git a/olcCodeJam2023Entry/olcCodeJam2023Entry.rc b/olcCodeJam2023Entry/olcCodeJam2023Entry.rc
new file mode 100644
index 0000000..fdb2919
Binary files /dev/null and b/olcCodeJam2023Entry/olcCodeJam2023Entry.rc differ
diff --git a/olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj b/olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
new file mode 100644
index 0000000..a4e3b34
--- /dev/null
+++ b/olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj
@@ -0,0 +1,158 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {fa5243be-6446-44b1-ade6-eb26118f6b3e}
+ olcCodeJam2023Entry
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters b/olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters
new file mode 100644
index 0000000..05d87c1
--- /dev/null
+++ b/olcCodeJam2023Entry/olcCodeJam2023Entry.vcxproj.filters
@@ -0,0 +1,67 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/olcCodeJam2023Entry/olcPGEX_PopUpMenu.h b/olcCodeJam2023Entry/olcPGEX_PopUpMenu.h
new file mode 100644
index 0000000..860b55f
--- /dev/null
+++ b/olcCodeJam2023Entry/olcPGEX_PopUpMenu.h
@@ -0,0 +1,585 @@
+/*
+ olcPGEX_PopUp.h
+
+ +-------------------------------------------------------------+
+ | OneLoneCoder Pixel Game Engine Extension |
+ | Retro PopUp Menu 1.0 |
+ +-------------------------------------------------------------+
+
+ What is this?
+ ~~~~~~~~~~~~~
+ This is an extension to the olcPixelGameEngine, which provides
+ a quick and easy to use, flexible, skinnable context pop-up
+ menu system.
+
+ License (OLC-3)
+ ~~~~~~~~~~~~~~~
+
+ Copyright 2018 - 2020 OneLoneCoder.com
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions or derivations of source code must retain the above
+ copyright notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions or derivative works in binary form must reproduce
+ the above copyright notice. This list of conditions and the following
+ disclaimer must be reproduced in the documentation and/or other
+ materials provided with the distribution.
+
+ 3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Links
+ ~~~~~
+ YouTube: https://www.youtube.com/javidx9
+ Discord: https://discord.gg/WhwHUMV
+ Twitter: https://www.twitter.com/javidx9
+ Twitch: https://www.twitch.tv/javidx9
+ GitHub: https://www.github.com/onelonecoder
+ Homepage: https://www.onelonecoder.com
+
+ Author
+ ~~~~~~
+ David Barr, aka javidx9, ©OneLoneCoder 2019, 2020
+*/
+
+
+/*
+ Example
+ ~~~~~~~
+
+ #define OLC_PGEX_POPUPMENU
+ #include "olcPGEX_PopUpMenu.h"
+
+ NOTE: Requires a 9-patch sprite, by default each patch is
+ 8x8 pixels, patches are as follows:
+
+ | PANEL TL | PANEL T | PANEL TR | SCROLL UP | CURSOR TL | CURSOR TR |
+ | PANEL L | PANEL M | PANEL R | SUBMENU | CURSOR BL | CURSOR BR |
+ | PANEL BL | PANEL B | PANEL BR | SCROLL DOWN | UNUSED | UNUSED |
+
+ You can find an example sprite here:
+ https://github.com/OneLoneCoder/olcPixelGameEngine/blob/master/Videos/RetroMenu.png
+
+ Constructing A Menu
+ ~~~~~~~~~~~~~~~~~~~
+
+ // Declaration (presumably inside class)
+ olc::popup::Menu m;
+
+ // Construction (root menu is a 1x5 table)
+ m.SetTable(1, 5);
+
+ // Add first item to root menu (A 1x5 submenu)
+ m["Menu1"].SetTable(1, 5);
+
+ // Add items to first item
+ m["Menu1"]["Item1"];
+ m["Menu1"]["Item2"];
+
+ // Add a 4x3 submenu
+ m["Menu1"]["Item3"].SetTable(4, 3);
+ m["Menu1"]["Item3"]["Option1"];
+ m["Menu1"]["Item3"]["Option2"];
+
+ // Set properties of specific item
+ m["Menu1"]["Item3"]["Option3"].Enable(false);
+ m["Menu1"]["Item3"]["Option4"];
+ m["Menu1"]["Item3"]["Option5"];
+ m["Menu1"]["Item4"];
+
+ // Add second item to root menu
+ m["Menu2"].SetTable(3, 3);
+ m["Menu2"]["Item1"];
+ m["Menu2"]["Item2"].SetID(1001).Enable(true);
+ m["Menu2"]["Item3"];
+
+ // Construct the menu structure
+ m.Build();
+
+
+ Displaying a Menu
+ ~~~~~~~~~~~~~~~~~
+
+ // Declaration of menu manager (presumably inside class)
+ olc::popup::Manager man;
+
+ // Set the Menu object to the MenuManager (call once per pop)
+ man.Open(&m);
+
+ // Draw Menu at position (30, 30), using "patch sprite"
+ man.Draw(sprGFX, { 30,30 });
+
+
+ Interacting with menu
+ ~~~~~~~~~~~~~~~~~~~~~
+
+ // Send key events to menu
+ if (GetKey(olc::Key::UP).bPressed) man.OnUp();
+ if (GetKey(olc::Key::DOWN).bPressed) man.OnDown();
+ if (GetKey(olc::Key::LEFT).bPressed) man.OnLeft();
+ if (GetKey(olc::Key::RIGHT).bPressed) man.OnRight();
+ if (GetKey(olc::Key::Z).bPressed) man.OnBack();
+
+ // "Confirm/Action" Key does something, if it returns non-null
+ // then a menu item has been selected. The specific item will
+ // be returned
+ olc::popup::Menu* command = nullptr;
+ if (GetKey(olc::Key::SPACE).bPressed) command = man.OnConfirm();
+ if (command != nullptr)
+ {
+ std::string sLastAction =
+ "Selected: " + command->GetName() +
+ " ID: " + std::to_string(command->GetID());
+
+ // Optionally close menu?
+ man.Close();
+ }
+
+*/
+
+#ifndef OLC_PGEX_POPUPMENU_H
+#define OLC_PGEX_POPUPMENU_H
+
+#include
+
+namespace olc
+{
+ namespace popup
+ {
+ constexpr int32_t nPatch = 8;
+
+ class Menu
+ {
+ public:
+ Menu();
+ Menu(const std::string n);
+
+ Menu& SetTable(int32_t nColumns, int32_t nRows);
+ Menu& SetID(int32_t id);
+ Menu& Enable(bool b);
+
+ int32_t GetID();
+ std::string& GetName();
+ bool Enabled();
+ bool HasChildren();
+ olc::vi2d GetSize();
+ olc::vi2d& GetCursorPosition();
+ Menu& operator[](const std::string& name);
+ void Build();
+ void DrawSelf(olc::PixelGameEngine& pge, olc::Sprite* sprGFX, olc::vi2d vScreenOffset);
+ void ClampCursor();
+ void OnUp();
+ void OnDown();
+ void OnLeft();
+ void OnRight();
+ Menu* OnConfirm();
+ Menu* GetSelectedItem();
+
+ protected:
+ int32_t nID = -1;
+ olc::vi2d vCellTable = { 1, 0 };
+ std::unordered_map itemPointer;
+ std::vector items;
+ olc::vi2d vSizeInPatches = { 0, 0 };
+ olc::vi2d vCellSize = { 0, 0 };
+ olc::vi2d vCellPadding = { 2, 0 };
+ olc::vi2d vCellCursor = { 0, 0 };
+ int32_t nCursorItem = 0;
+ int32_t nTopVisibleRow = 0;
+ int32_t nTotalRows = 0;
+ const olc::vi2d vPatchSize = { nPatch, nPatch };
+ std::string sName;
+ olc::vi2d vCursorPos = { 0, 0 };
+ bool bEnabled = true;
+ };
+
+ class Manager : public olc::PGEX
+ {
+ public:
+ Manager();
+ void Open(Menu* mo);
+ void Close();
+ void OnUp();
+ void OnDown();
+ void OnLeft();
+ void OnRight();
+ void OnBack();
+ Menu* OnConfirm();
+ void Draw(olc::Sprite* sprGFX, olc::vi2d vScreenOffset);
+
+ private:
+ std::list