data = {} data.load = function() -- Media local function lookup(ext, fn) local function halp(s, k) local base = s._path .. '/' .. k local function extLoad(ext) if love.filesystem.exists(base .. ext) then s[k] = fn(base .. ext) elseif love.filesystem.isDirectory(base) then local t = {} t._path = base setmetatable(t, {__index = halp}) s[k] = t else return false end return true end if type(ext) == 'table' then lume.each(ext, function(e) return extLoad(e) end) else extLoad(ext) end return rawget(s, k) end return halp end data.media = {} data.media.graphics = setmetatable({_path = 'media/graphics'}, {__index = lookup({'.png', '.dds'}, love.graphics and love.graphics.newImage or f.empty)}) data.media.sounds = setmetatable({_path = 'media/sounds'}, {__index = lookup('.ogg', love.audio and love.audio.newSource or f.empty)}) -- Data local function load(dir, type, fn) local id = 1 local function halp(dir, dst) for _, file in ipairs(love.filesystem.getDirectoryItems(dir)) do path = dir .. '/' .. file if love.filesystem.isDirectory(path) then dst[file] = {} halp(path, dst[file]) elseif file:match('%.lua$') and not file:match('^%.') then local obj = love.filesystem.load(path)() assert(obj, path .. ' did not return a value') obj.code = obj.code or file:gsub('%.lua', '') obj.id = id obj = lume.call(fn, obj) or obj data[type][id] = obj dst[obj.code] = obj id = id + 1 end end end data[type] = {} halp(dir, data[type]) end load('data/animation', 'animation', function(animation) -- Set up lazy loading for images local code = animation.code animation.graphics = setmetatable({_path = 'media/skeletons/' .. code}, { __index = lookup({'.png', '.dds'}, function(path) local img = love.graphics.newImage(path) if path:match('%.dds') then img:setMipmapFilter('nearest', 1) end return img end) }) -- Set up static spine data structures local s = {} s.__index = s if love.filesystem.exists('media/skeletons/' .. code .. '/' .. code .. '.atlas') then s.atlas = spine.Atlas.new('media/skeletons/' .. code .. '/' .. code .. '.atlas') s.atlasAttachmentLoader = spine.AtlasAttachmentLoader.new(s.atlas) end s.json = spine.SkeletonJson.new(s.atlasAttachmentLoader) s.skeletonData = s.json:readSkeletonDataFile('media/skeletons/' .. code .. '/' .. code .. '.json') s.animationStateData = spine.AnimationStateData.new(s.skeletonData) -- Reverse-index keys (sorted for consistent order) local keys = lume.keys(animation.states) table.sort(keys) for i = 1, #keys do local state = animation.states[keys[i]] animation.states[i] = state state.index = i state.name = keys[i] end -- Set mixes for i = 1, #animation.states do table.each(animation.states, function(state) if state.index ~= i then s.animationStateData:setMix(animation.states[i].name, state.name, Animation.defaultMix) end end) table.each(animation.states[i].mix or {}, function(time, to) s.animationStateData:setMix(animation.states[i].name, to, time) end) end animation.spine = s return animation end) load('data/particle', 'particle') end