Skip to content

Commit

Permalink
RSW: Add a workaround for NaN light positions
Browse files Browse the repository at this point in the history
It's not pretty, but it does prevent crashes when loading gl_step...
  • Loading branch information
rdw-software committed Jan 29, 2024
1 parent 20c113a commit a59efa1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Core/FileFormats/RagnarokRSW.lua
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ function RagnarokRSW:DecodeSceneObjects()
if objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_ANIMATED_PROP then
self:DecodeAnimatedProps()
elseif objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_DYNAMIC_LIGHT_SOURCE then
self:DecodeDynamicLightSources()
self:DecodeDynamicLightSource()
elseif objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_SPATIAL_AUDIO_SOURCE then
self:DecodeSpatialAudioSource()
elseif objectTypeID == RagnarokRSW.SCENE_OBJECT_TYPE_PARTICLE_EFFECT_EMITTER then
Expand Down Expand Up @@ -344,9 +344,14 @@ function RagnarokRSW:DecodeAnimatedProps()
tinsert(self.animatedProps, objectInfo)
end

function RagnarokRSW:DecodeDynamicLightSources()
function RagnarokRSW:DecodeDynamicLightSource()
local objectInfo = self.reader:GetTypedArray("rsw_dynamic_light_t")

-- Garbage data exists in gl_step: See https://github.com/RagnarokResearchLab/RagLite/issues/343
if not objectInfo.position.y then
objectInfo.position.y = -1 * 5 * 29.8 -- Denormalized Y of nearby light sources (workaround)
end

local lightSource = {
name = ffi_string(objectInfo.name),
normalizedWorldPosition = {
Expand Down
16 changes: 16 additions & 0 deletions Tests/FileFormats/RagnarokRSW.spec.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local BinaryReader = require("Core.FileFormats.BinaryReader")
local QuadTreeRange = require("Core.FileFormats.RSW.QuadTreeRange")
local RagnarokRSW = require("Core.FileFormats.RagnarokRSW")

Expand Down Expand Up @@ -904,4 +905,19 @@ describe("RagnarokRSW", function()
assertEquals(rsw.sceneGraph:GetBinaryStorageSize(), 65520) -- This will have to do (for now)
end)
end)

describe("DecodeDynamicLightSource", function()
it("should be able to handle NaN values without crashing", function()
local name = string.rep("\000", 80)
local position = string.rep("\000", 4) .. string.rep("\255", 4) .. string.rep("\000", 4)
local color = string.rep("\000", 12)
local intensity = string.rep("\000", 4)
local garbageBytes = name .. position .. color .. intensity

local rsw = RagnarokRSW()
rsw.reader = BinaryReader(garbageBytes)
rsw:DecodeDynamicLightSource()
assertEquals(rsw.dynamicLightSources[1].normalizedWorldPosition.y, 29.8)
end)
end)
end)

0 comments on commit a59efa1

Please sign in to comment.