local love = assert( love ) local lg = love.graphics local lt = love.timer local coroutine = assert( coroutine ) local bmp = require 'map.bmp' local scale = 1 local w, h = scale * 512, scale * 285 local dilateShader = require 'shaders.dilate' local finalCanvas = lg.newCanvas( w, h ) local canvas = lg.newCanvas( w, h ) local identityTransform = love.math.newTransform() local tiles = {} do local sideLength = 4 local i = 1 for x = 1, sideLength do for y = 1, sideLength do local width = math.floor( w / sideLength ) local height = math.floor( h / sideLength ) tiles[i] = function() return (x - 1) * width, (y - 1) * height, width, height end i = i + 1 end end end --the coroutine library doesn't reset all the global graphics state for us --so this yield function does local function y( s, currentTile ) lg.pop( "all" ) coroutine.yield( s ) lg.push( "all" ) lg.setCanvas( canvas ) lg.setShader( dilateShader ) lg.setScissor( currentTile() ) lg.setBlendMode( "add" ) end local function renderRadar( map, filename ) local statusString = "%s: rendering %s radius\n %s\n %d/%d" --we need this first push to the stack to keep y() simple lg.push( "all" ) y( filename, tiles[1] ) --then we clear the whole canvas to opaque black, pause, and select the first tile lg.setScissor() lg.clear( 0, 0, 0, 1 ) dilateShader:send( "sailable", map.sailable.img ) for tile = 1, #tiles do --dilate placeable land area by 30 degrees (radar radius) dilateShader:send( "radius", math.floor( 512 * 30 / 360 ) ) for name, terr in pairs( map.territory ) do y( statusString:format( filename, "radar", name, tile, #tiles ), tiles[tile] ) lg.setColor( 0.9 + terr.colour[1], 0.9 + terr.colour[2], 0.9 + terr.colour[3], 1 / 6 ) lg.draw( terr.img, 0, 0, 0, scale, scale ) end --dilate placeable land area by 45 degrees (sub launch radius) dilateShader:send( "radius", math.floor( 512 * 45 / 360 ) ) for name, terr in pairs( map.territory ) do y( statusString:format( filename, "sub", name, tile, #tiles ), tiles[tile] ) lg.setColor( 0.9 + terr.colour[1], 0.9 + terr.colour[2], 0.9 + terr.colour[3], 1 / 12 ) lg.draw( terr.img, 0, 0, 0, scale, scale ) end end lg.setCanvas( finalCanvas ) lg.setScissor() lg.setShader() lg.clear( 0, 0, 0, 1 ) lg.setColor( 1, 1, 1, 1 ) lg.draw( canvas ) lg.pop( "all" ) coroutine.yield( ("%s: encoding image data"):format( filename )) return bmp.blur( finalCanvas:newImageData() ) end local t = {} function t:save( ) return renderRadar( self.map, self.filename ) end function t.load( filename, map ) t.filename = filename t.map = map return t end function t.draw() lg.setScissor() return lg.draw( canvas ) end return t