refactor sreen scalar to support multiple resolutions
This commit is contained in:
parent
be7708edcf
commit
467c450349
@ -1,138 +0,0 @@
|
||||
--[[
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Semyon Entsov <swalrus@yandex.ru>
|
||||
|
||||
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 center = {}
|
||||
|
||||
function center:setupScreen(width, height)
|
||||
self._WIDTH = width
|
||||
self._HEIGHT = height
|
||||
self._MAX_WIDTH = 0
|
||||
self._MAX_HEIGHT = 0
|
||||
self._MAX_RELATIVE_WIDTH = 0
|
||||
self._MAX_RELATIVE_HEIGHT = 0
|
||||
self._SCREEN_WIDTH = love.graphics.getWidth()
|
||||
self._SCREEN_HEIGHT = love.graphics.getHeight()
|
||||
self._BORDERS = {
|
||||
['t'] = 0,
|
||||
['r'] = 0,
|
||||
['b'] = 0,
|
||||
['l'] = 0
|
||||
}
|
||||
self:apply()
|
||||
return self
|
||||
end
|
||||
|
||||
function center:setBorders(top, right, bottom, left)
|
||||
self._BORDERS.t = top
|
||||
self._BORDERS.r = right
|
||||
self._BORDERS.b = bottom
|
||||
self._BORDERS.l = left
|
||||
end
|
||||
|
||||
function center:getScale()
|
||||
return self._SCALE
|
||||
end
|
||||
|
||||
function center:getOffsetX()
|
||||
return self._OFFSET_X
|
||||
end
|
||||
|
||||
function center:getOffsetY()
|
||||
return self._OFFSET_Y
|
||||
end
|
||||
|
||||
function center:setMaxWidth(width)
|
||||
self._MAX_WIDTH = width
|
||||
end
|
||||
|
||||
function center:setMaxHeight(height)
|
||||
self._MAX_HEIGHT = height
|
||||
end
|
||||
|
||||
function center:setMaxRelativeWidth(width)
|
||||
self._MAX_RELATIVE_WIDTH = width
|
||||
end
|
||||
|
||||
function center:setMaxRelativeHeight(height)
|
||||
self._MAX_RELATIVE_HEIGHT = height
|
||||
end
|
||||
|
||||
function center:resize(width, height)
|
||||
self._SCREEN_WIDTH = width
|
||||
self._SCREEN_HEIGHT = height
|
||||
self:apply()
|
||||
end
|
||||
|
||||
function center:apply()
|
||||
local available_width = self._SCREEN_WIDTH - self._BORDERS.l - self._BORDERS.r
|
||||
local available_height = self._SCREEN_HEIGHT - self._BORDERS.t - self._BORDERS.b
|
||||
local max_width = available_width
|
||||
local max_height = available_height
|
||||
if self._MAX_RELATIVE_WIDTH > 0 and available_width * self._MAX_RELATIVE_WIDTH < max_width then
|
||||
max_width = available_width * self._MAX_RELATIVE_WIDTH
|
||||
end
|
||||
if self._MAX_RELATIVE_HEIGHT > 0 and available_height * self._MAX_RELATIVE_HEIGHT < max_height then
|
||||
max_height = available_height * self._MAX_RELATIVE_HEIGHT
|
||||
end
|
||||
if self._MAX_WIDTH > 0 and self._MAX_WIDTH < max_width then
|
||||
max_width = self._MAX_WIDTH
|
||||
end
|
||||
if self._MAX_HEIGHT > 0 and self._MAX_HEIGHT < max_height then
|
||||
max_height = self._MAX_HEIGHT
|
||||
end
|
||||
if max_height / max_width > self._HEIGHT / self._WIDTH then
|
||||
self._CANVAS_WIDTH = max_width
|
||||
self._CANVAS_HEIGHT = self._CANVAS_WIDTH * (self._HEIGHT / self._WIDTH)
|
||||
else
|
||||
self._CANVAS_HEIGHT = max_height
|
||||
self._CANVAS_WIDTH = self._CANVAS_HEIGHT * (self._WIDTH / self._HEIGHT)
|
||||
end
|
||||
self._SCALE = self._CANVAS_HEIGHT / self._HEIGHT
|
||||
self._OFFSET_X = self._BORDERS.l + (available_width - self._CANVAS_WIDTH) / 2
|
||||
self._OFFSET_Y = self._BORDERS.t + (available_height - self._CANVAS_HEIGHT) / 2
|
||||
end
|
||||
|
||||
function center:start()
|
||||
love.graphics.push()
|
||||
love.graphics.translate(self._OFFSET_X, self._OFFSET_Y)
|
||||
love.graphics.scale(self._SCALE, self._SCALE)
|
||||
end
|
||||
|
||||
function center:finish()
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
function center:toGame(x, y, w, h)
|
||||
if not (self._OFFSET_X and self._OFFSET_Y and self._SCALE) then
|
||||
return x, y, w, h
|
||||
end
|
||||
|
||||
return (x - self._OFFSET_X) / self._SCALE,
|
||||
(y - self._OFFSET_Y) / self._SCALE,
|
||||
w and w / self._SCALE,
|
||||
h and h / self._SCALE
|
||||
end
|
||||
|
||||
return center
|
||||
|
@ -1,7 +1,6 @@
|
||||
local Gamestate = require("lib.hump.gamestate")
|
||||
local binser = require("lib.binser")
|
||||
local Vec = require("lib.brinevector")
|
||||
require("screen-scaler")
|
||||
|
||||
binser.registerStruct("brinevector",
|
||||
function(v) return v.x, v.y end,
|
||||
|
@ -1,254 +0,0 @@
|
||||
--- Module resposible for scaling screen and centering contents
|
||||
-- while respecting ratios.
|
||||
-- @module ScreenScaler
|
||||
local ScreenScaler = {}
|
||||
|
||||
local canvas
|
||||
|
||||
-- This "Center" library will do most of the heavy lifting
|
||||
local Center = require("lib.center")
|
||||
|
||||
local getRealDimensions = love.graphics.getDimensions
|
||||
|
||||
--- Set the "ideal" dimensions from which everything else will be scaled.
|
||||
-- @tparam number w virtual width
|
||||
-- @tparam number h virtual height
|
||||
function ScreenScaler.setVirtualDimensions(w, h)
|
||||
assert(type(w) == "number", "Expected width to be number")
|
||||
assert(type(h) == "number", "Expected height to be number")
|
||||
ScreenScaler.width, ScreenScaler.height = nil, nil
|
||||
|
||||
-- Setup library resposible for scaling the screen
|
||||
Center:setupScreen(w, h)
|
||||
canvas = love.graphics.newCanvas(w, h)
|
||||
canvas:setFilter("nearest", "nearest")
|
||||
|
||||
ScreenScaler.width, ScreenScaler.height = w, h
|
||||
end
|
||||
|
||||
--- Unsets virtual dimensions. Effectively disables scaler.
|
||||
function ScreenScaler.unsetVirtualDimensions()
|
||||
ScreenScaler.width = nil
|
||||
ScreenScaler.height = nil
|
||||
end
|
||||
|
||||
--- Get virtual dimensions.
|
||||
-- @return width, height
|
||||
function ScreenScaler.getVirtualDimensions()
|
||||
return ScreenScaler.width, ScreenScaler.height
|
||||
end
|
||||
|
||||
--- Returns true if scaler is enabled.
|
||||
-- @treturn boolean
|
||||
function ScreenScaler.isEnabled()
|
||||
return ScreenScaler.width ~= nil
|
||||
end
|
||||
|
||||
-- Overwrite default love.mouse functions to return position
|
||||
-- relative to scaled window
|
||||
do
|
||||
local getX = love.mouse.getX
|
||||
function love.mouse.getX()
|
||||
local x = getX()
|
||||
if not ScreenScaler.isEnabled() then
|
||||
return x
|
||||
end
|
||||
return (x - Center:getOffsetX()) / Center:getScale()
|
||||
end
|
||||
|
||||
local getY = love.mouse.getY
|
||||
function love.mouse.getY()
|
||||
local y = getY()
|
||||
if not ScreenScaler.isEnabled() then
|
||||
return y
|
||||
end
|
||||
return (y - Center:getOffsetY()) / Center:getScale()
|
||||
end
|
||||
|
||||
local getPosition = love.mouse.getPosition
|
||||
function love.mouse.getPosition()
|
||||
if ScreenScaler.isEnabled() then
|
||||
return Center:toGame(getPosition())
|
||||
else
|
||||
return getPosition()
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: add replacements for setX, setY, setPosition
|
||||
end
|
||||
|
||||
-- Overwrite default getDimensions, getWidth, getHeight
|
||||
-- to return virtual width and height if scaler is enabled
|
||||
do
|
||||
local getWidth = love.graphics.getWidth
|
||||
function love.graphics.getWidth()
|
||||
return ScreenScaler.width or getWidth()
|
||||
end
|
||||
|
||||
local getHeight = love.graphics.getHeight
|
||||
function love.graphics.getHeight()
|
||||
return ScreenScaler.height or getHeight()
|
||||
end
|
||||
|
||||
function love.graphics.getDimensions()
|
||||
return love.graphics.getWidth(), love.graphics.getHeight()
|
||||
end
|
||||
end
|
||||
|
||||
-- Adjust setScissor and intersectScissor function, so that they are relative
|
||||
-- to the scaled screen. By default these functions are unaffected by transformations
|
||||
do
|
||||
local setScissor = love.graphics.setScissor
|
||||
function love.graphics.setScissor(x, y, w, h)
|
||||
if x and ScreenScaler.isEnabled() then
|
||||
setScissor(Center:toGame(x, y, w, h))
|
||||
else
|
||||
setScissor(x, y, w, h)
|
||||
end
|
||||
end
|
||||
|
||||
local intersectScissor = love.graphics.intersectScissor
|
||||
function love.graphics.intersectScissor(x, y, w, h)
|
||||
if x and ScreenScaler.isEnabled() then
|
||||
intersectScissor(Center:toGame(x, y, w, h))
|
||||
else
|
||||
intersectScissor(x, y, w, h)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function isInBounds(x, y)
|
||||
if not ScreenScaler.isEnabled() then return true end
|
||||
local w, h = ScreenScaler.getVirtualDimensions()
|
||||
return x >= 0 and x < w and y >= 0 and y < h
|
||||
end
|
||||
|
||||
-- Create event proccessors for converting normal screen coordinates
|
||||
-- to scaled screen coordinates
|
||||
-- If the user clicked out of bounds, it will not handled
|
||||
local eventPreProccessor = {}
|
||||
function eventPreProccessor.mousepressed(x, y, button, istouch, presses)
|
||||
x, y = Center:toGame(x, y)
|
||||
return isInBounds(x, y), x, y, button, istouch, presses
|
||||
end
|
||||
|
||||
function eventPreProccessor.mousereleased(x, y, button, istouch, presses)
|
||||
x, y = Center:toGame(x, y)
|
||||
return isInBounds(x, y), x, y, button, istouch, presses
|
||||
end
|
||||
|
||||
function eventPreProccessor.mousemoved(x, y, dx, dy, istouch)
|
||||
local scale = Center:getScale()
|
||||
x, y = Center:toGame(x, y)
|
||||
dx, dy = dx / scale, dy / scale
|
||||
return isInBounds(x, y), x, y, dx, dy, istouch, istouch
|
||||
end
|
||||
|
||||
function eventPreProccessor.wheelmoved(x, y)
|
||||
return isInBounds(love.mouse.getPosition()), x, y
|
||||
end
|
||||
|
||||
local function hideOutOfBounds()
|
||||
local r, g, b, a = love.graphics.getColor()
|
||||
love.graphics.setColor(0, 0, 0, 1)
|
||||
local w, h = getRealDimensions()
|
||||
|
||||
if Center._OFFSET_X ~= 0 then
|
||||
love.graphics.rectangle("fill", 0, 0, Center._OFFSET_X, h)
|
||||
love.graphics.rectangle("fill", Center._WIDTH*Center._SCALE+Center._OFFSET_X, 0, Center._OFFSET_X, h)
|
||||
end
|
||||
|
||||
if Center._OFFSET_Y ~= 0 then
|
||||
love.graphics.rectangle("fill", 0, 0, w, Center._OFFSET_Y)
|
||||
love.graphics.rectangle("fill", 0, Center._HEIGHT*Center._SCALE+Center._OFFSET_Y, w, Center._OFFSET_Y)
|
||||
end
|
||||
|
||||
love.graphics.setColor(r, g, b, a)
|
||||
end
|
||||
|
||||
-- Modify core game loop so that if scaler is enabled:
|
||||
-- * resize events are not handled
|
||||
-- * out of bounds mouse events are not handled
|
||||
-- * all drawing operations are centered
|
||||
function love.run()
|
||||
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
|
||||
|
||||
-- We don't want the first frame's dt to include time taken by love.load.
|
||||
if love.timer then love.timer.step() end
|
||||
|
||||
local dt = 0
|
||||
|
||||
-- Main loop time.
|
||||
return function()
|
||||
-- Process events.
|
||||
if love.event then
|
||||
love.event.pump()
|
||||
for name, a,b,c,d,e,f in love.event.poll() do
|
||||
if name == "quit" then
|
||||
if not love.quit or not love.quit() then
|
||||
return a or 0
|
||||
end
|
||||
end
|
||||
|
||||
if ScreenScaler.isEnabled() then
|
||||
if name == "resize" then
|
||||
Center:resize(a, b)
|
||||
goto continue
|
||||
elseif eventPreProccessor[name] then
|
||||
local success
|
||||
success, a, b, c, d, e, f = eventPreProccessor[name](a, b, c, d, e, f)
|
||||
if not success then goto continue end
|
||||
end
|
||||
end
|
||||
love.handlers[name](a, b, c, d, e, f)
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
-- Update dt, as we'll be passing it to update
|
||||
if love.timer then dt = love.timer.step() end
|
||||
|
||||
-- Call update and draw
|
||||
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
|
||||
|
||||
if love.graphics and love.graphics.isActive() then
|
||||
love.graphics.origin()
|
||||
|
||||
if canvas then
|
||||
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||
|
||||
love.graphics.setCanvas(canvas)
|
||||
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||
love.draw()
|
||||
love.graphics.setCanvas()
|
||||
|
||||
Center:start()
|
||||
love.graphics.draw(canvas)
|
||||
Center:finish()
|
||||
else
|
||||
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||
|
||||
if love.draw then
|
||||
if ScreenScaler.isEnabled() then
|
||||
love.graphics.setCanvas(canvas)
|
||||
love.draw()
|
||||
love.graphics.setCanvas()
|
||||
|
||||
Center:start()
|
||||
love.graphics.draw(canvas)
|
||||
Center:finish()
|
||||
hideOutOfBounds()
|
||||
else
|
||||
love.draw()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
love.graphics.present()
|
||||
end
|
||||
|
||||
if love.timer then love.timer.sleep(0.001) end
|
||||
end
|
||||
end
|
||||
|
||||
return ScreenScaler
|
@ -21,6 +21,7 @@ function MainState:enter(_, host_socket)
|
||||
require("systems.map"),
|
||||
require("systems.player"),
|
||||
require("systems.sprite"),
|
||||
require("systems.screen-scaler"),
|
||||
}
|
||||
|
||||
if host_socket then
|
||||
@ -34,6 +35,30 @@ function MainState:enter(_, host_socket)
|
||||
host_socket = host_socket
|
||||
}
|
||||
}
|
||||
|
||||
self.downscaled_canvas = nil
|
||||
self:refreshDownscaledCanvas()
|
||||
self.ecs:on("onMapSwitch", function(map)
|
||||
self:refreshDownscaledCanvas(map)
|
||||
end)
|
||||
love.graphics.setNewFont(48)
|
||||
end
|
||||
|
||||
function MainState:refreshDownscaledCanvas(map)
|
||||
if not map then
|
||||
local Map = self.ecs:getSystem(require("systems.map"))
|
||||
map = Map.map
|
||||
if not map then
|
||||
self.downscaled_canvas = nil
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
self.downscaled_canvas = love.graphics.newCanvas(
|
||||
map.width * map.tilewidth,
|
||||
map.height * map.tileheight
|
||||
)
|
||||
self.downscaled_canvas:setFilter("nearest", "nearest")
|
||||
end
|
||||
|
||||
function MainState:update(dt)
|
||||
@ -56,8 +81,14 @@ function MainState:quit()
|
||||
self:cleanup()
|
||||
end
|
||||
|
||||
function MainState:mousemoved(...)
|
||||
self.ecs:emit("mousemoved", ...)
|
||||
function MainState:mousemoved(x, y, dx, dy, istouch)
|
||||
local ScreenScaler = self.ecs:getSystem(require("systems.screen-scaler"))
|
||||
if not ScreenScaler:isInBounds(x, y) then return end
|
||||
|
||||
x, y = ScreenScaler:getPosition(x, y)
|
||||
dx = (ScreenScaler.scale or 1) * dx
|
||||
dy = (ScreenScaler.scale or 1) * dy
|
||||
self.ecs:emit("mousemoved", x, y, dx, dy, istouch)
|
||||
end
|
||||
|
||||
function MainState:keypressed(...)
|
||||
@ -65,7 +96,21 @@ function MainState:keypressed(...)
|
||||
end
|
||||
|
||||
function MainState:draw()
|
||||
local ScreenScaler = self.ecs:getSystem(require("systems.screen-scaler"))
|
||||
|
||||
-- Draw the game
|
||||
ScreenScaler:start(self.downscaled_canvas)
|
||||
self.ecs:emit("draw")
|
||||
ScreenScaler:finish()
|
||||
|
||||
-- Draw UI on top
|
||||
local w, h = self.downscaled_canvas:getDimensions()
|
||||
ScreenScaler:start(1000, h/w * 1000)
|
||||
love.graphics.print("Hello World!")
|
||||
ScreenScaler:finish()
|
||||
|
||||
-- Override scaling factors from UI, with scalers for the game
|
||||
ScreenScaler:overrideScaling(self.downscaled_canvas:getDimensions())
|
||||
end
|
||||
|
||||
return MainState
|
||||
|
@ -1,6 +1,5 @@
|
||||
local rgb = require("helpers.rgb")
|
||||
local sti = require("lib.sti")
|
||||
local ScreenScaler = require("screen-scaler")
|
||||
local Map = {}
|
||||
|
||||
local DEBUG_GRID = true
|
||||
@ -8,11 +7,7 @@ local DEBUG_GRID_COLOR = rgb(30, 30, 30)
|
||||
|
||||
function Map:init()
|
||||
self.map = sti("data/maps/test.lua")
|
||||
|
||||
ScreenScaler.setVirtualDimensions(
|
||||
self.map.width * self.map.tilewidth,
|
||||
self.map.height * self.map.tileheight
|
||||
)
|
||||
self.pool:emit("onMapSwitch", self.map)
|
||||
end
|
||||
|
||||
function Map:update(dt)
|
||||
|
@ -29,9 +29,11 @@ end
|
||||
|
||||
function Player:getAimDirection(player)
|
||||
if self.use_mouse_aim then
|
||||
local ScreenScaler = self.pool:getSystem(require("systems.screen-scaler"))
|
||||
|
||||
local MAX_DIRECTIONS = 8
|
||||
local angle_segment = math.pi*2/MAX_DIRECTIONS
|
||||
local angle = (Vec(love.mouse.getPosition()) - player.pos).angle
|
||||
local angle = (Vec(ScreenScaler:getMousePosition()) - player.pos).angle
|
||||
local new_angle = math.floor(angle/angle_segment+0.5)*angle_segment
|
||||
return Vec(math.cos(new_angle), math.sin(new_angle))
|
||||
else
|
||||
@ -92,7 +94,7 @@ function Player:update(dt)
|
||||
|
||||
-- If the player is nearby a non-moving bolt, pick it up
|
||||
for _, bolt in ipairs(self.pool.groups.bolt.entities) do
|
||||
if (e.pos-bolt.pos).length < 30 and bolt.vel.length < 1 then
|
||||
if (e.pos-bolt.pos).length < 20 and bolt.vel.length < 3 then
|
||||
self.pool:removeEntity(bolt)
|
||||
e.bolt_count = e.bolt_count + 1
|
||||
end
|
||||
@ -132,7 +134,7 @@ function Player:spawnPlayer()
|
||||
friction = 0.998,
|
||||
speed = 800,
|
||||
bolt_count = 1,
|
||||
bolt_speed = 1000,
|
||||
bolt_speed = 500,
|
||||
bolt_cooldown = 0.2,
|
||||
bolt_friction = 0.9
|
||||
}
|
||||
|
100
src/systems/screen-scaler.lua
Normal file
100
src/systems/screen-scaler.lua
Normal file
@ -0,0 +1,100 @@
|
||||
local ScreenScaler = {}
|
||||
|
||||
function ScreenScaler:hideBorders()
|
||||
local r, g, b, a = love.graphics.getColor()
|
||||
love.graphics.setColor(love.graphics.getBackgroundColor())
|
||||
local w, h = love.graphics.getDimensions()
|
||||
|
||||
if self.offset_x ~= 0 then
|
||||
love.graphics.rectangle("fill", 0, 0, self.offset_x, h)
|
||||
love.graphics.rectangle("fill", w-self.offset_x, 0, self.offset_x, h)
|
||||
end
|
||||
|
||||
if self.offset_y ~= 0 then
|
||||
love.graphics.rectangle("fill", 0, 0, w, self.offset_y)
|
||||
love.graphics.rectangle("fill", 0, h-self.offset_y, w, self.offset_y)
|
||||
end
|
||||
|
||||
love.graphics.setColor(r, g, b, a)
|
||||
end
|
||||
|
||||
function ScreenScaler:getPosition(x, y)
|
||||
return (x - self.offset_x) / self.scale,
|
||||
(y - self.offset_y) / self.scale
|
||||
end
|
||||
|
||||
function ScreenScaler:isInBounds(x, y)
|
||||
if self.scale then
|
||||
local w, h = love.graphics.getDimensions()
|
||||
return x >= self.offset_x and
|
||||
x < w-self.offset_x and
|
||||
y >= self.offset_y and
|
||||
y < h-self.offset_y
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function ScreenScaler:getMousePosition()
|
||||
if self.scale then
|
||||
return self:getPosition(love.mouse.getPosition())
|
||||
else
|
||||
return love.mouse.getPosition()
|
||||
end
|
||||
end
|
||||
|
||||
function ScreenScaler:getDimensions()
|
||||
if self.scale then
|
||||
local w, h = love.graphics.getDimensions()
|
||||
return w*self.scale, h*self.scale
|
||||
else
|
||||
return love.graphics.getDimensions()
|
||||
end
|
||||
end
|
||||
|
||||
function ScreenScaler:overrideScaling(width, height)
|
||||
local sw, sh = love.graphics.getDimensions()
|
||||
self.scale = math.min(sw / width, sh / height)
|
||||
self.offset_x = (sw - width * self.scale)/2
|
||||
self.offset_y = (sh - height * self.scale)/2
|
||||
end
|
||||
|
||||
function ScreenScaler:start(p1, p2)
|
||||
local width, height
|
||||
if type(p1) == "number" and type(p2) == "number" then
|
||||
width, height = p1, p2
|
||||
self.canvas = nil
|
||||
elseif p1:typeOf("Canvas") then
|
||||
self.canvas = p1
|
||||
width, height = self.canvas:getDimensions()
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local sw, sh = love.graphics.getDimensions()
|
||||
self.scale = math.min(sw / width, sh / height)
|
||||
self.offset_x = (sw - width * self.scale)/2
|
||||
self.offset_y = (sh - height * self.scale)/2
|
||||
|
||||
love.graphics.push()
|
||||
if self.canvas then
|
||||
love.graphics.setCanvas(self.canvas)
|
||||
love.graphics.clear()
|
||||
else
|
||||
love.graphics.translate(self.offset_x, self.offset_y)
|
||||
love.graphics.scale(self.scale)
|
||||
end
|
||||
end
|
||||
|
||||
function ScreenScaler:finish()
|
||||
love.graphics.pop()
|
||||
if self.canvas then
|
||||
love.graphics.setCanvas()
|
||||
love.graphics.draw(self.canvas, self.offset_x, self.offset_y, 0, self.scale)
|
||||
else
|
||||
self:hideBorders()
|
||||
end
|
||||
self.canvas = nil
|
||||
end
|
||||
|
||||
return ScreenScaler
|
Loading…
Reference in New Issue
Block a user