diff --git a/Core/NativeClient/NativeClient.lua b/Core/NativeClient/NativeClient.lua index be2c6714..5ef087ef 100644 --- a/Core/NativeClient/NativeClient.lua +++ b/Core/NativeClient/NativeClient.lua @@ -17,17 +17,27 @@ local Pyramid = require("Core.NativeClient.DebugDraw.Pyramid") local Sphere = require("Core.NativeClient.DebugDraw.Sphere") local WorldAxis = require("Core.NativeClient.DebugDraw.WorldAxis") +local RagnarokGRF = require("Core.FileFormats.RagnarokGRF") + local tonumber = tonumber local NativeClient = { mainWindow = nil, deferredEventQueue = nil, + -- Should probably move this to a dedicated Resources API (later) + GRF_FILE_PATH = "data.grf", + PERSISTENT_RESOURCES = { + ["data/sprite/cursors.act"] = false, + ["data/sprite/cursors.spr"] = false, + }, } function NativeClient:Start() self.mainWindow = self:CreateMainWindow() Renderer:InitializeWithGLFW(self.mainWindow) + self:PreloadPersistentResources() + local oldPyramidMesh = Pyramid() local worldAxesVisualizationMesh = WorldAxis() @@ -313,4 +323,28 @@ function NativeClient:IsShiftKeyDown() return (glfw.bindings.glfw_get_key(self.mainWindow, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) end +-- Can move to runtime later? +local function table_count(t) + local count = 0 + + for k, v in pairs(t) do + count = count + 1 + end + + return count +end + +-- Should probably move this to a dedicated Resources API (later) +function NativeClient:PreloadPersistentResources() + local grf = RagnarokGRF() + grf:Open(self.GRF_FILE_PATH) + + printf("Preloading %d persistent resources from %s", table_count(self.PERSISTENT_RESOURCES), self.GRF_FILE_PATH) + for filePath, isLoaded in pairs(self.PERSISTENT_RESOURCES) do + self.PERSISTENT_RESOURCES[filePath] = grf:ExtractFileInMemory(filePath) + end + + grf:Close() -- Probably best to leave it open? Revisit later, once more assets need to be loaded... +end + return NativeClient diff --git a/Tests/NativeClient/NativeClient.spec.lua b/Tests/NativeClient/NativeClient.spec.lua index 52887f5d..54aa68c6 100644 --- a/Tests/NativeClient/NativeClient.spec.lua +++ b/Tests/NativeClient/NativeClient.spec.lua @@ -4,6 +4,7 @@ local glfw = require("glfw") local C_Camera = require("Core.NativeClient.C_Camera") local C_Cursor = require("Core.NativeClient.C_Cursor") local NativeClient = require("Core.NativeClient.NativeClient") +local RagnarokGRF = require("Core.FileFormats.RagnarokGRF") local Vector3D = require("Core.VectorMath.Vector3D") describe("NativeClient", function() @@ -555,4 +556,61 @@ describe("NativeClient", function() assertEquals(newCameraTarget.z, expectedCameraTarget.z) end) end) + + describe("PreloadPersistentResources", function() + local DEFAULT_GRF_PATH = NativeClient.GRF_FILE_PATH + local PRELOADED_ASSET_FILES = NativeClient.PERSISTENT_RESOURCES + + after(function() + NativeClient.GRF_FILE_PATH = DEFAULT_GRF_PATH + NativeClient.PERSISTENT_RESOURCES = PRELOADED_ASSET_FILES + end) + + it("should throw if the configured asset container doesn't exist", function() + local function preloadFromNonExistingGRF() + NativeClient.GRF_FILE_PATH = "invalid.grf" + NativeClient:PreloadPersistentResources() + end + local expectedErrorMessage = "Failed to open archive invalid.grf (No such file exists)" + assertThrows(preloadFromNonExistingGRF, expectedErrorMessage) + end) + + it("should throw if the configured asset container isn't a valid GRF archive", function() + local SOME_EXISTING_FILE = path.join("Tests", "Fixtures", "test.rgz") + local function preloadFromInvalidGRF() + NativeClient.GRF_FILE_PATH = SOME_EXISTING_FILE + NativeClient:PreloadPersistentResources() + end + local expectedErrorMessage = format("Failed to open archive %s (Not a .grf file)", SOME_EXISTING_FILE) + assertThrows(preloadFromInvalidGRF, expectedErrorMessage) + end) + + it("should load and store all persistent resources from the configured asset container", function() + NativeClient.GRF_FILE_PATH = path.join("Tests", "Fixtures", "test.grf") + NativeClient.PERSISTENT_RESOURCES = { + ["hello-grf.txt"] = false, + ["subdirectory/hello.txt"] = false, + ["uppercase.png"] = false, + ["안녕하세요.txt"] = false, + } + NativeClient:PreloadPersistentResources() + + local grf = RagnarokGRF() + grf:Open(NativeClient.GRF_FILE_PATH) + local expectedFileContents = { + ["hello-grf.txt"] = grf:ExtractFileInMemory("hello-grf.txt"), + ["subdirectory/hello.txt"] = grf:ExtractFileInMemory("subdirectory/hello.txt"), + ["uppercase.png"] = grf:ExtractFileInMemory("uppercase.png"), + ["안녕하세요.txt"] = grf:ExtractFileInMemory("안녕하세요.txt"), + } + grf:Close() + + -- Might want to add metadata later, but for now just caching the file contents should suffice + local preloadedAssetFiles = NativeClient.PERSISTENT_RESOURCES + assertEquals(preloadedAssetFiles["hello-grf.txt"], expectedFileContents["hello-grf.txt"]) + assertEquals(preloadedAssetFiles["subdirectory/hello.txt"], expectedFileContents["subdirectory/hello.txt"]) + assertEquals(preloadedAssetFiles["uppercase.png"], expectedFileContents["uppercase.png"]) + assertEquals(preloadedAssetFiles["안녕하세요.txt"], expectedFileContents["안녕하세요.txt"]) + end) + end) end)