From 0a1fe61c8ceb9622cb62849a358a193ec800813b Mon Sep 17 00:00:00 2001 From: Jesse Freeman Date: Sun, 21 Feb 2021 10:39:03 -0500 Subject: [PATCH] Adding a VS Solution file, Unit Tests, fixes to the Settings Tool for new APIS, and removing old sprite drawing APIs. --- .../Libs/pixel-vision-os-clipboard-v2.lua | 2 +- .../Libs/pixel-vision-os-message-modal-v3.lua | 161 - .../Libs/pixel-vision-os-message-modal-v4.lua | 2 +- .../System/Libs/pixel-vision-os-v2.lua | 2 +- .../System/Libs/pixel-vision-ui-knob-v2.lua | 228 - .../System/Libs/pixel-vision-ui-knob-v3.lua | 17 +- .../System/Libs/pixel-vision-ui-slider-v3.lua | 190 - .../SettingsTool/code-controller-panel.lua | 59 +- .../SettingsTool/code-drop-down-menu.lua | 37 +- .../Tools/SettingsTool/code-settings-tool.lua | 6 +- .../System/Tools/SettingsTool/color-map.png | Bin 1135 -> 0 bytes .../System/Tools/SettingsTool/colors.png | Bin 2130 -> 257 bytes .../System/Tools/SettingsTool/data.json | 64 +- .../Tools/SettingsTool/meta-sprites.json | 152 +- .../System/Tools/SettingsTool/sb-sprites.lua | 83 - .../System/Tools/SettingsTool/sprites.png | Bin 6879 -> 9740 bytes .../System/Tools/SettingsTool/tilemap.json | 13869 +--------------- .../Tools/WorkspaceTool/code-window.lua | 2 +- .../System/Tools/WorkspaceTool/color-map.png | Bin 1135 -> 0 bytes PixelVision8.CoreDesktop.csproj | 2 +- PixelVision8.sln | 22 + .../Export/SpriteBuilder/action-btn-down.png | Bin 0 -> 164 bytes .../SpriteBuilder/checkbox-disabled.png | Bin 0 -> 126 bytes .../Export/SpriteBuilder/checkbox-over.png | Bin 0 -> 189 bytes .../SpriteBuilder/checkbox-selected-over.png | Bin 0 -> 181 bytes .../SpriteBuilder/checkbox-selected-up.png | Bin 0 -> 215 bytes .../Export/SpriteBuilder/checkbox-up.png | Bin 0 -> 146 bytes .../Export/SpriteBuilder/controller-1.png | Bin 0 -> 225 bytes .../Export/SpriteBuilder/controller-2.png | Bin 0 -> 248 bytes .../SpriteBuilder/controller-selected.png | Bin 0 -> 221 bytes .../Export/SpriteBuilder/controller-up.png | Bin 0 -> 236 bytes .../Export/SpriteBuilder/cursor-hand-down.png | Bin 0 -> 247 bytes .../Export/SpriteBuilder/cursor-hand.png | Bin 0 -> 261 bytes .../Export/SpriteBuilder/cursor-help.png | Bin 0 -> 233 bytes .../Export/SpriteBuilder/cursor-pointer.png | Bin 0 -> 274 bytes .../Export/SpriteBuilder/cursor-text.png | Bin 0 -> 234 bytes .../Export/SpriteBuilder/d-pad-down.png | Bin 0 -> 257 bytes .../Export/SpriteBuilder/d-pad-left.png | Bin 0 -> 330 bytes .../Export/SpriteBuilder/d-pad-right.png | Bin 0 -> 250 bytes .../Export/SpriteBuilder/d-pad-up.png | Bin 0 -> 282 bytes .../Export/SpriteBuilder/input-button-on.png | Bin 0 -> 122 bytes .../SpriteBuilder/keyboard-selected.png | Bin 0 -> 232 bytes .../Export/SpriteBuilder/keyboard-up.png | Bin 0 -> 219 bytes .../Export/SpriteBuilder/knob-100.png | Bin 0 -> 316 bytes .../Export/SpriteBuilder/knob-110.png | Bin 0 -> 311 bytes .../Export/SpriteBuilder/knob-120.png | Bin 0 -> 312 bytes .../Export/SpriteBuilder/knob-130.png | Bin 0 -> 303 bytes .../Export/SpriteBuilder/knob-140.png | Bin 0 -> 299 bytes .../Export/SpriteBuilder/knob-150.png | Bin 0 -> 307 bytes .../Export/SpriteBuilder/knob-160.png | Bin 0 -> 318 bytes .../Export/SpriteBuilder/knob-170.png | Bin 0 -> 318 bytes .../Export/SpriteBuilder/knob-180.png | Bin 0 -> 315 bytes .../Export/SpriteBuilder/knob-190.png | Bin 0 -> 325 bytes .../Export/SpriteBuilder/knob-200.png | Bin 0 -> 319 bytes .../Export/SpriteBuilder/knob-210.png | Bin 0 -> 309 bytes .../Export/SpriteBuilder/knob-220.png | Bin 0 -> 299 bytes .../Export/SpriteBuilder/knob-230.png | Bin 0 -> 300 bytes .../Export/SpriteBuilder/knob-240.png | Bin 0 -> 317 bytes .../Export/SpriteBuilder/knob-250.png | Bin 0 -> 315 bytes .../Export/SpriteBuilder/knob-260.png | Bin 0 -> 316 bytes .../Export/SpriteBuilder/knob-270.png | Bin 0 -> 308 bytes .../Export/SpriteBuilder/knob-280.png | Bin 0 -> 314 bytes .../Export/SpriteBuilder/knob-290.png | Bin 0 -> 314 bytes .../Export/SpriteBuilder/knob-30.png | Bin 0 -> 315 bytes .../Export/SpriteBuilder/knob-300.png | Bin 0 -> 308 bytes .../Export/SpriteBuilder/knob-310.png | Bin 0 -> 306 bytes .../Export/SpriteBuilder/knob-320.png | Bin 0 -> 304 bytes .../Export/SpriteBuilder/knob-330.png | Bin 0 -> 311 bytes .../Export/SpriteBuilder/knob-40.png | Bin 0 -> 306 bytes .../Export/SpriteBuilder/knob-50.png | Bin 0 -> 304 bytes .../Export/SpriteBuilder/knob-60.png | Bin 0 -> 313 bytes .../Export/SpriteBuilder/knob-70.png | Bin 0 -> 315 bytes .../Export/SpriteBuilder/knob-80.png | Bin 0 -> 317 bytes .../Export/SpriteBuilder/knob-90.png | Bin 0 -> 308 bytes .../modal-cancel-button-over.png | Bin 0 -> 270 bytes .../SpriteBuilder/modal-cancel-button-up.png | Bin 0 -> 262 bytes .../SpriteBuilder/modal-ok-button-over.png | Bin 0 -> 236 bytes .../SpriteBuilder/modal-ok-button-up.png | Bin 0 -> 237 bytes .../SpriteBuilder/player-1-selected.png | Bin 0 -> 213 bytes .../Export/SpriteBuilder/player-1-up.png | Bin 0 -> 220 bytes .../SpriteBuilder/player-2-selected.png | Bin 0 -> 213 bytes .../Export/SpriteBuilder/player-2-up.png | Bin 0 -> 222 bytes .../SpriteBuilder/pv8-tool-bar-icon-up.png | Bin 0 -> 174 bytes .../SpriteBuilder/pv8-toolbar-icon-down.png | Bin 0 -> 163 bytes .../SpriteBuilder/radio-button-disabled.png | Bin 0 -> 112 bytes .../SpriteBuilder/radio-button-over.png | Bin 0 -> 134 bytes .../radio-button-selected-over.png | Bin 0 -> 144 bytes .../radio-button-selected-up.png | Bin 0 -> 144 bytes .../Export/SpriteBuilder/radio-button-up.png | Bin 0 -> 134 bytes .../Export/SpriteBuilder/start-btn-down.png | Bin 0 -> 129 bytes .../Export/SpriteBuilder/start-input-on.png | Bin 0 -> 116 bytes .../SpriteBuilder/titlebar-volume-off.png | Bin 0 -> 114 bytes .../SpriteBuilder/titlebar-volume-on.png | Bin 0 -> 109 bytes .../SpriteBuilder/toolbar-icon-tool.png | Bin 0 -> 134 bytes .../Tools/SettingsTool/Export/sprites.png | Bin 0 -> 9125 bytes .../Tools/SettingsTool/Export/tilemap.png | Bin 0 -> 4235 bytes .../SettingsTool/settings-tool-design-v1.ase | Bin 16000 -> 16740 bytes SDK/Editor/Exporters/ZipExporter.cs | 4 +- SDK/Lua/Chips/Game/LuaGameChip.cs | 20 +- SDK/Player/Chips/Game/GameChip.Draw.cs | 10 +- SDK/Runner/Parsers/Loader.cs | 2 +- SDK/Runner/Parsers/SystemParser.cs | 8 +- SDK/Runner/Services/LogService.cs | 2 +- Tests/PixelVisoin8.Tests.csproj | 19 + Tests/SDK/ColorChip.Test.cs | 658 + Tests/SDK/PixelData.Test.cs | 315 + Tests/SDK/PixelDataUtilities.DataSets.cs | 378 + Tests/SDK/PixelDataUtilities.Test.cs | 682 + .../PixelDataUtiltities.Performance.Test.cs | 190 + Tests/SDK/PixelVision.Test.cs | 201 + 110 files changed, 2672 insertions(+), 14715 deletions(-) delete mode 100755 Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v3.lua delete mode 100755 Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v2.lua delete mode 100755 Disks/PixelVisionOS/System/Libs/pixel-vision-ui-slider-v3.lua delete mode 100755 Disks/PixelVisionOS/System/Tools/SettingsTool/color-map.png mode change 100755 => 100644 Disks/PixelVisionOS/System/Tools/SettingsTool/colors.png delete mode 100755 Disks/PixelVisionOS/System/Tools/SettingsTool/sb-sprites.lua mode change 100755 => 100644 Disks/PixelVisionOS/System/Tools/SettingsTool/sprites.png mode change 100755 => 100644 Disks/PixelVisionOS/System/Tools/SettingsTool/tilemap.json delete mode 100755 Disks/PixelVisionOS/System/Tools/WorkspaceTool/color-map.png create mode 100644 PixelVision8.sln create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/action-btn-down.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-disabled.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-over.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-selected-over.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-selected-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-1.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-2.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-selected.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-hand-down.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-hand.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-help.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-pointer.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-text.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-down.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-left.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-right.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/input-button-on.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/keyboard-selected.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/keyboard-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-100.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-110.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-120.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-130.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-140.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-150.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-160.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-170.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-180.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-190.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-200.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-210.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-220.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-230.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-240.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-250.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-260.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-270.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-280.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-290.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-30.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-300.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-310.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-320.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-330.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-40.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-50.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-60.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-70.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-80.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-90.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-cancel-button-over.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-cancel-button-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-ok-button-over.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-ok-button-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/player-1-selected.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/player-1-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/player-2-selected.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/player-2-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/pv8-tool-bar-icon-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/pv8-toolbar-icon-down.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-disabled.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-over.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-selected-over.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-selected-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-up.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/start-btn-down.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/start-input-on.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/titlebar-volume-off.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/titlebar-volume-on.png create mode 100644 Resources/Tools/SettingsTool/Export/SpriteBuilder/toolbar-icon-tool.png create mode 100644 Resources/Tools/SettingsTool/Export/sprites.png create mode 100644 Resources/Tools/SettingsTool/Export/tilemap.png create mode 100644 Tests/PixelVisoin8.Tests.csproj create mode 100644 Tests/SDK/ColorChip.Test.cs create mode 100644 Tests/SDK/PixelData.Test.cs create mode 100644 Tests/SDK/PixelDataUtilities.DataSets.cs create mode 100644 Tests/SDK/PixelDataUtilities.Test.cs create mode 100644 Tests/SDK/PixelDataUtiltities.Performance.Test.cs create mode 100644 Tests/SDK/PixelVision.Test.cs diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-clipboard-v2.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-clipboard-v2.lua index edd7fa95..7fea4f5b 100755 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-clipboard-v2.lua +++ b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-clipboard-v2.lua @@ -15,7 +15,7 @@ -- Shawn Rakowski - @shwany -- -print("Enable clipboard") +-- print("Enable clipboard") function PixelVisionOS:SystemCopy(data) diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v3.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v3.lua deleted file mode 100755 index c28e977f..00000000 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v3.lua +++ /dev/null @@ -1,161 +0,0 @@ -MessageModal = {} -MessageModal.__index = MessageModal - -function MessageModal:Init(title, message, width, showCancel, okButtonSpriteName, cancelButtonSpriteName) - - local _messageModal = {} -- our new object - setmetatable(_messageModal, MessageModal) -- make Account handle lookup - - _messageModal:Configure(title, message, width, showCancel, okButtonSpriteName, cancelButtonSpriteName) - - return _messageModal - -end - -function MessageModal:Configure(title, message, width, showCancel, okButtonSpriteName, cancelButtonSpriteName) - - self.showCancel = showCancel or false - - self.okButtonSpriteName = okButtonSpriteName or "ok" - self.cancelButtonSpriteName = cancelButtonSpriteName or "cancel" - -- Reset the modal so it redraws correctly when opened - self.firstRun = nil - - width = width or 96 - - -- Need to calculate the height ahead of time - -- Draw message text - local wrap = WordWrap(message, (width / 4) - 4) - self.lines = SplitLines(wrap) - - height = #self.lines * 8 + 42 - - -- Make sure width and height are on the grid - width = math.floor(width / 8) * 8 - height = math.floor(height / 8) * 8 - - self.canvas = NewCanvas(width, height) - - local displaySize = Display() - - self.title = title or "Message Modal" - - self.rect = { - x = math.floor(((displaySize.x - width) * .5) / 8) * 8, - y = math.floor(((displaySize.y - height) * .5) / 8) * 8, - w = width, - h = height - } - - self.selectionValue = false - -end - -function MessageModal:Open() - - if(self.firstRun == nil) then - - -- Draw the black background - self.canvas:SetStroke(5, 1) - self.canvas:SetPattern({0}, 1, 1) - self.canvas:DrawRectangle(0, 0, self.canvas.width, self.canvas.height, true) - - -- Draw the brown background - self.canvas:SetStroke(12, 1) - self.canvas:SetPattern({11}, 1, 1) - self.canvas:DrawRectangle(3, 9, self.canvas.width - 6, self.canvas.height - 12, true) - - local tmpX = (self.canvas.width - (#self.title * 4)) * .5 - - self.canvas:DrawText(self.title:upper(), tmpX, 1, "small", 15, - 4) - - -- draw highlight stroke - self.canvas:SetStroke(15, 1) - self.canvas:DrawLine(3, 9, self.canvas.width - 5, 9) - self.canvas:DrawLine(3, 9, 3, self.canvas.height - 5) - - local total = #self.lines - local startX = 8 - local startY = 16 - - -- We want to render the text from the bottom of the screen so we offset it and loop backwards. - for i = 1, total do - self.canvas:DrawText(self.lines[i]:upper(), startX, (startY + ((i - 1) * 8)), "medium", 0, - 4) - end - - self.buttons = {} - - local buttonSize = {x = 32, y = 16} - - -- TODO center ok button when no cancel button is shown - local bX = self.showCancel == true and (self.rect.w - buttonSize.x - 8) or ((self.rect.w - buttonSize.x) * .5) - - -- snap the x value to the grid - bX = math.floor((bX + self.rect.x) / 8) * 8 - - -- Fix the button to the bottom of the window - local bY = math.floor(((self.rect.y + self.rect.h) - buttonSize.y - 8) / 8) * 8 - - local backBtnData = editorUI:CreateButton({x = bX, y = bY}, "modal".. self.okButtonSpriteName .. "button", "") - - backBtnData.onAction = function() - - -- Set value to true when ok is pressed - self.selectionValue = true - - if(self.onParentClose ~= nil) then - self.onParentClose() - end - end - - table.insert(self.buttons, backBtnData) - - if(self.showCancel) then - - -- Offset the bX value and snap to the grid - bX = math.floor((bX - buttonSize.x - 8) / 8) * 8 - - local cancelBtnData = editorUI:CreateButton({x = bX, y = bY}, "modal".. self.cancelButtonSpriteName .. "button", "") - - cancelBtnData.onAction = function() - - -- Set value to true when cancel is pressed - self.selectionValue = false - - -- Close the panel - if(self.onParentClose ~= nil) then - self.onParentClose() - end - end - - table.insert(self.buttons, cancelBtnData) - - end - - self.firstRun = false; - - end - - for i = 1, #self.buttons do - editorUI:Invalidate(self.buttons[i]) - end - - self.canvas:DrawPixels(self.rect.x, self.rect.y, DrawMode.TilemapCache) - -end - -function MessageModal:Update(timeDelta) - - for i = 1, #self.buttons do - editorUI:UpdateButton(self.buttons[i]) - end - - if(Key(Keys.Enter, InputState.Released)) then - self.selectionValue = true - self.onParentClose() - elseif(Key(Keys.Escape, InputState.Released) and self.showCancel) then - self.selectionValue = false - self.onParentClose() - end - -end diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v4.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v4.lua index 16f0cf4f..c0aae797 100755 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v4.lua +++ b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-message-modal-v4.lua @@ -79,7 +79,7 @@ function MessageModal:Open() -- We want to render the text from the bottom of the screen so we offset it and loop backwards. for i = 1, total do - self.canvas:DrawText(self.lines[i]:upper(), startX, (startY + ((i - 1) * 8)), "medium", 0, - 4) + self.canvas:DrawText(self.lines[i], startX, (startY + ((i - 1) * 8)), "medium", 0, - 4) end self.buttons = {} diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-v2.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-v2.lua index f210d3dc..4d6cc3fc 100755 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-os-v2.lua +++ b/Disks/PixelVisionOS/System/Libs/pixel-vision-os-v2.lua @@ -24,7 +24,7 @@ LoadScript("pixel-vision-ui-v2") LoadScript("pixel-vision-os-title-bar-v2") LoadScript("pixel-vision-os-message-bar-v2") LoadScript("pixel-vision-os-modal-v2") -LoadScript("pixel-vision-os-message-modal-v3") +LoadScript("pixel-vision-os-message-modal-v4") LoadScript("pixel-vision-os-color-utils-v2") LoadScript("pixel-vision-os-undo-v2") LoadScript("pixel-vision-os-clipboard-v2") diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v2.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v2.lua deleted file mode 100755 index b38a00b6..00000000 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v2.lua +++ /dev/null @@ -1,228 +0,0 @@ --- --- Copyright (c) 2017, Jesse Freeman. All rights reserved. --- --- Licensed under the Microsoft Public License (MS-PL) License. --- See LICENSE file in the project root for full license information. --- --- Contributors --- -------------------------------------------------------- --- This is the official list of Pixel Vision 8 contributors: --- --- Jesse Freeman - @JesseFreeman --- Christina-Antoinette Neofotistou - @CastPixel --- Christer Kaitila - @McFunkypants --- Pedro Medeiros - @saint11 --- Shawn Rakowski - @shwany --- - -function EditorUI:CreateKnob(rect, spriteName, toolTip) - - -- Create a generic component data object - local data = self:CreateData(rect, spriteName, toolTip, forceDraw) - - data.rotation = - { - "50", - "60", - "70", - "80", - "90", - "100", - "110", - "120", - "130", - "140", - "150", - "160", - "170", - "180", - "190", - "200", - "210", - "220", - "230", - "240", - "250", - "260", - "270", - "280", - "290", - "300", - "310", - "320", - } - - -- Add the name of the component type to the default data name value - data.name = "Knob" .. data.name - - -- Configure extra data properties needed to run the slider component - data.horizontal = true - data.size = rect.w or rect.h - data.value = 0 - data.handleX = 0 - data.handleY = 0 - data.handleSize = 1 - - data.colorOffsetUp = 20 - data.colorOffsetOver = 24 - data.colorOffsetDisabled = 16 - - -- This is applied to the top when horizontal and the left when vertical - data.offset = offset or 0 - - -- Calculate the handle's size based on the sprite - local spriteData = _G[data.spriteName .. data.rotation[1]] - - if(spriteData ~= nil) then - - data.spriteDrawArgs = {spriteData.spriteIDs, data.rect.x, data.rect.y, spriteData.width, false, false, DrawMode.TilemapCache, 0, false} - - end - - -- Need to account for the correct orientation - data.handleCenter = data.handleSize / 2 - - -- Create a custom hit rect for the knob - data.hitRect = {x = data.rect.x + 2, y = data.rect.y + 2, w = 18, h = 18} - - -- Return the data - return data - -end - -function EditorUI:UpdateKnob(data, hitRect) - - -- Make sure we have data to work with and the component isn't disabled, if not return out of the update method - if(data == nil) then - return - end - - local size = data.size - data.handleSize - - if(data.enabled == true) then - - local overrideFocus = (data.inFocus == true and self.collisionManager.mouseDown) - - if(hitRect == nil) then - hitRect = data.hitRect or data.rect - end - - -- Ready to test finer collision if needed - if(self.collisionManager:MouseInRect(hitRect) == true or overrideFocus) then - - if(self.inFocusUI == nil) then - - self:SetFocus(data) - - end - - -- Check to see if the mouse is down to update the handle position - if(self.collisionManager.mouseDown == true and data.inFocus) then - - -- Need to calculate the new x position - local newPos = self.collisionManager.mousePos.x - data.handleCenter - - -- Make sure the position is in range - if(newPos > size + hitRect.x) then - newPos = size + hitRect.x - elseif(newPos < hitRect.x) then - newPos = hitRect.x - end - - -- Save the new position - data.handleX = newPos - - -- Need to calculate the value - local percent = math.ceil(((data.handleX - hitRect.x) / size) * 100) / 100 - - self:ChangeKnob(data, percent) - - else - self:DrawKnobSprite(data) - end - - else - - -- If the mouse is not in the rect, clear the focus - if(data.inFocus == true and self.collisionManager.mouseDown == false) then - self:ClearFocus(data) - self:DrawKnobSprite(data) - end - - end - - end - - -- If the component has changes and the mouse isn't over it, update the handle - if(data.invalid == true) then - - data.handleX = data.handleX + (data.value * size) - data.handleY = data.handleY + data.offset - - self:DrawKnobSprite(data) - - -- Clear the validation - self:ResetValidation(data) - - end - - -- Return the slider data value - return data.value - -end - -function EditorUI:CalculateKnobRotationID(data) - local rotationID = math.floor(data.value * #data.rotation) - - if(rotationID < 1) then - rotationID = 1 - elseif(rotationID > #data.rotation) then - rotationID = #data.rotation - end - - return rotationID - -end - -function EditorUI:DrawKnobSprite(data, mode) - - local spriteData = _G[data.spriteName .. data.rotation[self:CalculateKnobRotationID(data)]] -- data.enabled == true - - -- Make sure we have sprite data to render - if(spriteData ~= nil and data.spriteDrawArgs ~= nil) then - - -- Sprite Data - data.spriteDrawArgs[1] = spriteData.spriteIDs - - -- Color Offset - if(data.enabled) then - data.spriteDrawArgs[8] = data.inFocus == true and data.colorOffsetOver or data.colorOffsetUp - else - data.spriteDrawArgs[8] = data.colorOffsetDisabled - end - - self:NewDraw("DrawSprites", data.spriteDrawArgs) - - end - -end - -function EditorUI:ChangeKnob(data, percent, trigger) - - -- If there is no data or the value is the same as what's being passed in, don't update the component - if(data == nil or data.value == percent) then - return - end - - -- Set the new value - data.value = percent - - -- TODO shouldn't this be onUpdate? - if(data.onAction ~= nil and trigger ~= false) then - data.onAction(percent) - end - - -- Invalidate the component's display - self:Invalidate(data) - -end diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v3.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v3.lua index 7a4aaef3..e4a73122 100755 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v3.lua +++ b/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-knob-v3.lua @@ -63,12 +63,15 @@ function EditorUI:CreateKnob(rect, spriteName, toolTip) data.handleY = 0 data.handleSize = 1 - data.colorOffsetUp = 20 - data.colorOffsetOver = 24 - data.colorOffsetDisabled = 16 + data.colorOffsetDisabled = 144 + + data.colorOffsetUp = data.colorOffsetDisabled + 4 + data.colorOffsetOver = data.colorOffsetDisabled + 8 + -- This is applied to the top when horizontal and the left when vertical - data.offset = offset or 0 + -- data.offset = offset or 0 + -- Calculate the handle's size based on the sprite -- local spriteData = _G[data.spriteName .. data.rotation[1]] @@ -159,7 +162,7 @@ function EditorUI:UpdateKnob(data, hitRect) if(data.invalid == true) then data.handleX = data.handleX + (data.value * size) - data.handleY = data.handleY + data.offset + data.handleY = data.handleY self:DrawKnobSprite(data) @@ -198,9 +201,9 @@ function EditorUI:DrawKnobSprite(data, mode) -- Color Offset if(data.enabled) then - data.spriteDrawArgs[8] = data.inFocus == true and data.colorOffsetOver or data.colorOffsetUp + data.spriteDrawArgs[7] = data.inFocus == true and data.colorOffsetOver or data.colorOffsetUp else - data.spriteDrawArgs[8] = data.colorOffsetDisabled + data.spriteDrawArgs[7] = data.colorOffsetDisabled end self:NewDraw("DrawMetaSprite", data.spriteDrawArgs) diff --git a/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-slider-v3.lua b/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-slider-v3.lua deleted file mode 100755 index 43c77dcb..00000000 --- a/Disks/PixelVisionOS/System/Libs/pixel-vision-ui-slider-v3.lua +++ /dev/null @@ -1,190 +0,0 @@ --- --- Copyright (c) 2017, Jesse Freeman. All rights reserved. --- --- Licensed under the Microsoft Public License (MS-PL) License. --- See LICENSE file in the project root for full license information. --- --- Contributors --- -------------------------------------------------------- --- This is the official list of Pixel Vision 8 contributors: --- --- Jesse Freeman - @JesseFreeman --- Christina-Antoinette Neofotistou - @CastPixel --- Christer Kaitila - @McFunkypants --- Pedro Medeiros - @saint11 --- Shawn Rakowski - @shwany --- - -function EditorUI:CreateSlider(rect, spriteName, toolTip, horizontal, offset) - - -- Set up button states - local spriteData = MetaSprite(FindMetaSpriteId(spriteName))-- _G[spriteName] - - -- Create a generic component data object - local data = self:CreateData(rect, spriteName, toolTip, forceDraw) - - -- Add the name of the component type to the default data name value - data.name = "Slider" .. data.name - - -- Configure extra data properties needed to run the slider component - data.horizontal = horizontal - data.size = horizontal and rect.w or rect.h - data.value = 0 - data.handleX = 0 - data.handleY = 0 - data.handleSize = 0 - - -- This is applied to the top when horizontal and the left when vertical - data.offset = offset or 0 - - -- If there is a sprite calculate the handle size - if(spriteData ~= nil) then - -- Determine if the slider is horizontal or vertical and use the correct sprite dimensions - if(horizontal == true) then - data.handleSize = spriteData.Width - else - data.handleSize = spriteData.Height - end - - data.spriteDrawArgs = {FindMetaSpriteId(spriteName), 0, 0, false, false, DrawMode.Sprite, 0, false} - - end - -- Need to account for the correct orientation - data.handleCenter = data.handleSize / 2 - - -- Return the data - return data - -end - -function EditorUI:UpdateSlider(data) - - -- Make sure we have data to work with and the component isn't disabled, if not return out of the update method - if(data == nil) then - return - end - - local size = data.size - data.handleSize - - if(data.enabled == true) then - - - local overrideFocus = (data.inFocus == true and self.collisionManager.mouseDown) - - -- Ready to test finer collision if needed - if(self.collisionManager:MouseInRect(data.rect) == true or overrideFocus) then - - if(self.inFocusUI == nil) then - - self:SetFocus(data) - - end - - -- Check to see if the mouse is down to update the handle position - if(self.collisionManager.mouseDown == true and data.inFocus) then - - -- Calculate the position - self:UpdateSliderPosition(data) - - end - - else - - -- If the mouse is not in the rect, clear the focus - if(data.inFocus == true and self.collisionManager.mouseDown == false) then - self:ClearFocus(data) - end - - end - - end - - if(data.invalid == true) then - - -- If the mouse isn't on the slider, make sure it's position is correct - data.handleX = data.rect.x - data.handleY = data.rect.y - - if(data.horizontal == true) then - data.handleX = data.handleX + (data.value * size) - data.handleY = data.handleY + data.offset - else - data.handleX = data.handleX + data.offset - data.handleY = data.handleY + (data.value * size) - - end - - -- Clear the validation - self:ResetValidation(data) - - end - - if(data.enabled == true) then - - -- Make sure we have sprite data to render - if(data.spriteDrawArgs ~= nil) then - - -- Update X, Y, and Color Offset - data.spriteDrawArgs[2] = data.handleX - data.spriteDrawArgs[3] = data.handleY - data.spriteDrawArgs[7] = data.inFocus and 12 or 8 - - self:NewDraw("DrawMetaSprite", data.spriteDrawArgs) - - end - - end - - -- Return the slider data value - return data.value - -end - -function EditorUI:UpdateSliderPosition(data) - - local size = data.size - data.handleSize - local dir = data.horizontal and "x" or "y" - local prop = "handle" .. string.upper(dir) - - -- Need to calculate the new x position - local newPos = self.collisionManager.mousePos[dir] - data.handleCenter - - if(newPos > - 1) then - - -- Make sure the position is in range - if(newPos > size + data.rect[dir]) then - newPos = size + data.rect[dir] - elseif(newPos < data.rect[dir]) then - newPos = data.rect[dir] - end - - -- Save the new position - data[prop] = newPos - - -- Need to calculate the value - local percent = math.ceil(((data[prop] - data.rect[dir]) / size) * 100) / 100 - - self:ChangeSlider(data, percent) - - end -end - -function EditorUI:ChangeSlider(data, percent, trigger) - - -- If there is no data or the value is the same as what's being passed in, don't update the component - if(data == nil or data.value == percent) then - return - end - - -- Set the new value - data.value = percent - - -- TODO shouldn't this be onUpdate? - if(data.onAction ~= nil and trigger ~= false) then - data.onAction(percent) - end - - -- Invalidate the component's display - self:Invalidate(data) - -end diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/code-controller-panel.lua b/Disks/PixelVisionOS/System/Tools/SettingsTool/code-controller-panel.lua index 5439fcdf..c668cfe3 100755 --- a/Disks/PixelVisionOS/System/Tools/SettingsTool/code-controller-panel.lua +++ b/Disks/PixelVisionOS/System/Tools/SettingsTool/code-controller-panel.lua @@ -1,16 +1,16 @@ function SettingsTool:CreateControllerPanel() self.buttonSpriteMap = { - Up = {spriteData = dpadup, x = 96, y = 72}, - Down = {spriteData = dpaddown, x = 96, y = 72}, - Left = {spriteData = dpadleft, x = 96, y = 72}, - Right = {spriteData = dpadright, x = 96, y = 72}, - A = {spriteData = actionbtndown, x = 154, y = 82}, - B = {spriteData = actionbtndown, x = 170, y = 82}, - Select = {spriteData = startbtndown, x = 124, y = 90}, - Start = {spriteData = startbtndown, x = 136, y = 90} + Up = {spriteData = FindMetaSpriteId("dpadup"), x = 96, y = 72}, + Down = {spriteData = FindMetaSpriteId("dpaddown"), x = 96, y = 72}, + Left = {spriteData = FindMetaSpriteId("dpadleft"), x = 96, y = 72}, + Right = {spriteData = FindMetaSpriteId("dpadright"), x = 96, y = 72}, + A = {spriteData = FindMetaSpriteId("actionbtndown"), x = 154, y = 82}, + B = {spriteData = FindMetaSpriteId("actionbtndown"), x = 170, y = 82}, + Select = {spriteData = FindMetaSpriteId("startbtndown"), x = 124, y = 90}, + Start = {spriteData = FindMetaSpriteId("startbtndown"), x = 136, y = 90} } - + self.totalButtons = #ButtonTypes self.usedKeysInvalid = true self.blinkTime = 0 @@ -26,6 +26,7 @@ function SettingsTool:CreateControllerPanel() self.inputButtonGroupData = editorUI:CreateToggleGroup(true) self.inputButtonGroupData.onAction = function(value) + if(value == 2 and ControllerConnected(self.selectedPlayerID-1) == false) then pixelVisionOS:ShowMessageModal("No Controller", "It doesn't look like Player " .. self.selectedPlayerID .. "'s controller was detected.", 160, false, function() @@ -37,8 +38,8 @@ function SettingsTool:CreateControllerPanel() end end - editorUI:ToggleGroupButton(self.inputButtonGroupData, {x = 96, y = 152, w = 8, h = 8}, "radiobutton", "This is radio button 1.") - editorUI:ToggleGroupButton(self.inputButtonGroupData, {x = 144, y = 152, w = 8, h = 8}, "radiobutton", "This is radio button 2.") + editorUI:ToggleGroupButton(self.inputButtonGroupData, {x = 96, y = 152, w = 8, h = 8}, "radiobutton", "View keyboard mapping.") + editorUI:ToggleGroupButton(self.inputButtonGroupData, {x = 144, y = 152, w = 8, h = 8}, "radiobutton", "View controller mapping.") self.inputFields = { @@ -51,6 +52,9 @@ function SettingsTool:CreateControllerPanel() editorUI:CreateInputField({x = 184, y = 120, w = 8}, "", "A"), editorUI:CreateInputField({x = 208, y = 120, w = 8}, "", "B") } + + self.inputBlinkSpriteId = FindMetaSpriteId("inputbuttonon") + self.startInputSpriteId = FindMetaSpriteId("startinputon") -- -- TODO need to create a map for player 1 & 2 controller @@ -105,12 +109,15 @@ function SettingsTool:DrawInputSprite(type) local data = self.buttonSpriteMap[type] if(data ~= nil) then - local spriteData = data.spriteData - DrawSprites(spriteData.spriteIDs, data.x, data.y, spriteData.width) + -- local spriteData = data.spriteData + DrawMetaSprite( data.spriteData, data.x, data.y) + -- DrawSprites(spriteData.spriteIDs, data.x, data.y, spriteData.width) end if(type == "Select" or type == "Start") then - DrawSprites(startinputon.spriteIDs, type == "Select" and 126 or 138, 99, startinputon.width) + + DrawMetaSprite(self.startInputSpriteId, type == "Select" and 126 or 138, 99) + -- DrawSprites(startinputon.spriteIDs, type == "Select" and 126 or 138, 99, startinputon.width) else self:DrawBlinkSprite() end @@ -207,7 +214,9 @@ function SettingsTool:UpdateControllerPanel() end function SettingsTool:DrawBlinkSprite() - DrawSprites(inputbuttonon.spriteIDs, 154, 62, inputbuttonon.width) + + DrawMetaSprite(self.inputBlinkSpriteId, 154, 62) +-- DrawSprites(inputbuttonon.spriteIDs, 154, 62, inputbuttonon.width) end function SettingsTool:TriggerPlayerSelection(value) @@ -218,15 +227,20 @@ function SettingsTool:TriggerPlayerSelection(value) -- Display the correct highlight state for the player label for i = 1, 2 do - local spriteData = _G["player"..i..(i == value and "selected" or "up")] + -- local spriteData = _G["player"..i..(i == value and "selected" or "up")] - DrawSprites(spriteData.spriteIDs, 27, 2 + i, spriteData.width, false, false, DrawMode.Tile) + local metaSpriteId = FindMetaSpriteId("player"..i..(i == value and "selected" or "up")) + DrawMetaSprite(metaSpriteId, 27, 2 + i, false, false, DrawMode.Tile) + -- DrawSprites(spriteData.spriteIDs, 27, 2 + i, spriteData.width, false, false, DrawMode.Tile) end -- Update the controller number - local spriteData = _G["controller"..value] + -- local spriteData = _G["controller"..value] + + local metaSpriteId = FindMetaSpriteId("controller"..value) + DrawMetaSprite(metaSpriteId, 16, 7, false, false, DrawMode.Tile) - DrawSprites(spriteData.spriteIDs, 16, 7, spriteData.width, false, false, DrawMode.Tile) + -- DrawSprites(spriteData.spriteIDs, 16, 7, spriteData.width, false, false, DrawMode.Tile) -- Reset the input selection editorUI:SelectToggleButton(self.inputButtonGroupData, self.selectedInputID, false) @@ -259,10 +273,11 @@ function SettingsTool:TriggerInputSelection(value) -- Display the correct highlight state for the player label for i = 1, 2 do - local spriteName = i == 1 and "keyboard" or "controller" - local spriteData = _G[spriteName..(i == value and "selected" or "up")] + local spriteName = i == 1 and "keyboard" or "controller" + local metaSpriteId = FindMetaSpriteId(spriteName..(i == value and "selected" or "up")) - DrawSprites(spriteData.spriteIDs, pos[i], 19, spriteData.width, false, false, DrawMode.Tile) + DrawMetaSprite(metaSpriteId, pos[i], 19, false, false, DrawMode.Tile) + -- DrawSprites(spriteData.spriteIDs, pos[i], 19, spriteData.width, false, false, DrawMode.Tile) end for i = 1, #self.inputFields do diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/code-drop-down-menu.lua b/Disks/PixelVisionOS/System/Tools/SettingsTool/code-drop-down-menu.lua index 155442ab..28517e02 100755 --- a/Disks/PixelVisionOS/System/Tools/SettingsTool/code-drop-down-menu.lua +++ b/Disks/PixelVisionOS/System/Tools/SettingsTool/code-drop-down-menu.lua @@ -7,7 +7,7 @@ function SettingsTool:CreateDropDownMenu() {divider = true}, {name = "Sound Effects", action = function() self:ToggleSoundEffects() end, toolTip = "Toggle system sound."}, -- Reset all the values {divider = true}, - {name = "Save", action = function() self:OnSave() end, enabled = false, key = Keys.S, toolTip = "Save changes made to the controller mapping."}, -- Reset all the values + -- {name = "Save", action = function() self:OnSave() end, enabled = false, key = Keys.S, toolTip = "Save changes made to the controller mapping."}, -- Reset all the values {name = "Reset", action = function() self:OnReset() end, key = Keys.R, toolTip = "Revert controller mapping to its default value."}, -- Reset all the values {divider = true}, {name = "Quit", key = Keys.Q, action = function() self:OnQuit() end, toolTip = "Quit the current game."}, -- Quit the current game @@ -17,20 +17,6 @@ function SettingsTool:CreateDropDownMenu() end --- function SettingsTool:OnSave() - --- for i = 1, #self.inputFields do - --- local field = self.inputFields[i] --- local value = field.text --- RemapKey("Player" ..tostring(self.selectedPlayerID) .. field.type .. "Key", ConvertKeyToKeyCode(value)) - --- end - --- self:ResetDataValidation() - --- end - function SettingsTool:OnReset() @@ -49,27 +35,8 @@ function SettingsTool:CreateDropDownMenu() function SettingsTool:OnQuit() - -- if(self.invalid == true) then - - -- pixelVisionOS:ShowMessageModal("Unsaved Changes", "You have unsaved changes. Do you want to save your work before you quit?", 160, true, - -- function() - -- if(pixelVisionOS.messageModal.selectionValue == true) then - -- -- Save changes - -- OnSave() - - -- end - - -- -- Quit the tool - -- QuitCurrentTool() - - -- end - -- ) - - -- else - -- Quit the tool QuitCurrentTool() - -- end - + end function SettingsTool:ToggleSoundEffects() diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/code-settings-tool.lua b/Disks/PixelVisionOS/System/Tools/SettingsTool/code-settings-tool.lua index 25d48145..f942149f 100755 --- a/Disks/PixelVisionOS/System/Tools/SettingsTool/code-settings-tool.lua +++ b/Disks/PixelVisionOS/System/Tools/SettingsTool/code-settings-tool.lua @@ -19,7 +19,7 @@ function SettingsTool:Init() runnerName = SystemName(), rootPath = ReadMetadata("RootPath", "/"), invalid = true, - SaveShortcut = 6 + -- SaveShortcut = 6 } -- Create a global reference of the new workspace tool @@ -66,7 +66,7 @@ function SettingsTool:InvalidateData() self.invalid = true - pixelVisionOS:EnableMenuItem(self.self.SaveShortcut, true) + -- pixelVisionOS:EnableMenuItem(self.self.SaveShortcut, true) end @@ -80,6 +80,6 @@ function SettingsTool:InvalidateData() pixelVisionOS:ChangeTitle(toolName, "toolbaricontool") self.invalid = false - pixelVisionOS:EnableMenuItem(self.self.SaveShortcut, false) + -- pixelVisionOS:EnableMenuItem(self.self.SaveShortcut, false) end diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/color-map.png b/Disks/PixelVisionOS/System/Tools/SettingsTool/color-map.png deleted file mode 100755 index 39ea8f3a4826f93ddb78a3ae32ad8203944abdd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1135 zcmaJ=PiP!f7$2=lDHIX}ZR=&6dQj?{nK%D3GiF=1I~%jL8^dO4BczZw@4eX!$;=yP zUffOaFP171MXBE;yRnDRfq8$v_x*m~|MwRc zUOj&7)GNk-J-?U z()sO@FKsXM>GnDen0D^0Iy(x1Amfs#qiiFu!cjxp;|<|liw#ZPQ<3WpZQrTo?xNZf zC0AYDLlirvIuq#FGaVPdtXd|XF-+GmJ!In0^g|1)<4*%?B}>9yG&i;dw}!SRWf2<2 za5&V5wl2znfrB70Ov|t=1RAK?$|V`0ygEH$hgr<2de5o$fe%ui+)3-RAD@CU6Wjag`@q%H_pdoz}Qxh`4pnHf7 zOF&uT5SwwwB-$9y9?IZ;r-B3`DJBkujCvkVAc2gUE+Uo#Y|NWMEWruIrU$H4Gr&co zZk~slX(ECSt&azz0hfc};yFxI38VAXC;z+xV>iEevEL5E@Z;To|N7(Z{ql#)uMO^B zdt+r~4Ea#yK7HkIGyQ4&Hm`;_{Q{Yb~~P49o(4W&rB!3@_6d$c=gt;JI@ZL-g`Vgp*;4K X@wjglN&mHIdoO7$5h28SL~_zL`P77}#M2)>+}CA$d!U$Sm)jqn zHEOjyK2Db`vv*3<(B40gVH@qd1N z+~5B{pI-gHcxl}K|HgmZ5BB_*{P#co0P~Cwo_$&imNB{ATFySLc+FLwOtn=!AdoI4 pECB*OS7HP1Iz;F9X(a1tHw%0RcTaw+-UBRXyS!lQbV|%=7vVLGY z*-b8po(iW*h)ab;Z*V}II8dRA#|fztv;xr!NE|sNfDl}Ygc$Fu8rhnj%!(sWwSP&+TrB_C{{O&`7FdDkG zm1L#*EU^MFOYOj9*|ryQv>?o!X@}HWWr=9Ay6YFDUqAg!5?#9>o!6?c8Wvf@EpJ9_ zd2^v=ZLV6_md>0OXWE1lcr2k}+iUtUX&0mpFX8L-vn+`nNU~axW>bUWN_9~z1`!jr ztPU)sYGNK|k)BgAJ|!v;88S3vlmkd7DkO>`_I?t#7TFG2Dm~q^#or22BS}Ic%dJ)` z+sb8ws4gRnu?!ViQ28~9?%NX=j^DM(yt*99*e(E4#N zOgvz6n}#yV!qlY>(6$D+a4l+fjN6vXn#^N<5_2pXV8cd`1aTv{3-w@ohXEeiYIR^^ zS1q15FcBy7>)efAKz2pPwT+O;ODqo7B8$zhbD1YnZ$eUx7)^qx76i?Hq89s-#bPl{ z3>KfLQp@#IKcp;n(j@)XMRQx!hzQrn~g2W?~bzPe{IfEh1R)C5SzcGw}iA@BMiLn87Mm2@? z&zAygEviEkke;77rDGEX>*u0 zRb_KVLsu}hr~xQeO`vKl2TX-$0;b*N*ap@dJ+1vamisKT+`pKoJ?{0^9If|OP51P{ zMbF4-TX71pyXw-)d)x06J1M)Vo{gT0W%k-YkJzbiLanrK3zC%3cP;E;EW*%xh!ziyh z27|h3_Wd8$ZvaKDL7l)n(FQ$uVEw%SSqX+BPef<3K?ac?S-*|uf_7`Yt`R3K@qc1!H{=EJ1%G-yXdveEpVv%zN^lbLrHt%rBHantSEKKgZpmp#T5? diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/data.json b/Disks/PixelVisionOS/System/Tools/SettingsTool/data.json index 12cbd465..47d97a3e 100755 --- a/Disks/PixelVisionOS/System/Tools/SettingsTool/data.json +++ b/Disks/PixelVisionOS/System/Tools/SettingsTool/data.json @@ -1,10 +1,58 @@ { - "ColorChip": { "maxColors": 128, "backgroundColor": 0, "maskColor": "#FF00FF", "unique": false, "debug": false, }, - "DisplayChip": { "width": 256, "height": 240, "overscanX": 1, "overscanY": 1, "layers": 6 }, - "FontChip": {}, - "GameChip": { "lockSpecs": true, "maxSize": 512, "saveSlots": 8 }, - "MusicChip": { "totalSongs": 16, "notesPerTrack": 127, "totalPatterns": 24, "totalLoop": 24 }, - "SoundChip": { "totalChannels": 5, "totalSounds": 32, "channelTypes": [-1, -1, -1, -1, -1] }, - "SpriteChip": { "maxSpriteCount": 0, "unique": true, "spriteWidth": 8, "spriteHeight": 8, "pages": 4, "cps": 8 }, - "TilemapChip": { "columns": 36, "rows": 32, "totalFlags": 16, "autoImport": false, } + "ColorChip": + { + "backgroundColor":0, + "maskColor":"#FF00FF", + "unique":false, + "debug":false + }, + "DisplayChip": + { + "width":256, + "height":240, + "overscanX":1, + "overscanY":1, + "layers":6 + }, + "FontChip": + { + "unique":true, + "pages":2 + }, + "GameChip": + { + "totalMetaSprites":96, + "lockSpecs":true, + "maxSize":512, + "saveSlots":8 + }, + "MusicChip": + { + "totalSongs":16, + "notesPerTrack":127, + "totalPatterns":24, + "totalLoop":24 + }, + "SoundChip": + { + "totalChannels":5, + "totalSounds":32, + "channelTypes":[-1,-1,-1,-1,-1] + }, + + "SpriteChip":{ + "maxSpriteCount":0, + "unique":true, + "spriteWidth":8, + "spriteHeight":8, + "pages":6, + "cps":16 + }, + "TilemapChip": + { + "columns":36, + "rows":32, + "totalFlags":16, + "autoImport":false + } } \ No newline at end of file diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/meta-sprites.json b/Disks/PixelVisionOS/System/Tools/SettingsTool/meta-sprites.json index 66cd5dd4..5d6e8c2d 100755 --- a/Disks/PixelVisionOS/System/Tools/SettingsTool/meta-sprites.json +++ b/Disks/PixelVisionOS/System/Tools/SettingsTool/meta-sprites.json @@ -2,87 +2,79 @@ "MetaSprites": { "version": "v1", "collections": [ - {"name":"actionbtndown","width":2,"spriteIDs":[211,212,236,237]}, - {"name":"checkboxdisabled","width":2,"spriteIDs":[120,121]}, - {"name":"checkboxover","width":2,"spriteIDs":[187,188]}, - {"name":"checkboxselectedover","width":2,"spriteIDs":[234,235]}, - {"name":"checkboxselectedup","width":2,"spriteIDs":[207,208]}, - {"name":"checkboxup","width":2,"spriteIDs":[154,155]}, - {"name":"controller1","width":3,"spriteIDs":[146,147,148,179,180,181,199,200,201]}, - {"name":"controller2","width":3,"spriteIDs":[146,364,148,386,387,388,406,407,408]}, - {"name":"controllerselected","width":5,"spriteIDs":[397,398,399,400,401]}, - {"name":"controllerup","width":5,"spriteIDs":[373,374,375,376,377]}, - {"name":"cursorhanddown","width":2,"spriteIDs":[48,49,76,77]}, - {"name":"cursorhand","width":2,"spriteIDs":[44,45,72,73]}, - {"name":"cursorhelp","width":2,"spriteIDs":[50,51,78,79]}, - {"name":"cursorpointer","width":2,"spriteIDs":[42,43,70,71]}, - {"name":"cursortext","width":2,"spriteIDs":[46,47,74,75]}, - {"name":"dpaddown","width":3,"spriteIDs":[197,251,197,265,266,267,197,282,197]}, - {"name":"dpadleft","width":3,"spriteIDs":[197,313,314,335,336,337,197,357,358]}, - {"name":"dpadright","width":3,"spriteIDs":[197,268,197,283,284,285,302,303,197]}, - {"name":"dpadup","width":3,"spriteIDs":[197,363,197,378,379,380,302,402,403]}, - {"name":"inputbuttonon","width":1,"spriteIDs":[104]}, - {"name":"keyboardselected","width":4,"spriteIDs":[393,394,395,396]}, + {"name":"knob160","width":3,"spriteIDs":[227,268,229,279,247,237,260,259,258]}, + {"name":"knob30","width":3,"spriteIDs":[227,228,229,235,236,237,256,257,258]}, + {"name":"cursorpointer","width":2,"spriteIDs":[367,368,385,386]}, + {"name":"player2selected","width":4,"spriteIDs":[411,412,413,414]}, + {"name":"knob200","width":3,"spriteIDs":[227,272,229,279,247,237,260,259,258]}, + {"name":"radiobuttonselectedup","width":1,"spriteIDs":[350]}, + {"name":"radiobuttondisabled","width":1,"spriteIDs":[347]}, + {"name":"knob210","width":3,"spriteIDs":[227,273,229,279,247,237,260,259,258]}, + {"name":"titlebarvolumeon","width":1,"spriteIDs":[346]}, + {"name":"modalokbuttonover","width":4,"spriteIDs":[399,400,401,402,419,420,421,422]}, + {"name":"dpadright","width":3,"spriteIDs":[56,316,56,336,337,338,352,358,56]}, + {"name":"modalokbuttonup","width":4,"spriteIDs":[395,396,397,398,415,416,417,418]}, + {"name":"modalcancelbuttonover","width":4,"spriteIDs":[407,408,409,410,427,428,429,430]}, + {"name":"knob170","width":3,"spriteIDs":[227,269,229,279,247,237,260,259,258]}, + {"name":"cursorhelp","width":2,"spriteIDs":[361,362,379,380]}, + {"name":"knob300","width":3,"spriteIDs":[227,228,229,279,297,298,260,259,258]}, + {"name":"knob90","width":3,"spriteIDs":[227,228,229,248,247,237,260,259,258]}, + {"name":"knob260","width":3,"spriteIDs":[227,228,229,279,289,290,260,259,258]}, + {"name":"cursortext","width":2,"spriteIDs":[359,360,377,378]}, + {"name":"knob100","width":3,"spriteIDs":[227,228,229,249,247,237,260,259,258]}, + {"name":"startbtndown","width":2,"spriteIDs":[254,255]}, + {"name":"knob50","width":3,"spriteIDs":[227,228,229,240,241,237,260,259,258]}, + {"name":"dpadleft","width":3,"spriteIDs":[56,313,314,330,331,332,56,355,356]}, + {"name":"controllerup","width":5,"spriteIDs":[436,437,438,439,440]}, + {"name":"player2up","width":4,"spriteIDs":[391,392,393,394]}, + {"name":"knob40","width":3,"spriteIDs":[227,228,229,238,239,237,256,259,258]}, + {"name":"knob110","width":3,"spriteIDs":[230,228,229,250,251,237,260,259,258]}, + {"name":"knob270","width":3,"spriteIDs":[227,228,229,279,291,292,260,259,258]}, + {"name":"knob310","width":3,"spriteIDs":[227,228,229,279,299,237,260,259,258]}, + {"name":"knob80","width":3,"spriteIDs":[227,228,229,246,247,237,260,259,258]}, + {"name":"checkboxover","width":2,"spriteIDs":[343,344]}, + {"name":"titlebarvolumeoff","width":1,"spriteIDs":[345]}, + {"name":"startinputon","width":1,"spriteIDs":[233]}, + {"name":"radiobuttonup","width":1,"spriteIDs":[348]}, + {"name":"knob240","width":3,"spriteIDs":[227,282,283,279,286,237,260,259,258]}, + {"name":"knob320","width":3,"spriteIDs":[227,228,229,279,300,237,260,301,258]}, + {"name":"checkboxselectedup","width":2,"spriteIDs":[305,306]}, {"name":"keyboardup","width":4,"spriteIDs":[369,370,371,372]}, - {"name":"knob100","width":3,"spriteIDs":[3,4,5,160,92,12,109,32,31]}, - {"name":"knob110","width":3,"spriteIDs":[127,4,5,161,162,12,109,32,31]}, - {"name":"knob120","width":3,"spriteIDs":[128,129,5,163,164,12,109,32,31]}, - {"name":"knob130","width":3,"spriteIDs":[130,129,5,165,166,12,109,32,31]}, - {"name":"knob140","width":3,"spriteIDs":[131,132,5,167,166,12,109,32,31]}, - {"name":"knob150","width":3,"spriteIDs":[214,215,5,167,92,12,109,32,31]}, - {"name":"knob160","width":3,"spriteIDs":[3,216,5,167,92,12,109,32,31]}, - {"name":"knob170","width":3,"spriteIDs":[3,217,5,167,92,12,109,32,31]}, - {"name":"knob180","width":3,"spriteIDs":[3,218,5,167,92,12,109,32,31]}, - {"name":"knob190","width":3,"spriteIDs":[3,219,5,167,92,12,109,32,31]}, - {"name":"knob200","width":3,"spriteIDs":[3,269,5,167,92,12,109,32,31]}, - {"name":"knob210","width":3,"spriteIDs":[3,270,5,167,92,12,109,32,31]}, - {"name":"knob220","width":3,"spriteIDs":[3,271,5,167,286,12,109,32,31]}, - {"name":"knob230","width":3,"spriteIDs":[3,272,5,167,287,12,109,32,31]}, - {"name":"knob240","width":3,"spriteIDs":[3,273,274,167,288,12,109,32,31]}, - {"name":"knob250","width":3,"spriteIDs":[3,315,274,167,338,339,109,32,31]}, - {"name":"knob260","width":3,"spriteIDs":[3,4,5,167,340,341,109,32,31]}, - {"name":"knob270","width":3,"spriteIDs":[3,4,5,167,342,343,109,32,31]}, - {"name":"knob280","width":3,"spriteIDs":[3,4,5,167,344,345,109,32,31]}, - {"name":"knob290","width":3,"spriteIDs":[3,4,5,167,346,347,109,32,31]}, - {"name":"knob30","width":3,"spriteIDs":[3,4,5,10,11,12,29,30,31]}, - {"name":"knob300","width":3,"spriteIDs":[3,4,5,167,381,382,109,32,31]}, - {"name":"knob310","width":3,"spriteIDs":[3,4,5,167,383,12,109,32,31]}, - {"name":"knob320","width":3,"spriteIDs":[3,4,5,167,384,12,109,404,31]}, - {"name":"knob330","width":3,"spriteIDs":[3,4,5,167,385,12,109,405,31]}, - {"name":"knob40","width":3,"spriteIDs":[3,4,5,13,14,12,29,32,31]}, - {"name":"knob50","width":3,"spriteIDs":[3,4,5,85,86,12,109,32,31]}, - {"name":"knob60","width":3,"spriteIDs":[3,4,5,87,88,12,109,32,31]}, - {"name":"knob70","width":3,"spriteIDs":[3,4,5,89,90,12,109,32,31]}, - {"name":"knob80","width":3,"spriteIDs":[3,4,5,91,92,12,109,32,31]}, - {"name":"knob90","width":3,"spriteIDs":[3,4,5,93,92,12,109,32,31]}, - {"name":"modalcancelbuttonover","width":4,"spriteIDs":[389,390,391,392,409,410,411,412]}, - {"name":"modalcancelbuttonup","width":4,"spriteIDs":[359,360,361,362,365,366,367,368]}, - {"name":"modalokbuttonover","width":4,"spriteIDs":[304,305,306,307,319,320,321,322]}, - {"name":"modalokbuttonup","width":4,"spriteIDs":[275,276,277,278,292,293,294,295]}, - {"name":"modalokcancelover","width":4,"spriteIDs":[389,390,391,392,409,410,411,412]}, - {"name":"modalokcancelup","width":4,"spriteIDs":[359,360,361,362,365,366,367,368]}, - {"name":"muteover","width":4,"spriteIDs":[113,114,115,116,137,138,139,140,171,172,172,173]}, - {"name":"muteselectedover","width":4,"spriteIDs":[33,34,34,35,59,60,61,62,94,95,95,96]}, - {"name":"muteselectedup","width":4,"spriteIDs":[110,111,111,112,133,134,135,136,168,169,169,170]}, - {"name":"muteup","width":4,"spriteIDs":[36,37,38,39,63,64,65,66,97,98,98,99]}, - {"name":"player1selected","width":4,"spriteIDs":[55,56,57,58]}, - {"name":"player1up","width":4,"spriteIDs":[105,106,107,108]}, - {"name":"player2selected","width":4,"spriteIDs":[123,124,125,126]}, - {"name":"player2up","width":4,"spriteIDs":[81,82,83,84]}, - {"name":"pv8toolbaricondown","width":2,"spriteIDs":[40,41,67,68]}, - {"name":"pv8toolbariconup","width":2,"spriteIDs":[100,101,8,117]}, - {"name":"radiobuttondisabled","width":1,"spriteIDs":[156]}, - {"name":"radiobuttonover","width":1,"spriteIDs":[158]}, - {"name":"radiobuttonselectedover","width":1,"spriteIDs":[54]}, - {"name":"radiobuttonselectedup","width":1,"spriteIDs":[189]}, - {"name":"radiobuttonup","width":1,"spriteIDs":[157]}, - {"name":"settingstooltilemap_03","width":4,"spriteIDs":[275,276,277,278,292,293,294,295]}, - {"name":"startbtndown","width":2,"spriteIDs":[209,210]}, - {"name":"startinputon","width":1,"spriteIDs":[122]}, - {"name":"titlebarvolumeoff","width":1,"spriteIDs":[1]}, - {"name":"titlebarvolumeon","width":1,"spriteIDs":[2]}, - {"name":"toolbariconfile","width":1,"spriteIDs":[52]}, - {"name":"toolbaricontool","width":1,"spriteIDs":[53]} + {"name":"knob280","width":3,"spriteIDs":[227,228,229,279,293,294,260,259,258]}, + {"name":"pv8toolbariconup","width":2,"spriteIDs":[309,310,2,326]}, + {"name":"knob70","width":3,"spriteIDs":[227,228,229,244,245,237,260,259,258]}, + {"name":"modalcancelbuttonup","width":4,"spriteIDs":[403,404,405,406,423,424,425,426]}, + {"name":"knob120","width":3,"spriteIDs":[231,232,229,252,253,237,260,259,258]}, + {"name":"radiobuttonover","width":1,"spriteIDs":[349]}, + {"name":"inputbuttonon","width":1,"spriteIDs":[234]}, + {"name":"knob130","width":3,"spriteIDs":[263,232,229,277,278,237,260,259,258]}, + {"name":"dpadup","width":3,"spriteIDs":[56,312,56,327,328,329,352,353,354]}, + {"name":"knob60","width":3,"spriteIDs":[227,228,229,242,243,237,260,259,258]}, + {"name":"knob290","width":3,"spriteIDs":[227,228,229,279,295,296,260,259,258]}, + {"name":"cursorhanddown","width":2,"spriteIDs":[365,366,383,384]}, + {"name":"toolbaricontool","width":1,"spriteIDs":[311]}, + {"name":"controllerselected","width":5,"spriteIDs":[431,432,433,434,435]}, + {"name":"knob330","width":3,"spriteIDs":[227,228,229,279,317,237,260,339,258]}, + {"name":"radiobuttonselectedover","width":1,"spriteIDs":[351]}, + {"name":"dpaddown","width":3,"spriteIDs":[56,315,56,333,334,335,56,357,56]}, + {"name":"knob250","width":3,"spriteIDs":[227,284,283,279,287,288,260,259,258]}, + {"name":"actionbtndown","width":2,"spriteIDs":[261,262,275,276]}, + {"name":"controller1","width":3,"spriteIDs":[29,30,31,42,43,44,58,59,60]}, + {"name":"knob140","width":3,"spriteIDs":[264,265,229,279,278,237,260,259,258]}, + {"name":"checkboxdisabled","width":2,"spriteIDs":[303,304]}, + {"name":"player1up","width":4,"spriteIDs":[373,374,375,376]}, + {"name":"player1selected","width":4,"spriteIDs":[441,442,443,444]}, + {"name":"knob220","width":3,"spriteIDs":[227,274,229,279,280,237,260,259,258]}, + {"name":"keyboardselected","width":4,"spriteIDs":[387,388,389,390]}, + {"name":"checkboxup","width":2,"spriteIDs":[321,322]}, + {"name":"controller2","width":3,"spriteIDs":[29,302,31,318,319,320,340,341,342]}, + {"name":"knob180","width":3,"spriteIDs":[227,270,229,279,247,237,260,259,258]}, + {"name":"cursorhand","width":2,"spriteIDs":[363,364,381,382]}, + {"name":"knob190","width":3,"spriteIDs":[227,271,229,279,247,237,260,259,258]}, + {"name":"knob230","width":3,"spriteIDs":[227,281,229,279,285,237,260,259,258]}, + {"name":"knob150","width":3,"spriteIDs":[266,267,229,279,247,237,260,259,258]}, + {"name":"pv8toolbaricondown","width":2,"spriteIDs":[307,308,324,325]}, + {"name":"checkboxselectedover","width":2,"spriteIDs":[323,306]}, ], "total": 96 } diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/sb-sprites.lua b/Disks/PixelVisionOS/System/Tools/SettingsTool/sb-sprites.lua deleted file mode 100755 index 496a2815..00000000 --- a/Disks/PixelVisionOS/System/Tools/SettingsTool/sb-sprites.lua +++ /dev/null @@ -1,83 +0,0 @@ --- spritelib-start -actionbtndown={width=2,spriteIDs={211,212,236,237}} -checkboxdisabled={width=2,spriteIDs={120,121}} -checkboxover={width=2,spriteIDs={187,188}} -checkboxselectedover={width=2,spriteIDs={234,235}} -checkboxselectedup={width=2,spriteIDs={207,208}} -checkboxup={width=2,spriteIDs={154,155}} -controller1={width=3,spriteIDs={146,147,148,179,180,181,199,200,201}} -controller2={width=3,spriteIDs={146,364,148,386,387,388,406,407,408}} -controllerselected={width=5,spriteIDs={397,398,399,400,401}} -controllerup={width=5,spriteIDs={373,374,375,376,377}} -cursorhanddown={width=2,spriteIDs={48,49,76,77}} -cursorhand={width=2,spriteIDs={44,45,72,73}} -cursorhelp={width=2,spriteIDs={50,51,78,79}} -cursorpointer={width=2,spriteIDs={42,43,70,71}} -cursortext={width=2,spriteIDs={46,47,74,75}} -dpaddown={width=3,spriteIDs={197,251,197,265,266,267,197,282,197}} -dpadleft={width=3,spriteIDs={197,313,314,335,336,337,197,357,358}} -dpadright={width=3,spriteIDs={197,268,197,283,284,285,302,303,197}} -dpadup={width=3,spriteIDs={197,363,197,378,379,380,302,402,403}} -inputbuttonon={width=1,spriteIDs={104}} -keyboardselected={width=4,spriteIDs={393,394,395,396}} -keyboardup={width=4,spriteIDs={369,370,371,372}} -knob100={width=3,spriteIDs={3,4,5,160,92,12,109,32,31}} -knob110={width=3,spriteIDs={127,4,5,161,162,12,109,32,31}} -knob120={width=3,spriteIDs={128,129,5,163,164,12,109,32,31}} -knob130={width=3,spriteIDs={130,129,5,165,166,12,109,32,31}} -knob140={width=3,spriteIDs={131,132,5,167,166,12,109,32,31}} -knob150={width=3,spriteIDs={214,215,5,167,92,12,109,32,31}} -knob160={width=3,spriteIDs={3,216,5,167,92,12,109,32,31}} -knob170={width=3,spriteIDs={3,217,5,167,92,12,109,32,31}} -knob180={width=3,spriteIDs={3,218,5,167,92,12,109,32,31}} -knob190={width=3,spriteIDs={3,219,5,167,92,12,109,32,31}} -knob200={width=3,spriteIDs={3,269,5,167,92,12,109,32,31}} -knob210={width=3,spriteIDs={3,270,5,167,92,12,109,32,31}} -knob220={width=3,spriteIDs={3,271,5,167,286,12,109,32,31}} -knob230={width=3,spriteIDs={3,272,5,167,287,12,109,32,31}} -knob240={width=3,spriteIDs={3,273,274,167,288,12,109,32,31}} -knob250={width=3,spriteIDs={3,315,274,167,338,339,109,32,31}} -knob260={width=3,spriteIDs={3,4,5,167,340,341,109,32,31}} -knob270={width=3,spriteIDs={3,4,5,167,342,343,109,32,31}} -knob280={width=3,spriteIDs={3,4,5,167,344,345,109,32,31}} -knob290={width=3,spriteIDs={3,4,5,167,346,347,109,32,31}} -knob30={width=3,spriteIDs={3,4,5,10,11,12,29,30,31}} -knob300={width=3,spriteIDs={3,4,5,167,381,382,109,32,31}} -knob310={width=3,spriteIDs={3,4,5,167,383,12,109,32,31}} -knob320={width=3,spriteIDs={3,4,5,167,384,12,109,404,31}} -knob330={width=3,spriteIDs={3,4,5,167,385,12,109,405,31}} -knob40={width=3,spriteIDs={3,4,5,13,14,12,29,32,31}} -knob50={width=3,spriteIDs={3,4,5,85,86,12,109,32,31}} -knob60={width=3,spriteIDs={3,4,5,87,88,12,109,32,31}} -knob70={width=3,spriteIDs={3,4,5,89,90,12,109,32,31}} -knob80={width=3,spriteIDs={3,4,5,91,92,12,109,32,31}} -knob90={width=3,spriteIDs={3,4,5,93,92,12,109,32,31}} -modalcancelbuttonover={width=4,spriteIDs={389,390,391,392,409,410,411,412}} -modalcancelbuttonup={width=4,spriteIDs={359,360,361,362,365,366,367,368}} -modalokbuttonover={width=4,spriteIDs={304,305,306,307,319,320,321,322}} -modalokbuttonup={width=4,spriteIDs={275,276,277,278,292,293,294,295}} -modalokcancelover={width=4,spriteIDs={389,390,391,392,409,410,411,412}} -modalokcancelup={width=4,spriteIDs={359,360,361,362,365,366,367,368}} -muteover={width=4,spriteIDs={113,114,115,116,137,138,139,140,171,172,172,173}} -muteselectedover={width=4,spriteIDs={33,34,34,35,59,60,61,62,94,95,95,96}} -muteselectedup={width=4,spriteIDs={110,111,111,112,133,134,135,136,168,169,169,170}} -muteup={width=4,spriteIDs={36,37,38,39,63,64,65,66,97,98,98,99}} -player1selected={width=4,spriteIDs={55,56,57,58}} -player1up={width=4,spriteIDs={105,106,107,108}} -player2selected={width=4,spriteIDs={123,124,125,126}} -player2up={width=4,spriteIDs={81,82,83,84}} -pv8toolbaricondown={width=2,spriteIDs={40,41,67,68}} -pv8toolbariconup={width=2,spriteIDs={100,101,8,117}} -radiobuttondisabled={width=1,spriteIDs={156}} -radiobuttonover={width=1,spriteIDs={158}} -radiobuttonselectedover={width=1,spriteIDs={54}} -radiobuttonselectedup={width=1,spriteIDs={189}} -radiobuttonup={width=1,spriteIDs={157}} -settingstooltilemap_03={width=4,spriteIDs={275,276,277,278,292,293,294,295}} -startbtndown={width=2,spriteIDs={209,210}} -startinputon={width=1,spriteIDs={122}} -titlebarvolumeoff={width=1,spriteIDs={1}} -titlebarvolumeon={width=1,spriteIDs={2}} -toolbariconfile={width=1,spriteIDs={52}} -toolbaricontool={width=1,spriteIDs={53}} --- spritelib-end diff --git a/Disks/PixelVisionOS/System/Tools/SettingsTool/sprites.png b/Disks/PixelVisionOS/System/Tools/SettingsTool/sprites.png old mode 100755 new mode 100644 index 4b4135cfed7d6f29f55a4e3054d20d038cd1ebc2..8ac2ae4bda4e11a0e4c31e990462aae40763cbb1 GIT binary patch literal 9740 zcmeHN`#Tek_eZ=VB=k-fl90quqH>#1YRkRIUAbRZ<~|#ha=#QNgwRB}+a|XmmyukP zjhTrUW@fnzGyC@WH@?sNmvhc@&hwlf&U4OropYX(XlZULdgSyG9v&XiyLU{i|MFNK z9)2FdfBs6!omPLT;*Yx~H}6NhqZb7Bh1%QW8PvrTl;DNq;`4@g-T&NA(-V24_3h-s z;rNvoqr`+vxn=&{KXM$66AGw|+e^o;-aC#PDYYiXXBaBTM*9Yzyny$!lwC?bYAqxu zl6qtIcW5sSQ4KBdclNL1gl#u*xw6yK-bHPMDRo-ogbM^#G-%<CXCf{Y~C+x4Geg6@im4vQ+nS0IVR_OLb*auGkqyjVJe1en{XWQ=2-IwQY8W zC(NL^k~B%@G+)GBW~=lt(m%5H2t%F0)!nM_mZ11%Vr16N zoxxM%W*N|&BZ5(-u1n#&W8OahlPx2!<-$hFzN2OQ!#rRi=2th~x;HQd-zX0i@SxZ+ zXxztJqaX{5nGq1yqVEJ~uF^JEmDjPw50xN^-XZ81o`_k#uEyOW|Ju`a;Z!$-{+Wb8 z2<#^Syhd5~r^NGw(h8;ZV>=GbZKfni#`?nek@EipP6CSW#&XLfJwvL z_38AY=%pSp2$1{d5I6GAcNS-1`#M~l?BJ2}^{yhl&@_yu8eG`Edk7efjV9OZcczV; z&9_3!D()dL`p*DOU66UnQG{B5Mpb6FodWaUyZa|5Y;zJG(gB7(ug`%3Ixp0^G9>jb zl>j$dsSqxBEoP8&EfDyZuMXCb5Xk9vg*X1dn0iuW!SlhqD0b8(N8<&bCIH&HCCuT2 zg}sDF&%rTmzwvQ#vEp#mR^+@srrT};$;KbcKDk%0`8wd$g=pW4jpMADF(u$}vpbGY zHxu*767_+g%8K79Bl8=}Dim6H5u7;ATav3#rCW!&m&|p6M)Ar%KqcT){s5 zyGg&J7v2UVRCKcqmG=%-+7GIfW6_epE7r{ig&?C|ZdD`tHs^FUzK8YX8YsLuiq2zs81)r#}g}=e*IF67-MX zmS6M1GnH#;q?<2QnczmUt-`(nhbM2R>IO9Ecf@bVr}@N1 zLA?+%$zqM&0kM$a%H>wd`+Vyr^dD*SG3u|o=X`#5C#b1He>I~s|8yQZUVA>2EyKIm zN?C)+vL~s3(ZX(-&K2C@P zbk&4ulz+7G5*3OOROrMbr#?%I_yM-XGp1K0o3Kt@LG8Xmt-q@t!Ng+b3VL8o(^Oaz zjK0%Eea(O~k+}KD*(7a&aFw#D_H(q~4_PXS;kM~@<8fKIBvuj8vA<}oGJR24#1o?W z{%S;R9RE~E12^0F+GUtZPL4z(VLZ-h0nl;9G&AU;KK^we=||jZarjzEZRASqgr>r3 z?s;ZtkehnUW}!vu49j{)jUm#M>UZtHHdafq)nZ*a>A)S-ciCsoJNI_=$0}p`J;56x zrWqEi#uQfiYllQ-8Xe%X9(U~OhdJBkaPUiYKY{PT(v(2nd;KeU&-@iXV{+D709qV5 zAstWD&R6QpUQz*-4_yF2Yd=`s-ZoIU^#$$QkU4(9w$|18Jnl2?@1uAJbx9{(Q2$y* zoEbb{Wh*ml(Kv3wp^*n;Lx?^YUnV2 zoe8NAo68dOBxYjRtvg@mPrO%rv3YO(*y361MrP4eiPzAHXOF38JhIX5ofpcv44|ox zvVYg!!VH}r3|K9jFn@PQmood7GPR%!=}n=q3?wg?v59B#*i#V+msgEL#w%Z!zaeMt zxU)htI?ow!V^XcH09nn+{sa1KzrD6t2VG4+Q`$Bl#TS1xm2!3?i@slxUej3AZ9_Xe ziNMx4D-{pwDmgo<`GqoKzTVrluXgbD+w&U%i^SzObfVT@x#1lat(;w%YVUrJ zI0F|EZ8_nP=J_cQTNPU_vz!BVF3?xqYR;K)AD?%~z1XrXRmMp$(am{U#mHR@YydkHfR|6I(y?8#+7#iIJc@k^p+x+f&db^ zS!URFJoTNN0>}72&$tG=g+y?3ddSjkG5Iw@H2~ZlWx#yVqc% zdcdMz>7Jx3)bZhU?0iAe3cyVex7f6eU9Xd2WWB>;3wusU!&iDDC$Gb!^#g-BPCD_(jYboT3+$b( zh_S*BE&aKG(M%@N+hp*4odx&yQ!jSWioNzF}&QMkj9UE$krGcg)l8(9ro zhcf2fG_mEn>3qA*CSb~5UbS(^{@!E_h4^ptmFC0M%V%$Fc8(R!LCu78;>sm_Zv9-S z;z60PUN387=+y3Zo=;Sk$foFHz`Mr1yA@e}c@klL{OJ$pSRxKOVXI;Ok{A4pObe`T z@z%S1*6P!sGESNFcn|+6R+e!ce}K5q@iyou>K9v}Z2oJz%Wj{l%uPjffr>~Z0`V#A z$^8bql03wT^jH1Jz}8U&2>*-q<8*bH^tYRZ!VhU18}31YR-%qAuKx2U^#6F0Nm{Q< zH+204vW^D%ZOY(`CD2*y_{Euubt$YT7ZaDbZ6$1XW-xX8sVyH`+GJU#6~I`;+#?s< zP#6Wv=pZNZ;L1u<{-=L-z%jLmGcl!Mcu=Zlw z^4LpJ|FHP(=sq&FoTx?**z01lE8)5d2C|SU{j&we7H13`C$2Ak5xw>AupEi8b;yJM zvv3h4hKj(ud~rCVm(-3T7lvYP3*k(LeHjMZy?hQSGI=}pLwhgw zu47jwy~TM;*osDLz<-EhJVVouP||08)bZ1ApGj`K%RAWtQN|8&X+A*$0Rk~)@5NU7U}*74mcl^RLHf%Vg0t!e z?hpidsGgG>If=a{?jYId$<@N*w|&@k*(2;tC&in}2R$^N?YV)MEGgg~4*A}G-)1!i z6!6l#F8iwMBbArFsjf(RxWPdc5481&T9W4Hird6M2Ziz;ioCUQT5%TW@?B}yITHy% zNb8=uGc%{Vj#)(JLq^NKcX_Cs22%QbD?5OcdFZ$h6t2j-_0_ZqJ_O2@cBHrdZtlA* zq8|!VRE&R7?w&`5nueuDkZ*_$QSk86%B>n^!^N?licGfm%E##cg82psq>!0)aTJSjveSiT&%jKX&TG>fV!T0rKnsUmq`p*%2NjA$-K9{eki z=%7o8XC)FPXG#($Teua3baD)!RnJ{H(P?ksy1#&+gJjiDBLOWd|2pkfZ=Z<#4cJ$b zlb-fIaSMEwd+cjrhr^urVXywEalc;;-8C->^F=CuZSE{rM?#mm&^eQ)FIfrL!vova zoC(e9$gSycip_LW94pX<@_;Q1f!WxJ%|yz!=H|6YykFo0eZ?r?f*gfir`iL4kl>^i zeVs=t9m660xAFA{%gA*A+s?sD&5VrF55pM&_KOJ&GM^qwu-=IxX&~(1)u@0Qk67rD z1SD#P;bO07?-y5WALD+ql!PKKb zMc9VGjIB!yHdVgmJ>UjVm_Z;&pu?guTeQ2m0_%zM>H%31_Cc(+S19owYw3Ek3op_s z5F6TJwakmkcnL$_rYD%>oY4L$@iqyJnsW=HFZ$(JR4SNYr}E4__mhOwLbY}L&$qjL zdBo;HVj;G!_4f~pIJ}aHGkH{dav-)nH?mpDM(DVvPv(s%arm61}TPTe-LYp#2tVGApx&^*3AFpzJ zyb>>qH$Odin+zi0tL;G42WM21FFiF7$5&FsJ1jEO$^r>~ZxQ**G`{$g5cR6zvMhFB z){=tMn}A;HxF$cj#?;;E8y1+q?1p>d2zKVp207arHOUXA(z z-G3cD8l~c;T{QQgk>l3PNdMs9PCD{s;Rgj_9e&#E$0dwSsnY#)K&!=ugTE^q8?sMo7`BR^_UhZ9etk_#w!tIAKeTNF z79?gl3{LM*@MflgF5}2Sg(Jiw`~*fGV6}7k(CIdEpH;-K;kAR0nUqMv@EZJt-;Je_ z{W${g-L|9?7Y~`f>mzQIqj@9CY*_4)DUh%?n*)selYN+5r@Swh!Jm$^5poHk{j_2N zpDgr-aELoaTff{|+n*u3rJD1fg?SAh2JXd^xWg^G)MSZqwG8i70TuB?H>M_Xe?tJ* z1}7}k1ag5PlzF8b7w+cOweqTikx&Tm3@2rRve751i`O8i_%|=|gMtVq1nxC%xBAui zobI3eYVe_2$UGXd`n~Wbx(B}8;?tbRF*g7|UvgFc{&3%*%qU0*XYf8Go97MD_PH*E z%UOF-r)abc?FHlhpc;m^MGNg;-ji?w$KFY}=Dfc$b8EP;LiQ_SAN~sl;Wg+4H^!~m zcjhg%B|@MP%g|SFu^PA?gvQ=?fpXc{7<}IdOa7ug{C&&Ob4?{5iH*|dS+csL(J2rF zq~wk;#%r#ON_FvctXSU)UYb_dquE4CZWBksMZM6Q;!Y9!D=J0fsaxQR$rXK?ylgv5 zbtD7913rF$ui@rjO~Hd~Xi6DdV?#BG7clGPM=kS9%N6Ya2-ipBI;K@=qo=uV=PAUv z8u6_|g6@0b$Pf3S?bO#C#{aHK$)p?!b8JpGIaRlM6w=u8_L^9rWP{G?8OtN?tjnKd z4KtEoZyk#8@LHdwwm_tvik3XTdF6L6D30tn<~^x6F8OphFW(nvEJC+5;smh5?E!+Gsb zCUP3(vTh>QyI&ZG2uSK)&lL+>1!Q+dlAB7f^KYlt>sHduz={<6v!J=0y7*-EcZ(;y z91lD5iO>)CeHB|aKWlU;$ns3hE9C&$mx&57pH304b=c?>77rReB8iQR4ISS%cbKY^ z;s$X&Td>q27N1`OI`q2D2%WlwKgo_=v{sz990J8EPvu69R-MF9sYr#D_zbV*D)pl3 z-G%-=k+?C7r4@!Mts~zQJXH6K6~t?ERV!LI(hR<(ZMwo~{wV9dY9OHAlWno;Vk&M; zJN_J~eZ!>%ac}2Eo80eJ{TDAI=}@#eS`u{0D{qH{pI{t#XjP_|_PJ$oYx+*U6tP@> zc#Dp|@bNbIviggXP<8dLRX&ki!VHwl=xi^2k3!0Fqyv1PfGmaXCtw=x2xScVbCI88 zhREv0P3<2Oy%U4Er!Ou zFZo~|pxYZ!r%D+*0^5l54}E{KEn$-1wu!tvzKi6r4EQz6_?2bCGkFl>e!c-UNKVkj zs9&fxOK=3Z3U^*AvMC-ePztH>)PE?jXd22 zqacWW4m;_QvetRuDA{K=0newp(L&2m9N;GC7hGCASS|ShA0CwTTI&%Y>Sjp^T9HbO zYaH`n5gim&LEp>IiqpG5QvH_3R}3G-%9Y01ysBBKtQ2ZN{YiUgyDvb`{q8U|QItPp z1lmeiJu&a;gW7}f)-=D__cCC=@sZ#|WhwLvp8B!I#88rJ`WjF2@`{V+W$F z=ut%)VgK{N(sZu>n6%%#bXO79dg=B!=;C0lxB@imQs`u};N1wb=)2M!$$)>xhnvkM zYVR|Ys~VV-QjUF;ihuep`A2nLHC++uNMeBpwjhPA)oU^$}#( zWhYIAOrP7M{@(5Wx2hWl2jAS;qxMUT987MBTP+7`TT;g49;<(G3E^H4b%rnp4$i|m zOZdmaNw=ROB?f!Fq0!qeACQkJGs%i_@z{`0fRmUESLTYOEQD0Y{Cn7p^N za%2K#tI%n#KH*N6k*CVE?SMtt4hk{>U$3S9VPH@0?rjrFjkhd-7#O}AY&LZ_xuMi}%c z^0RFDPvYQ`gyUFy?;Nes)u{ZDsqV3@(R#`ZP+apC@Ht0%OWuS1@CsADq?>|(NPz|g zowsGAp4W(*@-5H4S`;)hw4WHp%Frc=k}^e7-{Xf}+$FV?<2U7rV~;MrvD{M{Hr?Uc zK>bK@&mp&og%>$LjtZ;ao_Kfs>di_+tJF4y_j9_=t!|g%6jw~w^)pfP%gd%CbbRf& zQTnjzK&-t`230#-W|qHBW_Yw&k<-j6oE$XA|j*e^+p9wFJ>~ zAad2zhdg|r2>LU=$_bjyLZgkT9-?eu2ryw9`{BOY1EXv1y*Zj6f_>EY9Y~$fVrmT2 zV?jOPqLx_ipV^!maynu9XrVCd0GIeF`+k#W*2E+i(T3P=l$Ny{0QlAsx~niUt;Z*y zJRRsdk1J6n?RY_aWhXHd+7av-AanMId3DP!NtfHs$mwkhCSNeI7i#eu%(#l-_c_yviRZ9rZx1VU9S~KV+!4lvRtO!xDp= z0-Ld$$vbrL4Fd*Vd%K&CnO_v;7ZZmrib-D2Gsc%$2s;|wq7PCG9B4&jiBOMuy@TU^4 zMCAfVG|7S(`hE!)!48;oDMBJU3VATR@l66d?d>tpW<(_qv@I4?A!MoBUblIqHeC4O z-oj{MT~*3yDra90BjNu#-dK$MkGHIeUeqOyU_&VXq!)g=$0d&J&Df+VKm4&P9ITQM zbT}WSHYBI^eBqeH!=sT0Q|a%klt|2wUr-3VN44}BZj#vq-0i;+X7ihhU{S)6c!RQ; zfvKT({`eQey9fSVqf$ZbbkPPO!(Pd@A~(kPn~DGHA<9FF2v zKO1W~T(Yx&Bjwa^Bef`WZ0YKrA|mkjeX-uNZx4nS$->PB`DuY&S#v*5wE!4mwV78M zSi+lUT~8G0Qxhhb(XfNj2;7LShBmSw?HtztH?;#**^Ss92%GTCN`r(KB6bDD6ze0o zsEU;+Jw(CcAG!J6X8M~S)V#kC*$PWmb%d5K_>8@1o7Ki|4Si0ZQFlw6V-1YTyV+`U zB@&Q??n#;_G#c3l=Jt)dXpS7rSZtnYiuYQc-(XAD!za>)W26+nhyue^Vh202H5+;I zo5BqzMA^I@#XPf?JWnq2TtChueT3(z08cz$tnq*9|6=lALi|?^|Fweu+T(xN@EB$e}4aU&U4Or-|zc*zx((5oO340?6@Hh*KRHV0FSYezB%(w zXP#>uFy^%g9fo7xIH^Xq0RSL`woeFTW{Cm-M|xS>1lpJ$!@E)ZFfK%jD+v?oM`fY` zIHVIwb#e0{1tMKZ9$sWE)M8CN3h71ELRqVt;!LS}Bu_7+a2m-X{J5oCxR2XGB1%Ua zc_4`LM6lvNHMR6r`>6g99o4XmOvT2T$Jg2O8*A^-ZJn9^uOcf7g&k-uayXId!F zz(6VdVDujPLcz;vyt=`R`oRu@0NUm^km4T70w{N<2;iw>|1 zqmr=ZqyS0~&5dLb%v4iy+Zrlfk4AC{q|huW6yLuCW%jqqNIkvnz#K%%n7X)mk+hcI|)cc)L&$;|F;MJWEfN=h{EY{BJn3cWe)TH7(}kSKA|z znZ1t2Y-(vW0p$P)GXt+{89FeZt&AF!{`fat}wkDvF?P@uxuD%Hg~MS|8f z`KYj(K9~ksSk=~QgA?>jtjrQXi(lPurn;$Dp=sL4=2n=_s`L~mTYyPIdh~93Ez6CR zw1+(8h0F#2FjLxwIEeRNy|JbMnT0L+ozOk8_sN}(Pa_pz?#Tq;XR}_2fcic5^XWiz z2BGiKBpLR}h%#!y0)j-0_~jkU^5NVynzRm6U_PzNQ4b=60mJfBW&P%aY5` zw1ajrVzg>#?RM)48IZqj2#luLp+ZdiO_a|?*Q;!$C?wq3VVwiCHQUkUqk7lO-v1%V zK3y>biRm0R-OID8?I!3pTY2_3r`Z?UU@6{ULG}3x=4g)RK*7ayXRoAZoBR^uHiKJRW7s;G~ ze@qrkjq=wa^Q};N)1TZq7ab`;&_yJ6E>$l{YTXqsoQq9ciug86k_9GhE4gQ1FIr@y zZc9L;(S4Ob^Nl3e+r0OJXi`7ScTxz-m8%g9pWKHq(v=6lnefx^Pm|CLt8$JcUcxJE z+OW76loB`>{1BLl<74J2!%oG!SF|A>a&X(&akDVE ziD}x};3X#sFZnVYD-}0){li5Sp9~2Y)lkj4{k%=lTj)~`67)zGey5ZuGGL;Q>8C*( z{>~%XH}0}MgY1Oibf4BSkoFkW(ilI7d$%)nhMEAM|nq7 zzQ+@nst%-oK+%`L^xwMXc zn>)L(2XxDYWrZox6R*54PwONfb_U}W>;4g?G3{eJ^A&Kc&N?BOlobnuJNhg?LnU0T zb^Au$O%D2d5fY@|ZH|~~A>GM18LSfY=?A8P4Rz;Do5v;bXNcehfc<33V@6mVwBwB8X1FlKMCQR#cktpx= zNl5h677f^~3K#(Wz^lrDwMYlnmGgupm9`JO>WN)IAaC351LLjKr3?B_wfy~WKq;iv z6SwbNKWyq`AF;MV1V}J&$$;J28hWw#>YGGs@t)uaL!GCr&IvJCTlwIK8)TeyOFD6W z;p^JXp3_?_aJC~mxz<;&R;lrdeCDK&-5&y>2(xI;!7YOLS^w-*o)!!yW6h=$qV~3! zqI27}=z+T3p?#^s7LZNGCM(@YW*xJczJ9eOB3ghx z6B91dvnAi#m2Rq?aX%)qoIA)WOH9ROIwW#@qVmx2S1aMx4sQ9bYS%9+VDQ*J`k0fJ zkXM6rrptTrRS5?V0fq^pG`j$f^M%Y4-w8J@UPHYd+vIavY+yNT3l>6L5Y(1pUxZnA z&f8aZYOGkfoVw%N^(>9fwf0M2ueaRA>wI#3H$iGaM^57M(>*(=4>>&`%e$|+7>|N` z-d08w?&Rm5jNVTdoNj^gVf>ZPcuuUSf(DV@S)7Drseoz!%N)Sf%q%XUT>cMbeV2|B zi8RgFazELeGY!q_XApu1ALoV|PEDRR{@S^4qXu_5IYlH47gzwT|v$-8qXoLg;mfqYN!8{uu*mc74chEmv-bWu@*NqI^ zci|vAZse%olaC73Yea{{{q||6_6Htn#FmNV?a0b~vJiA>&!x$%LCjJ+I>|rVb#z@% z26)HZd#OHNxU3LeJ8^RO=#PC0U`gJrtCM3?o3fM&s)9TP89X()nk)prqb#YND}fD) z3w#7GlabwHsr5eTBXdJPXb)y$yIwxb7 zn|fiUU9kaPn!1|q9w}$%c7EUQDL>0P6&NDfP!ktlR5%dV-1kh_XYiW81n|y^%$h0@ z%3TKe1^4Dz7twUfZ)pW5(IDjLx)lTeh}a9*zGqJJ5fT0SXmTmfde%f!L;Z1$q9Z{RVer_it8$|047F?3&P z^;I7q3$pAu{Vhw^G(X|P*GO*gIVd)5NCMVh4gEecvA)+NB+8GsH0q3npGk-Ez|(bU z^}J>%H@Sohh}fofl}6TH@cBNo+29PLSNG&4#Ylnf%Ma2Q@0joDm;{9_W8jY)P-3ZX zv`mz$8wbqnL59ye8RCzR`Bjy$YwvmW&I(hY%U^2YtqvE^!e>+ZHeNZa)6>Pnthx{M z>U6`GwQg~O%bSzN(6J>QF`LiGLFw-h7}VwIef?(4KgcZgRgy)l`)a#TCIP*`wc3AH@p!1ILE^=3&BIg_JW!?$rMMB)Jq`QWQKAX>#(M6uRyx4v3gtKR`^`6qM z<000WCApKyIX$pBR&Q6;_-m62NqHS%SIS51vtC<1qg{bhvuwDXHBfm2Y1s=UETwf4 z*ZE9CiZ{yMR)ygT*>MLlf`ILbu)CzzPZ82>=eV*$6^yGtMzJBE?)yRmO$_6=7MrQZ zGqf`~+Xl`n_%{z?Lk#kvLnjfb>Wi4{?gxsr?Xo}8@LzdL~ArO7Ffb7<6i zc+j+vol%>@otGONjG7c1G^k9rL33E$u39<@?lH6;FcXHKNIvjh1Ts=A0d_GRM82x)6*0j0o!km@7?WF#EA`3@}hfSU1Ibo@j z9&gZ$A$M~G;c2>*DABLVAZRyTQ(gbfxx68r>b+DUP*@=dy;ITzxzmSP!FfW&EsUqk zercp58$@uhk2$iszVUfz`fxsi3%VwHR)C)7ei!iXLc>HczT8mNn{%!{o{=|RwB0$) zOK+92*)Mo9{-UCP(6?j|>U?b<-87E+L!TA-d!GnMq-0e$UvX{x;JUi5-}^X&j~A(Q zS^J{2XB6rwc7BWnxu|UmF+>vQ43Z_}-lycJZQM&wO;WnR?Ynr=H9LrB2t$9-*{q4Y zFT0t7-PYw%rebs=DPu5&?2z*S=8}0 zXR0y6hSPh8lZDCMJedVq{BW08o_E8C@rN#2jYrk?rqoPu&flQ7MX)RWVGaQ2j!D4KyV}=nz=HkwRtMMG5=0TE#6NJ1Jrwr^j9#Q#+*H7uAc2sOr zS&<_SFQLLA6`tvWb3je8G~l$IyaQPH90ZsTBBo5L6?mm$;lz=vLkS+StT7?fK5K@j z3F`;voJhZ=7G56yzM$|E##Nm@=UB9ZJ{Lbomi+=1PJ7OuZmR&klW~@1mbJ*`ni358 zKmj*{ciM@UvGXW|{NO!D)DX;n5tBh=CDgY+*!&^?ZKDAoZ-`PL{~TcLdJ>o{N$>%s zdJ*2ng(4XbAa=bI0Z;-F^n0<%cUUu^5$==Z^Z4M zgD&}i1Av->>f_{BeLp?hZ~Iw#^%f{x>ABa_u}odHa`}4s%*ws*mqC`u6F(R=!E*1c z--MbPOv7FPlF z1SZVAy{P<^LVcsG62k9 zz(#9^=2>cl(RMe1-IJUsfchGb0LNGmuvXYGm-Ds#&|tv@o4G&Y9j2DZHJ3nq+_mu0 zuk8UqPx>&_zdO4@;%rh7=e*=^y@uKhi!|%*jERu<$~5mn1VO9m)0v#29}65(JntSz zB4iujLX}dsIAgS@rKwc8=D>IfWqib0E7tevzVFLJU~Wb4rja4l{1EnLHra97j>d z0{+ie&rdb_N4*;`M%l3ogKwGqU(oHXkzydl#347HZ3A9V$9>ZH_i1;CpNBPF)(ev6 z9w2L}PmCG=7$o(N4Ny#u<*%EYxmf`%V7~@G(8r>(NXSj=H6tW z9Sa3|Ed6d431;wQdHt~WFqGo$7qgFTkj=00%^_SK8H%K?yIw=`q2w2oC;n&RKS=bn z-^pHczeUv^A2@<}=Tbtg)T=2Ti*~l_)p;FcQ=1zqqQb4M#+n=X#&WYi&a}Yp3%QaiNC3u;zrcl+1Aynp`E`kQ;NEGJ{8bgHh#A0%96 z6%R2?cA-JOziGop8&jJe$bB7#@zWhoZ+OpCR5(>W7^&sM@8$G5_B@gkDM)k~z~W23 z_K%ej#w@%wS?-^I7T+DNV$JDnfpSPKp8gRk|EPR~hq0fnBL4lUikwL@2)fP~xb!CL*$iGv++uGCRb1)Sz{Mt{_+jbnk^6cCR>xS2lWmqHYOmFdr|Wf`ce4q2!OhML7cF6KE-DB6;b|`hI+2Z9lBu_+ESmEP8SvnqaIAr}!d5NM7NooURe zhI5}&wLG5?K3ponoqWC_LUOXYUVEM|b}v;JJi&BNR%HsX;|fY|MG#g~hFf;mCfj+< z#fh*`V?Wd);}3EQ(oLlf*t6s+YwQ6M6hG^yd%#TdlSO~wIDLfCF26OFf}Ry2p#R8` zX1#J(lD78hyp7qqq4t-VlD$n;^^NJ$oA&FP171MXBE;yRnDRfq8$v_x*m~|MwRc zUOj&7)GNk-J-?U z()sO@FKsXM>GnDen0D^0Iy(x1Amfs#qiiFu!cjxp;|<|liw#ZPQ<3WpZQrTo?xNZf zC0AYDLlirvIuq#FGaVPdtXd|XF-+GmJ!In0^g|1)<4*%?B}>9yG&i;dw}!SRWf2<2 za5&V5wl2znfrB70Ov|t=1RAK?$|V`0ygEH$hgr<2de5o$fe%ui+)3-RAD@CU6Wjag`@q%H_pdoz}Qxh`4pnHf7 zOF&uT5SwwwB-$9y9?IZ;r-B3`DJBkujCvkVAc2gUE+Uo#Y|NWMEWruIrU$H4Gr&co zZk~slX(ECSt&azz0hfc};yFxI38VAXC;z+xV>iEevEL5E@Z;To|N7(Z{ql#)uMO^B zdt+r~4Ea#yK7HkIGyQ4&Hm`;_{Q{Yb~~P49o(4W&rB!3@_6d$c=gt;JI@ZL-g`Vgp*;4K X@ WinExe - netcoreapp3.1 + net5.0 true false true diff --git a/PixelVision8.sln b/PixelVision8.sln new file mode 100644 index 00000000..599a766d --- /dev/null +++ b/PixelVision8.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixelVision8.CoreDesktop", "PixelVision8.CoreDesktop.csproj", "{2590A596-C437-4B7D-A91C-0AD59CB2DBBA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixelVisoin8.Tests", "Tests\PixelVisoin8.Tests.csproj", "{97F0347F-2A33-4302-9376-C8B46934F154}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2590A596-C437-4B7D-A91C-0AD59CB2DBBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2590A596-C437-4B7D-A91C-0AD59CB2DBBA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2590A596-C437-4B7D-A91C-0AD59CB2DBBA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2590A596-C437-4B7D-A91C-0AD59CB2DBBA}.Release|Any CPU.Build.0 = Release|Any CPU + {97F0347F-2A33-4302-9376-C8B46934F154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97F0347F-2A33-4302-9376-C8B46934F154}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97F0347F-2A33-4302-9376-C8B46934F154}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97F0347F-2A33-4302-9376-C8B46934F154}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/action-btn-down.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/action-btn-down.png new file mode 100644 index 0000000000000000000000000000000000000000..49754675927ebe4649f61f57b2495a56608a1b3b GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`*`6+rAr`&Kf6jmSzkl8qJLZiK zE?w@{sBw$U-230<^|2%l?oBPz8dV+7Ue}Xxe`q{$(M>mdKIb0JZmUTLRxmc7Vvzo8 zvF2lsPCxGgm8V;NysXHbz13iHVX zBu4oQg&fBPk{zG9xNc9px+5o3)XzEc0_z3Q$3`M-Gd`RWVr09=&|{$RBz+It1Mb`y Z1_ljHeo@^Xe+i(044$rjF6*2UngF*RCJX=o literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-over.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-over.png new file mode 100644 index 0000000000000000000000000000000000000000..26cb1def8267dd2c091c1a42f29cb9335f2ccb76 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQZ1e?jv*QolmDFm@ZX+UB*t>X zBu4oQg&fBPk{zG9xNc9>@aUd@?!kj^63Z9rykLrAn^v%`w@!u`2%2Yg3Ljo;{Ck7c zftEaJAK{*PTMdMlzm;G+AadA5e&-I3^=UlJ6HEmc&unD$mWbJ1Fz4Z|*2gZH#|#o~ nUeaPS6;@wlYHVO&z`$_-o^rtds^o1z_b_<6`njxgN@xNAP+~*( literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-selected-over.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/checkbox-selected-over.png new file mode 100644 index 0000000000000000000000000000000000000000..f82cfa33b74d1fb94c555c1f8681e5b24b2c4efe GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQZ=3~jv*QolmDFm@ZX+UB*t>X zBu4oQg&fBPk{zG9xNc9>uqZC(KfKoXcY)NYCcOz__Ob`p1*IkcL4a}Lp-c|pUAYFn z2De=9vMzrs!FE98u*vzX-M!()ZHy;obzD4iph1-nEb zjt^0H%pQMY@)0(iB`I-%X(CYa;jPxk1=AX zBu4oQg&fBPk{zG9xNc9px+5o3)XzEc0_zqYoxmU0^<>fmj0=-?l%~mtG0!NF@>P+j sU^Y1P;8yG7C(;{$YMWzopr0E!zh-~a#s literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-1.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-1.png new file mode 100644 index 0000000000000000000000000000000000000000..3d00f30c98e41031d758d97deec9724445fb56b5 GIT binary patch literal 225 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjD?D8sLp(Z@uS~u6`@Dnm0T=JX zk`fXU5osO-MhJ1aNQn7VFpK+W z2q@lmNGS&Dli+(ZDK$aSP0^5H`r!>x4r|h!_$-SG1s_^0P&pwX!Qo=Gv`u(RgA~Jh zR&KRDirR-dw>3y5TwyvS79iEhqPt+_%P$)mR&45+lyD@A(X@+Wj#z;8rS>`%W`>mG WY7GWLyC(wO%;4$j=d#Wzp$PzQaZBI; literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-2.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-2.png new file mode 100644 index 0000000000000000000000000000000000000000..ce13afff4e47590d068fbb7cfcf92ae8d9d5227c GIT binary patch literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gj`#oJ8Lp(Z@uS~u6`@Dnm0T=JX zk`fXU5osO-MhJ1aNQn7VFpK+W z2q@lmNGS&Dli+(ZDK$aSP0^5H`r!>x4n1y3GDS}wDg7yQ(Ad$z={HAAKw7-z%0-*S zf~g0aIP*_*Rj{$yOzg>1*m-ighJ3)JNgPoQoex=b7hEY|0|K!aF3*$9KXjyJPEHYW rC^1^Pigk*}O`!C&(}@W$+>IDsxmp+)?msLF^a_KgtDnm{r-UW|IYm_K literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-selected.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..77c675ddef967e7fb5070bcfea70eea7ab875ad6 GIT binary patch literal 221 zcmeAS@N?(olHy`uVBq!ia0vp^8bHj!!3HF|gZ4%PsU@B+jv*Gk$vofv{+~DKV7%;L z-JtN}=hLh85_~|R{%-kqbN#m2`0$C#&#(010RpvGdSHBAPbR(LqojmHz>n@Qv&APC zu5Le>e3^f7BE#JN^EP5Lm~@%Fn-bP0l+XkKR;*Oo literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/controller-up.png new file mode 100644 index 0000000000000000000000000000000000000000..eebd69c88e6b4304b3b5931d3cff1465c2a3e52d GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^8bHj!!3HF|gZ4%Psm-1)jv*Gk$vofv{+~DKV7%;L z-5`*#rzU~bh9!E}cjGHltc(&KZ!dYDo{*5B;4P=dKH2^GW8?nL#>PfPtzEq!{P0%m zV;%!LW@ctC`DKD??d#-jDwX^-kYc;=^T(OwM$HRG8;)FP;aeAL(YJ{2SlqTPT<uSEV7tMS{8-SH*Cj`4;?o2P$%G?JcFr3ZMVK$l_2g+derV?GY6+h! zu@dLb{yKL62ok0o>s%Ae1DiE?_jtqx`V;T nSjRC@!hy%ZueWDPS~>&k*{E9)uI8*jpD=j3`njxgN@xNAU1?mT literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-hand.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-hand.png new file mode 100644 index 0000000000000000000000000000000000000000..aae769f597d1d9cf06b322dc76f4b00ecf9ce36e GIT binary patch literal 261 zcmV+g0s8)lP)pND(*yI>tdEwWW*YLoc z5ha7u#*Af8;1;s+h@z%MLdh0cGlmP$U4aY0G{d}(VE{1zIXMFW&}d}Hn%?L{00000 LNkvXXu0mjf7^`dn literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-help.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-help.png new file mode 100644 index 0000000000000000000000000000000000000000..a4285fdd99e4c1ec75103270e9ccd813958f6ab1 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`8$4YcLo9le|D6Bu-=3MZf%Vvr zuTM=c&bm?I@-XMvf1dyU51Y(hv0LCu&9i56BF+!k4w%fhTF@1|dFJ8V9f}6bGbV_h z>6mmd+uH1Kwyr*B4a`U>rg()}7T%FJ`v4(xH@c)-J))5$4) hK#J`K!>-Ff7aIfwtT9~pbv4lK44$rjF6*2UngG`!Sxx`| literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-pointer.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-pointer.png new file mode 100644 index 0000000000000000000000000000000000000000..63b5c267b604fbc33368b17f6dc51266f409aab8 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`H$7b(Lo9liPTt7XY#`#g-jS{p7M=@Wb;F`wvmRx!pV3fx=A>Ci&^_vDvCs>+N*NwsNOAr_P$A@}hpu z^&SPgTW-RD$-tC*cNmw#HA#trq+oD-*_iR4{O?}L>txmb!wV+W-In literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-text.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/cursor-text.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce4df928f041906c8a8d307ae3cf279199b2bc9 GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`8$DedLo9le|D6Bu-=3MZfpzBR z*Qc|aq;6EW6iOcef`moynu0&ioL&84Hv^lWY(Q!P5LlSMwvN$BzA3z>Ey?u2nTKY~ zKybK6LvoJP!w2?<|Nl4m^ZB&4#kHx|e*gbl_MtvD(^jM~_-)78&qol`;+04d5_h5!Hn literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-down.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-down.png new file mode 100644 index 0000000000000000000000000000000000000000..b3ef755391928ade34f77aba367fe4c5ec5af42e GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjCp=voLp(Z@|I}IkuxI9F z;ex+w0k_dK+l8|ho=6q(l8M<}AhWtnGSDcZtIJ{$mo?C^KdyR9kA8j7k&@&2>BLdj zE1MgH9Hy||P?8UCa$t7}w>Toz!IvTD(z7LR8v{eMk;NAI^}G9leq!)+^>bP0l+XkK DDMwuB literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-left.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/d-pad-left.png new file mode 100644 index 0000000000000000000000000000000000000000..597444f0baf01f67ee4d4952edeb8e2b44052c0f GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x}o+U=;LpaSZY3O#V}6{llJ_myuhM zHH~lk$5ZpI7I@8MH84>2Vr!kh@eL<45FFkad0(>Ul7;4GhtmfpC0;URvG;#%*gUOK z_3&2i_eV)n>)IzOAzouO0H?sJ>R-!WzXkt%6tOR*;Fo7v-6DD?1t+8z0_kear(C z=P~m_x~Z#RwxAtZd>BPvEX&%QllqNx+nU0dUox&k|h~&NLTXLM4$N~Ej&429vg^A{>@8G zNH`$(?8U48n3xvZNygJ`8#fsl@*JFcXkDy@--ZLp2h$l=9lgQ0@X;*0!h|WuI-`#o xozjtLJ1HXX;6Ev3wb4h_#4cTh;Vap~pu-6?rHex;OR_Id><&|o=fs$XIV~@RPZ~6w z7oWWD#qd6VeZ^X`Pu8?Qnli53hh% cTMGk&z)B0@8BxgrK+iIGy85}Sb4q9e0H>&G6aWAK literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/input-button-on.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/input-button-on.png new file mode 100644 index 0000000000000000000000000000000000000000..8dcb0ce1e9718d674d18de382dc2c7c056691489 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqj-D=#Are!QuS~u6`+Nh7p6%X_ zGpPxQ2?+@i+qQH$ZYz{^d7{~6!z|3q%P)=w##)(k_*-gzP&`_&`{A7YYW( zG_pAW;PreI??U03R?G8!@4~IVhg&^i5V1&I7OBe}Ca%|j_+Pozdl$+C0PDOVu^vLEc-?EjgPZMLkPHEUSfu_s1qUCU9f8_9pf!Zc}BQq@qAy4ygi&fS}{OyyC+B_IRTq zV$0zG5SOV30O-$W{Te5{e2?4wDuB*mT=9AyHK3dY8rLSnxSrx3xB29ej(wYvayd0f zxm26KH^5@w<}Yp+WPP*_7O)9LsqGC=s90}73Ic#|>8?MoAmvhpsr?V6To78H;Rn1v VW9)!wY1#k)002ovPDHLkV1kxpTBra3 literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-100.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-100.png new file mode 100644 index 0000000000000000000000000000000000000000..ce17b60ff557f7949fed24daa8a12b3cae28fd6d GIT binary patch literal 316 zcmV-C0mJ@@P)*T+0 zr%p2i#z4YYq!b4LSo#)hiY@#8**}5+nbaalcrJ(qQ1SP9Z#}Osw_u0^z~WSx1_ntG z>yWW{-gK%sT_d%W{ffqo#qKDIk2#-_34k38RS82?iVz9RRiVxS2jRqV71z(#$~kk8 zH{B$RLu;27?4X4laA*Wy6@6Pn-`4Q}u02?ogK&EsfHWwapj64}b(aC0BdsN4PIK=7 za239dbPeYo;7^ww7C)@)rbJ)Y)Oj$#2hv>60sy$jh^1IzX6I*jaV7Cpzz*+w zJ20E{(DyK*W>cC20L*;_t86Vkzc;raK%%usGad^P0o1%ZZms*}=@JZK0BlZ;sW3=` zSRWair)BLlr!`tj)xW6C4P=|WYCf#_f_wl{f;Km--`Jc=@?bki%bKOahLSn1KR;jA znmPwA$QVsN$-#i8Dxj%~ctD#Q(OkNAy~6<7ph$+=P7aT&4v-SLS~9G;(lY?wh3`dL zBc%uU(P4+pcMH2I(Z@AS9t`k-T&YI^0QmS*MFV2=KS#y4dIN-ScmBSLx6l9p002ov JPDHLkV1iM-flmMc literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-120.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-120.png new file mode 100644 index 0000000000000000000000000000000000000000..644a8d7b44f13c38f2a1ccbfcaa0ef52aedff0bf GIT binary patch literal 312 zcmV-80muG{P)nm)-eUL=s;G?9TgU zW|@r|Gz~`7WK44am}(oA@rwL@tFJ+Th-(pN+!sUwT=U0q*Lk0(c`(ES*ygUWD;vZ? zI)@zE7Nf=aqQ;7U(LBw)b{NH*g9i}-b_QCIF?U5((Vl@>7U=Gw zvIl;2+1cjy46pzS!pY4%7@&cqta||f;PiZn>w^J9^gma{w|WB~DtB$TOBde&0000< KMNUMnLSTZ6K!#cX literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-130.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-130.png new file mode 100644 index 0000000000000000000000000000000000000000..102f6dcb006cae546d6495a295897defe307bc78 GIT binary patch literal 303 zcmV+~0nq-5P)yrtQKI?h|3abi%bl)cr8G80X|D$hNA;) zzQFJSvcdez&%iN0!;$4@fBT0bM=&4YGng1a^PEhy1y4^*XLx#II^`C8j5NV&I5svu zJs1|?$|%?j#O0IR+vjmxfXzktf&?aq&-EAU77(%spQ}l-fPn!s`=bMjEuaJpo}z+W0064}c>?kD^YZ`z002ovPDHLkV1j!B BewY9N literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-140.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-140.png new file mode 100644 index 0000000000000000000000000000000000000000..b0fbd67f16a9b6fed4460a0469e38edb9f2cff30 GIT binary patch literal 299 zcmV+`0o4A9P)Mr6&{ERnXz#IOXf1=w7GOEb)Hbb!qa z3?HByitZb1h9k?*{`L<=j$l5(XD~5<<~f;Y3!a{s&hYfabjmIG7-@plaBOURdN3@& zl~J%6h|4Frx6k9Y0Go^O1qn~H^2idP)7O;wQ?NWNr@`qDXN|S zzLUmT2VDmf#%xM)0DyU@AU6g3{bBD>fJ{0fNq8)X1#sf+VLPms$8$8qy8|qaMJWvD zv~C>$E?ix%4urbKH5!Edi~5bGtVCyh4nw#Y{vyeNDJ!soIE~yC-hFr-aE`DbCyw`= z-XA9yd;{l}C$O%fF?4LIoz&X;6q|a&YJpk?^ zw2{_u?g1i)9i2&ZY+&)-!abDaaZQ~^141Cp^(X*<|NLnr15)CDM#Zo31@~@tw{bIF Qz5oCK07*qoM6N<$g4Rid&j0`b literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-170.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-170.png new file mode 100644 index 0000000000000000000000000000000000000000..26146e8987b0daf3223478744a803b47186f6e5c GIT binary patch literal 318 zcmV-E0m1%>P)~Az*i-^Gw;2f zVJ2yzZDB&prX&Xdn1=$^=|((%RnI7aL@SX-+*e2}kw#wU8Ps{!%Lo&|2@;`nZi#pT zIB<2lv*6|V>iy#wO++k_OH6mi&M}3%lZ;?=O}5-uWg(I~eD>S!n>L-jKyri$DLKu# zG+*y7I0qJS3?`rCXo0FMST6<%;D%vx>D$U-0@}z+gxX6^?}siRIkHOP?kx9A0KX!X zNMj`T0LnI{V^1fUt_)0mSolR5y{@VAXn~NB<+_&u03Uyf(E?-eKdWLWe&nutBDkm3 QQUCw|07*qoM6N<$g58URE&u=k literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-180.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-180.png new file mode 100644 index 0000000000000000000000000000000000000000..52155fdbace3946ec26b3407e884a6a7a3e21f92 GIT binary patch literal 315 zcmV-B0mS}^P)kH;R_O&96r}$Sb*#cLK@N4U~@eK1CG)ZUt!0< zfGC5o8J^088YmPO*XS-M+5$or;d3=f7BDbiW`A@*u?3WX!BbR_3jomQcUts1bkhI; N002ovPDHLkV1jrCd@TR~ literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-190.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-190.png new file mode 100644 index 0000000000000000000000000000000000000000..a2766a15d61b88bd114fb8656bb932d631b0f4d8 GIT binary patch literal 325 zcmV-L0lNN)P)QVMuZDAQggmM zUxym46RQJEzPjD5L_>ywbF@yx5t+h#cVsc+-o&U8is6!7?wh)@{;BY1za75ms8|P* zBTOiDg=;R|*NS=Hfr~f<$zO7?KvP%jE+z@!3&Z5nx2uK;Xb(jq)H*r6AG(0#$TboZ zbGc^%xC>t)&5_&#DBDz8b{KSRVDiJl9!m7Orp|)}d_peQqXYo>^QVXwh{6A?imCVk X9u9h1BwV$H00000NkvXXu0mjfdiRJf literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-200.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-200.png new file mode 100644 index 0000000000000000000000000000000000000000..78ee48679b677cf1e5a35537c4154d832781d6ab GIT binary patch literal 319 zcmV-F0l@x=P)e^i|MD{!ieavY8IG(5mnB$J5lo}BMJ7&{!Q`+x1R22N z0H5oho|ul+a2WU)X#!`X#|MTFu(=4?Ky1E3)-(ItKNLBF`2e56!~mM-WTGv2dSW_8 zT##h}a)copj*X2^4~7M}aw9eaarq?o_IcbEU~>_^Ac4u@b3KLy$i5(?5nT;7*E2AX zQP?psU>11DhNp6&1`5T+HM+}*wt$dD_*_kr1q=+B*&iKHYyl-;@Dvr~0sy#=eBA2? R2!a3r002ovPDHLkV1fhze}(`6 literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-210.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-210.png new file mode 100644 index 0000000000000000000000000000000000000000..523f9ad132c7938b5fe38ff2302a8b00f975f406 GIT binary patch literal 309 zcmV-50m}Y~P)hNByd3+PGfg5QQ9ICt0rVMxEz9E0WKGy zTk<788KDQ7h6TvJAfypp4K~*^Fi@$mLpD5> z3pG$EF0RpCPP7GtEW+n%k}P0gz|8*WfMN?M0fVQgAQu1tyY_R^V`)8O00000NkvXX Hu0mjfod0|$ literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-220.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-220.png new file mode 100644 index 0000000000000000000000000000000000000000..e890b3d7f4ffdf1456a29cc5d0ac84ea89eeed26 GIT binary patch literal 299 zcmV+`0o4A9P)_^Ac4u@b3KLy$i5(?5nT;7*E29ssjx#fJe3PIP$(|0(Opio x1%xcZ=W3EHU|_(^{^)>W3n&4Dr>Gzo001;3cgQ$oLBRk3002ovPDHLkV1htpb;bYy literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-230.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-230.png new file mode 100644 index 0000000000000000000000000000000000000000..f9eaf54c2630e38f431eb797f836550aec72bf41 GIT binary patch literal 300 zcmV+{0n`48P)h_ie7^G0GlPG0Gj7yqAhrOVmiaq6VoZT;A5l-R>QHe@#(>^ z09QuAW*{z~0000nm)V)wMI`Z6z%1{Z zpUg%Lng%0kGNw5IOnnEI@rwO^tFJ+TNNSN}+!w?GsQF{R?Yz$qr(lQ!u+6D4l?{?0 zogv%ii}OV_r;=LA4%wK;Ns7A2oj7fgrnUkpgE&c51G`erqn&{XO06-KNWlAM4FJfh z61&-_^WHr$@>L>f^i2*1)J4t?yf?t~lA3eR+CL6JS`^MuswAsQ8Ng+vwZz1<>>Yqz zh3`jthRYuK(Pd|w+dCivIEW;gc`(2S(z5Oa0D$B3rN##XhUkB;if{D>_j7o8T4KFM P00000NkvXXu0mjfbBl>G literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-250.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-250.png new file mode 100644 index 0000000000000000000000000000000000000000..a499e0a7d45e22f9dadc5d953e41846546296417 GIT binary patch literal 315 zcmV-B0mS}^P)#tsdL@JR4o-1Mn6#hKzjqkLqy(JR?hEp&NERrO~ zA!B&fbXGW>BbAiBMZ-ds7b0Bc1w3|JXA+}8%7BxkWzE7l#$*RvX|RL}v!*lFoL_Ha z+}Q^l*yntPh~CNGg1)VwZ>w+tcX$}gNo==i6iAK20i~TB?-yCXWn?SKFy`t7Lx6YT z(?oa%X*doVA}pPf(0S*KTpNC@d5DAcmBdw>n8vJ N002ovPDHLkV1n8qgy;YO literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-260.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-260.png new file mode 100644 index 0000000000000000000000000000000000000000..34c1fc7ba8861ec1fc583ea280845ef9a0052eba GIT binary patch literal 316 zcmV-C0mJ@@P)|`koTTETuRR(L9u}&Np!W)jXpBnbsmrcq|A4qxsT8Vzv(TwDsv;2;fR zePk}ay4}6vGDmAE{EN)Se0xyE&05IF0MHyDh?#54g4(he=8=X|0dmA4TpY#a^R>po zbATYolm?6jAkmnJzABo!qNc7!8*u=rR4$AlT6-*jc2JO@R>|@G&;iJiuO(*9=iUME zDnc7&4suWQr^}9u?-zDcCSTXmc{Csd^0^)bAaaktjLCp0k^Iq54)_5Xwt9ZzY*6_C O0000KGt`}n?@ zeHAt88X2RP6Al3V*nn|4G23s|HAzsgC1T*VB2%E@&&|U7A8rrHl0YEg8mvQ#n8e#; z2_GHLjc`4NEvb2m+{ALWqHxz2OXMqH8CVh~wirPLRz?zN!R4I&>+SVL?*Rip=F_Bk z|G&vDs?!bt-&|HvP=Phj!S#0x?g`jMv4B<^0Ics9F0e9UAlVn&Y)>GoNI4~PjFmm` zqsLCdmji!MIzQJs^JGCx)Rc8A0T5n)9i0VTBKuR3UGM={es%g=1cF@v00003mrzO$@qzpKS1m--V8E_e4L(UwJIeorCpLz~b#uk|Y zRIl~2Z>QG5d{uO916|vwFcrWBV`Ja8Y~uhR9TYBW48frN^CknZ{4AuB;J#FOA^@I+ zHju_}*#rFPvcu-vNm!KZ>zZb6256vE)`I{5@$sk12IQ#tqhB2G1I+(=ihjVZhyVZp M07*qoM6N<$f@HRX$p8QV literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-290.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-290.png new file mode 100644 index 0000000000000000000000000000000000000000..97d1fce63e9d9aa64aa95dbb7a8e4fd195705054 GIT binary patch literal 314 zcmV-A0mc4_P)Vak0njc& zZA&?ld*DZx9Ti`X+(YSoU32HjfEXy`x)T8K$Dc=UK%dBdRb&Tz0a!A30zkfV`~Uy| M07*qoM6N<$g1q8?lmGw# literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-30.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-30.png new file mode 100644 index 0000000000000000000000000000000000000000..57654f2476dd038b905cc5bdff53aed893578f60 GIT binary patch literal 315 zcmV-B0mS}^P)52CX4u%yNnY0L()P>vF?>?^PECD5N8jgr|a702LokJL`RUzD7eF02ZghG%!el zSU(wyuWom*IL(ocl)Xi!u-qO*akCaO@&!l^IEV!1G@Ko9j<6snj%zNjx3w1R1D|kA zWbfo?fNC31ZIccd>WUTTo_#eAKx&ksuAI)5c5-|^WB}*L=gdHSISv5t0vAdn1Ltt= z0hnvrt1dW6>5*aa{lY$! zjLi%TA7FD4vVqtPN7gg@+dmXJg82ZS!NdTX=VYQSczR+w!_yPfDYxKbqzP8Tk=Y+3 zP2d=p9t;a`WfVfLMm9Y6_IcbEVAF)l@Gtqv1amo73y^(*&)e7lHrF#SP^qv(HawLJ zHBcxnuF+jiv;~AL!slv|EMQ>3%>L+rVhbn%gQut<7XSdA9d!a8vb*sB0000Lp(Z@|D6Bu-=3M5QCOEZ zJpl+5mpJ%G$*=ygbh&uvrUt=qfrmyjLb^9ZHRS!6{wGDm?);IRF40YijGG?5U|Ytq_u0o2SUHIe_MrP);Z|>|O(GHvvHmh+PDIpTx+QjcU zY3;(0F_bX|IpIV^!_bClIfL(S%{59;Xji0x`--4I!rR@-dLHkO(Go|%;Swx^i!_P# zkvV*FI(y-Ak9MW-FX|G@#YTm9YoS6u0<8ih(Zq=1oB&nCfe6lX4$qgh7VHBbI3}`p za-T@W{uELBM7!YU4)B$DYDjkpztjs+CQpHG_f*gO6l&BJ(`mx`0 z(#Ay(eGenXWK1{!z%-VysFvdMdwWX~6xtSP;GrT>K;hkS>)n^eCQFzA!zq{s7HJai zBV+jddr;brjkXmlNuq3GgbkLOecjj?_I9 zP)TVl8*EZw_-^JSv&S{nro7v(5^@WcNIZ_gtxnuGam1c$r4Y%;Swx^i!_Pz zkvV*FItSr$k9MW-FS3c{Vxz+CTC9+dK&t>rG%;d$CqNZ(AcFIp!}H~=Mf)HGPKn+- zIa$!u6*YC0FL*5H-k8rJiOhil)F@h_c9QM=q6;LL!%;_DNvL{HfKCy5E;t-jPxPb5 zj>Fd@_foQ-Ygu`+ASMb`-AO>?x4(>RK~DV7Q}J!Q0kkG`JW3fO@c;k-07*qoM6N<$ Eg7t5H^#A|> literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-50.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-50.png new file mode 100644 index 0000000000000000000000000000000000000000..891564591f51c2869a9911040be68e69ffd5b903 GIT binary patch literal 304 zcmV-00nh%4P) zjLi%TA7FD4vVqtPN7gg@+dmXJg82ZS!NdTX=VYQSczR+w!_yPfDYxKbqzMWehLJ78 zrw6A6=otlB6MBZj<&)go=W$y=tl{XE;B!5O1?avYR8$}vj?MK93{)!YkPT1eLJbs( zi)(b36Kw$@i}1OcBnucAFta~8px6RRz~Ct=$OQmdvvvaZENLGA0000WvRACo1XfWlp{8&o7o ztWBoy+36gFyYEO#%Kk+rv8-wlZsuZzbONaYP9ljphW7 zP&ijT@T0?y!Z#CpTeFXAxAJ5`OcbiRmjLkF-;HcRPW;bN@ojtnR*iG|T|}p#00000 LNkvXXu0mjfm8OTW literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-70.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-70.png new file mode 100644 index 0000000000000000000000000000000000000000..2cfafd3b91ffd28db28f249bbcca45f6a8b5d2fd GIT binary patch literal 315 zcmV-B0mS}^P)1?L=#I4s{$z_3Y6e<&*l9w=DdC20*A!^ zI=LzGVVsr~>f0H>_)4q_nj$yg00uZ8OUbALsZr9h5}Qqu0KnmO*98(>15t@9drLs8 z@NML4r0jtoU3L_{TbPG3`MTzr2Mc^6SJtBhfZhH)CJUxS^s6Ge;0prjcLG@61Oos7 N002ovPDHLkV1l%Me#ig- literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-80.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-80.png new file mode 100644 index 0000000000000000000000000000000000000000..b571cb200f21f79e063df68b2dd12c1ccdefd1a7 GIT binary patch literal 317 zcmV-D0mA-?P)e!s9I2)3TVxiNn}Y~9W1%2}KuW+#Br(VE?tn`~fgGH!xqQCXSa2U`;Fw|s zukCs`j(ONxc`c%FT3u72YpQesEt8&tIf)d?63~sZs9P4UNdVyZyvYJCk=7D3rlt1; z^e#dR-8o!(;7=br3g6G{rX+u^-Q>}NkVs2CN&xuV->qapN@f4)XBYec+va+T5D{?j P00000NkvXXu0mjfqq~R> literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-90.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/knob-90.png new file mode 100644 index 0000000000000000000000000000000000000000..1824f6d973510ff8c4334b73648b0556750ed70f GIT binary patch literal 308 zcmV-40n7f0P)mb7Tq8y^wnWpjE^Y`5DbU z@T1F)iZ2I#Q#xPQ+<7t}1`4^(0swOSd2|MJiQ-p9ali*Z{&oIT3wb>N0000{NF!si``*| z25*0TBZF67um7eeBqUgrI!s+RZMNl|G$1D-!ExIh&myb4G6m1nn43FyaWf11G|Zc( z%q&*YSbyI5;hX#EHzXo_>k^;-w>y07z<~n|!E!VI|K^cq-u>R?kxWC5g(2JHAb*_% zr8O*9ryp6R9>yQYr*PEW;OmiB2VXG+)in6pn*H1Vd?t^*`Sau#M?IK#Jen-v>tV0g z@Q@*9<hWWV=L~`eTRi;|$Z2(!6qu SoM!_)$l&Sf=d#Wzp$P!Aacm0! literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-cancel-button-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-cancel-button-up.png new file mode 100644 index 0000000000000000000000000000000000000000..ef1fcbd5c6153ca1fdc767e528f6faee0f43a057 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3HGD8EPYe)LBm##}JRs{NF!si``*| z25*0TBZF67um7eeBqUfA7xTyJng^CA0yzy93~4|2Kc87r+A{NSE}NP}`@Lz08HC#! zo|IVlX$TxV=?^5d`_F)=mkeS#O@$A)O8jxvo^ANUp!CL-$+Ap07&bjUvPwOSKafx1 zsJp?}Bd-p=VhE~f@U=CwTepSbeA|YY2K|Ep%sMkZu$?n2-qAagW1{EU3h)|2Z00wi**aa|wd=lN;(7O%f^7U(esPgg&ebxsLQ E0Dq2WR{#J2 literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-ok-button-over.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-ok-button-over.png new file mode 100644 index 0000000000000000000000000000000000000000..54c1d0900bf2244a00367a84800f0e4dec8c334c GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3HGD8EPYe)Mif?#}JRs{NF!si``*| z25*0TBZF67um7eeBqUgrI!s+RZMNl|G$1D-!ExIh&myb4G6m1nn43FyaWf11G|Zc( z%q$jU`losxXZnA;!^aL}ed2CS`##rWQl(GJ)P$z{={HVXbhBk&z&ztU`x(X!8VhDK zpV-PHtzap*h~2cuKTl-B8-}1@OT`064j2@qGTdRbH-CQlZqkgoIxm>Mu=(%+!8O(J imwAR~{EjuQ>tnQ^Z{>RXYOyBJ`3#<}elF{r5}E+Gf?GcT literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-ok-button-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/modal-ok-button-up.png new file mode 100644 index 0000000000000000000000000000000000000000..557dc7e611e65aa65176c686f8e546e729a6551c GIT binary patch literal 237 zcmeAS@N?(olHy`uVBq!ia0vp^3P3Et!3HGD8EPYe)D}+{#}JRs{NF!si``*| z25*0TBZF67um7eeBqUfA7xTyJng^CA0yzy93~4|2Kc87r+A{NSE}NP}`@Lz08H5v6 zGo)0OA1-uifytityuqzdXCIC8+CAeG?`SVvx9eZf0J0tk$z*)9Z$ eNV4y;Vq=)H*rrCc_&_Sq{S2P2elF{r5}E)nO;*JK literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-1-selected.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-1-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..e21843cf6e2f477a15b862e06f2827400da09539 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^3P8-k!3HE}wEkTWq~>_KIEGmCCi8sv`+we`p&?U2 zH$4Fe5`j2k%O**^ghlTT6+C+;$0l4V&Zf)kJ*Vh|3D1$%>xZr${*uhx9cFg;=|e@J zqNdAJUlg5~rnGuz*+Yvi=fs+l(-Rr*Fy7#4m27zDUE+T5hJpNHr*?_+3tAX9scc%h zgU5NBz|G??0-JsLc{U_`W;DB>D17*tMUG+%--M?U>{ilD44&8gv?ivUSPpb2gQu&X J%Q~loCIE#>Q>g#| literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-1-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-1-up.png new file mode 100644 index 0000000000000000000000000000000000000000..3e5a6957f9b16a60cac38c618694b966fda1a8da GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^3P8-k!3HE}wEkTWq!xR+IEGmCCi8sv`+we`p&?U2 zH$4Fe5`lPyW@!tzi|ckno#?2e0-|@1El5r14Cb5J);R6m--53Oe{VSWu2hbZlVb|J zm}?Q+sn?#PxoK9mc;8|Rkz?-LWh4*CHk=KZ!T4gIOSwo7?`K1ul8%o&UK|SEO3_`X z4N|x#*7nGm-uQBWA$dpnulgBoGgP)Ma5iIzwA~d|Vwm%iA=3V_L%K6V$+cLwcU{uu QK<6@ey85}Sb4q9e0FsGOY5)KL literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-2-selected.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-2-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..597dc5fa8f24b623698600f2852635008f91c9ae GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^3P8-k!3HE}wEkTWq~>_KIEGmCCi8sv`+we`p&?U2 zH$4Fe5`j2k%O**^ghlTT6+C+;$0l4V&Zf)kJ*Vh|$u66owW$f6Ns_xFqu8c(2p9yG zAAIRmVwvK-ab=_BlUuEiE6ye+ICL@Pv?Wb$mTbyXWM*c*b9}>vgQOycK>k zM9Nr3Ow@G=_g~WKzA~Dy85}S Ib4q9e0Dyx~2mk;8 literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-2-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/player-2-up.png new file mode 100644 index 0000000000000000000000000000000000000000..ef1eccada98fa721a64a7abb9ea04a5177f326ab GIT binary patch literal 222 zcmV<403rX0P)=02cO@_@d81u^F*@D)}jzEcL|ao=!`Lu}uOD@CMxHSlKZ0e_d#p#(D9FE*PWZ5;ZWt$BhF=uBd$m=qmiV Y-p0sU+3Z#ts{jB107*qoM6N<$f|vPU&;S4c literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/pv8-tool-bar-icon-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/pv8-tool-bar-icon-up.png new file mode 100644 index 0000000000000000000000000000000000000000..012b73737c1e6565adaa0f0dbfd74c111e921e82 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`rJgR1Ar`&KSEgS3ecnNB$Cock z%)&coB{uA0lL@<=V6kS|!2>`bP#rU0@!JkNW*|5`{ZC4p{?C&~b{_b4jn|@j<5O3Q z+3AmB{;(a$X}ihCyd&q>E2f~_c4>!oZ+U>A$Jt(XLxyC;r1ifww+27DV8X!gSxEVL U$+yX(KnE~*y85}Sb4q9e0C0~)P5=M^ literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/pv8-toolbar-icon-down.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/pv8-toolbar-icon-down.png new file mode 100644 index 0000000000000000000000000000000000000000..e61201be9218eb632c0d9082b2c83d7c41faef62 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`S)MMAAr`&KSEgS3ecnNB$Cock z%)&coB{n?0!WcTqWQOG(w}-|Hy$^{zNLtLyqpz@=LtJ__;|a3|Nx~(JE4LlyRk&Wp z1_a06Z*TVWVn5LqS5-B!u~j1a1LG;-Nz)otf9{$ebddG%0R{%&4_fC8E%*)rZDsIu L^>bP0l+XkKAUJ k+hNfyCGXQgiu_m^mc9@-NmJA`2U@}4>FVdQ&MBb@07P3X>;M1& literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-up.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/radio-button-up.png new file mode 100644 index 0000000000000000000000000000000000000000..7333bb0cf079f0fabbade145fb1ed4a22ea17015 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqzMd|QAre!QdA|GoKi|M^5NEf6 zX?4@IcYk?6KnFyymz`YXVYS0HZAaNdi{@#Ks?5T6k0m7}RxD^>O;h({)xG;$a$T%N cUoay>#xkLk$7Zm<1RBiX>FVdQ&MBb@07-KwWdHyG literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/start-btn-down.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/start-btn-down.png new file mode 100644 index 0000000000000000000000000000000000000000..65d11a0b9a46f372938a939f9d0ec5ee5e576cfc GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQXZZzjv*Qoldnv@_WQhp%8oBz zl-eYOH_j?#6q9g1eL!gap=|NKWYOg}SY0F&7R$E>_q8@QHY)1YS>4o2_;dcl{1*`i c*fjW<88|2L7{x8)0GY|)>FVdQ&MBb@0KdK}kpKVy literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/SpriteBuilder/start-input-on.png b/Resources/Tools/SettingsTool/Export/SpriteBuilder/start-input-on.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0ab8dfcffe7075d5addf64f353c3c22d8a707a GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFq)}AhoAre!QuS~u6`+Ng)OjXsy z#@5EhM#XPC?Ao3ro$lrV0s&S7KC=Tq=0CLe)0O~&86P|^c``CI?B?F(c=M|! LS3j3^P6`K{_>Pn$viI@B70b8D;Oo5%G`WNz(p+CN!;N&!*-=_KU_4pLm7p`x+gL` hu5bJQ|Dz@Y!>RXbyUY&FoB%YK!PC{xWt~$(699F=G)e#f literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/sprites.png b/Resources/Tools/SettingsTool/Export/sprites.png new file mode 100644 index 0000000000000000000000000000000000000000..407ec40da94fd5a2c57a16bf816f7b1da7dabd9f GIT binary patch literal 9125 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 Heek~ktcAe% literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/Export/tilemap.png b/Resources/Tools/SettingsTool/Export/tilemap.png new file mode 100644 index 0000000000000000000000000000000000000000..5aa88e528eb5fb04da4b28abe6a6d7ade034a5f9 GIT binary patch literal 4235 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 X;zkaIJ|6YgS%dLKvkS%NQIGxszvAVb literal 0 HcmV?d00001 diff --git a/Resources/Tools/SettingsTool/settings-tool-design-v1.ase b/Resources/Tools/SettingsTool/settings-tool-design-v1.ase index 9f26a88d56d8d79a901edc9af029545dc4827aa2..0b7e818cbe08259346a3029ce8ed1afc51597ed9 100755 GIT binary patch delta 1161 zcmaiye@s(X6vxlw`Rb;TVyd(ZSt|^oo6y(tqx8q4Eh>~{#s>Zn1Ia2>2U*v48!#fB zZN)5(ut0M%FcX8(OmRz?=r*@BOBY=t*_NP*il`Wu5o5P9S~iGV>E3P&`;mo&_mX$d z_kHd;_j^vR_wDH;REo{yPdU6{+6eGRbO3AsFfjVw#2O3=B%;@xw*B@3=c@&cZLO_N zM?srwJ4Tqz;!W^>;%qmHFzX0fBQm%BpU{+V-^r>5`rZh7a2 z2O&u@7ru6I)_7Og)Vqln+7_=~$q=9YEPnGFHn#SP!xro9KXhZt(RXreLAa)Jgcf}J z3r{zY<7zwsjQGfrjBG2&Rx)U1>-`j2Rqs^`JkKHeZuRW5w7lduR=*O2ULbQ0O zFFxit$2{BfyHggf^nA`YpBGQf2qxdP^G55m)_N-Zr{U{)1>Cp1Y3@(@$^q+YzE+w{ z($}8va$cV^+1+zv?zG+AarTmbUUd4#tuw#MN2Mn`kx9;QGrp(C^Yn+p26x3mPT*vE z2m2`KyO23~xFOWlFR|rajMF~<&tBif7!MOcsJkr;?M~Wy4vrzkK7+lAjVMq^>0Iz8 z^(~@niQWbs%Un+9foqw`seI%WYDNw&uwYcV4NvQ;@gsH}{X8_IL@C1www!ta)0GG5 z?O-KYBJ^?$4k)we0;u~(j}u*(sH)4vb*g$s0hVMvG5S>dC>HOj25BYS!6}stKPYOU zRWMBAY|Jlyiz>oX#mAUp(uD=t^37OSx)!TTDyb6eD>=%Pl8gBF|4v#BEOP2y7%i=) z%2227qBIy(n;9*z%e%IgxfmU}I!iepmvu6Fr~@PNnmnx0lv5n~H7!&*#x!=u0A@mh zS~#auT#=v(o-Bpw802yVW+I*d{=}J>Y7zoz*76seSjMUV delta 441 zcmXYsO-mb56o$|BdM8i~>OwRMI({3Y*32Z%Bs000R09=Mf_4#CRj^_~(1oBPN>Fj< z7w@W23F5|$(Be`={R0INsk?UJTI`}55%fmf9G>?%=fF94Yb>`?l#_c!tA3J1kN&k ztiqS*80*A&^gHjOTU0-iKrBGwXrhp5kFDN10uNU3;1v zq${pNAU4lU>On(1jhom2i=aNf&Z0Psf8@Q&m)X_OoLO#>r#OH;XNlXC#c-k>dDjQm zwRueCgV&s7ar|*-n1jK@2y>B7^oa!Rs{Xiag(Display); - LuaScript.Globals["DrawPixels"] = - new Action(DrawPixels); - LuaScript.Globals["DrawSprite"] = - new Action(DrawSingleSprite); - LuaScript.Globals["DrawSprites"] = - new Action(DrawSprites); - LuaScript.Globals["DrawSpriteBlock"] = - // new Action(DrawSpriteBlock); - LuaScript.Globals["DrawText"] = new Action(DrawText); + LuaScript.Globals["DrawPixels"] = new Action(DrawPixels); + LuaScript.Globals["DrawSprite"] = new Action(DrawSingleSprite); + LuaScript.Globals["DrawText"] = new Action(DrawText); LuaScript.Globals["DrawTilemap"] = new Action(DrawTilemap); - LuaScript.Globals["DrawRect"] = new Action(DrawRect); LuaScript.Globals["RedrawDisplay"] = new Action(RedrawDisplay); LuaScript.Globals["ScrollPosition"] = new Func(ScrollPosition); - + #endregion #region File IO APIs @@ -145,7 +138,7 @@ protected virtual void RegisterLuaServices() #region Sprite APIs LuaScript.Globals["Sprite"] = new Func(Sprite); - // luaScript.Globals["Sprites"] = new Func(Sprites); + LuaScript.Globals["ChangeSizeMode"] = new Action(ChangeSizeMode); LuaScript.Globals["SpriteSize"] = new Func(SpriteSize); LuaScript.Globals["TotalSprites"] = new Func(TotalSprites); LuaScript.Globals["MaxSpriteCount"] = new Func(MaxSpriteCount); @@ -217,6 +210,9 @@ protected virtual void RegisterLuaServices() UserData.RegisterType(); LuaScript.Globals["DrawMode"] = UserData.CreateStatic(); + UserData.RegisterType(); + LuaScript.Globals["SpriteSizes"] = UserData.CreateStatic(); + UserData.RegisterType(); LuaScript.Globals["Buttons"] = UserData.CreateStatic(); diff --git a/SDK/Player/Chips/Game/GameChip.Draw.cs b/SDK/Player/Chips/Game/GameChip.Draw.cs index 91cac022..e5a7dc16 100644 --- a/SDK/Player/Chips/Game/GameChip.Draw.cs +++ b/SDK/Player/Chips/Game/GameChip.Draw.cs @@ -185,11 +185,11 @@ public partial class GameChip } } - public virtual void DrawSprites(int[] ids, int x, int y, int width, bool flipH = false, bool flipV = false, - DrawMode drawMode = DrawMode.Sprite, int colorOffset = 0) - { - // TODO need to delete this after the refactoring - } + // public virtual void DrawSprites(int[] ids, int x, int y, int width, bool flipH = false, bool flipV = false, + // DrawMode drawMode = DrawMode.Sprite, int colorOffset = 0) + // { + // // TODO need to delete this after the refactoring + // } /// /// This method allows you to draw a rectangle with a fill color. By default, this method is used to clear the screen diff --git a/SDK/Runner/Parsers/Loader.cs b/SDK/Runner/Parsers/Loader.cs index e9299d10..27b1512c 100755 --- a/SDK/Runner/Parsers/Loader.cs +++ b/SDK/Runner/Parsers/Loader.cs @@ -70,7 +70,7 @@ public Loader(IFileLoader fileLoadHelper, IImageParser imageParser) for (int i = 0; i < methods.Length; i++) { - Console.WriteLine("Method " + i + " " + methods[i].Name); + // Console.WriteLine("Method " + i + " " + methods[i].Name); Type thisType = this.GetType(); MethodInfo theMethod = thisType.GetMethod(methods[i].Name); diff --git a/SDK/Runner/Parsers/SystemParser.cs b/SDK/Runner/Parsers/SystemParser.cs index 49fdd364..35401586 100755 --- a/SDK/Runner/Parsers/SystemParser.cs +++ b/SDK/Runner/Parsers/SystemParser.cs @@ -116,6 +116,9 @@ public void ConfigureColorChip(Dictionary data) // if (data.ContainsKey("maxColors")) colorChip.maxColors = (int)(long)data["maxColors"]; + // Force the color chip to have 256 colors + colorChip.Total = 256; + // Make sure we have data to parse if (data.ContainsKey("colors")) { @@ -124,9 +127,6 @@ public void ConfigureColorChip(Dictionary data) // Pull out the color data var colors = (List) data["colors"]; - // Force the color chip to have 256 colors - // colorChip.total = 256; - // Clear the colors colorChip.Clear(); @@ -234,7 +234,7 @@ public void ConfigureGameChip(Dictionary data) if (data.ContainsKey("metaSprites")) { - Console.WriteLine("ContainsKey metaSprites"); + // Console.WriteLine("ContainsKey metaSprites"); var metaSprites = data["metaSprites"] as List; diff --git a/SDK/Runner/Services/LogService.cs b/SDK/Runner/Services/LogService.cs index 8a0731e2..8a33301c 100755 --- a/SDK/Runner/Services/LogService.cs +++ b/SDK/Runner/Services/LogService.cs @@ -85,7 +85,7 @@ public void UpdateLog(string logString, LogType type = LogType.Log, string stack if (logBuffer.Count > totalItems) logBuffer.RemoveAt(0); - Debug.WriteLine(sb.ToString()); + // Debug.WriteLine(sb.ToString()); Console.WriteLine(sb.ToString()); diff --git a/Tests/PixelVisoin8.Tests.csproj b/Tests/PixelVisoin8.Tests.csproj new file mode 100644 index 00000000..04588746 --- /dev/null +++ b/Tests/PixelVisoin8.Tests.csproj @@ -0,0 +1,19 @@ + + + + net5.0 + + false + + + + + + + + + + + + + diff --git a/Tests/SDK/ColorChip.Test.cs b/Tests/SDK/ColorChip.Test.cs new file mode 100644 index 00000000..ee77049d --- /dev/null +++ b/Tests/SDK/ColorChip.Test.cs @@ -0,0 +1,658 @@ + +using System; +using System.Linq; +using NUnit.Framework; + +namespace PixelVision8.Player +{ + + public class ColorChipTest + { + private PixelVision _pixelVision; + private readonly string[] _defaultColors = + { + "#2D1B2E", + "#218A91", + "#3CC2FA", + "#9AF6FD", + "#4A247C", + "#574B67", + "#937AC5", + "#8AE25D", + "#8E2B45", + "#F04156", + "#F272CE", + "#D3C0A8", + "#C5754A", + "#F2A759", + "#F7DB53", + "#F9F4EA" + }; + + [SetUp] + public void Setup() + { + + var chips = new[] + { + typeof(ColorChip).FullName + }; + + _pixelVision = new PixelVision(chips); + + } + + [Test] + public void GetColorChipTest() + { + + var tmpChip = _pixelVision.GetChip(typeof(ColorChip).FullName); + + Assert.NotNull(tmpChip); + + } + + [Test] + public void ReadFromColorChipTest() + { + + Assert.NotNull(_pixelVision.ColorChip); + + } + + #region Validate Hex Color + + /// + /// Test validating a hex color + /// + [Test] + public void ValidateValidHexColor() + { + Assert.IsTrue(ColorChip.ValidateHexColor("#FFFFFF")); + } + + /// + /// Test validating an invalid hex color + /// + [Test] + public void ValidateInvalidHexColor() + { + Assert.IsFalse(ColorChip.ValidateHexColor("#ZZDWAF")); + } + + /// + /// Test validating a 3 character hex color + /// + [Test] + public void ValidateShortHexColor() + { + Assert.IsTrue(ColorChip.ValidateHexColor("#FFF")); + } + + /// + /// Test validating a invalid 7 character hex color + /// + [Test] + public void ValidateLongHexColor() + { + Assert.IsFalse(ColorChip.ValidateHexColor("#FFFFFFF")); + } + + #endregion + + #region Background Color + + /// + /// Test the default background color value which should be -1 + /// + [Test] + public void BGDefaultValueTest() + { + Assert.AreEqual(-1, _pixelVision.ColorChip.BackgroundColor); + } + + /// + /// Test setting a background color that is out of range + /// + [Test] + public void BGOutBoundsTest() + { + + _pixelVision.ColorChip.BackgroundColor = 200; + + Assert.AreEqual(-1, _pixelVision.ColorChip.BackgroundColor); + + } + + #endregion + + #region Mask Color + + /// + /// Test reading the default mask color + /// + [Test] + public void MaskColorTest() + { + Assert.AreEqual("#FF00FF", _pixelVision.ColorChip.MaskColor); + } + + /// + /// Test changing mask color + /// + [Test] + public void ChangeMaskColorTest() + { + _pixelVision.ColorChip.MaskColor = "#FFFF00"; + + Assert.AreEqual("#FFFF00", _pixelVision.ColorChip.MaskColor); + } + + /// + /// Test changing mask to invalid color + /// + [Test] + public void ChangeMaskToInvalidColorTest() + { + _pixelVision.ColorChip.MaskColor = "#FFFF0000"; + + Assert.AreEqual("#FF00FF", _pixelVision.ColorChip.MaskColor); + } + + #endregion + + #region Total Used Colors + + /// + /// Test the default number of colors after adding additional mask colors + /// + [Test] + public void DefaultTotalUsedColorsTest() + { + Assert.AreEqual(_defaultColors.Length, _pixelVision.ColorChip.TotalUsedColors); + } + + /// + /// Test the default number of colors after adding additional mask colors + /// + [Test] + public void ResizeTotalUsedColorsTest() + { + + _pixelVision.ColorChip.Total = 255; + + Assert.AreEqual(_defaultColors.Length, _pixelVision.ColorChip.TotalUsedColors); + } + + /// + /// Test setting the total colors below 2 + /// + [Test] + public void ResizeLowTotalColorTest() + { + _pixelVision.ColorChip.Total = 1; + Assert.AreEqual(2, _pixelVision.ColorChip.TotalUsedColors); + } + + /// + /// Test the default number of colors after adding additional mask colors + /// + [Test] + public void TotalUsedColorsMaskTest() + { + var testColors = _defaultColors.ToList(); + + for (int i = 0; i < 25; i++) + { + testColors.Add(_pixelVision.ColorChip.MaskColor); + } + + _pixelVision.ColorChip.Total = testColors.Count; + + // the mask color counts as a color + Assert.AreEqual(_defaultColors.Length, _pixelVision.ColorChip.TotalUsedColors); + } + + #endregion + + + #region Hex Colors + + + /// + /// Test default hex colors + /// + [Test] + public void DefaultHexColorTest() + { + CollectionAssert.AreEqual(_defaultColors, _pixelVision.ColorChip.HexColors); + } + + /// + /// Test that additional colors are returned as mask colors + /// + [Test] + public void AdditionalHexColorTest() + { + + _pixelVision.ColorChip.Total = 20; + + var colors = _defaultColors.ToList(); + + var total = _pixelVision.ColorChip.Total - _defaultColors.Length; + + for (int i = 0; i < total ; i++) + { + colors.Add(_pixelVision.ColorChip.MaskColor); + } + + CollectionAssert.AreEqual(colors.ToArray(), _pixelVision.ColorChip.HexColors); + } + + #endregion + + #region Total Colors + + /// + /// Check the default total colors + /// + [Test] + public void DefaultTotalTest() + { + Assert.AreEqual(_defaultColors.Length, _pixelVision.ColorChip.Total); + } + + /// + /// Test changing total colors to higher value + /// + [Test] + public void NewTotalTest() + { + + _pixelVision.ColorChip.Total = 255; + + Assert.AreEqual(255, _pixelVision.ColorChip.Total); + } + + /// + /// Test changing total colors to invalid number that's too small + /// + [Test] + public void NewInvalidTotalATest() + { + + _pixelVision.ColorChip.Total = 1; + + Assert.AreEqual(2, _pixelVision.ColorChip.Total); + } + + /// + /// Test changing total colors to negative number + /// + [Test] + public void NewNegativeTotalATest() + { + + _pixelVision.ColorChip.Total = -100; + + Assert.AreEqual(2, _pixelVision.ColorChip.Total); + } + + #endregion + + #region Debug Mode + + /// + /// Test that default debug flag is set to false + /// + [Test] + public void DefaultDebugColorTest() + { + + Assert.IsFalse(_pixelVision.ColorChip.DebugMode); + + } + + /// + /// Test changing the debug color flag to true + /// + [Test] + public void DebugColorTest() + { + _pixelVision.ColorChip.DebugMode = true; + + Assert.IsTrue(_pixelVision.ColorChip.DebugMode); + + } + + /// + /// Test that out of range colors still return the mask even with debug mode set to true + /// + [Test] + public void DebugTrueColorTest() + { + _pixelVision.ColorChip.DebugMode = true; + + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(-1) ); + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(17) ); + + } + + /// + /// Test that out of range colors still return the mask even with debug mode set to false + /// + [Test] + public void DebugFalseColorTest() + { + _pixelVision.ColorChip.DebugMode = false; + + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(-1) ); + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(17) ); + + } + + #endregion + + #region Invalidate Test + + /// + /// Test default invalid value is set to true + /// + [Test] + public void DefaultInvalidTest() + { + Assert.IsTrue(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test default invalid value is set to true + /// + [Test] + public void ResetInvalidTest() + { + _pixelVision.ColorChip.ResetValidation(); + + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test invalid flag becomes true after updating color + /// + [Test] + public void ChangeInvalidTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.UpdateColorAt(0, "#FFFFFF"); + Assert.IsTrue(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test invalid flag isn't triggered on invalid hex + /// + [Test] + public void ChangeValidationOutOfRangeTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.UpdateColorAt(40, "#FFFFFF"); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test invalid flag isn't triggered on invalid hex + /// + [Test] + public void ChangeValidationInvalidHexTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.UpdateColorAt(0, "#FFFFFF00"); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test invalid flag isn't triggered when reading color + /// + [Test] + public void NoValidationChangeOnReadTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + var color = _pixelVision.ColorChip.ReadColorAt(0); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test invalid flag isn't triggered when reading hex colors + /// + [Test] + public void NoValidationChangeOnHexTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + var colors = _pixelVision.ColorChip.HexColors; + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + } + + /// + /// Test invalid flag is set when changing total + /// + [Test] + public void ChangeTotalInvalidTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.Total = 255; + Assert.IsTrue(_pixelVision.ColorChip.Invalid); + + } + + /// + /// Test invalid flag is set when changing to debug mode + /// + [Test] + public void ChangeDebugInvalidTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.DebugMode = true; + Assert.IsTrue(_pixelVision.ColorChip.Invalid); + + } + + /// + /// Test invalid flag is set when changing background + /// + [Test] + public void ChangeBackgroundInvalidTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.BackgroundColor = 5; + Assert.IsTrue(_pixelVision.ColorChip.Invalid); + + } + + /// + /// Test invalid flag is set when clearing color chip + /// + [Test] + public void ChangeClearInvalidTest() + { + // Make sure the chip has reset the validation correctly + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.Clear(); + Assert.IsTrue(_pixelVision.ColorChip.Invalid); + + } + + /// + /// Testing that changing a color to the same value doesn't invalidate it + /// + [Test] + public void ChangeSameColorInvalidTest() + { + + _pixelVision.ColorChip.ResetValidation(); + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + _pixelVision.ColorChip.UpdateColorAt(0, _defaultColors[0]); + + // The mask color counts as a color + Assert.IsFalse(_pixelVision.ColorChip.Invalid); + + } + + #endregion + + #region Read Color + + /// + /// Test reading the first color from the color chip + /// + [Test] + public void ReadColorTest() + { + + Assert.AreEqual(_defaultColors[0], _pixelVision.ColorChip.ReadColorAt(0)); + + } + + /// + /// Test reading colors that are out of range which should always return the mask color + /// + [Test] + public void ReadColorOutOfRangeTest() + { + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(-20)); + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(20)); + } + + #endregion + + #region Clear + + /// + /// Test reading colors that are out of range which should always return the mask color + /// + [Test] + public void ClearDefaultTest() + { + + _pixelVision.ColorChip.Clear(); + + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(0)); + } + + /// + /// Test reading colors that are out of range which should always return the mask color + /// + [Test] + public void ClearWithValueTest() + { + + _pixelVision.ColorChip.Clear("#FFFF00"); + + Assert.AreEqual("#FFFF00", _pixelVision.ColorChip.ReadColorAt(0)); + } + + #endregion + + + #region Update Color + + /// + /// Testing updating a color that is in range + /// + [Test] + public void AddColorTest() + { + + _pixelVision.ColorChip.UpdateColorAt(0, "#FFFF00"); + + // The mask color counts as a color + Assert.AreEqual("#FFFF00", _pixelVision.ColorChip.ReadColorAt(0)); + + } + + /// + /// Test that adding a color out of bounds doesn't change the total and returns the mask + /// + [Test] + public void UpdateColorOutOfBoundsTest() + { + + _pixelVision.ColorChip.UpdateColorAt(50, "#FFFFFF"); + + // The mask color counts as a color + Assert.AreEqual(_pixelVision.ColorChip.MaskColor, _pixelVision.ColorChip.ReadColorAt(55)); + + } + + /// + /// Test that adding a color out of bounds doesn't change the total and returns the mask + /// + [Test] + public void UpdateInvalidedColorTest() + { + + _pixelVision.ColorChip.UpdateColorAt(0, "#FFFFFF00"); + + // The mask color counts as a color + Assert.AreEqual(_defaultColors[0], _pixelVision.ColorChip.ReadColorAt(0)); + + } + + /// + /// Test that adding a color out of bounds doesn't change the total and returns the mask + /// + [Test] + public void UpdateLowercaseColorTest() + { + + _pixelVision.ColorChip.UpdateColorAt(0, "#aaff00"); + + // The mask color counts as a color + Assert.AreEqual("#AAFF00", _pixelVision.ColorChip.ReadColorAt(0)); + + } + + /// + /// Test changing color after resize + /// + [Test] + public void ResizeUpdateColorTest() + { + + _pixelVision.ColorChip.Total = 20; + + _pixelVision.ColorChip.UpdateColorAt(19, "#FFFF00"); + + // The mask color counts as a color + Assert.AreEqual("#FFFF00", _pixelVision.ColorChip.ReadColorAt(19)); + + } + + #endregion + + } +} \ No newline at end of file diff --git a/Tests/SDK/PixelData.Test.cs b/Tests/SDK/PixelData.Test.cs new file mode 100644 index 00000000..7f6159e2 --- /dev/null +++ b/Tests/SDK/PixelData.Test.cs @@ -0,0 +1,315 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; + +namespace PixelVision8.Player +{ + + public class PixelDataTest + { + + #region Default Sizes + + [Test] + public void DefaultPixelDataSizeTest() + { + + var data = new PixelData(); + + Assert.AreEqual(1, data.Width); + Assert.AreEqual(1, data.Height); + Assert.AreEqual(1, data.Total); + + } + + [Test] + public void InvalidDefaultSizeTest() + { + + var data = new PixelData(); + + data.Resize(-1, -1); + + Assert.AreEqual(1, data.Width); + Assert.AreEqual(1, data.Height); + Assert.AreEqual(1, data.Total); + + } + + [Test] + public void InvalidWidthDefaultSizeTest() + { + + var data = new PixelData(); + + data.Resize(-1, 8); + + Assert.AreEqual(1, data.Width); + Assert.AreEqual(8, data.Height); + Assert.AreEqual(8, data.Total); + + } + + [Test] + public void InvalidHeightDefaultSizeTest() + { + + var data = new PixelData(); + + data.Resize(8, -1); + + Assert.AreEqual(8, data.Width); + Assert.AreEqual(1, data.Height); + Assert.AreEqual(8, data.Total); + + } + + [Test] + public void ValidDefaultSizeTest() + { + + var data = new PixelData(8, 8); + + data.Resize(8, 8); + + Assert.AreEqual(8, data.Width); + Assert.AreEqual(8, data.Height); + Assert.AreEqual(64, data.Total); + + } + + #endregion + + #region Resize + + [Test] + public void ResizePixelTest() + { + + var data = new PixelData(); + + + data.Resize(8, 8); + + Assert.AreEqual(8, data.Width); + Assert.AreEqual(8, data.Height); + Assert.AreEqual(64, data.Total); + + } + + [Test] + public void InvalidResizeTest() + { + + var data = new PixelData(8, 8); + + data.Resize(-1, -1); + + Assert.AreEqual(1, data.Width); + Assert.AreEqual(1, data.Height); + Assert.AreEqual(1, data.Total); + + } + + [Test] + public void InvalidedWidthResizeTest() + { + + var data = new PixelData(); + + data.Resize(-1, 8); + + Assert.AreEqual(1, data.Width); + Assert.AreEqual(8, data.Height); + Assert.AreEqual(8, data.Total); + + } + + [Test] + public void InvalidedHeightResizeTest() + { + + var data = new PixelData(); + + data.Resize(8, -1); + + Assert.AreEqual(8, data.Width); + Assert.AreEqual(1, data.Height); + Assert.AreEqual(8, data.Total); + + } + + #endregion + + #region Iterate Get Value + + [Test] + public void GetValueInRangeTest() + { + + var data = new PixelData(); + + Assert.AreEqual(0, data[0]); + + } + + [Test] + public void GetNegateValueTest() + { + var data = new PixelData(); + + Assert.Throws(() => + { + var i = data[-1]; + }); + + } + + [Test] + public void GetOutOfBoundsValueTest() + { + var data = new PixelData(); + + Assert.Throws(() => + { + var i = data[100]; + }); + + } + + [Test] + public void GetIterateInRangeTest() + { + + var data = new PixelData(8, 8); + + var pixels = new List(); + + for (int i = 0; i < data.Total; i++) + { + pixels.Add(data[i]); + } + + CollectionAssert.AreEqual(pixels.ToArray(), data.Pixels); + + } + + [Test] + public void GetIterateOutOfRangeTest() + { + + var data = new PixelData(8, 8); + + Assert.Throws(() => + { + + var pixels = new List(); + + for (int i = 0; i < 100; i++) + { + pixels.Add(data[i]); + } + + }); + + } + + #endregion + + #region Iterate Set Value + + [Test] + public void SetValueInRangeTest() + { + + var data = new PixelData(); + data[0] = 1; + Assert.AreEqual(1, data[0]); + + } + + [Test] + public void SetNegateValueTest() + { + var data = new PixelData(); + + Assert.Throws(() => + { + data[-1] = 1; + }); + + } + + [Test] + public void SetOutOfBoundsValueTest() + { + var data = new PixelData(); + + Assert.Throws(() => + { + data[100] = 1; + }); + + } + + [Test] + public void SetIterateInRangeTest() + { + + var data = new PixelData(8, 8); + + var newPixels = Enumerable.Repeat(-1, 64).ToArray(); + + for (int i = 0; i < newPixels.Length; i++) + { + data[i] = newPixels[i]; + } + + CollectionAssert.AreEqual(newPixels.ToArray(), data.Pixels); + + } + + [Test] + public void SetIterateOutOfRangeTest() + { + + var data = new PixelData(8, 8); + var newPixels = Enumerable.Repeat(-1, 100).ToArray(); + + Assert.Throws(() => + { + + for (int i = 0; i < newPixels.Length; i++) + { + data[i] = newPixels[i]; + } + + }); + + } + + [Test] + public void SetPixelsCleanCopyTest() + { + + var pixels = new int[] + { + 0, 1, 2, 3 + }; + + var data = new PixelData(2, 2); + data.SetPixels(pixels, 2, 2); + + pixels[0] = -1; + + CollectionAssert.AreEqual(new[]{0, 1, 2, 3}, data.Pixels); + + } + + + #endregion + + } +} \ No newline at end of file diff --git a/Tests/SDK/PixelDataUtilities.DataSets.cs b/Tests/SDK/PixelDataUtilities.DataSets.cs new file mode 100644 index 00000000..192c6f22 --- /dev/null +++ b/Tests/SDK/PixelDataUtilities.DataSets.cs @@ -0,0 +1,378 @@ +using Microsoft.Xna.Framework; + +namespace PixelVision8.Player +{ + public partial class PixelDataUtilitiesTest + { + + class MergeTestData + { + public Point DestPos; + public Rectangle SampleRect; + public int[] FinalMerge; + public int[] FinalSet; + public int[] FinalOffsetMerge; + public int[] FinalFlipHVMerge; + public int ColorOffset; + } + + private readonly Rectangle _srcRect = new Rectangle(0, 0, 3, 3); + + private readonly int[] _srcData = new int[] + { + // Normal Horizontal Vertical H+V Flip + 00, 01, 02,// 02, 01, 00, 20, 21, 22, 22, 21, 20, + 10, -1, 12,// 12, -1, 10, 10, -1, 12, 12, -1, 10, + 20, 21, 22,// 22, 21, 20, 00, 01, 02, 02, 01, 00, + }; + + private readonly Rectangle _destRect = new Rectangle(0, 0, 4, 4); + + private readonly int[] _destData = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }; + + + readonly MergeTestData[] _testData = new MergeTestData[] + { + + // Example 0 - Inside Bottom Right Bounds + // + // -1 0 1 2 3 4 + // -1 + // 0 --, --, --, --, + // 1 --, 00, 01, 02 + // 2 --, 10, -1, 12 + // 3 --, 20, 21, 22 + // 4 + // + // Dest 1, 1 + // Sample 0, 0, 3, 3 + // + new MergeTestData() + { + SampleRect = new Rectangle(0, 0, 3, 3), + DestPos = new Point(1, 1), + ColorOffset = 10, + FinalMerge = new int[] + { + 00, 01, 02, 03, + 04, 00, 01, 02, + 08, 10, 10, 12, + 12, 20, 21, 22, + }, + FinalFlipHVMerge = new int[] + { + 00, 01, 02, 03, + 04, 22, 21, 20, + 08, 12, 10, 10, + 12, 02, 01, 00, + }, + FinalOffsetMerge = new int[] + { + 00, 01, 02, 03, + 04, 10, 11, 12, + 08, 20, 10, 22, + 12, 30, 31, 32, + }, + FinalSet = new int[] + { + 00, 01, 02, 03, + 04, 00, 01, 02, + 08, 10, -1, 12, + 12, 20, 21, 22, + } + }, + + // Example 1 - Inside Bounds Src Offset + // + // -1 0 1 2 3 4 + // -1 + // 0 --, --, --, --, + // 1 --, -1, 12, -- + // 2 --, 21, 22, -- + // 3 --, --, --, -- + // 4 + // + // Dest 1, 1 + // Sample 0, 0, 3, 3 + // + new MergeTestData() + { + DestPos = new Point(1, 1), + SampleRect = new Rectangle(1, 1, 2, 2), + FinalMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 12, 07, + 08, 21, 22, 11, + 12, 13, 14, 15, + }, + FinalFlipHVMerge = new int[] + { + 00, 01, 02, 03, + 04, 22, 21, 07, + 08, 12, 10, 11, + 12, 13, 14, 15, + }, + FinalOffsetMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 12, 07, + 08, 21, 22, 11, + 12, 13, 14, 15, + }, + FinalSet = new int[] + { + 00, 01, 02, 03, + 04, 00, 01, 07, + 08, 10, -1, 11, + 12, 13, 14, 15, + } + }, + + // Example 2 - Out Bounds Upper Left + // + // -1 0 1 2 3 4 + // -1 XX, XX, XX + // 0 XX, -1, 12, --, --, + // 1 XX, 21, 22, --, --, + // 2 --, --, --, --, + // 3 --, --, --, --, + // 4 + // + // Dest -1,-1 + // Sample 0, 0, 3, 3 + // + new MergeTestData() + { + SampleRect = new Rectangle(0, 0, 3, 3), + DestPos = new Point(-1, -1), + ColorOffset = 10, + FinalMerge = new int[] + { + 00, 12, 02, 03, + 21, 22, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalFlipHVMerge = new int[] + { + 00, 10, 02, 03, + 01, 00, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalOffsetMerge = new int[] + { + 00, 22, 02, 03, + 31, 32, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalSet = new int[] + { + -1, 12, 02, 03, + 21, 22, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + } + }, + + // Example 3 - Out Bounds Upper Right + // + // -1 0 1 2 3 4 + // -1 XX, XX, XX + // 0 --, --, 10, -1, XX + // 1 --, --, 20, 21, XX + // 2 --, --, --, --, + // 3 --, --, --, --, + // 4 + // + // Dest 2,-1 + // Sample 0, 0, 3, 3 + // + new MergeTestData() + { + SampleRect = new Rectangle(0, 0, 3, 3), + DestPos = new Point(2, -1), + ColorOffset = 10, + FinalMerge = new int[] + { + 00, 01, 10, 03, + 04, 05, 20, 21, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalFlipHVMerge = new int[] + { + 00, 01, 12, 03, + 04, 05, 02, 01, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalOffsetMerge = new int[] + { + 00, 01, 20, 03, + 04, 05, 30, 31, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalSet = new int[] + { + 00, 01, 10, -1, + 04, 05, 20, 21, + 08, 09, 10, 11, + 12, 13, 14, 15, + } + }, + + // Example 4 - Out Bounds Bottom Right + // + // -1 0 1 2 3 4 + // -1 + // 0 --, --, --, --, + // 1 --, --, --, --, + // 2 --, --, 00, 01, XX + // 3 --, --, 10, -1, XX + // 4 XX, XX, XX + // + // Dest 2,2 + // Sample 0, 0, 3, 3 + // + new MergeTestData() + { + SampleRect = new Rectangle(0, 0, 3, 3), + DestPos = new Point(2, 2), + ColorOffset = 10, + FinalMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 00, 01, + 12, 13, 10, 15, + }, + FinalFlipHVMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 22, 21, + 12, 13, 12, 15, + }, + FinalOffsetMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 20, 15, + }, + FinalSet = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 00, 01, + 12, 13, 10, -1, + } + }, + + // Example 5 - Out Bounds Bottom Left + // + // -1 0 1 2 3 4 + // -1 + // 0 --, --, --, --, + // 1 --, --, --, --, + // 2 XX, 01, 02, --, --, + // 3 XX, -1, 12, --, --, + // 4 XX, XX, XX + // + // Dest -1,2 + // Sample 0, 0, 3, 3 + // + new MergeTestData() + { + SampleRect = new Rectangle(0, 0, 3, 3), + DestPos = new Point(-1, 2), + ColorOffset = 10, + FinalMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 01, 02, 10, 11, + 12, 12, 14, 15, + }, + FinalFlipHVMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 21, 20, 10, 11, + 12, 10, 14, 15, + }, + FinalOffsetMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 11, 12, 10, 11, + 12, 22, 14, 15, + }, + FinalSet = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 01, 02, 10, 11, + -1, 12, 14, 15, + } + }, + // Example 6 - Out Of Bounds Top Src Offset + // + // -1 0 1 2 3 4 + // -1 XX + // 0 --, --, 21, --, + // 1 --, --, --, --, + // 2 --, --, --, --, + // 3 --, --, --, --, + // 4 + // + // Dest -1,2 + // Sample 1, 1, 1, 2 + // + new MergeTestData() + { + SampleRect = new Rectangle(1, 1, 1, 2), + DestPos = new Point(2, -1), + ColorOffset = 10, + FinalMerge = new int[] + { + 00, 01, 21, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalFlipHVMerge = new int[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalOffsetMerge = new int[] + { + 00, 01, 31, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + }, + FinalSet = new int[] + { + 00, 01, 10, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15, + } + }, + }; + } +} \ No newline at end of file diff --git a/Tests/SDK/PixelDataUtilities.Test.cs b/Tests/SDK/PixelDataUtilities.Test.cs new file mode 100644 index 00000000..0086b2e0 --- /dev/null +++ b/Tests/SDK/PixelDataUtilities.Test.cs @@ -0,0 +1,682 @@ + +using System; +using System.Linq; +using NUnit.Framework; + +namespace PixelVision8.Player +{ + + public partial class PixelDataUtilitiesTest + { + + // private PixelData pixelData = new PixelData(4, 4); + + private int[] _pixelMap = new[] + { + 00, 01, 02, 03, + 04, 05, 06, 07, + 08, 09, 10, 11, + 12, 13, 14, 15 + }; + + #region Get Pixels + + [Test] + public void GetAllPixelsTest() + { + var pixelData = new PixelData(4, 4); + + CollectionAssert.AreEqual(Enumerable.Repeat(0, 16).ToArray(), Utilities.GetPixels(pixelData)); + } + + [Test] + public void GetTopLeftPixelsTest() + { + + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 00, 01, + 04, 05, + }; + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, 0, 0, 2, 2)); + } + + [Test] + public void GetTopRightPixelsTest() + { + + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 02, 03, + 06, 07, + }; + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, 2, 0, 2, 2)); + } + + [Test] + public void GetBottomRightPixelsTest() + { + + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 10, 11, + 14, 15 + }; + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, 2, 2, 2, 2)); + } + + [Test] + public void GetBottomLeftPixelsTest() + { + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 08, 09, + 12, 13, + }; + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, 0, 2, 2, 2)); + } + + [Test] + public void GetOutOfBoundsTopLeftPixelsTest() + { + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 00, 01, + 04, 05, + }; + + // Example + // XX, XX, XX + // XX, 00, 01, --, --, + // XX, 04, 05, --, --, + // --, --, --, --, + // --, --, --, -- + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, -1, -1, 3, 3)); + } + + [Test] + public void GetOutOfBoundsTopRightPixelsTest() + { + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 02, 03, + 06, 07, + }; + + // Example + // XX, XX, XX + // --, --, 02, 03, XX + // --, --, 06, 07, XX + // --, --, --, --, + // --, --, --, --, + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, 2, -1, 3, 3)); + } + + [Test] + public void GetOutOfBoundsBottomRightPixelsTest() + { + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 10, 11, + 14, 15 + }; + + // Example + // --, --, --, --, + // --, --, --, --, + // --, --, 10, 11, XX + // --, --, 14, 15, XX + // XX, XX, XX + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, 2, 2, 3, 3)); + } + + [Test] + public void GetOutOfBoundsBottomLeftPixelsTest() + { + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + var pixels = new int[] + { + 08, 09, + 12, 13, + }; + + // Example + // --, --, --, --, + // --, --, --, --, + // XX, 08, 09, --, --, + // XX, 12, 13, --, --, + // XX, XX, XX + + CollectionAssert.AreEqual(pixels, Utilities.GetPixels(pixelData, -1, 2, 3, 3)); + } + #endregion + + + #region Resize + + + [Test] + public void ResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData, 8, 8); + + Assert.AreEqual(8, pixelData.Width); + Assert.AreEqual(8, pixelData.Height); + Assert.AreEqual(64, pixelData.Total); + CollectionAssert.AreEqual(Enumerable.Repeat(-1, 64).ToArray(), pixelData.Pixels); + } + + [Test] + public void ResizeClearPixelsTest() + { + var pixelData = new PixelData(4, 4); + + for (int i = 0; i < pixelData.Total; i++) + { + pixelData[i] = _pixelMap[i]; + } + + Utilities.Resize(pixelData, 8, 8); + + CollectionAssert.AreEqual(Enumerable.Repeat(-1, 64).ToArray(), pixelData.Pixels); + + } + + [Test] + public void InvalidResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData,-1, -1); + Assert.AreEqual(1, pixelData.Width); + Assert.AreEqual(1, pixelData.Height); + Assert.AreEqual(1, pixelData.Total); + } + + [Test] + public void InvalidWidthResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData,-1, 8); + Assert.AreEqual(1, pixelData.Width); + Assert.AreEqual(8, pixelData.Height); + Assert.AreEqual(8, pixelData.Total); + } + + [Test] + public void InvalidHeightResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData,8, -1); + Assert.AreEqual(8, pixelData.Width); + Assert.AreEqual(1, pixelData.Height); + Assert.AreEqual(8, pixelData.Total); + } + + [Test] + public void OutOfBoundsResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData,10000, 10000); + Assert.AreEqual(2048, pixelData.Width); + Assert.AreEqual(2048, pixelData.Height); + Assert.AreEqual(4194304, pixelData.Total); + } + + [Test] + public void OutOfBoundsWidthResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData,10000, 8); + Assert.AreEqual(2048, pixelData.Width); + Assert.AreEqual(8, pixelData.Height); + Assert.AreEqual(16384, pixelData.Total); + } + + [Test] + public void OutOfBoundsHeightResizePixelsTest() + { + var pixelData = new PixelData(4, 4); + + Utilities.Resize(pixelData, 8, 10000); + Assert.AreEqual(8, pixelData.Width); + Assert.AreEqual(2048, pixelData.Height); + Assert.AreEqual(16384, pixelData.Total); + } + + #endregion + + // #region Flip + // + // [Test] + // public void HorizontalFlipPixelsTest() + // { + // + // var pixels = new int[_pixelMap.Length]; + // + // Array.Copy(_pixelMap, pixels, _pixelMap.Length); + // + // Utilities.FlipPixelData(ref pixels, 4, 4, true, false); + // + // CollectionAssert.AreEqual(_pixelMapFlipH, pixels); + // } + // + // [Test] + // public void VerticalFlipPixelsTest() + // { + // + // var pixels = new int[_pixelMap.Length]; + // + // Array.Copy(_pixelMap, pixels, _pixelMap.Length); + // + // Utilities.FlipPixelData(ref pixels, 4, 4, false, true); + // + // CollectionAssert.AreEqual(_pixelMapFlipV, pixels); + // } + // + // [Test] + // public void FullFlipPixelsTest() + // { + // + // var pixels = new int[_pixelMap.Length]; + // + // Array.Copy(_pixelMap, pixels, _pixelMap.Length); + // + // Utilities.FlipPixelData(ref pixels, 4, 4, true, true); + // + // CollectionAssert.AreEqual(_pixelMapFlipHV, pixels); + // } + // + // #endregion + + // #region Set Pixels + // + // [Test] + // public void SetTopLeftPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 00, 01, + // 04, 05, + // }; + // + // var results = new[] + // { + // 00, 01, 00, 00, + // 04, 05, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 00, 00 + // }; + // + // Utilities.SetPixels(pixels, 0, 0, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // } + // + // [Test] + // public void SetTopRightPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 02, 03, + // 06, 07, + // }; + // + // var results = new[] + // { + // 00, 00, 02, 03, + // 00, 00, 06, 07, + // 00, 00, 00, 00, + // 00, 00, 00, 00 + // }; + // + // Utilities.SetPixels(pixels, 2, 0, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // + // } + // + // [Test] + // public void SetBottomRightPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 10, 11, + // 14, 15 + // }; + // + // var results = new[] + // { + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 10, 11, + // 00, 00, 14, 15 + // }; + // + // Utilities.SetPixels(pixels, 2, 2, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // + // } + // + // [Test] + // public void SetBottomLeftPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 08, 09, + // 12, 13, + // }; + // + // var results = new[] + // { + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 08, 09, 00, 00, + // 12, 13, 00, 00 + // }; + // + // Utilities.SetPixels(pixels, 0, 2, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // + // } + // + // [Test] + // public void SetOutOfBoundsTopLeftPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 00, 01, 02, + // 03, 04, 05, + // 06, 07, 08 + // }; + // + // var results = new[] + // { + // 05, 00, 00, 00, + // 08, 00, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 00, 00 + // }; + // + // // Example + // // 00, 01, 02 + // // 03, 04, 05, 00, 00, + // // 06, 07, 08, 00, 00, + // // 00, 00, 00, 00, + // // 00, 00, 00, 00 + // + // // Utilities.SetPixels(pixels, 0, 0, 3, 3, pixelData); + // + // Utilities.SetPixels(pixels, -2, -1, 3, 3, pixelData); + // + // // Utilities.SetPixels(pixels, 2, -1, 3, 3, pixelData); + // + // // Utilities.SetPixels(pixels, 8, 20, 3, 3, pixelData); + // + // // var tmpPD = new PixelData(); + // // tmpPD.SetPixels(pixels, 2, 2); + // // + // // Utilities.MergePixels(tmpPD, 0, 0, 2, 2, pixelData, -1, -1); + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // } + // + // [Test] + // public void SetOutOfBoundsTopRightPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 02, 03, + // 06, 07, + // }; + // + // var results = new[] + // { + // 00, 00, 00, 06, + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 00, 00 + // }; + // + // // Example + // // 02, 03 + // // 00, 00, 00, 06, 07 + // // 00, 00, 00, 00, + // // 00, 00, 00, 00, + // // 00, 00, 00, 00, + // + // Utilities.SetPixels(pixels, 3, -1, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // + // } + // + // [Test] + // public void SetOutOfBoundsBottomRightPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 10, 11, + // 14, 15 + // }; + // + // var results = new[] + // { + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 00, 10 + // }; + // + // // Example + // // 00, 00, 00, 00, + // // 00, 00, 00, 00, + // // 00, 00, 00, 00, + // // 00, 00, 00, 10, 11 + // // 14, 15 + // + // Utilities.SetPixels(pixels, 3, 3, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // + // } + // + // [Test] + // public void SetOutOfBoundsBottomLeftPixelsTest() + // { + // var pixelData = new PixelData(4, 4); + // + // var pixels = new int[] + // { + // 08, 09, + // 12, 13, + // }; + // + // var results = new[] + // { + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 00, 00, 00, 00, + // 09, 00, 00, 00 + // }; + // + // // Example + // // 00, 00, 00, 00, + // // 00, 00, 00, 00, + // // 00, 00, 00, 00, + // // 08, 09, 00, 00, 00, + // // 12, 13 + // + // Utilities.SetPixels(pixels, -1, 3, 2, 2, pixelData); + // + // CollectionAssert.AreEqual(results, Utilities.GetPixels(pixelData)); + // + // } + // + // #endregion + + [Test] + public void MergeDataTest() + { + + // int i = 6; + for (var i = 0; i < _testData.Length; i++) + { + Console.WriteLine("Merge Data Set Test " + i +"\n"); + + var data = _testData[i]; + + var finalSets = new int[][] + { + data.FinalMerge, + data.FinalFlipHVMerge, + data.FinalOffsetMerge, + }; + + var labels = new string[] {"Merge", "FlipHV", "Color Offset"}; + + for (int j = 0; j < finalSets.Length; j++) + { + var finalSet = finalSets[j]; + + var srcPixelData = new PixelData(); + srcPixelData.SetPixels(_srcData, _srcRect.Width, _srcRect.Height); + + var destPixelData = new PixelData(); + destPixelData.SetPixels(_destData, _destRect.Width, _destRect.Height); + + var flipH = j == 1; + var flipV = j == 1; + var color = j == 2 ? data.ColorOffset : 0; + Console.WriteLine(" Test " + labels[j] +" - H {0} V {1}\n", flipH, flipV); + + + Utilities.MergePixels(srcPixelData, data.SampleRect.X, data.SampleRect.Y, data.SampleRect.Width, data.SampleRect.Height, destPixelData, data.DestPos.X, data.DestPos.Y, flipH, flipV, color); + + CollectionAssert.AreEqual(destPixelData.Pixels, finalSet); + } + + } + + } + + [Test] + public void SetDataTest() + { + + // int i = 1; + for (var i = 0; i < _testData.Length; i++) + { + Console.WriteLine("Merge Data Set Test " + i +"\n"); + + var data = _testData[i]; + + var finalSet = data.FinalSet; + + var srcPixelData = new PixelData(); + srcPixelData.SetPixels(_srcData, _srcRect.Width, _srcRect.Height); + + var destPixelData = new PixelData(); + destPixelData.SetPixels(_destData, _destRect.Width, _destRect.Height); + + Console.WriteLine("src " + string.Join(",", srcPixelData.Pixels)); + Console.WriteLine("dest " + string.Join(",", destPixelData.Pixels)); + + Utilities.SetPixels(srcPixelData.Pixels, data.DestPos.X, data.DestPos.Y, data.SampleRect.Width, data.SampleRect.Height, destPixelData); + + Console.WriteLine("final " + string.Join(",", finalSet)); + Console.WriteLine("dest " + string.Join(",", destPixelData.Pixels)); + + CollectionAssert.AreEqual(destPixelData.Pixels, finalSet); + + } + + } + + } + + +} diff --git a/Tests/SDK/PixelDataUtiltities.Performance.Test.cs b/Tests/SDK/PixelDataUtiltities.Performance.Test.cs new file mode 100644 index 00000000..bce19ab3 --- /dev/null +++ b/Tests/SDK/PixelDataUtiltities.Performance.Test.cs @@ -0,0 +1,190 @@ +using System; +using System.Diagnostics; +using NUnit.Framework; +using Microsoft.Xna.Framework; +using System.Collections.Generic; +using System.Linq; + +namespace PixelVision8.Player +{ + public partial class PixelDataUtilitiesTest + { + + #region Performance Tests + + [Test] + public void MergePerformanceTest() + { + Random r = new Random(); + int Iterations = 1000000; + + + var srcPixelData = new PixelData(8,8); + for (int i = 0; i < srcPixelData.Total; i++) + { + srcPixelData[i] = r.Next(-1, 16); + } + + var destPixelData = new PixelData(256, 240); + + var destPixels = Enumerable.Range(0, destPixelData.Total-1).ToArray();//, destPixelData.Width, destPixelData.Height); + + var srcRect = new Rectangle(0, 0, 8, 8); + + var destPos = new Point(); + + var average = new List(); + + Stopwatch sw = Stopwatch.StartNew(); + + // Test 1 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: false, V: false, offset: 0, ignore: false, speed: {0}ms", average.Last()); + + // Test 2 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y, false, false , 10); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: false, V: false, offset: 100, ignore: false, speed: {0}ms", average.Last()); + + // Test 3 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y, true, false , 0); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: true, V: false, offset: 0, ignore: false, speed: {0}ms", average.Last()); + + // Test 4 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y, false, true , 0); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: false, V: true, offset: 0, ignore: false, speed: {0}ms", average.Last()); + + // Test 3 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y, true, true , 0); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: true, V: true, offset: 0, ignore: false, speed: {0}ms", average.Last()); + + // Test 4 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y, true, true , 100); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: true, V: true, offset: 100, ignore: false, speed: {0}ms", average.Last()); + + + // Test 5 + sw = Stopwatch.StartNew(); + destPixelData.SetPixels(destPixels, destPixelData.Width, destPixelData.Height); + + for (int i=0; i < Iterations; i++) + { + Utilities.MergePixels(srcPixelData, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, destPixelData, destPos.X, destPos.Y, true, true , 100, false); + } + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Merge H: true, V: true, offset: 100, ignore: true, speed: {0}ms", average.Last()); + + Console.WriteLine("Merge average: {0}ms", average.Average()); + + } + + [Test] + public void SetPerformanceTest() + { + Random r = new Random(); + int Iterations = 1000000; + + + var srcPixelData = new PixelData(8, 8); + + var pixels = new int[8 * 8]; + + for (int i = 0; i < pixels.Length; i++) + { + pixels[i] = r.Next(-1, 16); + } + + var average = new List(); + + Stopwatch sw = Stopwatch.StartNew(); + + // Test 1 + sw = Stopwatch.StartNew(); + // Utilities.Clear(destPixelData); + for (int i = 0; i < Iterations; i++) + { + srcPixelData.SetPixels(pixels); + } + + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Set all speed: {0}ms", average.Last()); + + + // Test 2 + sw = Stopwatch.StartNew(); + // Utilities.Clear(destPixelData); + for (int i = 0; i < Iterations; i++) + { + Utilities.SetPixels(pixels, 0, 0, srcPixelData.Width, srcPixelData.Height, srcPixelData); + } + + sw.Stop(); + average.Add(sw.ElapsedMilliseconds); + Console.WriteLine("Set area speed: {0}ms", average.Last()); + + // Test 3 + sw = Stopwatch.StartNew(); + + var pxD = new PixelData(8, 8); + pxD.SetPixels(pixels); + + for (int i = 0; i < Iterations; i++) + { + Utilities.MergePixels(pxD, 0, 0, pxD.Width, pxD.Height, srcPixelData, 0, 0); + } + + sw.Stop(); + Console.WriteLine("Merge speed: {0}ms", sw.ElapsedMilliseconds); + } + + #endregion + } +} \ No newline at end of file diff --git a/Tests/SDK/PixelVision.Test.cs b/Tests/SDK/PixelVision.Test.cs new file mode 100644 index 00000000..b516aee8 --- /dev/null +++ b/Tests/SDK/PixelVision.Test.cs @@ -0,0 +1,201 @@ + +using System; +using NUnit.Framework; + +namespace PixelVision8.Player +{ + public class TestChip : AbstractChip, IUpdate, IDraw + { + + public bool HasConfigured; + public bool HasInitialized; + public bool HasUpdated; + public bool HasDrawn; + public bool HasReset; + public bool HasShutdown; + + public override void Init() + { + HasInitialized = true; + } + + protected override void Configure() + { + HasConfigured = true; + } + + public void Update(int timeDelta) + { + HasUpdated = true; + } + + public void Draw() + { + HasDrawn = true; + } + + public override void Shutdown() + { + HasShutdown = true; + } + + public override void Reset() + { + HasReset = true; + } + + } + + public partial class PixelVisionTest + { + + [Test] + public void EngineNameTest() + { + var player = new PixelVision(null, "TestPlayer"); + + Assert.AreEqual(player.Name, "TestPlayer"); + } + + [Test] + public void DefaultEngineNameTest() + { + + var tmpPlayer = new PixelVision(); + + Assert.AreEqual(tmpPlayer.Name, "Player"); + } + + [Test] + public void ActivateChipTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + Assert.NotNull(player.GetChip(chipId)); + + } + + [Test] + public void HasChipTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + Assert.NotNull(player.HasChip(chipId)); + + } + + [Test] + public void GetChipTest() + { + + var player = new PixelVision(); + + var tmpChip = player.GetChip(typeof(AbstractChip).FullName); + + Assert.NotNull(tmpChip); + + } + + [Test] + public void ChipConfigTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + var tmpChip = player.GetChip(typeof(TestChip).FullName) as TestChip; + + Assert.IsTrue(tmpChip != null && tmpChip.HasConfigured); + + } + + [Test] + public void ChipInitTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + var tmpChip = player.GetChip(typeof(TestChip).FullName) as TestChip; + + player.RunGame(); + + Assert.IsTrue(tmpChip != null && tmpChip.HasInitialized); + + } + + [Test] + public void ChipUpdateTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + var tmpChip = player.GetChip(typeof(TestChip).FullName) as TestChip; + + player.RunGame(); + player.Update(0); + + Assert.IsTrue(tmpChip != null && tmpChip.HasUpdated); + + } + + [Test] + public void ChipDrawTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + var tmpChip = player.GetChip(typeof(TestChip).FullName) as TestChip; + + player.RunGame(); + player.Draw(); + + Assert.IsTrue(tmpChip != null && tmpChip.HasDrawn); + + } + + [Test] + public void ChipResetTest() + { + + var player = new PixelVision(); + + var chipId = typeof(TestChip).FullName; + + player.ActivateChip(chipId, new TestChip()); + + var tmpChip = player.GetChip(typeof(TestChip).FullName) as TestChip; + + player.RunGame(); + player.ResetGame(); + + Assert.IsTrue(tmpChip != null && tmpChip.HasReset); + + } + + } +} \ No newline at end of file