finally make it object oriented and add shim support (nogame 0.9.0 now works)
This commit is contained in:
parent
f9198fec8b
commit
c5dbed728c
|
@ -47,12 +47,20 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="https://github.com/love2d/love/blob/3053278048cceb7ca71b944517e886804314a246/src/scripts/nogame.lua">LÖVE 10.0 <i>nogame.lua</i></a></td>
|
<td><a href="https://github.com/love2d/love/blob/3053278048cceb7ca71b944517e886804314a246/src/scripts/nogame.lua">LÖVE 10.0 <i>nogame.lua</i></a></td>
|
||||||
<td>blending modes</td>
|
<td>SpriteBatch</td>
|
||||||
<td><span class="medium">Running</span></td>
|
<td><span class="medium">Running</span></td>
|
||||||
<td><span class="bad">Broken</span></td>
|
<td><span class="bad">Broken</span></td>
|
||||||
<td><span class="bad">Broken</span></td>
|
<td><span class="bad">Broken</span></td>
|
||||||
<td><span class="bad">Broken</span></td>
|
<td><span class="bad">Broken</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://bitbucket.org/rude/love/src/63ed6cbfb2853009bb49572d975569d43cba2705/src/scripts/boot.lua">LÖVE 0.9.0 <i>nogame.lua</i></a></td>
|
||||||
|
<td>blending modes</td>
|
||||||
|
<td><span class="medium">Running</span></td>
|
||||||
|
<td><span class="bad">Broken</span></td>
|
||||||
|
<td><span class="bad">Perfect</span></td>
|
||||||
|
<td><span class="bad">Perfect</span></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="https://github.com/TurtleP/LovePotion/tree/master/nogame">LovePotion <i>nogame<i></a></td>
|
<td><a href="https://github.com/TurtleP/LovePotion/tree/master/nogame">LovePotion <i>nogame<i></a></td>
|
||||||
<td><a href="https://github.com/TurtleP">Jeremy Postelnek</a></td>
|
<td><a href="https://github.com/TurtleP">Jeremy Postelnek</a></td>
|
||||||
|
|
30
main.js
30
main.js
|
@ -2,35 +2,13 @@ window.infatuated = {};
|
||||||
(function() {
|
(function() {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function assert(cond, msg) { if (!cond) { throw msg; } }
|
infatuated.newImage = function() {
|
||||||
|
return new Image();
|
||||||
var images = {};
|
|
||||||
infatuated.newImage = function(path, b64) {
|
|
||||||
var image = new Image();
|
|
||||||
images[path] = image;
|
|
||||||
if (b64) {
|
|
||||||
image.src = "data:image/png;base64,"+path;
|
|
||||||
} else {
|
|
||||||
image.src = infatuated.game+"/"+path;
|
|
||||||
}
|
|
||||||
image.getWidth = function() { return image.width; }
|
|
||||||
image.getHeight = function() { return image.height; }
|
|
||||||
return {
|
|
||||||
"type": "Image",
|
|
||||||
"path": path,
|
|
||||||
"getWidth": function() { return image.width; },
|
|
||||||
"getHeight": function() { return image.height; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
infatuated.drawImage = function(ctx, obj, x, y) {
|
|
||||||
if (!obj.type) { return; }
|
|
||||||
assert(obj.type == "Image", "bad argument #2 to drawImage");
|
|
||||||
if (images[obj.path].complete) {
|
|
||||||
ctx.drawImage(images[obj.path], x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = new URL(location.href);
|
var url = new URL(location.href);
|
||||||
var game = url.searchParams.get("game");
|
var game = url.searchParams.get("game");
|
||||||
infatuated.game = game ? "game-"+game : "game";
|
infatuated.game = game ? "game-"+game : "game";
|
||||||
|
var shim = url.searchParams.get("shim");
|
||||||
|
infatuated.shim = shim ? shim : false;
|
||||||
})();
|
})();
|
||||||
|
|
120
main.lua
120
main.lua
|
@ -61,10 +61,12 @@ infatuated.conf = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class = require "middleclass"
|
||||||
|
infatuated.classes = {}
|
||||||
|
|
||||||
local js = require "js"
|
local js = require "js"
|
||||||
infatuated.js = js
|
infatuated.js = js
|
||||||
local window = js.global
|
local window = js.global
|
||||||
infatuated.path = window.infatuated.game;
|
|
||||||
local document = window.document
|
local document = window.document
|
||||||
local canvas = document:getElementById("infatuated-canvas")
|
local canvas = document:getElementById("infatuated-canvas")
|
||||||
infatuated.canvas = canvas
|
infatuated.canvas = canvas
|
||||||
|
@ -109,6 +111,9 @@ function infatuated.msgbox:hide()
|
||||||
end
|
end
|
||||||
--infatuated.msgbox:show("sample title", "the quick brown fox", {"a", "b", "c"}, oldprint)
|
--infatuated.msgbox:show("sample title", "the quick brown fox", {"a", "b", "c"}, oldprint)
|
||||||
|
|
||||||
|
infatuated.path = window.infatuated.game
|
||||||
|
infatuated.shim = window.infatuated.shim
|
||||||
|
|
||||||
print("Running game from path %q", path)
|
print("Running game from path %q", path)
|
||||||
|
|
||||||
local function errorprint(...)
|
local function errorprint(...)
|
||||||
|
@ -139,7 +144,6 @@ function infatuated.parseColor(r, g, b, a)
|
||||||
assert(type(g) == "number", "bad argument #2 to parseColor")
|
assert(type(g) == "number", "bad argument #2 to parseColor")
|
||||||
assert(type(b) == "number", "bad argument #3 to parseColor")
|
assert(type(b) == "number", "bad argument #3 to parseColor")
|
||||||
assert(type(a) == "number", "bad argument #4 to parseColor")
|
assert(type(a) == "number", "bad argument #4 to parseColor")
|
||||||
--return {r, g, b, a}, string.format("rgba(%f, %f, %f, %f)", r, g, b, a)
|
|
||||||
return {r, g, b, a}, string.format("rgba(%f, %f, %f, %f)", r*255, g*255, b*255, a)
|
return {r, g, b, a}, string.format("rgba(%f, %f, %f, %f)", r*255, g*255, b*255, a)
|
||||||
else
|
else
|
||||||
error("bad argument #1 to parseColor")
|
error("bad argument #1 to parseColor")
|
||||||
|
@ -209,66 +213,76 @@ end
|
||||||
|
|
||||||
print("Coroutining now")
|
print("Coroutining now")
|
||||||
infatuated.thread = coroutine.create(function()
|
infatuated.thread = coroutine.create(function()
|
||||||
require "modules.data"
|
xpcall(function()
|
||||||
require "modules.event"
|
require "modules.data"
|
||||||
require "modules.filesystem"
|
require "modules.event"
|
||||||
require "modules.graphics"
|
require "modules.filesystem"
|
||||||
require "modules.handlers"
|
require "modules.graphics"
|
||||||
require "modules.image"
|
require "modules.handlers"
|
||||||
require "modules.math"
|
require "modules.image"
|
||||||
require "modules.system"
|
require "modules.math"
|
||||||
require "modules.timer"
|
require "modules.system"
|
||||||
require "modules.window"
|
require "modules.timer"
|
||||||
|
require "modules.window"
|
||||||
|
|
||||||
love.run()
|
love.run()
|
||||||
|
|
||||||
local oldrequire = require
|
if infatuated.shim then
|
||||||
infatuated.require = oldrequire
|
print("Shimming %s", infatuated.shim)
|
||||||
function require(path)
|
infatuated.shim = infatuated.shim:gsub("%.", "-")
|
||||||
assert(type(path) == "string", "bad argument #1 to require")
|
require("shims."..infatuated.shim)
|
||||||
if path == "love" then return love end
|
end
|
||||||
return oldrequire(infatuated.path.."."..path)
|
|
||||||
end
|
|
||||||
|
|
||||||
print("Importing conf")
|
local oldrequire = require
|
||||||
|
infatuated.require = oldrequire
|
||||||
|
function require(path)
|
||||||
|
assert(type(path) == "string", "bad argument #1 to require")
|
||||||
|
if path == "love" then return love end
|
||||||
|
return oldrequire(infatuated.path.."."..path)
|
||||||
|
end
|
||||||
|
|
||||||
local status, errmsg = pcall(oldrequire, infatuated.path..".conf")
|
print("Importing conf")
|
||||||
if not status and not errmsg:find("^module '.-%.conf' not found:") then
|
|
||||||
infatuated.crash(errmsg)
|
|
||||||
end
|
|
||||||
local status, errmsg = pcall(love.conf, infatuated.conf)
|
|
||||||
if not status then infatuated.crash(errmsg) end
|
|
||||||
|
|
||||||
print("Importing main")
|
local status, errmsg = pcall(oldrequire, infatuated.path..".conf")
|
||||||
|
if not status and not errmsg:find("^module '.-%.conf' not found:") then
|
||||||
|
infatuated.crash(errmsg)
|
||||||
|
end
|
||||||
|
local status, errmsg = pcall(love.conf, infatuated.conf)
|
||||||
|
if not status then infatuated.crash(errmsg) end
|
||||||
|
|
||||||
local status, errmsg = pcall(oldrequire, infatuated.path..".main")
|
print("Importing main")
|
||||||
if not status then infatuated.crash(errmsg) end
|
|
||||||
local status, errmsg = pcall(love.run)
|
|
||||||
if not status then
|
|
||||||
infatuated.crash(errmsg)
|
|
||||||
else
|
|
||||||
infatuated.loopGuest = errmsg
|
|
||||||
end
|
|
||||||
|
|
||||||
print("Starting event loop")
|
local status, errmsg = pcall(oldrequire, infatuated.path..".main")
|
||||||
|
if not status then infatuated.crash(errmsg) end
|
||||||
infatuated.dt1 = window.performance:now()
|
local status, errmsg = pcall(love.run)
|
||||||
local function resume()
|
|
||||||
coroutine.resume(infatuated.thread)
|
|
||||||
end
|
|
||||||
while true do
|
|
||||||
local dt2 = window.performance:now()
|
|
||||||
infatuated.dt = (dt2-infatuated.dt1)/1000
|
|
||||||
infatuated.dt1 = dt2
|
|
||||||
local status, errmsg = pcall(infatuated.loopGuest)
|
|
||||||
if not status then
|
if not status then
|
||||||
infatuated.crash(errmsg)
|
infatuated.crash(errmsg)
|
||||||
elseif errmsg then
|
else
|
||||||
print("Exited with code %d", errmsg or -1)
|
infatuated.loopGuest = errmsg
|
||||||
return
|
|
||||||
end
|
end
|
||||||
window:requestAnimationFrame(resume)
|
|
||||||
coroutine.yield()
|
print("Starting event loop")
|
||||||
end
|
|
||||||
|
infatuated.dt1 = window.performance:now()
|
||||||
|
local function resume()
|
||||||
|
coroutine.resume(infatuated.thread)
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
local dt2 = window.performance:now()
|
||||||
|
infatuated.dt = (dt2-infatuated.dt1)/1000
|
||||||
|
infatuated.dt1 = dt2
|
||||||
|
local status, errmsg = pcall(infatuated.loopGuest)
|
||||||
|
if not status then
|
||||||
|
infatuated.crash(errmsg)
|
||||||
|
elseif errmsg then
|
||||||
|
print("Exited with code %d", errmsg or -1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
window:requestAnimationFrame(resume)
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end, function(errmsg)
|
||||||
|
infatuated.crash(errmsg)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
coroutine.resume(infatuated.thread)
|
coroutine.resume(infatuated.thread)
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
local middleclass = {
|
||||||
|
_VERSION = 'middleclass v4.1.1',
|
||||||
|
_DESCRIPTION = 'Object Orientation for Lua',
|
||||||
|
_URL = 'https://github.com/kikito/middleclass',
|
||||||
|
_LICENSE = [[
|
||||||
|
MIT LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2011 Enrique García Cota
|
||||||
|
|
||||||
|
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 function _createIndexWrapper(aClass, f)
|
||||||
|
if f == nil then
|
||||||
|
return aClass.__instanceDict
|
||||||
|
else
|
||||||
|
return function(self, name)
|
||||||
|
local value = aClass.__instanceDict[name]
|
||||||
|
|
||||||
|
if value ~= nil then
|
||||||
|
return value
|
||||||
|
elseif type(f) == "function" then
|
||||||
|
return (f(self, name))
|
||||||
|
else
|
||||||
|
return f[name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _propagateInstanceMethod(aClass, name, f)
|
||||||
|
f = name == "__index" and _createIndexWrapper(aClass, f) or f
|
||||||
|
aClass.__instanceDict[name] = f
|
||||||
|
|
||||||
|
for subclass in pairs(aClass.subclasses) do
|
||||||
|
if rawget(subclass.__declaredMethods, name) == nil then
|
||||||
|
_propagateInstanceMethod(subclass, name, f)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _declareInstanceMethod(aClass, name, f)
|
||||||
|
aClass.__declaredMethods[name] = f
|
||||||
|
|
||||||
|
if f == nil and aClass.super then
|
||||||
|
f = aClass.super.__instanceDict[name]
|
||||||
|
end
|
||||||
|
|
||||||
|
_propagateInstanceMethod(aClass, name, f)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _tostring(self) return "class " .. self.name end
|
||||||
|
local function _call(self, ...) return self:new(...) end
|
||||||
|
|
||||||
|
local function _createClass(name, super)
|
||||||
|
local dict = {}
|
||||||
|
dict.__index = dict
|
||||||
|
|
||||||
|
local aClass = { name = name, super = super, static = {},
|
||||||
|
__instanceDict = dict, __declaredMethods = {},
|
||||||
|
subclasses = setmetatable({}, {__mode='k'}) }
|
||||||
|
|
||||||
|
if super then
|
||||||
|
setmetatable(aClass.static, {
|
||||||
|
__index = function(_,k)
|
||||||
|
local result = rawget(dict,k)
|
||||||
|
if result == nil then
|
||||||
|
return super.static[k]
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
})
|
||||||
|
else
|
||||||
|
setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) end })
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(aClass, { __index = aClass.static, __tostring = _tostring,
|
||||||
|
__call = _call, __newindex = _declareInstanceMethod })
|
||||||
|
|
||||||
|
return aClass
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _includeMixin(aClass, mixin)
|
||||||
|
assert(type(mixin) == 'table', "mixin must be a table")
|
||||||
|
|
||||||
|
for name,method in pairs(mixin) do
|
||||||
|
if name ~= "included" and name ~= "static" then aClass[name] = method end
|
||||||
|
end
|
||||||
|
|
||||||
|
for name,method in pairs(mixin.static or {}) do
|
||||||
|
aClass.static[name] = method
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(mixin.included)=="function" then mixin:included(aClass) end
|
||||||
|
return aClass
|
||||||
|
end
|
||||||
|
|
||||||
|
local DefaultMixin = {
|
||||||
|
__tostring = function(self) return "instance of " .. tostring(self.class) end,
|
||||||
|
|
||||||
|
initialize = function(self, ...) end,
|
||||||
|
|
||||||
|
isInstanceOf = function(self, aClass)
|
||||||
|
return type(aClass) == 'table'
|
||||||
|
and type(self) == 'table'
|
||||||
|
and (self.class == aClass
|
||||||
|
or type(self.class) == 'table'
|
||||||
|
and type(self.class.isSubclassOf) == 'function'
|
||||||
|
and self.class:isSubclassOf(aClass))
|
||||||
|
end,
|
||||||
|
|
||||||
|
static = {
|
||||||
|
allocate = function(self)
|
||||||
|
assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
|
||||||
|
return setmetatable({ class = self }, self.__instanceDict)
|
||||||
|
end,
|
||||||
|
|
||||||
|
new = function(self, ...)
|
||||||
|
assert(type(self) == 'table', "Make sure that you are using 'Class:new' instead of 'Class.new'")
|
||||||
|
local instance = self:allocate()
|
||||||
|
instance:initialize(...)
|
||||||
|
return instance
|
||||||
|
end,
|
||||||
|
|
||||||
|
subclass = function(self, name)
|
||||||
|
assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
|
||||||
|
assert(type(name) == "string", "You must provide a name(string) for your class")
|
||||||
|
|
||||||
|
local subclass = _createClass(name, self)
|
||||||
|
|
||||||
|
for methodName, f in pairs(self.__instanceDict) do
|
||||||
|
_propagateInstanceMethod(subclass, methodName, f)
|
||||||
|
end
|
||||||
|
subclass.initialize = function(instance, ...) return self.initialize(instance, ...) end
|
||||||
|
|
||||||
|
self.subclasses[subclass] = true
|
||||||
|
self:subclassed(subclass)
|
||||||
|
|
||||||
|
return subclass
|
||||||
|
end,
|
||||||
|
|
||||||
|
subclassed = function(self, other) end,
|
||||||
|
|
||||||
|
isSubclassOf = function(self, other)
|
||||||
|
return type(other) == 'table' and
|
||||||
|
type(self.super) == 'table' and
|
||||||
|
( self.super == other or self.super:isSubclassOf(other) )
|
||||||
|
end,
|
||||||
|
|
||||||
|
include = function(self, ...)
|
||||||
|
assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'")
|
||||||
|
for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function middleclass.class(name, super)
|
||||||
|
assert(type(name) == 'string', "A name (string) is needed for the new class")
|
||||||
|
return super and super:subclass(name) or _includeMixin(_createClass(name), DefaultMixin)
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end })
|
||||||
|
|
||||||
|
return middleclass
|
|
@ -1,12 +1,13 @@
|
||||||
love.filesystem = {}
|
love.filesystem = {}
|
||||||
|
local FileData = class("FileData")
|
||||||
|
infatuated.classes.FileData = FileData
|
||||||
|
function FileData:initialize(contents, name)
|
||||||
|
self.contents = contents
|
||||||
|
self.name = name
|
||||||
|
end
|
||||||
function love.filesystem.newFileData(contents, name)
|
function love.filesystem.newFileData(contents, name)
|
||||||
if name then
|
if name then
|
||||||
-- TODO: use an actual class
|
return infatuated.classes.FileData:new(contents, name)
|
||||||
return {
|
|
||||||
type = "FileData",
|
|
||||||
data = contents,
|
|
||||||
name = name
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
return nil, "not implemented"
|
return nil, "not implemented"
|
||||||
end
|
end
|
||||||
|
|
|
@ -85,33 +85,71 @@ function love.graphics.setLineWidth(width)
|
||||||
infatuated.lineWidth = width
|
infatuated.lineWidth = width
|
||||||
end
|
end
|
||||||
|
|
||||||
function love.graphics.newSpriteBatch(image, maxsprites, usage)
|
local SpriteBatch = class("SpriteBatch")
|
||||||
maxsprites = maxsprites or 1000
|
infatuated.classes.SpriteBatch = SpriteBatch
|
||||||
assert(type(image) == "userdata" and image.type == "Image", "bad argument #1 to newSpriteBatch (expected Image)")
|
function SpriteBatch:initialize(image, max)
|
||||||
assert(type(maxsprites) == "number" and maxsprites > 0, "bad argument #2 to newSpriteBatch")
|
self._max = max
|
||||||
return {
|
|
||||||
type = "SpriteBatch",
|
|
||||||
maxsprites = maxsprites,
|
|
||||||
getBufferSize = function(self) return self.maxsprites end,
|
|
||||||
setBufferSize = function(self, maxsprites)
|
|
||||||
assert(type(maxsprites) == "number" and maxsprites > 0, "bad argument #2 to setBufferSize (expected number)")
|
|
||||||
self.maxsprites = maxsprites
|
|
||||||
end,
|
|
||||||
add = function() end,
|
|
||||||
flush = function() end,
|
|
||||||
clear = function() end
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
function love.graphics.newImage(path)
|
function SpriteBatch:getBufferSize()
|
||||||
if path.type == "ImageData" then
|
return self._max
|
||||||
return newImage(nil, path, true)
|
end
|
||||||
|
function SpriteBatch:setBufferSize(maxsprites)
|
||||||
|
assert(type(maxsprites) == "number", "bad argument #1 to setBufferSize (expected number)")
|
||||||
|
assert(maxsprites > 0, "maxsprites must be greater than 0")
|
||||||
|
self._max = maxsprites
|
||||||
|
end
|
||||||
|
function SpriteBatch:add() end
|
||||||
|
function SpriteBatch:flush() end
|
||||||
|
function SpriteBatch:clear() end
|
||||||
|
function love.graphics.newSpriteBatch(image, maxsprites)
|
||||||
|
maxsprites = maxsprites or 1000
|
||||||
|
assert(type(image) == "table" and tostring(image.class) == "class Image", "bad argument #1 to newSpriteBatch (expected Image)")
|
||||||
|
assert(type(maxsprites) == "number", "bad argument #2 to newSpriteBatch (expected number)")
|
||||||
|
assert(maxsprites > 0, "maxsprites must be greater than 0")
|
||||||
|
return SpriteBatch:new(image, maxsprites, usage)
|
||||||
|
end
|
||||||
|
|
||||||
|
local Image = class("Image")
|
||||||
|
infatuated.classes.Image = Image
|
||||||
|
function Image:initialize(a)
|
||||||
|
if type(a) == "string" then
|
||||||
|
infatuated.print("Loading image from %q", a)
|
||||||
|
local image = newImage()
|
||||||
|
a = ("/"..a):gsub("/%.%.", "/")
|
||||||
|
image.src = "game"..a
|
||||||
|
image.onload = function(self)
|
||||||
|
infatuated.print("Loaded image")
|
||||||
|
coroutine.resume(infatuated.thread)
|
||||||
|
end
|
||||||
|
coroutine.yield()
|
||||||
|
self.image = image
|
||||||
else
|
else
|
||||||
assert(type(path) == "string", "bad argument #1 to newImage")
|
infatuated.print("Loading image from ImageData")
|
||||||
return newImage(nil, path)
|
local image = newImage()
|
||||||
|
image.src = "data:image/png;base64,"..a.data
|
||||||
|
image.onload = function(self)
|
||||||
|
infatuated.print("Loaded image")
|
||||||
|
coroutine.resume(infatuated.thread)
|
||||||
|
end
|
||||||
|
coroutine.yield()
|
||||||
|
self.image = image
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function Image:getWidth()
|
||||||
|
return self.image.width
|
||||||
|
end
|
||||||
|
function Image:getHeight()
|
||||||
|
return self.image.height
|
||||||
|
end
|
||||||
|
function love.graphics.newImage(a)
|
||||||
|
local t = type(a)
|
||||||
|
assert(t == "string" or (t == "table" and tostring(a.class) == "class ImageData"), "bad argument #1 to newImage (expected string or ImageData)")
|
||||||
|
return Image:new(a)
|
||||||
|
end
|
||||||
|
|
||||||
function love.graphics.draw(obj, x, y, r, sx, sy, ox, oy)
|
function love.graphics.draw(obj, x, y, r, sx, sy, ox, oy)
|
||||||
|
if type(obj) == "table" and tostring(obj.class) == "class SpriteBatch" then return end
|
||||||
|
assert(type(obj) == "table" and tostring(obj.class) == "class Image", "bad argument #1 to draw (expected Image)")
|
||||||
r = r or 0
|
r = r or 0
|
||||||
ox = ox or 0
|
ox = ox or 0
|
||||||
oy = oy or 0
|
oy = oy or 0
|
||||||
|
@ -126,7 +164,7 @@ function love.graphics.draw(obj, x, y, r, sx, sy, ox, oy)
|
||||||
ctx:rotate(r)
|
ctx:rotate(r)
|
||||||
-- color tinting looks HARD!
|
-- color tinting looks HARD!
|
||||||
ctx.globalAlpha = infatuated.color[4]
|
ctx.globalAlpha = infatuated.color[4]
|
||||||
drawImage(nil, ctx, obj, -ox, -oy)
|
ctx:drawImage(obj.image, -ox, -oy)
|
||||||
ctx:restore()
|
ctx:restore()
|
||||||
end
|
end
|
||||||
function love.graphics.print(text, x, y, r, sx, sy, ox, oy, kx, ky)
|
function love.graphics.print(text, x, y, r, sx, sy, ox, oy, kx, ky)
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
love.image = {}
|
love.image = {}
|
||||||
function love.image.newImageData(w, h, f, d)
|
local ImageData = class("ImageData")
|
||||||
if h or f or d then
|
infatuated.classes.ImageData = ImageData
|
||||||
error("not implemented")
|
function ImageData:initialize(a)
|
||||||
else
|
self.data = a.contents
|
||||||
-- TODO: use an actual class
|
end
|
||||||
return {
|
function love.image.newImageData(a, b, c, d)
|
||||||
type = "ImageData",
|
assert(type(a) == "table" and tostring(a.class) == "class FileData", "bad argument #1 to newImageData (expected FileData)")
|
||||||
content = w
|
if b or c or d then
|
||||||
}
|
error("not implemented")
|
||||||
end
|
end
|
||||||
|
return ImageData:new(a)
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,10 +27,13 @@ local platformIDs = {
|
||||||
win64 = "Windows",
|
win64 = "Windows",
|
||||||
wince = "Windows" -- amirite
|
wince = "Windows" -- amirite
|
||||||
}
|
}
|
||||||
function love.system.getOS()
|
local function getOS()
|
||||||
if useragent:find("android") then return "Android" end -- fucking "Linux 50m3_r4nd0m_5h1t"
|
if useragent:find("android") then return "Android" end -- fucking "Linux 50m3_r4nd0m_5h1t"
|
||||||
if useragent:find("iphone") then return "iOS" end -- fucking "general Mobile Device"
|
if useragent:find("iphone") then return "iOS" end -- fucking "general Mobile Device"
|
||||||
return platformIDs[platform] or platform:find("mobile") and "Android" or "Windows"
|
return platformIDs[platform] or platform:find("mobile") and "Android" or "Windows"
|
||||||
end
|
end
|
||||||
love._os = love.system.getOS() -- 0.8.0 compatibility
|
infatuated.os = getOS()
|
||||||
infatuated.print("Detected OS as %s", love._os)
|
infatuated.print("Detected OS as %s", infatuated.os)
|
||||||
|
function love.system.getOS()
|
||||||
|
return infatuated.os
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
function infatuated.parseColor(r, g, b, a)
|
||||||
|
if type(r) == "table" then
|
||||||
|
return infatuated.parseColor(r[1], r[2], r[3], r[4])
|
||||||
|
elseif type(r) == "number" then
|
||||||
|
a = a or 1
|
||||||
|
assert(type(g) == "number", "bad argument #2 to parseColor")
|
||||||
|
assert(type(b) == "number", "bad argument #3 to parseColor")
|
||||||
|
assert(type(a) == "number", "bad argument #4 to parseColor")
|
||||||
|
return {r, g, b, a}, string.format("rgba(%f, %f, %f, %f)", r, g, b, a)
|
||||||
|
else
|
||||||
|
error("bad argument #1 to parseColor")
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue