From 3cbec9a3dff586ea01a5333a93aef52dd7a4a1fe Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sat, 23 Mar 2019 12:02:01 +0100 Subject: [PATCH 1/3] core: use latest gamecore --- sonic-radiance.love/core/debug.lua | 3 +- sonic-radiance.love/core/init.lua | 21 +- sonic-radiance.love/core/input.lua | 2 +- sonic-radiance.love/core/lang.lua | 13 +- sonic-radiance.love/core/libs/binser.lua | 687 ++++++++++++++++ sonic-radiance.love/core/libs/classic.lua | 68 ++ sonic-radiance.love/core/libs/cscreen.lua | 99 +++ sonic-radiance.love/core/libs/lovebird.lua | 737 ++++++++++++++++++ .../core/modules/assets/animator.lua | 4 + .../core/modules/assets/autotile.lua | 3 +- .../core/modules/assets/imagefonts.lua | 3 +- .../core/modules/assets/init.lua | 20 +- .../core/modules/assets/sprites.lua | 14 +- .../core/modules/assets/texture.lua | 65 ++ .../core/modules/assets/tileset.lua | 19 +- .../core/modules/menusystem/init.lua | 37 +- .../core/modules/menusystem/parent.lua | 15 + sonic-radiance.love/core/modules/scenes.lua | 10 +- sonic-radiance.love/core/options.lua | 30 +- sonic-radiance.love/core/scenemanager.lua | 38 +- sonic-radiance.love/core/screen.lua | 3 +- sonic-radiance.love/core/utils/filesystem.lua | 16 + sonic-radiance.love/core/utils/graphics.lua | 64 ++ sonic-radiance.love/core/utils/init.lua | 7 + sonic-radiance.love/core/utils/math.lua | 88 +++ sonic-radiance.love/main.lua | 2 - 26 files changed, 2026 insertions(+), 42 deletions(-) create mode 100644 sonic-radiance.love/core/libs/binser.lua create mode 100644 sonic-radiance.love/core/libs/classic.lua create mode 100644 sonic-radiance.love/core/libs/cscreen.lua create mode 100644 sonic-radiance.love/core/libs/lovebird.lua create mode 100644 sonic-radiance.love/core/modules/assets/texture.lua create mode 100644 sonic-radiance.love/core/utils/filesystem.lua create mode 100644 sonic-radiance.love/core/utils/graphics.lua create mode 100644 sonic-radiance.love/core/utils/init.lua create mode 100644 sonic-radiance.love/core/utils/math.lua diff --git a/sonic-radiance.love/core/debug.lua b/sonic-radiance.love/core/debug.lua index 9a85811..fe6076d 100644 --- a/sonic-radiance.love/core/debug.lua +++ b/sonic-radiance.love/core/debug.lua @@ -23,7 +23,8 @@ local DebugSystem = Object:extend() -local lovebird = require("libs.lovebird") +local cwd = (...):gsub('%.debug$', '') .. "." +local lovebird = require(cwd .. "libs.lovebird") function DebugSystem:new(controller, active) self.controller = controller diff --git a/sonic-radiance.love/core/init.lua b/sonic-radiance.love/core/init.lua index 63bba08..101f49c 100644 --- a/sonic-radiance.love/core/init.lua +++ b/sonic-radiance.love/core/init.lua @@ -23,15 +23,24 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] +local cwd = (...):gsub('%.init$', '') .. "." + +-- GLOBAL UTILS/FUNCTION LOADING +-- Load in the global namespace utilities that'll need to be reusable everywhere +-- in the game + +Object = require(cwd .. "libs.classic") +utils = require(cwd .. "utils") + local CoreSystem = Object:extend() -local DebugSystem = require "core.debug" +local DebugSystem = require(cwd .. "debug") -local Options = require "core.options" -local Input = require "core.input" -local Screen = require "core.screen" -local Lang = require "core.lang" -local SceneManager= require "core.scenemanager" +local Options = require(cwd .. "options") +local Input = require(cwd .. "input") +local Screen = require(cwd .. "screen") +local Lang = require(cwd .. "lang") +local SceneManager = require(cwd .. "scenemanager") function CoreSystem:new() self.debug = DebugSystem(self) diff --git a/sonic-radiance.love/core/input.lua b/sonic-radiance.love/core/input.lua index 7513d25..578c05b 100644 --- a/sonic-radiance.love/core/input.lua +++ b/sonic-radiance.love/core/input.lua @@ -26,7 +26,7 @@ local InputManager = Object:extend() function InputManager:new(controller) self.controller = controller - self.data = self.controller.options.data.input[1] + self.data = self.controller.options:getPlayerInputData(1) self.keys = self:getKeyList() self.fakekeys = self:getKeyList() diff --git a/sonic-radiance.love/core/lang.lua b/sonic-radiance.love/core/lang.lua index 1144806..6c6a69f 100644 --- a/sonic-radiance.love/core/lang.lua +++ b/sonic-radiance.love/core/lang.lua @@ -23,11 +23,22 @@ ]] local LanguageManager = Object:extend() -local langs = require "datas.languages" function LanguageManager:new(controller) self.controller = controller self:setLang(self.controller.options.data.language) + self:getTranslationData() +end + +function LanguageManager:getTranslationData() + local _path = "datas/languages/init.lua" + local fileinfo = love.filesystem.getInfo(_path) + + if fileinfo ~= nil then + self.datas = require "datas.languages" + else + self.datas = nil + end end function LanguageManager:getStringList(library, file) diff --git a/sonic-radiance.love/core/libs/binser.lua b/sonic-radiance.love/core/libs/binser.lua new file mode 100644 index 0000000..5aa1299 --- /dev/null +++ b/sonic-radiance.love/core/libs/binser.lua @@ -0,0 +1,687 @@ +-- binser.lua + +--[[ +Copyright (c) 2016 Calvin Rose + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + +local assert = assert +local error = error +local select = select +local pairs = pairs +local getmetatable = getmetatable +local setmetatable = setmetatable +local tonumber = tonumber +local type = type +local loadstring = loadstring or load +local concat = table.concat +local char = string.char +local byte = string.byte +local format = string.format +local sub = string.sub +local dump = string.dump +local floor = math.floor +local frexp = math.frexp +local unpack = unpack or table.unpack + +-- Lua 5.3 frexp polyfill +-- From https://github.com/excessive/cpml/blob/master/modules/utils.lua +if not frexp then + local log, abs, floor = math.log, math.abs, math.floor + local log2 = log(2) + frexp = function(x) + if x == 0 then return 0, 0 end + local e = floor(log(abs(x)) / log2 + 1) + return x / 2 ^ e, e + end +end + +-- NIL = 202 +-- FLOAT = 203 +-- TRUE = 204 +-- FALSE = 205 +-- STRING = 206 +-- TABLE = 207 +-- REFERENCE = 208 +-- CONSTRUCTOR = 209 +-- FUNCTION = 210 +-- RESOURCE = 211 +-- INT64 = 212 + +local mts = {} +local ids = {} +local serializers = {} +local deserializers = {} +local resources = {} +local resources_by_name = {} + +local function pack(...) + return {...}, select("#", ...) +end + +local function not_array_index(x, len) + return type(x) ~= "number" or x < 1 or x > len or x ~= floor(x) +end + +local function type_check(x, tp, name) + assert(type(x) == tp, + format("Expected parameter %q to be of type %q.", name, tp)) +end + +local bigIntSupport = false +local isInteger +if math.type then -- Detect Lua 5.3 + local mtype = math.type + bigIntSupport = loadstring[[ + local char = string.char + return function(n) + local nn = n < 0 and -(n + 1) or n + local b1 = nn // 0x100000000000000 + local b2 = nn // 0x1000000000000 % 0x100 + local b3 = nn // 0x10000000000 % 0x100 + local b4 = nn // 0x100000000 % 0x100 + local b5 = nn // 0x1000000 % 0x100 + local b6 = nn // 0x10000 % 0x100 + local b7 = nn // 0x100 % 0x100 + local b8 = nn % 0x100 + if n < 0 then + b1, b2, b3, b4 = 0xFF - b1, 0xFF - b2, 0xFF - b3, 0xFF - b4 + b5, b6, b7, b8 = 0xFF - b5, 0xFF - b6, 0xFF - b7, 0xFF - b8 + end + return char(212, b1, b2, b3, b4, b5, b6, b7, b8) + end]]() + isInteger = function(x) + return mtype(x) == 'integer' + end +else + isInteger = function(x) + return floor(x) == x + end +end + +-- Copyright (C) 2012-2015 Francois Perrad. +-- number serialization code modified from https://github.com/fperrad/lua-MessagePack +-- Encode a number as a big-endian ieee-754 double, big-endian signed 64 bit integer, or a small integer +local function number_to_str(n) + if isInteger(n) then -- int + if n <= 100 and n >= -27 then -- 1 byte, 7 bits of data + return char(n + 27) + elseif n <= 8191 and n >= -8192 then -- 2 bytes, 14 bits of data + n = n + 8192 + return char(128 + (floor(n / 0x100) % 0x100), n % 0x100) + elseif bigIntSupport then + return bigIntSupport(n) + end + end + local sign = 0 + if n < 0.0 then + sign = 0x80 + n = -n + end + local m, e = frexp(n) -- mantissa, exponent + if m ~= m then + return char(203, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) + elseif m == 1/0 then + if sign == 0 then + return char(203, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) + else + return char(203, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) + end + end + e = e + 0x3FE + if e < 1 then -- denormalized numbers + m = m * 2 ^ (52 + e) + e = 0 + else + m = (m * 2 - 1) * 2 ^ 52 + end + return char(203, + sign + floor(e / 0x10), + (e % 0x10) * 0x10 + floor(m / 0x1000000000000), + floor(m / 0x10000000000) % 0x100, + floor(m / 0x100000000) % 0x100, + floor(m / 0x1000000) % 0x100, + floor(m / 0x10000) % 0x100, + floor(m / 0x100) % 0x100, + m % 0x100) +end + +-- Copyright (C) 2012-2015 Francois Perrad. +-- number deserialization code also modified from https://github.com/fperrad/lua-MessagePack +local function number_from_str(str, index) + local b = byte(str, index) + if b < 128 then + return b - 27, index + 1 + elseif b < 192 then + return byte(str, index + 1) + 0x100 * (b - 128) - 8192, index + 2 + end + local b1, b2, b3, b4, b5, b6, b7, b8 = byte(str, index + 1, index + 8) + if b == 212 then + local flip = b1 >= 128 + if flip then -- negative + b1, b2, b3, b4 = 0xFF - b1, 0xFF - b2, 0xFF - b3, 0xFF - b4 + b5, b6, b7, b8 = 0xFF - b5, 0xFF - b6, 0xFF - b7, 0xFF - b8 + end + local n = ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 + if flip then + return (-n) - 1, index + 9 + else + return n, index + 9 + end + end + local sign = b1 > 0x7F and -1 or 1 + local e = (b1 % 0x80) * 0x10 + floor(b2 / 0x10) + local m = ((((((b2 % 0x10) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 + local n + if e == 0 then + if m == 0 then + n = sign * 0.0 + else + n = sign * (m / 2 ^ 52) * 2 ^ -1022 + end + elseif e == 0x7FF then + if m == 0 then + n = sign * (1/0) + else + n = 0.0/0.0 + end + else + n = sign * (1.0 + m / 2 ^ 52) * 2 ^ (e - 0x3FF) + end + return n, index + 9 +end + +local types = {} + +types["nil"] = function(x, visited, accum) + accum[#accum + 1] = "\202" +end + +function types.number(x, visited, accum) + accum[#accum + 1] = number_to_str(x) +end + +function types.boolean(x, visited, accum) + accum[#accum + 1] = x and "\204" or "\205" +end + +function types.string(x, visited, accum) + local alen = #accum + if visited[x] then + accum[alen + 1] = "\208" + accum[alen + 2] = number_to_str(visited[x]) + else + visited[x] = visited.next + visited.next = visited.next + 1 + accum[alen + 1] = "\206" + accum[alen + 2] = number_to_str(#x) + accum[alen + 3] = x + end +end + +local function check_custom_type(x, visited, accum) + local res = resources[x] + if res then + accum[#accum + 1] = "\211" + types[type(res)](res, visited, accum) + return true + end + local mt = getmetatable(x) + local id = mt and ids[mt] + if id then + if x == visited.temp then + error("Infinite loop in constructor.") + end + visited.temp = x + accum[#accum + 1] = "\209" + types[type(id)](id, visited, accum) + local args, len = pack(serializers[id](x)) + accum[#accum + 1] = number_to_str(len) + for i = 1, len do + local arg = args[i] + types[type(arg)](arg, visited, accum) + end + visited[x] = visited.next + visited.next = visited.next + 1 + return true + end +end + +function types.userdata(x, visited, accum) + if visited[x] then + accum[#accum + 1] = "\208" + accum[#accum + 1] = number_to_str(visited[x]) + else + if check_custom_type(x, visited, accum) then return end + error("Cannot serialize this userdata.") + end +end + +function types.table(x, visited, accum) + if visited[x] then + accum[#accum + 1] = "\208" + accum[#accum + 1] = number_to_str(visited[x]) + else + if check_custom_type(x, visited, accum) then return end + visited[x] = visited.next + visited.next = visited.next + 1 + local xlen = #x + accum[#accum + 1] = "\207" + accum[#accum + 1] = number_to_str(xlen) + for i = 1, xlen do + local v = x[i] + types[type(v)](v, visited, accum) + end + local key_count = 0 + for k in pairs(x) do + if not_array_index(k, xlen) then + key_count = key_count + 1 + end + end + accum[#accum + 1] = number_to_str(key_count) + for k, v in pairs(x) do + if not_array_index(k, xlen) then + types[type(k)](k, visited, accum) + types[type(v)](v, visited, accum) + end + end + end +end + +types["function"] = function(x, visited, accum) + if visited[x] then + accum[#accum + 1] = "\208" + accum[#accum + 1] = number_to_str(visited[x]) + else + if check_custom_type(x, visited, accum) then return end + visited[x] = visited.next + visited.next = visited.next + 1 + local str = dump(x) + accum[#accum + 1] = "\210" + accum[#accum + 1] = number_to_str(#str) + accum[#accum + 1] = str + end +end + +types.cdata = function(x, visited, accum) + if visited[x] then + accum[#accum + 1] = "\208" + accum[#accum + 1] = number_to_str(visited[x]) + else + if check_custom_type(x, visited, #accum) then return end + error("Cannot serialize this cdata.") + end +end + +types.thread = function() error("Cannot serialize threads.") end + +local function deserialize_value(str, index, visited) + local t = byte(str, index) + if not t then return end + if t < 128 then + return t - 27, index + 1 + elseif t < 192 then + return byte(str, index + 1) + 0x100 * (t - 128) - 8192, index + 2 + elseif t == 202 then + return nil, index + 1 + elseif t == 203 then + return number_from_str(str, index) + elseif t == 204 then + return true, index + 1 + elseif t == 205 then + return false, index + 1 + elseif t == 206 then + local length, dataindex = deserialize_value(str, index + 1, visited) + local nextindex = dataindex + length + local substr = sub(str, dataindex, nextindex - 1) + visited[#visited + 1] = substr + return substr, nextindex + elseif t == 207 then + local count, nextindex = number_from_str(str, index + 1) + local ret = {} + visited[#visited + 1] = ret + for i = 1, count do + ret[i], nextindex = deserialize_value(str, nextindex, visited) + end + count, nextindex = number_from_str(str, nextindex) + for i = 1, count do + local k, v + k, nextindex = deserialize_value(str, nextindex, visited) + v, nextindex = deserialize_value(str, nextindex, visited) + ret[k] = v + end + return ret, nextindex + elseif t == 208 then + local ref, nextindex = number_from_str(str, index + 1) + return visited[ref], nextindex + elseif t == 209 then + local count + local name, nextindex = deserialize_value(str, index + 1, visited) + count, nextindex = number_from_str(str, nextindex) + local args = {} + for i = 1, count do + args[i], nextindex = deserialize_value(str, nextindex, visited) + end + local ret = deserializers[name](unpack(args)) + visited[#visited + 1] = ret + return ret, nextindex + elseif t == 210 then + local length, dataindex = deserialize_value(str, index + 1, visited) + local nextindex = dataindex + length + local ret = loadstring(sub(str, dataindex, nextindex - 1)) + visited[#visited + 1] = ret + return ret, nextindex + elseif t == 211 then + local res, nextindex = deserialize_value(str, index + 1, visited) + return resources_by_name[res], nextindex + elseif t == 212 then + return number_from_str(str, index) + else + error("Could not deserialize type byte " .. t .. ".") + end +end + +local function serialize(...) + local visited = {next = 1} + local accum = {} + for i = 1, select("#", ...) do + local x = select(i, ...) + types[type(x)](x, visited, accum) + end + return concat(accum) +end + +local function make_file_writer(file) + return setmetatable({}, { + __newindex = function(_, _, v) + file:write(v) + end + }) +end + +local function serialize_to_file(path, mode, ...) + local file, err = io.open(path, mode) + assert(file, err) + local visited = {next = 1} + local accum = make_file_writer(file) + for i = 1, select("#", ...) do + local x = select(i, ...) + types[type(x)](x, visited, accum) + end + -- flush the writer + file:flush() + file:close() +end + +local function writeFile(path, ...) + return serialize_to_file(path, "wb", ...) +end + +local function appendFile(path, ...) + return serialize_to_file(path, "ab", ...) +end + +local function deserialize(str, index) + assert(type(str) == "string", "Expected string to deserialize.") + local vals = {} + index = index or 1 + local visited = {} + local len = 0 + local val + while index do + val, index = deserialize_value(str, index, visited) + if index then + len = len + 1 + vals[len] = val + end + end + return vals, len +end + +local function deserializeN(str, n, index) + assert(type(str) == "string", "Expected string to deserialize.") + n = n or 1 + assert(type(n) == "number", "Expected a number for parameter n.") + assert(n > 0 and floor(n) == n, "N must be a poitive integer.") + local vals = {} + index = index or 1 + local visited = {} + local len = 0 + local val + while index and len < n do + val, index = deserialize_value(str, index, visited) + if index then + len = len + 1 + vals[len] = val + end + end + vals[len + 1] = index + return unpack(vals, 1, n + 1) +end + +local function readFile(path) + local file, err = io.open(path, "rb") + assert(file, err) + local str = file:read("*all") + file:close() + return deserialize(str) +end + +local function default_deserialize(metatable) + return function(...) + local ret = {} + for i = 1, select("#", ...), 2 do + ret[select(i, ...)] = select(i + 1, ...) + end + return setmetatable(ret, metatable) + end +end + +local function default_serialize(x) + assert(type(x) == "table", + "Default serialization for custom types only works for tables.") + local args = {} + local len = 0 + for k, v in pairs(x) do + args[len + 1], args[len + 2] = k, v + len = len + 2 + end + return unpack(args, 1, len) +end + +-- Templating + +local function normalize_template(template) + local ret = {} + for i = 1, #template do + ret[i] = template[i] + end + local non_array_part = {} + -- The non-array part of the template (nested templates) have to be deterministic, so they are sorted. + -- This means that inherently non deterministicly sortable keys (tables, functions) should NOT be used + -- in templates. Looking for way around this. + for k in pairs(template) do + if not_array_index(k, #template) then + non_array_part[#non_array_part + 1] = k + end + end + table.sort(non_array_part) + for i = 1, #non_array_part do + local name = non_array_part[i] + ret[#ret + 1] = {name, normalize_template(template[name])} + end + return ret +end + +local function templatepart_serialize(part, argaccum, x, len) + local extras = {} + local extracount = 0 + for k, v in pairs(x) do + extras[k] = v + extracount = extracount + 1 + end + for i = 1, #part do + extracount = extracount - 1 + if type(part[i]) == "table" then + extras[part[i][1]] = nil + len = templatepart_serialize(part[i][2], argaccum, x[part[i][1]], len) + else + extras[part[i]] = nil + len = len + 1 + argaccum[len] = x[part[i]] + end + end + if extracount > 0 then + argaccum[len + 1] = extras + else + argaccum[len + 1] = nil + end + return len + 1 +end + +local function templatepart_deserialize(ret, part, values, vindex) + for i = 1, #part do + local name = part[i] + if type(name) == "table" then + local newret = {} + ret[name[1]] = newret + vindex = templatepart_deserialize(newret, name[2], values, vindex) + else + ret[name] = values[vindex] + vindex = vindex + 1 + end + end + local extras = values[vindex] + if extras then + for k, v in pairs(extras) do + ret[k] = v + end + end + return vindex + 1 +end + +local function template_serializer_and_deserializer(metatable, template) + return function(x) + argaccum = {} + local len = templatepart_serialize(template, argaccum, x, 0) + return unpack(argaccum, 1, len) + end, function(...) + local ret = {} + local len = select("#", ...) + local args = {...} + templatepart_deserialize(ret, template, args, 1) + return setmetatable(ret, metatable) + end +end + +local function register(metatable, name, serialize, deserialize) + name = name or metatable.name + serialize = serialize or metatable._serialize + deserialize = deserialize or metatable._deserialize + if not serialize then + if metatable._template then + local t = normalize_template(metatable._template) + serialize, deserialize = template_serializer_and_deserializer(metatable, t) + elseif not deserialize then + serialize = default_serialize + deserialize = default_deserialize(metatable) + else + serialize = metatable + end + end + type_check(metatable, "table", "metatable") + type_check(name, "string", "name") + type_check(serialize, "function", "serialize") + type_check(deserialize, "function", "deserialize") + assert(not ids[metatable], "Metatable already registered.") + assert(not mts[name], ("Name %q already registered."):format(name)) + mts[name] = metatable + ids[metatable] = name + serializers[name] = serialize + deserializers[name] = deserialize + return metatable +end + +local function unregister(item) + local name, metatable + if type(item) == "string" then -- assume name + name, metatable = item, mts[item] + else -- assume metatable + name, metatable = ids[item], item + end + type_check(name, "string", "name") + type_check(metatable, "table", "metatable") + mts[name] = nil + ids[metatable] = nil + serializers[name] = nil + deserializers[name] = nil + return metatable +end + +local function registerClass(class, name) + name = name or class.name + if class.__instanceDict then -- middleclass + register(class.__instanceDict, name) + else -- assume 30log or similar library + register(class, name) + end + return class +end + +local function registerResource(resource, name) + type_check(name, "string", "name") + assert(not resources[resource], + "Resource already registered.") + assert(not resources_by_name[name], + format("Resource %q already exists.", name)) + resources_by_name[name] = resource + resources[resource] = name + return resource +end + +local function unregisterResource(name) + type_check(name, "string", "name") + assert(resources_by_name[name], format("Resource %q does not exist.", name)) + local resource = resources_by_name[name] + resources_by_name[name] = nil + resources[resource] = nil + return resource +end + +return { + -- aliases + s = serialize, + d = deserialize, + dn = deserializeN, + r = readFile, + w = writeFile, + a = appendFile, + + serialize = serialize, + deserialize = deserialize, + deserializeN = deserializeN, + readFile = readFile, + writeFile = writeFile, + appendFile = appendFile, + register = register, + unregister = unregister, + registerResource = registerResource, + unregisterResource = unregisterResource, + registerClass = registerClass +} diff --git a/sonic-radiance.love/core/libs/classic.lua b/sonic-radiance.love/core/libs/classic.lua new file mode 100644 index 0000000..cbd6f81 --- /dev/null +++ b/sonic-radiance.love/core/libs/classic.lua @@ -0,0 +1,68 @@ +-- +-- classic +-- +-- Copyright (c) 2014, rxi +-- +-- This module is free software; you can redistribute it and/or modify it under +-- the terms of the MIT license. See LICENSE for details. +-- + + +local Object = {} +Object.__index = Object + + +function Object:new() +end + + +function Object:extend() + local cls = {} + for k, v in pairs(self) do + if k:find("__") == 1 then + cls[k] = v + end + end + cls.__index = cls + cls.super = self + setmetatable(cls, self) + return cls +end + + +function Object:implement(...) + for _, cls in pairs({...}) do + for k, v in pairs(cls) do + if self[k] == nil and type(v) == "function" then + self[k] = v + end + end + end +end + + +function Object:is(T) + local mt = getmetatable(self) + while mt do + if mt == T then + return true + end + mt = getmetatable(mt) + end + return false +end + + +function Object:__tostring() + return "Object" +end + + +function Object:__call(...) + local obj = setmetatable({}, self) + obj:new(...) + return obj +end + + +return Object diff --git a/sonic-radiance.love/core/libs/cscreen.lua b/sonic-radiance.love/core/libs/cscreen.lua new file mode 100644 index 0000000..579ea0d --- /dev/null +++ b/sonic-radiance.love/core/libs/cscreen.lua @@ -0,0 +1,99 @@ +--[[ +CScreen v1.3 by CodeNMore +A simple way to make resolution-independent Love2D games +Tested for LOVE 0.10.1 +See: https://github.com/CodeNMore/CScreen +Zlib License: +Copyright (c) 2016 CodeNMore +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from +the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: +1. The origin of this software must not be misrepresented; you must not +claim that you wrote the original software. If you use this software in +a product, an acknowledgment in the product documentation would be appreciated +but is not required. +2. Altered source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +--]] + +local CScreen = {} +local rx, ry, ctr = 800, 600, true +local rxv, ryv, fsv, fsvr = 800, 600, 1.0, 1.0 +local tx, ty, rwf, rhf = 0, 0, 800, 600 +local cr, cg, cb, ca = 0, 0, 0, 255 + +-- Initializes CScreen with the initial size values +function CScreen.init(tw, th, cntr) + rx = tw or 800 + ry = th or 600 + ctr = cntr or false + CScreen.update(love.graphics.getWidth(), love.graphics.getHeight()) +end + +-- Draws letterbox borders +function CScreen.cease() + if ctr then + local pr, pg, pb, pa = love.graphics.getColor() + love.graphics.setColor(cr, cg, cb, ca) + love.graphics.scale(fsvr, fsvr) + + if tx ~= 0 then + love.graphics.rectangle("fill", -tx, 0, tx, rhf) + love.graphics.rectangle("fill", rxv, 0, tx, rhf) + elseif ty ~= 0 then + love.graphics.rectangle("fill", 0, -ty, rwf, ty) + love.graphics.rectangle("fill", 0, ryv, rwf, ty) + end + + love.graphics.setColor(pr, pg, pb, pa) + end +end + +-- Scales and centers all graphics properly +function CScreen.apply() + if ctr then + love.graphics.translate(tx, ty) + end + love.graphics.scale(fsv, fsv) +end + +-- Updates CScreen when the window size changes +function CScreen.update(w, h) + local sx = w / rx + local sy = h / ry + fsv = math.min(sx, sy) + fsvr = 1 / fsv + -- Centering + if ctr and fsv == sx then -- Vertically + tx = 0 + ty = (h / 2) - (ry * fsv / 2) + elseif ctr and fsv == sy then -- Horizontally + ty = 0 + tx = (w / 2) - (rx * fsv / 2) + end + -- Variable sets + rwf = w + rhf = h + rxv = rx * fsv + ryv = ry * fsv +end + +-- Convert from window coordinates to target coordinates +function CScreen.project(x, y) + return math.floor((x - tx) / fsv), math.floor((y - ty) / fsv) +end + +-- Change letterbox color +function CScreen.setColor(r, g, b, a) + cr = r + cg = g + cb = b + ca = a +end + +-- Return the table for use +return CScreen diff --git a/sonic-radiance.love/core/libs/lovebird.lua b/sonic-radiance.love/core/libs/lovebird.lua new file mode 100644 index 0000000..8b296eb --- /dev/null +++ b/sonic-radiance.love/core/libs/lovebird.lua @@ -0,0 +1,737 @@ +-- +-- lovebird +-- +-- Copyright (c) 2017 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- + +local socket = require "socket" + +local lovebird = { _version = "0.4.3" } + +lovebird.loadstring = loadstring or load +lovebird.inited = false +lovebird.host = "*" +lovebird.buffer = "" +lovebird.lines = {} +lovebird.connections = {} +lovebird.pages = {} + +lovebird.wrapprint = true +lovebird.timestamp = true +lovebird.allowhtml = false +lovebird.echoinput = true +lovebird.port = 8000 +lovebird.whitelist = { "127.0.0.1" } +lovebird.maxlines = 200 +lovebird.updateinterval = .5 + + +lovebird.pages["index"] = [[ + + + + + + + + lovebird + + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + + +]] + + +lovebird.pages["buffer"] = [[ ]] + + +lovebird.pages["env.json"] = [[ + +{ + "valid": true, + "path": "", + "vars": [ + + { + "key": "", + "value": , + "type": "", + }, + + ] +} +]] + + + +function lovebird.init() + -- Init server + lovebird.server = assert(socket.bind(lovebird.host, lovebird.port)) + lovebird.addr, lovebird.port = lovebird.server:getsockname() + lovebird.server:settimeout(0) + -- Wrap print + lovebird.origprint = print + if lovebird.wrapprint then + local oldprint = print + print = function(...) + oldprint(...) + lovebird.print(...) + end + end + -- Compile page templates + for k, page in pairs(lovebird.pages) do + lovebird.pages[k] = lovebird.template(page, "lovebird, req", + "pages." .. k) + end + lovebird.inited = true +end + + +function lovebird.template(str, params, chunkname) + params = params and ("," .. params) or "" + local f = function(x) return string.format(" echo(%q)", x) end + str = ("?>"..str.."(.-)<%?lua", f) + str = "local echo " .. params .. " = ..." .. str + local fn = assert(lovebird.loadstring(str, chunkname)) + return function(...) + local output = {} + local echo = function(str) table.insert(output, str) end + fn(echo, ...) + return table.concat(lovebird.map(output, tostring)) + end +end + + +function lovebird.map(t, fn) + local res = {} + for k, v in pairs(t) do res[k] = fn(v) end + return res +end + + +function lovebird.trace(...) + local str = "[lovebird] " .. table.concat(lovebird.map({...}, tostring), " ") + print(str) + if not lovebird.wrapprint then lovebird.print(str) end +end + + +function lovebird.unescape(str) + local f = function(x) return string.char(tonumber("0x"..x)) end + return (str:gsub("%+", " "):gsub("%%(..)", f)) +end + + +function lovebird.parseurl(url) + local res = {} + res.path, res.search = url:match("/([^%?]*)%??(.*)") + res.query = {} + for k, v in res.search:gmatch("([^&^?]-)=([^&^#]*)") do + res.query[k] = lovebird.unescape(v) + end + return res +end + + +local htmlescapemap = { + ["<"] = "<", + ["&"] = "&", + ['"'] = """, + ["'"] = "'", +} + +function lovebird.htmlescape(str) + return ( str:gsub("[<&\"']", htmlescapemap) ) +end + + +function lovebird.truncate(str, len) + if #str <= len then + return str + end + return str:sub(1, len - 3) .. "..." +end + + +function lovebird.compare(a, b) + local na, nb = tonumber(a), tonumber(b) + if na then + if nb then return na < nb end + return false + elseif nb then + return true + end + return tostring(a) < tostring(b) +end + + +function lovebird.checkwhitelist(addr) + if lovebird.whitelist == nil then return true end + for _, a in pairs(lovebird.whitelist) do + local ptn = "^" .. a:gsub("%.", "%%."):gsub("%*", "%%d*") .. "$" + if addr:match(ptn) then return true end + end + return false +end + + +function lovebird.clear() + lovebird.lines = {} + lovebird.buffer = "" +end + + +function lovebird.pushline(line) + line.time = os.time() + line.count = 1 + table.insert(lovebird.lines, line) + if #lovebird.lines > lovebird.maxlines then + table.remove(lovebird.lines, 1) + end + lovebird.recalcbuffer() +end + + +function lovebird.recalcbuffer() + local function doline(line) + local str = line.str + if not lovebird.allowhtml then + str = lovebird.htmlescape(line.str):gsub("\n", "
") + end + if line.type == "input" then + str = '' .. str .. '' + else + if line.type == "error" then + str = '! ' .. str + str = '' .. str .. '' + end + if line.count > 1 then + str = '' .. line.count .. ' ' .. str + end + if lovebird.timestamp then + str = os.date('%H:%M:%S ', line.time) .. + str + end + end + return str + end + lovebird.buffer = table.concat(lovebird.map(lovebird.lines, doline), "
") +end + + +function lovebird.print(...) + local t = {} + for i = 1, select("#", ...) do + table.insert(t, tostring(select(i, ...))) + end + local str = table.concat(t, " ") + local last = lovebird.lines[#lovebird.lines] + if last and str == last.str then + -- Update last line if this line is a duplicate of it + last.time = os.time() + last.count = last.count + 1 + lovebird.recalcbuffer() + else + -- Create new line + lovebird.pushline({ type = "output", str = str }) + end +end + + +function lovebird.onerror(err) + lovebird.pushline({ type = "error", str = err }) + if lovebird.wrapprint then + lovebird.origprint("[lovebird] ERROR: " .. err) + end +end + + +function lovebird.onrequest(req, client) + local page = req.parsedurl.path + page = page ~= "" and page or "index" + -- Handle "page not found" + if not lovebird.pages[page] then + return "HTTP/1.1 404\r\nContent-Length: 8\r\n\r\nBad page" + end + -- Handle page + local str + xpcall(function() + local data = lovebird.pages[page](lovebird, req) + local contenttype = "text/html" + if string.match(page, "%.json$") then + contenttype = "application/json" + end + str = "HTTP/1.1 200 OK\r\n" .. + "Content-Type: " .. contenttype .. "\r\n" .. + "Content-Length: " .. #data .. "\r\n" .. + "\r\n" .. data + end, lovebird.onerror) + return str +end + + +function lovebird.receive(client, pattern) + while 1 do + local data, msg = client:receive(pattern) + if not data then + if msg == "timeout" then + -- Wait for more data + coroutine.yield(true) + else + -- Disconnected -- yielding nil means we're done + coroutine.yield(nil) + end + else + return data + end + end +end + + +function lovebird.send(client, data) + local idx = 1 + while idx < #data do + local res, msg = client:send(data, idx) + if not res and msg == "closed" then + -- Handle disconnect + coroutine.yield(nil) + else + idx = idx + res + coroutine.yield(true) + end + end +end + + +function lovebird.onconnect(client) + -- Create request table + local requestptn = "(%S*)%s*(%S*)%s*(%S*)" + local req = {} + req.socket = client + req.addr, req.port = client:getsockname() + req.request = lovebird.receive(client, "*l") + req.method, req.url, req.proto = req.request:match(requestptn) + req.headers = {} + while 1 do + local line, msg = lovebird.receive(client, "*l") + if not line or #line == 0 then break end + local k, v = line:match("(.-):%s*(.*)$") + req.headers[k] = v + end + if req.headers["Content-Length"] then + req.body = lovebird.receive(client, req.headers["Content-Length"]) + end + -- Parse body + req.parsedbody = {} + if req.body then + for k, v in req.body:gmatch("([^&]-)=([^&^#]*)") do + req.parsedbody[k] = lovebird.unescape(v) + end + end + -- Parse request line's url + req.parsedurl = lovebird.parseurl(req.url) + -- Handle request; get data to send and send + local data = lovebird.onrequest(req) + lovebird.send(client, data) + -- Clear up + client:close() +end + + +function lovebird.update() + if not lovebird.inited then lovebird.init() end + -- Handle new connections + while 1 do + -- Accept new connections + local client = lovebird.server:accept() + if not client then break end + client:settimeout(0) + local addr = client:getsockname() + if lovebird.checkwhitelist(addr) then + -- Connection okay -- create and add coroutine to set + local conn = coroutine.wrap(function() + xpcall(function() lovebird.onconnect(client) end, function() end) + end) + lovebird.connections[conn] = true + else + -- Reject connection not on whitelist + lovebird.trace("got non-whitelisted connection attempt: ", addr) + client:close() + end + end + -- Handle existing connections + for conn in pairs(lovebird.connections) do + -- Resume coroutine, remove if it has finished + local status = conn() + if status == nil then + lovebird.connections[conn] = nil + end + end +end + + +return lovebird diff --git a/sonic-radiance.love/core/modules/assets/animator.lua b/sonic-radiance.love/core/modules/assets/animator.lua index 7bce90c..716263c 100644 --- a/sonic-radiance.love/core/modules/assets/animator.lua +++ b/sonic-radiance.love/core/modules/assets/animator.lua @@ -77,6 +77,10 @@ function Animator:draw(x, y, r, sx, sy, ox, oy, kx, ky) self.sprite:drawFrame(self.frame, x, y, r, sx, sy, ox, oy, kx, ky) end +function Animator:drawMask(x, y, r, sx, sy, ox, oy, kx, ky) + self.sprite:drawFrameMask(self.frame, x, y, r, sx, sy, ox, oy, kx, ky) +end + function Animator:changeAnimation(name, restart) -- Force restart if animation name is different if (self.currentAnimation ~= name) then diff --git a/sonic-radiance.love/core/modules/assets/autotile.lua b/sonic-radiance.love/core/modules/assets/autotile.lua index 4104303..0cfaf6d 100644 --- a/sonic-radiance.love/core/modules/assets/autotile.lua +++ b/sonic-radiance.love/core/modules/assets/autotile.lua @@ -23,7 +23,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] -local Tileset = require "core.modules.assets.tileset" +local cwd = (...):gsub('%.autotile$', '') .. "." +local Tileset = require(cwd .. "tileset") local Autotile = Object:extend() function Autotile:new(filepath) diff --git a/sonic-radiance.love/core/modules/assets/imagefonts.lua b/sonic-radiance.love/core/modules/assets/imagefonts.lua index 16e0b7a..3cf2c1b 100644 --- a/sonic-radiance.love/core/modules/assets/imagefonts.lua +++ b/sonic-radiance.love/core/modules/assets/imagefonts.lua @@ -1,4 +1,5 @@ -local Font = require "core.modules.assets.fonts" +local cwd = (...):gsub('%.imagefonts$', '') .. "." +local Font = require(cwd.. "fonts") local ImageFont = Font:extend() function ImageFont:new(filename, extraspacing) diff --git a/sonic-radiance.love/core/modules/assets/init.lua b/sonic-radiance.love/core/modules/assets/init.lua index b6e11dc..5fe379f 100644 --- a/sonic-radiance.love/core/modules/assets/init.lua +++ b/sonic-radiance.love/core/modules/assets/init.lua @@ -24,13 +24,17 @@ local Assets = Object:extend() -local Sprite = require "core.modules.assets.sprites" -local Font = require "core.modules.assets.fonts" -local ImageFont = require "core.modules.assets.imagefonts" +local cwd = (...):gsub('%.init$', '') .. "." -local Tileset = require "core.modules.assets.tileset" -local Autotile = require "core.modules.assets.autotile" -local Background = require "core.modules.assets.background" +local Texture = require(cwd .. "texture") + +local Sprite = require(cwd .. "sprites") +local Font = require(cwd .. "fonts") +local ImageFont = require(cwd .. "imagefonts") + +local Tileset = require(cwd .. "tileset") +local Autotile = require(cwd .. "autotile") +local Background = require(cwd .. "background") function Assets:new() @@ -121,11 +125,11 @@ end -- Background -- function Assets:addImage(name, filename) - self.images[name] = love.graphics.newImage(filename) + self.images[name] = Texture(filename) end function Assets:drawImage(name, x, y, r, sx, sy, ox, oy, kx, ky) - love.graphics.draw(self.images[name], x, y, r, sx, sy, ox, oy, kx, ky) + self.images[name]:draw(x, y, r, sx, sy, ox, oy, kx, ky) end -- Images -- diff --git a/sonic-radiance.love/core/modules/assets/sprites.lua b/sonic-radiance.love/core/modules/assets/sprites.lua index 326db34..0749b63 100644 --- a/sonic-radiance.love/core/modules/assets/sprites.lua +++ b/sonic-radiance.love/core/modules/assets/sprites.lua @@ -24,8 +24,10 @@ ]] local Sprite = Object:extend() -local Animator = require("core.modules.assets.animator") -local Tileset = require("core.modules.assets.tileset") +local cwd = (...):gsub('%.sprites$', '') .. "." + +local Animator = require(cwd .. "animator") +local Tileset = require(cwd .. "tileset") function Sprite:new(filepath) self.tileset = Tileset(filepath) @@ -66,10 +68,18 @@ function Sprite:drawAnimation(x, y, r, sx, sy, ox, oy, kx, ky) self.animator:draw(x, y, r, sx, sy, ox, oy, kx, ky) end +function Sprite:drawAnimationMask(x, y, r, sx, sy, ox, oy, kx, ky) + self.animator:drawMask(x, y, r, sx, sy, ox, oy, kx, ky) +end + function Sprite:drawFrame(frame, x, y, r, sx, sy, ox, oy, kx, ky) self.tileset:drawTile(frame, x, y, r, sx, sy, ox, oy, kx, ky) end +function Sprite:drawFrameMask(frame, x, y, r, sx, sy, ox, oy, kx, ky) + self.tileset:drawTileMask(frame, x, y, r, sx, sy, ox, oy, kx, ky) +end + function Sprite:drawPart(x, y, w, h, r, sx, sy, ox, oy, kx, ky) local w = math.floor(w) local h = math.floor(h) diff --git a/sonic-radiance.love/core/modules/assets/texture.lua b/sonic-radiance.love/core/modules/assets/texture.lua new file mode 100644 index 0000000..63313d9 --- /dev/null +++ b/sonic-radiance.love/core/modules/assets/texture.lua @@ -0,0 +1,65 @@ +-- assets/texture :: the texture object, essentially used to be able to draw easily +-- the mask of the texture (used for stuff like flashing sprite, etc) + +--[[ + Copyright © 2019 Kazhnuz + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + + +local Texture = Object:extend() + +local function getMask(x, y, r, g, b, a) + -- template for defining your own pixel mapping function + -- perform computations giving the new values for r, g, b and a + -- ... + return 1, 1, 1, a +end + +function Texture:new(filename) + self.imageData = love.image.newImageData(filename) + + local maskData = self.imageData:clone() + maskData:mapPixel( getMask ) + + self.image = love.graphics.newImage( self.imageData ) + self.mask = love.graphics.newImage( maskData ) +end + +function Texture:getDimensions() + return self.image:getDimensions() +end + +function Texture:draw(x, y, r, sx, sy, ox, oy, kx, ky) + love.graphics.draw(self.image, x, y, r, sx, sy, ox, oy, kx, ky) +end + +function Texture:drawQuad(quad, x, y, r, sx, sy, ox, oy, kx, ky) + love.graphics.draw(self.image, quad, x, y, r, sx, sy, ox, oy, kx, ky) +end + +function Texture:drawMask(x, y, r, sx, sy, ox, oy, kx, ky) + love.graphics.draw(self.mask, x, y, r, sx, sy, ox, oy, kx, ky) +end + +function Texture:drawMaskQuad(quad, x, y, r, sx, sy, ox, oy, kx, ky) + love.graphics.draw(self.mask, quad, x, y, r, sx, sy, ox, oy, kx, ky) +end + +return Texture diff --git a/sonic-radiance.love/core/modules/assets/tileset.lua b/sonic-radiance.love/core/modules/assets/tileset.lua index c86aa44..40ae249 100644 --- a/sonic-radiance.love/core/modules/assets/tileset.lua +++ b/sonic-radiance.love/core/modules/assets/tileset.lua @@ -27,9 +27,12 @@ ]] local Tileset = Object:extend() +local cwd = (...):gsub('%.tileset$', '') .. "." + +local Texture = require(cwd .. "texture") function Tileset:new(filepath) - self.texture = love.graphics.newImage(filepath .. ".png") + self.texture = Texture(filepath .. ".png") local data = require(filepath) self.metadata = data.metadata @@ -79,11 +82,21 @@ end function Tileset:drawTile_Grid(i, j, x, y, r, sx, sy, ox, oy, kx, ky) local tileID = self:getTileID_Grid(i, j) - love.graphics.draw(self.texture, self.quads[tileID], x, y, r, sx, sy, ox, oy, kx, ky) + self.texture:drawQuad(self.quads[tileID], x, y, r, sx, sy, ox, oy, kx, ky) end function Tileset:drawTile(id, x, y, r, sx, sy, ox, oy, kx, ky) - love.graphics.draw(self.texture, self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky) + self.texture:drawQuad(self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky) end +function Tileset:drawTileMask_Grid(i, j, x, y, r, sx, sy, ox, oy, kx, ky) + local tileID = self:getTileID_Grid(i, j) + self.texture:drawMaskQuad(self.quads[tileID], x, y, r, sx, sy, ox, oy, kx, ky) +end + +function Tileset:drawTileMask(id, x, y, r, sx, sy, ox, oy, kx, ky) + self.texture:drawMaskQuad(self.quads[id], x, y, r, sx, sy, ox, oy, kx, ky) +end + + return Tileset diff --git a/sonic-radiance.love/core/modules/menusystem/init.lua b/sonic-radiance.love/core/modules/menusystem/init.lua index db5ee4d..6078277 100644 --- a/sonic-radiance.love/core/modules/menusystem/init.lua +++ b/sonic-radiance.love/core/modules/menusystem/init.lua @@ -46,9 +46,22 @@ function MenuSystem:update(dt) end +function MenuSystem:switchMenu(menu) + for k,v in pairs(self.menus) do + if k == menu then + v:getFocus() + v:setVisibility(true) + v.isActive = true + else + v:setVisibility(false) + v.isActive = false + end + end +end + function MenuSystem:setAllMenuVisibility(visibility) for k,v in pairs(self.menus) do - v.isVisible = visibility + v:setVisibility(visibility) end end @@ -93,10 +106,26 @@ function MenuSystem:mousepressed( x, y, button, istouch ) end end -function MenuSystem:draw(dt) -- On dessine les entitées +function MenuSystem:getDrawList() + local drawList = {} for k,v in pairs(self.menus) do - if (v.isVisible) then - v:draw(dt) + local drawObject = {} + drawObject.name = k + drawObject.depth = v.depth + table.insert(drawList, drawObject) + end + table.sort(drawList, function(a,b) return a.depth > b.depth end) + + return drawList +end + +function MenuSystem:draw(dt) -- On dessine les entitées + self.drawList = self:getDrawList() + + for i,v in ipairs(self.drawList) do + local v2 = self.menus[v.name] + if (v2.isVisible) then + v2:draw(dt) end end diff --git a/sonic-radiance.love/core/modules/menusystem/parent.lua b/sonic-radiance.love/core/modules/menusystem/parent.lua index a6bb2a5..b9f6135 100644 --- a/sonic-radiance.love/core/modules/menusystem/parent.lua +++ b/sonic-radiance.love/core/modules/menusystem/parent.lua @@ -19,6 +19,9 @@ function Menu:new(menusystem, name, x, y, w, h) self.isDestroyed = false self.isVisible = true self.isActive = true + self.isLocked = false + + self.depth = 0 self.sound = {} self.sound.asset = nil @@ -27,6 +30,18 @@ function Menu:new(menusystem, name, x, y, w, h) self:register() end +function Menu:setDepth(depth) + self.depth = depth or 0 +end + +function Menu:setVisibility(visibility) + if self.isLocked == false then + self.isVisible = visibility + else + self.isVisible = true + end +end + function Menu:getFocus() self.menusystem.focusedMenu = self.name end diff --git a/sonic-radiance.love/core/modules/scenes.lua b/sonic-radiance.love/core/modules/scenes.lua index c87f29e..60f378c 100644 --- a/sonic-radiance.love/core/modules/scenes.lua +++ b/sonic-radiance.love/core/modules/scenes.lua @@ -22,9 +22,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] +local cwd = (...):gsub('%.scenes$', '') .. "." + local Scene = Object:extend() -local Assets = require "core.modules.assets" -local MenuSystem = require "core.modules.menusystem" +local Assets = require(cwd .. "assets") +local MenuSystem = require(cwd .. "menusystem") function Scene:new() self.mouse = {} @@ -33,10 +35,12 @@ function Scene:new() self.assets = Assets() self.menusystem = MenuSystem() self.keys = core.input:getKeyList() + + self:register() end function Scene:register() - core.scenemanager.currentScene = self + core.scenemanager:setScene(self) end function Scene:update(dt) diff --git a/sonic-radiance.love/core/options.lua b/sonic-radiance.love/core/options.lua index 57111c9..c83a333 100644 --- a/sonic-radiance.love/core/options.lua +++ b/sonic-radiance.love/core/options.lua @@ -24,7 +24,8 @@ local OptionsManager = Object:extend() -local binser = require "libs.binser" +local cwd = (...):gsub('%.options$', '') .. "." +local binser = require(cwd .. "libs.binser") function OptionsManager:new() -- We begin by creating an empty data table before reading the data. @@ -42,7 +43,7 @@ function OptionsManager:reset() self.data.video.fullscreen = false -- We load the default files - self.data.input = require "datas.inputs" + self.data.input = self:getInputDefaultData() -- TODO: have a way to auto-load a language according to the OS ? self.data.language = "en" @@ -66,6 +67,31 @@ function OptionsManager:getFile(absolute) return filepath end +function OptionsManager:getInputDefaultData() + local _path = "datas/inputs.lua" + local datas = {} + local fileinfo = love.filesystem.getInfo(_path) + + if fileinfo ~= nil then + datas = require "datas.inputs" + else + datas = {} + end + + return datas +end + +function OptionsManager:getPlayerInputData(id) + local _playerInputData = self.data.input[id] + + if _playerInputData == nil then + _playerInputData = {} + _playerInputData.keys = {} + end + + return _playerInputData +end + function OptionsManager:write() local data = self:getData() diff --git a/sonic-radiance.love/core/scenemanager.lua b/sonic-radiance.love/core/scenemanager.lua index 5d403ca..008d0a2 100644 --- a/sonic-radiance.love/core/scenemanager.lua +++ b/sonic-radiance.love/core/scenemanager.lua @@ -28,6 +28,28 @@ local SceneManager = Object:extend() function SceneManager:new(controller) self.controller = controller self.currentScene = nil + + self.storage = {} +end + +function SceneManager:setScene(scene) + self.currentScene = scene +end + +function SceneManager:storeCurrentScene(name) + self.storage[name] = self.currentScene +end + +function SceneManager:setStoredScene(name) + local storedScene = self.storage[name] + if storedScene ~= nil then + self.currentScene = storedScene + self.storage[name] = nil + end +end + +function SceneManager:clearStorage() + self.storage = {} end function SceneManager:update(dt) @@ -42,15 +64,19 @@ function SceneManager:update(dt) end function SceneManager:mousemoved(x, y, dx, dy) - self.currentScene.mouse.x, - self.currentScene.mouse.y = x, y - self.currentScene:mousemoved(x, y, dx, dy) - self.currentScene.menusystem:mousemoved(x, y, dx, dy) + if (self.currentScene ~= nil) then + self.currentScene.mouse.x, + self.currentScene.mouse.y = x, y + self.currentScene:mousemoved(x, y, dx, dy) + self.currentScene.menusystem:mousemoved(x, y, dx, dy) + end end function SceneManager:mousepressed( x, y, button, istouch ) - self.currentScene:mousepressed( x, y, button, istouch ) - self.currentScene.menusystem:mousepressed( x, y, button, istouch ) + if (self.currentScene ~= nil) then + self.currentScene:mousepressed( x, y, button, istouch ) + self.currentScene.menusystem:mousepressed( x, y, button, istouch ) + end end function SceneManager:clearScene() diff --git a/sonic-radiance.love/core/screen.lua b/sonic-radiance.love/core/screen.lua index 4e962a8..24a3c4b 100644 --- a/sonic-radiance.love/core/screen.lua +++ b/sonic-radiance.love/core/screen.lua @@ -24,7 +24,8 @@ local ScreenManager = Object:extend() -local CScreen = require "libs.cscreen" +local cwd = (...):gsub('%.screen$', '') .. "." +local CScreen = require(cwd .. "libs.cscreen") function ScreenManager:new(controller) self.controller = controller diff --git a/sonic-radiance.love/core/utils/filesystem.lua b/sonic-radiance.love/core/utils/filesystem.lua new file mode 100644 index 0000000..3d38e27 --- /dev/null +++ b/sonic-radiance.love/core/utils/filesystem.lua @@ -0,0 +1,16 @@ +local Filesystem = {} + +function Filesystem.exists(filepath) + local info = love.filesystem.getInfo( filepath ) + local exists = false + + if (info == nil) then + exists = false + else + exists = true + end + + return exists +end + +return Filesystem diff --git a/sonic-radiance.love/core/utils/graphics.lua b/sonic-radiance.love/core/utils/graphics.lua new file mode 100644 index 0000000..79ad753 --- /dev/null +++ b/sonic-radiance.love/core/utils/graphics.lua @@ -0,0 +1,64 @@ +local Graphics = {} + +function Graphics.resetColor() + love.graphics.setColor(1,1,1,1) +end + +function Graphics.box(x, y, w, h) + local x = math.floor(x) + local y = math.floor(y) + local w = math.floor(w) + local h = math.floor(h) + local a = a or 1 + + local r, g, b, a = love.graphics.getColor( ) + + love.graphics.setColor(r, g, b, 0.3 * a) + love.graphics.rectangle("fill", x, y, w, h) + + love.graphics.setColor(r, g, b, a) + love.graphics.rectangle("line", x, y, w, h) +end + +function Graphics.print(text, x, y, align, r, sx, sy, ox, oy, kx, ky) + local width + local font = love.graphics.getFont() + width = font:getWidth(text) + + if align == "center" then + width = (width/2) + elseif align == "right" then + width = width + else + width = 0 + end + + love.graphics.print(text, x - (width), y, r, sx, sy, ox, oy, kx, ky) +end + +function Graphics.printWithSpacing(text, spacing, align, x, y, r, sx, sy, ox, oy, kx, ky) + -- DO NOT USE THIS FUNCTION IN A "UPDATE" FUNCTION ! + -- it's pretty heavy to use as it use a loop to get every character in a text + local font = love.graphics.getFont() + local xx = 0 + local lenght = string.len(text) + local basewidth = font:getWidth(text) + local width = basewidth + (spacing * lenght) + + if align == "center" then + width = (width/2) + elseif align == "right" then + width = width + else + width = 0 + end + + for i=1, lenght do + local char = string.sub(text, i, i) + pos = math.floor(x + xx - width) + love.graphics.print(char, pos, y) + xx = xx + font:getWidth(char) + spacing + end +end + +return Graphics diff --git a/sonic-radiance.love/core/utils/init.lua b/sonic-radiance.love/core/utils/init.lua new file mode 100644 index 0000000..0f6ea3c --- /dev/null +++ b/sonic-radiance.love/core/utils/init.lua @@ -0,0 +1,7 @@ +local cwd = (...):gsub('%.init$', '') .. "." + +return { + math = require(cwd .. "math"), + graphics = require(cwd .. "graphics"), + filesystem = require(cwd .. "filesystem") +} diff --git a/sonic-radiance.love/core/utils/math.lua b/sonic-radiance.love/core/utils/math.lua new file mode 100644 index 0000000..678720f --- /dev/null +++ b/sonic-radiance.love/core/utils/math.lua @@ -0,0 +1,88 @@ +local Math = {} + +function Math.sign(x) + if (x < 0) then + return -1 + elseif (x > 0) then + return 1 + else + return 0 + end +end + +function Math.round(num) + return math.floor(num + 0.5) +end + +function Math.vector(x1, y1, x2, y2) + local vecx, vecy + + vecx = x2 - x1 + vexy = y2 - y1 + + return vecx, vecy +end + +function Math.getMiddlePoint(x1, y1, x2, y2) + local newx, newy, vecx, vecy + + vecx = math.max(x1, x2) - math.min(x1, x2) + vecy = math.max(y1, y2) - math.min(y1, y2) + + newx = math.min(x1, x2) + (vecx / 2) + newy = math.min(y1, y2) + (vecy / 2) + + return newx, newy +end + +function Math.pointDistance(x1, y1, x2, y2) + local vecx, vecy + + vecx = math.max(x1, x2) - math.min(x1, x2) + vexy = math.max(y1, y2) - math.min(y1, y2) + + return math.sqrt(vecx^2 + vecy^2) + +end + +function Math.pointDirection(x1,y1,x2,y2) + local vecx, vecy, angle + vecy = y2 - y1 + vecx = x2 - x1 + angle = math.atan2(vecy, vecx) + + return angle +end + +function Math.numberToString(x, length) + local length = length or 1 + local string = "" + local x = x + if (x >= math.pow(10, length)) then + x = unitsNumber*10 - 1 + string = string .. x + else + for i=1, (length-1) do + if (x < math.pow(10, length-i)) then + string = string .. "0" + end + end + string = string .. x + end + return string +end + +function Math.floorCoord(x, y) + return math.floor(x), math.floor(y) +end + +function Math.pixeliseCoord(x, y, factor) + x, y = Math.floorCoord(x / factor, y / factor) + + x = x * factor + y = y * factor + + return x, y +end + +return Math diff --git a/sonic-radiance.love/main.lua b/sonic-radiance.love/main.lua index 8837a3a..a565372 100644 --- a/sonic-radiance.love/main.lua +++ b/sonic-radiance.love/main.lua @@ -21,8 +21,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ]] -utils = require "libs.loveutils" -Object = require "libs.classic" Core = require "core" Game = require "game" From 9310a47e6b8240986789572ab79bc4920ae3d7cd Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sat, 23 Mar 2019 12:02:18 +0100 Subject: [PATCH 2/3] libs: remove libs that are already in gamecore --- sonic-radiance.love/libs/binser.lua | 687 ---------------- sonic-radiance.love/libs/classic.lua | 68 -- sonic-radiance.love/libs/cscreen.lua | 99 --- sonic-radiance.love/libs/lovebird.lua | 737 ------------------ .../libs/loveutils/filesystem.lua | 16 - .../libs/loveutils/graphics.lua | 64 -- sonic-radiance.love/libs/loveutils/init.lua | 7 - sonic-radiance.love/libs/loveutils/math.lua | 88 --- 8 files changed, 1766 deletions(-) delete mode 100644 sonic-radiance.love/libs/binser.lua delete mode 100644 sonic-radiance.love/libs/classic.lua delete mode 100644 sonic-radiance.love/libs/cscreen.lua delete mode 100644 sonic-radiance.love/libs/lovebird.lua delete mode 100644 sonic-radiance.love/libs/loveutils/filesystem.lua delete mode 100644 sonic-radiance.love/libs/loveutils/graphics.lua delete mode 100644 sonic-radiance.love/libs/loveutils/init.lua delete mode 100644 sonic-radiance.love/libs/loveutils/math.lua diff --git a/sonic-radiance.love/libs/binser.lua b/sonic-radiance.love/libs/binser.lua deleted file mode 100644 index 5aa1299..0000000 --- a/sonic-radiance.love/libs/binser.lua +++ /dev/null @@ -1,687 +0,0 @@ --- binser.lua - ---[[ -Copyright (c) 2016 Calvin Rose - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -]] - -local assert = assert -local error = error -local select = select -local pairs = pairs -local getmetatable = getmetatable -local setmetatable = setmetatable -local tonumber = tonumber -local type = type -local loadstring = loadstring or load -local concat = table.concat -local char = string.char -local byte = string.byte -local format = string.format -local sub = string.sub -local dump = string.dump -local floor = math.floor -local frexp = math.frexp -local unpack = unpack or table.unpack - --- Lua 5.3 frexp polyfill --- From https://github.com/excessive/cpml/blob/master/modules/utils.lua -if not frexp then - local log, abs, floor = math.log, math.abs, math.floor - local log2 = log(2) - frexp = function(x) - if x == 0 then return 0, 0 end - local e = floor(log(abs(x)) / log2 + 1) - return x / 2 ^ e, e - end -end - --- NIL = 202 --- FLOAT = 203 --- TRUE = 204 --- FALSE = 205 --- STRING = 206 --- TABLE = 207 --- REFERENCE = 208 --- CONSTRUCTOR = 209 --- FUNCTION = 210 --- RESOURCE = 211 --- INT64 = 212 - -local mts = {} -local ids = {} -local serializers = {} -local deserializers = {} -local resources = {} -local resources_by_name = {} - -local function pack(...) - return {...}, select("#", ...) -end - -local function not_array_index(x, len) - return type(x) ~= "number" or x < 1 or x > len or x ~= floor(x) -end - -local function type_check(x, tp, name) - assert(type(x) == tp, - format("Expected parameter %q to be of type %q.", name, tp)) -end - -local bigIntSupport = false -local isInteger -if math.type then -- Detect Lua 5.3 - local mtype = math.type - bigIntSupport = loadstring[[ - local char = string.char - return function(n) - local nn = n < 0 and -(n + 1) or n - local b1 = nn // 0x100000000000000 - local b2 = nn // 0x1000000000000 % 0x100 - local b3 = nn // 0x10000000000 % 0x100 - local b4 = nn // 0x100000000 % 0x100 - local b5 = nn // 0x1000000 % 0x100 - local b6 = nn // 0x10000 % 0x100 - local b7 = nn // 0x100 % 0x100 - local b8 = nn % 0x100 - if n < 0 then - b1, b2, b3, b4 = 0xFF - b1, 0xFF - b2, 0xFF - b3, 0xFF - b4 - b5, b6, b7, b8 = 0xFF - b5, 0xFF - b6, 0xFF - b7, 0xFF - b8 - end - return char(212, b1, b2, b3, b4, b5, b6, b7, b8) - end]]() - isInteger = function(x) - return mtype(x) == 'integer' - end -else - isInteger = function(x) - return floor(x) == x - end -end - --- Copyright (C) 2012-2015 Francois Perrad. --- number serialization code modified from https://github.com/fperrad/lua-MessagePack --- Encode a number as a big-endian ieee-754 double, big-endian signed 64 bit integer, or a small integer -local function number_to_str(n) - if isInteger(n) then -- int - if n <= 100 and n >= -27 then -- 1 byte, 7 bits of data - return char(n + 27) - elseif n <= 8191 and n >= -8192 then -- 2 bytes, 14 bits of data - n = n + 8192 - return char(128 + (floor(n / 0x100) % 0x100), n % 0x100) - elseif bigIntSupport then - return bigIntSupport(n) - end - end - local sign = 0 - if n < 0.0 then - sign = 0x80 - n = -n - end - local m, e = frexp(n) -- mantissa, exponent - if m ~= m then - return char(203, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - elseif m == 1/0 then - if sign == 0 then - return char(203, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - else - return char(203, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) - end - end - e = e + 0x3FE - if e < 1 then -- denormalized numbers - m = m * 2 ^ (52 + e) - e = 0 - else - m = (m * 2 - 1) * 2 ^ 52 - end - return char(203, - sign + floor(e / 0x10), - (e % 0x10) * 0x10 + floor(m / 0x1000000000000), - floor(m / 0x10000000000) % 0x100, - floor(m / 0x100000000) % 0x100, - floor(m / 0x1000000) % 0x100, - floor(m / 0x10000) % 0x100, - floor(m / 0x100) % 0x100, - m % 0x100) -end - --- Copyright (C) 2012-2015 Francois Perrad. --- number deserialization code also modified from https://github.com/fperrad/lua-MessagePack -local function number_from_str(str, index) - local b = byte(str, index) - if b < 128 then - return b - 27, index + 1 - elseif b < 192 then - return byte(str, index + 1) + 0x100 * (b - 128) - 8192, index + 2 - end - local b1, b2, b3, b4, b5, b6, b7, b8 = byte(str, index + 1, index + 8) - if b == 212 then - local flip = b1 >= 128 - if flip then -- negative - b1, b2, b3, b4 = 0xFF - b1, 0xFF - b2, 0xFF - b3, 0xFF - b4 - b5, b6, b7, b8 = 0xFF - b5, 0xFF - b6, 0xFF - b7, 0xFF - b8 - end - local n = ((((((b1 * 0x100 + b2) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 - if flip then - return (-n) - 1, index + 9 - else - return n, index + 9 - end - end - local sign = b1 > 0x7F and -1 or 1 - local e = (b1 % 0x80) * 0x10 + floor(b2 / 0x10) - local m = ((((((b2 % 0x10) * 0x100 + b3) * 0x100 + b4) * 0x100 + b5) * 0x100 + b6) * 0x100 + b7) * 0x100 + b8 - local n - if e == 0 then - if m == 0 then - n = sign * 0.0 - else - n = sign * (m / 2 ^ 52) * 2 ^ -1022 - end - elseif e == 0x7FF then - if m == 0 then - n = sign * (1/0) - else - n = 0.0/0.0 - end - else - n = sign * (1.0 + m / 2 ^ 52) * 2 ^ (e - 0x3FF) - end - return n, index + 9 -end - -local types = {} - -types["nil"] = function(x, visited, accum) - accum[#accum + 1] = "\202" -end - -function types.number(x, visited, accum) - accum[#accum + 1] = number_to_str(x) -end - -function types.boolean(x, visited, accum) - accum[#accum + 1] = x and "\204" or "\205" -end - -function types.string(x, visited, accum) - local alen = #accum - if visited[x] then - accum[alen + 1] = "\208" - accum[alen + 2] = number_to_str(visited[x]) - else - visited[x] = visited.next - visited.next = visited.next + 1 - accum[alen + 1] = "\206" - accum[alen + 2] = number_to_str(#x) - accum[alen + 3] = x - end -end - -local function check_custom_type(x, visited, accum) - local res = resources[x] - if res then - accum[#accum + 1] = "\211" - types[type(res)](res, visited, accum) - return true - end - local mt = getmetatable(x) - local id = mt and ids[mt] - if id then - if x == visited.temp then - error("Infinite loop in constructor.") - end - visited.temp = x - accum[#accum + 1] = "\209" - types[type(id)](id, visited, accum) - local args, len = pack(serializers[id](x)) - accum[#accum + 1] = number_to_str(len) - for i = 1, len do - local arg = args[i] - types[type(arg)](arg, visited, accum) - end - visited[x] = visited.next - visited.next = visited.next + 1 - return true - end -end - -function types.userdata(x, visited, accum) - if visited[x] then - accum[#accum + 1] = "\208" - accum[#accum + 1] = number_to_str(visited[x]) - else - if check_custom_type(x, visited, accum) then return end - error("Cannot serialize this userdata.") - end -end - -function types.table(x, visited, accum) - if visited[x] then - accum[#accum + 1] = "\208" - accum[#accum + 1] = number_to_str(visited[x]) - else - if check_custom_type(x, visited, accum) then return end - visited[x] = visited.next - visited.next = visited.next + 1 - local xlen = #x - accum[#accum + 1] = "\207" - accum[#accum + 1] = number_to_str(xlen) - for i = 1, xlen do - local v = x[i] - types[type(v)](v, visited, accum) - end - local key_count = 0 - for k in pairs(x) do - if not_array_index(k, xlen) then - key_count = key_count + 1 - end - end - accum[#accum + 1] = number_to_str(key_count) - for k, v in pairs(x) do - if not_array_index(k, xlen) then - types[type(k)](k, visited, accum) - types[type(v)](v, visited, accum) - end - end - end -end - -types["function"] = function(x, visited, accum) - if visited[x] then - accum[#accum + 1] = "\208" - accum[#accum + 1] = number_to_str(visited[x]) - else - if check_custom_type(x, visited, accum) then return end - visited[x] = visited.next - visited.next = visited.next + 1 - local str = dump(x) - accum[#accum + 1] = "\210" - accum[#accum + 1] = number_to_str(#str) - accum[#accum + 1] = str - end -end - -types.cdata = function(x, visited, accum) - if visited[x] then - accum[#accum + 1] = "\208" - accum[#accum + 1] = number_to_str(visited[x]) - else - if check_custom_type(x, visited, #accum) then return end - error("Cannot serialize this cdata.") - end -end - -types.thread = function() error("Cannot serialize threads.") end - -local function deserialize_value(str, index, visited) - local t = byte(str, index) - if not t then return end - if t < 128 then - return t - 27, index + 1 - elseif t < 192 then - return byte(str, index + 1) + 0x100 * (t - 128) - 8192, index + 2 - elseif t == 202 then - return nil, index + 1 - elseif t == 203 then - return number_from_str(str, index) - elseif t == 204 then - return true, index + 1 - elseif t == 205 then - return false, index + 1 - elseif t == 206 then - local length, dataindex = deserialize_value(str, index + 1, visited) - local nextindex = dataindex + length - local substr = sub(str, dataindex, nextindex - 1) - visited[#visited + 1] = substr - return substr, nextindex - elseif t == 207 then - local count, nextindex = number_from_str(str, index + 1) - local ret = {} - visited[#visited + 1] = ret - for i = 1, count do - ret[i], nextindex = deserialize_value(str, nextindex, visited) - end - count, nextindex = number_from_str(str, nextindex) - for i = 1, count do - local k, v - k, nextindex = deserialize_value(str, nextindex, visited) - v, nextindex = deserialize_value(str, nextindex, visited) - ret[k] = v - end - return ret, nextindex - elseif t == 208 then - local ref, nextindex = number_from_str(str, index + 1) - return visited[ref], nextindex - elseif t == 209 then - local count - local name, nextindex = deserialize_value(str, index + 1, visited) - count, nextindex = number_from_str(str, nextindex) - local args = {} - for i = 1, count do - args[i], nextindex = deserialize_value(str, nextindex, visited) - end - local ret = deserializers[name](unpack(args)) - visited[#visited + 1] = ret - return ret, nextindex - elseif t == 210 then - local length, dataindex = deserialize_value(str, index + 1, visited) - local nextindex = dataindex + length - local ret = loadstring(sub(str, dataindex, nextindex - 1)) - visited[#visited + 1] = ret - return ret, nextindex - elseif t == 211 then - local res, nextindex = deserialize_value(str, index + 1, visited) - return resources_by_name[res], nextindex - elseif t == 212 then - return number_from_str(str, index) - else - error("Could not deserialize type byte " .. t .. ".") - end -end - -local function serialize(...) - local visited = {next = 1} - local accum = {} - for i = 1, select("#", ...) do - local x = select(i, ...) - types[type(x)](x, visited, accum) - end - return concat(accum) -end - -local function make_file_writer(file) - return setmetatable({}, { - __newindex = function(_, _, v) - file:write(v) - end - }) -end - -local function serialize_to_file(path, mode, ...) - local file, err = io.open(path, mode) - assert(file, err) - local visited = {next = 1} - local accum = make_file_writer(file) - for i = 1, select("#", ...) do - local x = select(i, ...) - types[type(x)](x, visited, accum) - end - -- flush the writer - file:flush() - file:close() -end - -local function writeFile(path, ...) - return serialize_to_file(path, "wb", ...) -end - -local function appendFile(path, ...) - return serialize_to_file(path, "ab", ...) -end - -local function deserialize(str, index) - assert(type(str) == "string", "Expected string to deserialize.") - local vals = {} - index = index or 1 - local visited = {} - local len = 0 - local val - while index do - val, index = deserialize_value(str, index, visited) - if index then - len = len + 1 - vals[len] = val - end - end - return vals, len -end - -local function deserializeN(str, n, index) - assert(type(str) == "string", "Expected string to deserialize.") - n = n or 1 - assert(type(n) == "number", "Expected a number for parameter n.") - assert(n > 0 and floor(n) == n, "N must be a poitive integer.") - local vals = {} - index = index or 1 - local visited = {} - local len = 0 - local val - while index and len < n do - val, index = deserialize_value(str, index, visited) - if index then - len = len + 1 - vals[len] = val - end - end - vals[len + 1] = index - return unpack(vals, 1, n + 1) -end - -local function readFile(path) - local file, err = io.open(path, "rb") - assert(file, err) - local str = file:read("*all") - file:close() - return deserialize(str) -end - -local function default_deserialize(metatable) - return function(...) - local ret = {} - for i = 1, select("#", ...), 2 do - ret[select(i, ...)] = select(i + 1, ...) - end - return setmetatable(ret, metatable) - end -end - -local function default_serialize(x) - assert(type(x) == "table", - "Default serialization for custom types only works for tables.") - local args = {} - local len = 0 - for k, v in pairs(x) do - args[len + 1], args[len + 2] = k, v - len = len + 2 - end - return unpack(args, 1, len) -end - --- Templating - -local function normalize_template(template) - local ret = {} - for i = 1, #template do - ret[i] = template[i] - end - local non_array_part = {} - -- The non-array part of the template (nested templates) have to be deterministic, so they are sorted. - -- This means that inherently non deterministicly sortable keys (tables, functions) should NOT be used - -- in templates. Looking for way around this. - for k in pairs(template) do - if not_array_index(k, #template) then - non_array_part[#non_array_part + 1] = k - end - end - table.sort(non_array_part) - for i = 1, #non_array_part do - local name = non_array_part[i] - ret[#ret + 1] = {name, normalize_template(template[name])} - end - return ret -end - -local function templatepart_serialize(part, argaccum, x, len) - local extras = {} - local extracount = 0 - for k, v in pairs(x) do - extras[k] = v - extracount = extracount + 1 - end - for i = 1, #part do - extracount = extracount - 1 - if type(part[i]) == "table" then - extras[part[i][1]] = nil - len = templatepart_serialize(part[i][2], argaccum, x[part[i][1]], len) - else - extras[part[i]] = nil - len = len + 1 - argaccum[len] = x[part[i]] - end - end - if extracount > 0 then - argaccum[len + 1] = extras - else - argaccum[len + 1] = nil - end - return len + 1 -end - -local function templatepart_deserialize(ret, part, values, vindex) - for i = 1, #part do - local name = part[i] - if type(name) == "table" then - local newret = {} - ret[name[1]] = newret - vindex = templatepart_deserialize(newret, name[2], values, vindex) - else - ret[name] = values[vindex] - vindex = vindex + 1 - end - end - local extras = values[vindex] - if extras then - for k, v in pairs(extras) do - ret[k] = v - end - end - return vindex + 1 -end - -local function template_serializer_and_deserializer(metatable, template) - return function(x) - argaccum = {} - local len = templatepart_serialize(template, argaccum, x, 0) - return unpack(argaccum, 1, len) - end, function(...) - local ret = {} - local len = select("#", ...) - local args = {...} - templatepart_deserialize(ret, template, args, 1) - return setmetatable(ret, metatable) - end -end - -local function register(metatable, name, serialize, deserialize) - name = name or metatable.name - serialize = serialize or metatable._serialize - deserialize = deserialize or metatable._deserialize - if not serialize then - if metatable._template then - local t = normalize_template(metatable._template) - serialize, deserialize = template_serializer_and_deserializer(metatable, t) - elseif not deserialize then - serialize = default_serialize - deserialize = default_deserialize(metatable) - else - serialize = metatable - end - end - type_check(metatable, "table", "metatable") - type_check(name, "string", "name") - type_check(serialize, "function", "serialize") - type_check(deserialize, "function", "deserialize") - assert(not ids[metatable], "Metatable already registered.") - assert(not mts[name], ("Name %q already registered."):format(name)) - mts[name] = metatable - ids[metatable] = name - serializers[name] = serialize - deserializers[name] = deserialize - return metatable -end - -local function unregister(item) - local name, metatable - if type(item) == "string" then -- assume name - name, metatable = item, mts[item] - else -- assume metatable - name, metatable = ids[item], item - end - type_check(name, "string", "name") - type_check(metatable, "table", "metatable") - mts[name] = nil - ids[metatable] = nil - serializers[name] = nil - deserializers[name] = nil - return metatable -end - -local function registerClass(class, name) - name = name or class.name - if class.__instanceDict then -- middleclass - register(class.__instanceDict, name) - else -- assume 30log or similar library - register(class, name) - end - return class -end - -local function registerResource(resource, name) - type_check(name, "string", "name") - assert(not resources[resource], - "Resource already registered.") - assert(not resources_by_name[name], - format("Resource %q already exists.", name)) - resources_by_name[name] = resource - resources[resource] = name - return resource -end - -local function unregisterResource(name) - type_check(name, "string", "name") - assert(resources_by_name[name], format("Resource %q does not exist.", name)) - local resource = resources_by_name[name] - resources_by_name[name] = nil - resources[resource] = nil - return resource -end - -return { - -- aliases - s = serialize, - d = deserialize, - dn = deserializeN, - r = readFile, - w = writeFile, - a = appendFile, - - serialize = serialize, - deserialize = deserialize, - deserializeN = deserializeN, - readFile = readFile, - writeFile = writeFile, - appendFile = appendFile, - register = register, - unregister = unregister, - registerResource = registerResource, - unregisterResource = unregisterResource, - registerClass = registerClass -} diff --git a/sonic-radiance.love/libs/classic.lua b/sonic-radiance.love/libs/classic.lua deleted file mode 100644 index cbd6f81..0000000 --- a/sonic-radiance.love/libs/classic.lua +++ /dev/null @@ -1,68 +0,0 @@ --- --- classic --- --- Copyright (c) 2014, rxi --- --- This module is free software; you can redistribute it and/or modify it under --- the terms of the MIT license. See LICENSE for details. --- - - -local Object = {} -Object.__index = Object - - -function Object:new() -end - - -function Object:extend() - local cls = {} - for k, v in pairs(self) do - if k:find("__") == 1 then - cls[k] = v - end - end - cls.__index = cls - cls.super = self - setmetatable(cls, self) - return cls -end - - -function Object:implement(...) - for _, cls in pairs({...}) do - for k, v in pairs(cls) do - if self[k] == nil and type(v) == "function" then - self[k] = v - end - end - end -end - - -function Object:is(T) - local mt = getmetatable(self) - while mt do - if mt == T then - return true - end - mt = getmetatable(mt) - end - return false -end - - -function Object:__tostring() - return "Object" -end - - -function Object:__call(...) - local obj = setmetatable({}, self) - obj:new(...) - return obj -end - - -return Object diff --git a/sonic-radiance.love/libs/cscreen.lua b/sonic-radiance.love/libs/cscreen.lua deleted file mode 100644 index 579ea0d..0000000 --- a/sonic-radiance.love/libs/cscreen.lua +++ /dev/null @@ -1,99 +0,0 @@ ---[[ -CScreen v1.3 by CodeNMore -A simple way to make resolution-independent Love2D games -Tested for LOVE 0.10.1 -See: https://github.com/CodeNMore/CScreen -Zlib License: -Copyright (c) 2016 CodeNMore -This software is provided 'as-is', without any express or implied warranty. -In no event will the authors be held liable for any damages arising from -the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software in -a product, an acknowledgment in the product documentation would be appreciated -but is not required. -2. Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. ---]] - -local CScreen = {} -local rx, ry, ctr = 800, 600, true -local rxv, ryv, fsv, fsvr = 800, 600, 1.0, 1.0 -local tx, ty, rwf, rhf = 0, 0, 800, 600 -local cr, cg, cb, ca = 0, 0, 0, 255 - --- Initializes CScreen with the initial size values -function CScreen.init(tw, th, cntr) - rx = tw or 800 - ry = th or 600 - ctr = cntr or false - CScreen.update(love.graphics.getWidth(), love.graphics.getHeight()) -end - --- Draws letterbox borders -function CScreen.cease() - if ctr then - local pr, pg, pb, pa = love.graphics.getColor() - love.graphics.setColor(cr, cg, cb, ca) - love.graphics.scale(fsvr, fsvr) - - if tx ~= 0 then - love.graphics.rectangle("fill", -tx, 0, tx, rhf) - love.graphics.rectangle("fill", rxv, 0, tx, rhf) - elseif ty ~= 0 then - love.graphics.rectangle("fill", 0, -ty, rwf, ty) - love.graphics.rectangle("fill", 0, ryv, rwf, ty) - end - - love.graphics.setColor(pr, pg, pb, pa) - end -end - --- Scales and centers all graphics properly -function CScreen.apply() - if ctr then - love.graphics.translate(tx, ty) - end - love.graphics.scale(fsv, fsv) -end - --- Updates CScreen when the window size changes -function CScreen.update(w, h) - local sx = w / rx - local sy = h / ry - fsv = math.min(sx, sy) - fsvr = 1 / fsv - -- Centering - if ctr and fsv == sx then -- Vertically - tx = 0 - ty = (h / 2) - (ry * fsv / 2) - elseif ctr and fsv == sy then -- Horizontally - ty = 0 - tx = (w / 2) - (rx * fsv / 2) - end - -- Variable sets - rwf = w - rhf = h - rxv = rx * fsv - ryv = ry * fsv -end - --- Convert from window coordinates to target coordinates -function CScreen.project(x, y) - return math.floor((x - tx) / fsv), math.floor((y - ty) / fsv) -end - --- Change letterbox color -function CScreen.setColor(r, g, b, a) - cr = r - cg = g - cb = b - ca = a -end - --- Return the table for use -return CScreen diff --git a/sonic-radiance.love/libs/lovebird.lua b/sonic-radiance.love/libs/lovebird.lua deleted file mode 100644 index 8b296eb..0000000 --- a/sonic-radiance.love/libs/lovebird.lua +++ /dev/null @@ -1,737 +0,0 @@ --- --- lovebird --- --- Copyright (c) 2017 rxi --- --- This library is free software; you can redistribute it and/or modify it --- under the terms of the MIT license. See LICENSE for details. --- - -local socket = require "socket" - -local lovebird = { _version = "0.4.3" } - -lovebird.loadstring = loadstring or load -lovebird.inited = false -lovebird.host = "*" -lovebird.buffer = "" -lovebird.lines = {} -lovebird.connections = {} -lovebird.pages = {} - -lovebird.wrapprint = true -lovebird.timestamp = true -lovebird.allowhtml = false -lovebird.echoinput = true -lovebird.port = 8000 -lovebird.whitelist = { "127.0.0.1" } -lovebird.maxlines = 200 -lovebird.updateinterval = .5 - - -lovebird.pages["index"] = [[ - - - - - - - - lovebird - - - - -
-
-
-
-
- -
-
-
-
-
-
-
-
- - - -]] - - -lovebird.pages["buffer"] = [[ ]] - - -lovebird.pages["env.json"] = [[ - -{ - "valid": true, - "path": "", - "vars": [ - - { - "key": "", - "value": , - "type": "", - }, - - ] -} -]] - - - -function lovebird.init() - -- Init server - lovebird.server = assert(socket.bind(lovebird.host, lovebird.port)) - lovebird.addr, lovebird.port = lovebird.server:getsockname() - lovebird.server:settimeout(0) - -- Wrap print - lovebird.origprint = print - if lovebird.wrapprint then - local oldprint = print - print = function(...) - oldprint(...) - lovebird.print(...) - end - end - -- Compile page templates - for k, page in pairs(lovebird.pages) do - lovebird.pages[k] = lovebird.template(page, "lovebird, req", - "pages." .. k) - end - lovebird.inited = true -end - - -function lovebird.template(str, params, chunkname) - params = params and ("," .. params) or "" - local f = function(x) return string.format(" echo(%q)", x) end - str = ("?>"..str.."(.-)<%?lua", f) - str = "local echo " .. params .. " = ..." .. str - local fn = assert(lovebird.loadstring(str, chunkname)) - return function(...) - local output = {} - local echo = function(str) table.insert(output, str) end - fn(echo, ...) - return table.concat(lovebird.map(output, tostring)) - end -end - - -function lovebird.map(t, fn) - local res = {} - for k, v in pairs(t) do res[k] = fn(v) end - return res -end - - -function lovebird.trace(...) - local str = "[lovebird] " .. table.concat(lovebird.map({...}, tostring), " ") - print(str) - if not lovebird.wrapprint then lovebird.print(str) end -end - - -function lovebird.unescape(str) - local f = function(x) return string.char(tonumber("0x"..x)) end - return (str:gsub("%+", " "):gsub("%%(..)", f)) -end - - -function lovebird.parseurl(url) - local res = {} - res.path, res.search = url:match("/([^%?]*)%??(.*)") - res.query = {} - for k, v in res.search:gmatch("([^&^?]-)=([^&^#]*)") do - res.query[k] = lovebird.unescape(v) - end - return res -end - - -local htmlescapemap = { - ["<"] = "<", - ["&"] = "&", - ['"'] = """, - ["'"] = "'", -} - -function lovebird.htmlescape(str) - return ( str:gsub("[<&\"']", htmlescapemap) ) -end - - -function lovebird.truncate(str, len) - if #str <= len then - return str - end - return str:sub(1, len - 3) .. "..." -end - - -function lovebird.compare(a, b) - local na, nb = tonumber(a), tonumber(b) - if na then - if nb then return na < nb end - return false - elseif nb then - return true - end - return tostring(a) < tostring(b) -end - - -function lovebird.checkwhitelist(addr) - if lovebird.whitelist == nil then return true end - for _, a in pairs(lovebird.whitelist) do - local ptn = "^" .. a:gsub("%.", "%%."):gsub("%*", "%%d*") .. "$" - if addr:match(ptn) then return true end - end - return false -end - - -function lovebird.clear() - lovebird.lines = {} - lovebird.buffer = "" -end - - -function lovebird.pushline(line) - line.time = os.time() - line.count = 1 - table.insert(lovebird.lines, line) - if #lovebird.lines > lovebird.maxlines then - table.remove(lovebird.lines, 1) - end - lovebird.recalcbuffer() -end - - -function lovebird.recalcbuffer() - local function doline(line) - local str = line.str - if not lovebird.allowhtml then - str = lovebird.htmlescape(line.str):gsub("\n", "
") - end - if line.type == "input" then - str = '' .. str .. '' - else - if line.type == "error" then - str = '! ' .. str - str = '' .. str .. '' - end - if line.count > 1 then - str = '' .. line.count .. ' ' .. str - end - if lovebird.timestamp then - str = os.date('%H:%M:%S ', line.time) .. - str - end - end - return str - end - lovebird.buffer = table.concat(lovebird.map(lovebird.lines, doline), "
") -end - - -function lovebird.print(...) - local t = {} - for i = 1, select("#", ...) do - table.insert(t, tostring(select(i, ...))) - end - local str = table.concat(t, " ") - local last = lovebird.lines[#lovebird.lines] - if last and str == last.str then - -- Update last line if this line is a duplicate of it - last.time = os.time() - last.count = last.count + 1 - lovebird.recalcbuffer() - else - -- Create new line - lovebird.pushline({ type = "output", str = str }) - end -end - - -function lovebird.onerror(err) - lovebird.pushline({ type = "error", str = err }) - if lovebird.wrapprint then - lovebird.origprint("[lovebird] ERROR: " .. err) - end -end - - -function lovebird.onrequest(req, client) - local page = req.parsedurl.path - page = page ~= "" and page or "index" - -- Handle "page not found" - if not lovebird.pages[page] then - return "HTTP/1.1 404\r\nContent-Length: 8\r\n\r\nBad page" - end - -- Handle page - local str - xpcall(function() - local data = lovebird.pages[page](lovebird, req) - local contenttype = "text/html" - if string.match(page, "%.json$") then - contenttype = "application/json" - end - str = "HTTP/1.1 200 OK\r\n" .. - "Content-Type: " .. contenttype .. "\r\n" .. - "Content-Length: " .. #data .. "\r\n" .. - "\r\n" .. data - end, lovebird.onerror) - return str -end - - -function lovebird.receive(client, pattern) - while 1 do - local data, msg = client:receive(pattern) - if not data then - if msg == "timeout" then - -- Wait for more data - coroutine.yield(true) - else - -- Disconnected -- yielding nil means we're done - coroutine.yield(nil) - end - else - return data - end - end -end - - -function lovebird.send(client, data) - local idx = 1 - while idx < #data do - local res, msg = client:send(data, idx) - if not res and msg == "closed" then - -- Handle disconnect - coroutine.yield(nil) - else - idx = idx + res - coroutine.yield(true) - end - end -end - - -function lovebird.onconnect(client) - -- Create request table - local requestptn = "(%S*)%s*(%S*)%s*(%S*)" - local req = {} - req.socket = client - req.addr, req.port = client:getsockname() - req.request = lovebird.receive(client, "*l") - req.method, req.url, req.proto = req.request:match(requestptn) - req.headers = {} - while 1 do - local line, msg = lovebird.receive(client, "*l") - if not line or #line == 0 then break end - local k, v = line:match("(.-):%s*(.*)$") - req.headers[k] = v - end - if req.headers["Content-Length"] then - req.body = lovebird.receive(client, req.headers["Content-Length"]) - end - -- Parse body - req.parsedbody = {} - if req.body then - for k, v in req.body:gmatch("([^&]-)=([^&^#]*)") do - req.parsedbody[k] = lovebird.unescape(v) - end - end - -- Parse request line's url - req.parsedurl = lovebird.parseurl(req.url) - -- Handle request; get data to send and send - local data = lovebird.onrequest(req) - lovebird.send(client, data) - -- Clear up - client:close() -end - - -function lovebird.update() - if not lovebird.inited then lovebird.init() end - -- Handle new connections - while 1 do - -- Accept new connections - local client = lovebird.server:accept() - if not client then break end - client:settimeout(0) - local addr = client:getsockname() - if lovebird.checkwhitelist(addr) then - -- Connection okay -- create and add coroutine to set - local conn = coroutine.wrap(function() - xpcall(function() lovebird.onconnect(client) end, function() end) - end) - lovebird.connections[conn] = true - else - -- Reject connection not on whitelist - lovebird.trace("got non-whitelisted connection attempt: ", addr) - client:close() - end - end - -- Handle existing connections - for conn in pairs(lovebird.connections) do - -- Resume coroutine, remove if it has finished - local status = conn() - if status == nil then - lovebird.connections[conn] = nil - end - end -end - - -return lovebird diff --git a/sonic-radiance.love/libs/loveutils/filesystem.lua b/sonic-radiance.love/libs/loveutils/filesystem.lua deleted file mode 100644 index 3d38e27..0000000 --- a/sonic-radiance.love/libs/loveutils/filesystem.lua +++ /dev/null @@ -1,16 +0,0 @@ -local Filesystem = {} - -function Filesystem.exists(filepath) - local info = love.filesystem.getInfo( filepath ) - local exists = false - - if (info == nil) then - exists = false - else - exists = true - end - - return exists -end - -return Filesystem diff --git a/sonic-radiance.love/libs/loveutils/graphics.lua b/sonic-radiance.love/libs/loveutils/graphics.lua deleted file mode 100644 index 79ad753..0000000 --- a/sonic-radiance.love/libs/loveutils/graphics.lua +++ /dev/null @@ -1,64 +0,0 @@ -local Graphics = {} - -function Graphics.resetColor() - love.graphics.setColor(1,1,1,1) -end - -function Graphics.box(x, y, w, h) - local x = math.floor(x) - local y = math.floor(y) - local w = math.floor(w) - local h = math.floor(h) - local a = a or 1 - - local r, g, b, a = love.graphics.getColor( ) - - love.graphics.setColor(r, g, b, 0.3 * a) - love.graphics.rectangle("fill", x, y, w, h) - - love.graphics.setColor(r, g, b, a) - love.graphics.rectangle("line", x, y, w, h) -end - -function Graphics.print(text, x, y, align, r, sx, sy, ox, oy, kx, ky) - local width - local font = love.graphics.getFont() - width = font:getWidth(text) - - if align == "center" then - width = (width/2) - elseif align == "right" then - width = width - else - width = 0 - end - - love.graphics.print(text, x - (width), y, r, sx, sy, ox, oy, kx, ky) -end - -function Graphics.printWithSpacing(text, spacing, align, x, y, r, sx, sy, ox, oy, kx, ky) - -- DO NOT USE THIS FUNCTION IN A "UPDATE" FUNCTION ! - -- it's pretty heavy to use as it use a loop to get every character in a text - local font = love.graphics.getFont() - local xx = 0 - local lenght = string.len(text) - local basewidth = font:getWidth(text) - local width = basewidth + (spacing * lenght) - - if align == "center" then - width = (width/2) - elseif align == "right" then - width = width - else - width = 0 - end - - for i=1, lenght do - local char = string.sub(text, i, i) - pos = math.floor(x + xx - width) - love.graphics.print(char, pos, y) - xx = xx + font:getWidth(char) + spacing - end -end - -return Graphics diff --git a/sonic-radiance.love/libs/loveutils/init.lua b/sonic-radiance.love/libs/loveutils/init.lua deleted file mode 100644 index 0f6ea3c..0000000 --- a/sonic-radiance.love/libs/loveutils/init.lua +++ /dev/null @@ -1,7 +0,0 @@ -local cwd = (...):gsub('%.init$', '') .. "." - -return { - math = require(cwd .. "math"), - graphics = require(cwd .. "graphics"), - filesystem = require(cwd .. "filesystem") -} diff --git a/sonic-radiance.love/libs/loveutils/math.lua b/sonic-radiance.love/libs/loveutils/math.lua deleted file mode 100644 index 678720f..0000000 --- a/sonic-radiance.love/libs/loveutils/math.lua +++ /dev/null @@ -1,88 +0,0 @@ -local Math = {} - -function Math.sign(x) - if (x < 0) then - return -1 - elseif (x > 0) then - return 1 - else - return 0 - end -end - -function Math.round(num) - return math.floor(num + 0.5) -end - -function Math.vector(x1, y1, x2, y2) - local vecx, vecy - - vecx = x2 - x1 - vexy = y2 - y1 - - return vecx, vecy -end - -function Math.getMiddlePoint(x1, y1, x2, y2) - local newx, newy, vecx, vecy - - vecx = math.max(x1, x2) - math.min(x1, x2) - vecy = math.max(y1, y2) - math.min(y1, y2) - - newx = math.min(x1, x2) + (vecx / 2) - newy = math.min(y1, y2) + (vecy / 2) - - return newx, newy -end - -function Math.pointDistance(x1, y1, x2, y2) - local vecx, vecy - - vecx = math.max(x1, x2) - math.min(x1, x2) - vexy = math.max(y1, y2) - math.min(y1, y2) - - return math.sqrt(vecx^2 + vecy^2) - -end - -function Math.pointDirection(x1,y1,x2,y2) - local vecx, vecy, angle - vecy = y2 - y1 - vecx = x2 - x1 - angle = math.atan2(vecy, vecx) - - return angle -end - -function Math.numberToString(x, length) - local length = length or 1 - local string = "" - local x = x - if (x >= math.pow(10, length)) then - x = unitsNumber*10 - 1 - string = string .. x - else - for i=1, (length-1) do - if (x < math.pow(10, length-i)) then - string = string .. "0" - end - end - string = string .. x - end - return string -end - -function Math.floorCoord(x, y) - return math.floor(x), math.floor(y) -end - -function Math.pixeliseCoord(x, y, factor) - x, y = Math.floorCoord(x / factor, y / factor) - - x = x * factor - y = y * factor - - return x, y -end - -return Math From c41cdfdacc8ad8241a5f81f165f87b688783bc37 Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Sat, 23 Mar 2019 12:02:51 +0100 Subject: [PATCH 3/3] game: use the gamecore version of binser --- sonic-radiance.love/game/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonic-radiance.love/game/init.lua b/sonic-radiance.love/game/init.lua index 91476ef..bb4bee7 100644 --- a/sonic-radiance.love/game/init.lua +++ b/sonic-radiance.love/game/init.lua @@ -26,7 +26,7 @@ local Game = Object:extend() local Characters = require "game.characters" -local binser = require "libs.binser" +local binser = require "core.libs.binser" function Game:new() self.slot = -1