Glove: LÖVE Compatibility Library

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
conroy
Prole
Posts: 46
Joined: Thu May 24, 2012 3:33 pm

Glove: LÖVE Compatibility Library

Post by conroy » Wed Jan 15, 2014 6:27 pm

Image

Glove is a LOVE 0.8 and 0.9 compatibility library. It provides utility
functions for smoothing over the differences between LOVE versions with the
goal of writing Lua and LOVE code that is compatible on both versions.

Glove is a single Lua file, so it's easy to integrate. Once you've download the
file, migrating involves only a few changes. First, load the module. Next,
replace calls to backward-incompatible methods by change love to
glove. For example, love.filesystem.mkdir no longer works in LOVE 0.9.

Change this code:

Code: Select all

love.filesystem.mkdir('foo')
to

Code: Select all

local glove = require 'glove'
glove.filesystem.mkdir('foo')
The second code snippet will now work across both LOVE versions.

See the documentation for supported methods.

Read more on the StackMachine blog and checkout the code on GitHub.

User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Glove: LÖVE Compatibility Library

Post by bartbes » Wed Jan 15, 2014 8:34 pm

Sounds interesting, but this seems more useful for things that changed behaviour, not names. Why is turning love.filesystem.mkdir into glove.filesystem.mkdir easier than love.filesystem.createDirectory (considering you first need to find all occurrences of mkdir anyway)?

jjmafiae
Party member
Posts: 1331
Joined: Tue Jul 24, 2012 8:22 am

Re: Glove: LÖVE Compatibility Library

Post by jjmafiae » Thu Jan 16, 2014 3:08 pm

I had a idea to make something similar. Bartbes is right why the heck is the library like that??

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Glove: LÖVE Compatibility Library

Post by Robin » Thu Jan 16, 2014 5:14 pm

To be really useful, it would probably need to mess with the global love table.
Help us help you: attach a .love.

User avatar
conroy
Prole
Posts: 46
Joined: Thu May 24, 2012 3:33 pm

Re: Glove: LÖVE Compatibility Library

Post by conroy » Thu Jan 16, 2014 8:20 pm

bartbes wrote:Sounds interesting, but this seems more useful for things that changed behaviour, not names. Why is turning love.filesystem.mkdir into glove.filesystem.mkdir easier than love.filesystem.createDirectory (considering you first need to find all occurrences of mkdir anyway)?
For a very simple reason: you can't use love.filesystem.createDirectory in Love 0.8.0. This library isn't for porting your game to Love 0.9.0, it's for writing Love modules that work across both versions.

A much better example are threads. The Thread API changed dramatically in 0.9.0. Glove gives you the old thread interface across both versions of Love.

User avatar
slime
Solid Snayke
Posts: 2918
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Glove: LÖVE Compatibility Library

Post by slime » Thu Jan 16, 2014 8:25 pm

conroy wrote:For a very simple reason: you can't use love.filesystem.createDirectory in Love 0.8.0. This library isn't for porting your game to Love 0.9.0, it's for writing Love modules that work across both versions.
But with your library you still have to change game code to use it.

You can do this to use renamed functions in both versions without mass-changing game code:

Code: Select all

love.filesystem.mkdir = love.filesystem.mkdir or love.filesystem.createDirectory
lovefilesystem.createDirectory = love.filesystem.createDirectory or love.filesystem.mkdir
(or you could do a more 'thorough' check with love._version_minor).

User avatar
conroy
Prole
Posts: 46
Joined: Thu May 24, 2012 3:33 pm

Re: Glove: LÖVE Compatibility Library

Post by conroy » Thu Jan 16, 2014 9:59 pm

slime wrote: You can do this to use renamed functions in both versions without mass-changing game code:

Code: Select all

love.filesystem.mkdir = love.filesystem.mkdir or love.filesystem.createDirectory
lovefilesystem.createDirectory = love.filesystem.createDirectory or love.filesystem.mkdir
(or you could do a more 'thorough' check with love._version_minor).
Yes, that works for simple renaming, but not for the more complicated cases such as the Thread API changes.

User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Glove: LÖVE Compatibility Library

Post by Robin » Thu Jan 16, 2014 10:25 pm

I'd prefer something like:

Code: Select all

require 'glove' '0.8.0'
And then glove could modify the LÖVE table, and replace APIs like the Thread one, etc.

I'm not making much sense now, but I can see it working inside my head and I'll probably forget all about it in the morning but still.
Help us help you: attach a .love.

Santos
Party member
Posts: 384
Joined: Sat Oct 22, 2011 7:37 am

Re: Glove: LÖVE Compatibility Library

Post by Santos » Fri Jan 17, 2014 2:38 am

Just thought I'd post this here in case it's somehow useful, an untested script for making some things work in 0.9.0:

Code: Select all

math.randomseed(os.time())
math.random()
math.random()

love.filesystem.mkdir = love.filesystem.createDirectory
love.filesystem.enumerate = love.filesystem.getDirectoryItems

if love.audio then
  love.audio._newSource = love.audio.newSource

  love.audio.newSource = function(a, b)
  local s
    if b == 'static' then
      s = love.audio._newSource(a, 'static')
    else
      s = love.audio._newSource(a)
    end
   
    local mt = getmetatable(s)
    mt.__index.setDistance = s.setAttenuationDistances
    mt.__index.getDistance = s.getAttenuationDistances
    return s
  end
end

if love.mouse then
  love.mouse.setGrab = love.mouse.setGrabbed
end

if love.timer then
  love.timer.getMicroTime = love.timer.getTime
end

if love.graphics then
  love.graphics.checkMode = function(width, height, fullscreen)
    if fullscreen == false then
      return true
    else
      for i, v in ipairs(love.window.getFullscreenModes()) do
        if width == v.width and height == v.height then
          return true
        end
      end
      return false
    end
  end

  love.graphics.toggleFullscreen = function()
    return love.window.setFullscreen(not love.window.getFullscreen())
  end

  love.graphics.setLine = function(a, b)
    love.graphics.setLineWidth(a)
    love.graphics.setLineStyle(b or 'smooth')
  end

  love.graphics.setPoint = function(a, b)
    love.graphics.setPointSize(a)
    love.graphics.setPointHeight(b)
  end

  love.graphics.setMode = function ( width, height, fullscreen, vsync, fsaa )
    local flags = {} 
    if fullscreen ~= nil then
      flags.fullscreen = fullscreen
    end 
    if vsync ~= nil then
      flags.vsync = vsync
    end 
    if fsaa ~= nil then
      flags.fsaa = fsaa
    end
    love.window.setMode(width, height, flags)
  end

  love.graphics.setIcon = function(a)
    if a:type() == 'Image' then
      a = a:getData()
    end
    love.window.setIcon(a)
  end

  love.graphics._isSupported = love.graphics.isSupported
  function love.graphics.isSupported(...)
    local t = {...}
    for k, v in pairs(t) do
      if v == 'pixeleffect' then
        t[k] = 'shader'
      end
    end
    love.graphics._isSupported(unpack(t))
  end

  love.graphics.getMode = function()
    local w, h, flags = love.window.getMode()
    return w, h, flags.fullscreen, flags.vsync, flags.fsaa
  end

  love.graphics.newPixelEffect = function(a) return love.graphics.newShader(a) end
  love.graphics.setPixelEffect = love.graphics.setShader
  love.graphics.getPixelEffect = love.graphics.getShader
  love.graphics.getModes = love.window.getFullscreenModes
  love.graphics.quad = love.graphics.polygon
  love.graphics.triangle = love.graphics.polygon
  love.graphics.newStencil = function(a) return a end
  love.graphics.setCaption = love.window.setTitle
  love.graphics.getCaption = love.window.getTitle
  love.graphics.hasFocus = love.window.hasFocus
  love.graphics.isCreated = love.window.isCreated
  love.graphics.setDefaultImageFilter = love.graphics.setDefaultFilter

  love.graphics._newParticleSystem = love.graphics.newParticleSystem

  love.graphics.newParticleSystem = function(...)
    local ps = love.graphics._newParticleSystem(...)
    local mt = getmetatable(ps)
    local sizevariation = mt.__index.setSizeVariation
    mt.__index.setSizeVariation = function(self, min, max)
      if max then
        sizevariation(self, math.min(math.max(min, 0), 1), math.min(math.max(max, 0), 1))
      else
        sizevariation(self, math.min(math.max(min, 0), 1))
      end
    end
    mt.__index.setSprite = ps.setImage 
    mt.__index.setGravity = ps.setLinearAcceleration
    mt.__index.setLifetime = ps.setEmitterLifetime
    mt.__index.setParticleLife = ps.setParticleLifetime
    mt.__index.count = ps.getCount
    mt.__index.isEmpty = function() return ps.count(ps) == 0 end
    mt.__index.setGravity = function(self, min, max) self:setLinearAcceleration(0, min, 0, max) end
    --mt.__index.isFull = function() return false end
    return ps
  end

  love.graphics._newQuad = love.graphics.newQuad
  love.graphics.newQuad = function(x, y, width, height, sw, sh)
    local quad =  love.graphics._newQuad(x, y, width, height, sw, sh)
    return {sw, sh, quad, flip = function(self, h, v)
        if h then
          local x, y, w, h = self[3]:getViewport()
          x = -x-w
          self[1] = -self[1]
          self[3]:setViewport(x, y, w, h, self[1], self[2])
        end
        if v then
          local x, y, w, h = self[3]:getViewport()
          y = -y-h
          self[2] = -self[2]
          self[3]:setViewport(x, y, w, h, self[1], self[2])
        end
      end,
      setViewport = function(self, x, y, w, h) self[3]:setViewport(x, y, w, h) end,
      getViewport = function(self) return self[3]:getViewport() end
    }
  end

  love.graphics.drawq = function(image, quad, ...)
    love.graphics.draw(image, quad[3], ...)
  end

  love.graphics._newSpriteBatch = love.graphics.newSpriteBatch
  love.graphics.newSpriteBatch = function(...)
    local sb = love.graphics._newSpriteBatch(...)
    local mt = getmetatable(sb)
    mt.__index.addq = function(self, quad, x, y, r, sx, sy, ox, oy, kx, ky)
      self.add(self, quad[3], x, y, r, sx, sy, ox, oy, kx, ky)
    end
    mt.__index.setq = function(self, id, quad, x, y, r, sx, sy, ox, oy, kx, ky)
      self.set(self, id, quad[3], x, y, r, sx, sy, ox, oy, kx, ky)
    end
    return sb
  end
end

if love.joystick then
  love.joystick.getNumJoysticks = love.joystick.getJoystickCount
  local __joysticks = love.joystick.getJoysticks()
  love.joystick.isDown = function(i) if __joysticks[i] then return __joysticks[i]:isDown() else return false end end
  love.joystick.getAxes = function(i) if __joysticks[i] then return __joysticks[i]:getAxes() else return 0 end end
  love.joystick.getAxis = function(i) if __joysticks[i] then return __joysticks[i]:getAxis() else return 0 end end
  love.joystick.getHat = function(i) if __joysticks[i] then return __joysticks[i]:getHat() end end
  love.joystick.getName = function(i) if __joysticks[i] then return __joysticks[i]:getName() end end
  love.joystick.getNumAxes = function(i) if __joysticks[i] then return __joysticks[i]:getNumAxes() else return 0 end end
  love.joystick.getNumButtons = function(i) if __joysticks[i] then return __joysticks[i]:getNumButtons() else return 0 end end
  love.joystick.getNumHats = function(i) if __joysticks[i] then return __joysticks[i]:getNumHats() else return 0 end end
  --love.joystick.isOpen = function() return true end
  --love.joystick.open = function() end
  --love.joystick.close = function() end
end

--love.graphics.setColorMode = function() end

User avatar
SiENcE
Party member
Posts: 791
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: Glove: LÖVE Compatibility Library

Post by SiENcE » Fri Jan 17, 2014 7:10 pm

@Santos:

Tested :)
* Fullscreenswitching does not work.
* quads are drawn wrong...whole image is drawn
* getColorMode and setColorMode needs to be added.

I dunno how to emulate this. Any hints!?

Code: Select all

love.graphics.getColorMode = function() end
love.graphics.setColorMode = function() end
and someone forgot to mention that getColorMode was also removed:
https://www.love2d.org/wiki/0.9.0

Post Reply

Who is online

Users browsing this forum: No registered users and 29 guests