Add color blind accessibility filter

This commit is contained in:
Your Name 2026-08-11 14:08:36 -04:00
parent b42569eb9c
commit fa0bada313
2 changed files with 132 additions and 2 deletions

View file

@ -31,6 +31,7 @@ function love.load()
_initGridVars()
_initSounds()
_initGlobalColors()
_initAccessibility()
gameWorld = World:new()
_initLevelEditor()
@ -116,16 +117,42 @@ function love.draw()
love.graphics.pop()
love.graphics.setCanvas()
-- Collect every visible layer before the accessibility pass. Applying the
-- shader here also covers the editor sidebar, FPS display, and dialogue,
-- rather than only recolouring the room sprites.
love.graphics.setCanvas(presentationCanvas)
love.graphics.clear()
love.graphics.setBlendMode("alpha")
love.graphics.setColor(1, 1, 1, 1)
love.graphics.draw(finalCanvas, 0, 0)
love.graphics.draw(sideBarCanvas, sideBarBox.x, sideBarBox.y)
love.graphics.print("Current FPS: "..tostring(love.timer.getFPS( )), 10, 10)
Dialogue.draw()
love.graphics.setCanvas()
love.graphics.setColor(1, 1, 1, 1)
local filter = accessibilityModes[accessibilityModeIndex]
if filter.shader then
filter.shader:send("accessibilityTime", love.timer.getTime())
love.graphics.setShader(filter.shader)
end
love.graphics.draw(presentationCanvas, 0, 0)
love.graphics.setShader()
if accessibilityMessage and love.timer.getTime() < accessibilityMessageExpires then
love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(accessibilityMessage, 0, 30, love.graphics.getWidth(), "center")
end
end
function love.keypressed(key)
-- Available even while a dialogue is open, so the player never has to
-- dismiss something important just to change the colour treatment.
if key == "f4" then
cycleAccessibilityMode()
return
end
-- Talking to a sign captures input: navigate/choose, don't move the player.
if Dialogue.isOpen() then
Dialogue.keypressed(key)
@ -237,6 +264,7 @@ end
function _initCanvases()
gameCanvas = love.graphics.newCanvas()
finalCanvas = love.graphics.newCanvas()
presentationCanvas = love.graphics.newCanvas()
sideBarCanvas = love.graphics.newCanvas(math.max(1, sideBarBox.w), math.max(1, sideBarBox.h))
sideBarCanvas:setFilter("nearest", "nearest") -- never average when sampled
end
@ -253,6 +281,37 @@ function _initGlobalColors()
gColor.red, gColor.green, gColor.blue, gColor.white = Color:new("red"), Color:new("green"), Color:new("blue"), Color:new("white")
end
function _initAccessibility()
accessibilityModes = {
{ id = "normal", label = "Normal", shader = nil },
{ id = "deuteranopia", label = "Deuteranopia", shader = accessibilityColorShader },
}
accessibilityModeIndex = 1
local savedMode = love.filesystem.read("accessibility_mode.txt")
if savedMode then
savedMode = savedMode:match("[%w_]+")
if savedMode == "deuteranopia_high_contrast" then savedMode = "deuteranopia" end
for index, mode in ipairs(accessibilityModes) do
if mode.id == savedMode then
accessibilityModeIndex = index
break
end
end
end
local mode = accessibilityModes[accessibilityModeIndex]
accessibilityMessage = "Color filter: " .. mode.label .. " (F4 to change)"
accessibilityMessageExpires = love.timer.getTime() + 4
end
function cycleAccessibilityMode()
accessibilityModeIndex = accessibilityModeIndex % #accessibilityModes + 1
local mode = accessibilityModes[accessibilityModeIndex]
love.filesystem.write("accessibility_mode.txt", mode.id)
accessibilityMessage = "Color filter: " .. mode.label .. " (F4 to change)"
accessibilityMessageExpires = love.timer.getTime() + 2.5
end
function _initSounds()
staticWave = sfxr.newSound()
staticWave.waveform = sfxr.WAVEFORM.NOISE -- was `wavetype = 3`; field renamed in this sfxr