diff --git a/conf.lua b/conf.lua index c822011..88ba4d4 100644 --- a/conf.lua +++ b/conf.lua @@ -11,7 +11,7 @@ function love.conf(t) t.audio.mixwithsystem = true -- Keep background music playing when opening LOVE (boolean, iOS and Android only) t.window.title = "ᐊᑯᓕᕕᒃ" -- The window title (string) - t.window.icon = nil -- Filepath to an image to use as the window's icon (string) + t.window.icon = "tex/favicon.png" -- Filepath to an image to use as the window's icon (string) t.window.width = 800 -- The window width (number) t.window.height = 600 -- The window height (number) t.window.borderless = false -- Remove all border visuals from the window (boolean) @@ -36,16 +36,16 @@ function love.conf(t) t.modules.font = true -- Enable the font module (boolean) t.modules.graphics = true -- Enable the graphics module (boolean) t.modules.image = true -- Enable the image module (boolean) - t.modules.joystick = true -- Enable the joystick module (boolean) + t.modules.joystick = false -- Enable the joystick module (boolean) t.modules.keyboard = true -- Enable the keyboard module (boolean) t.modules.math = true -- Enable the math module (boolean) t.modules.mouse = true -- Enable the mouse module (boolean) - t.modules.physics = true -- Enable the physics module (boolean) + t.modules.physics = false -- Enable the physics module (boolean) t.modules.sound = true -- Enable the sound module (boolean) t.modules.system = true -- Enable the system module (boolean) t.modules.thread = true -- Enable the thread module (boolean) t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update - t.modules.touch = true -- Enable the touch module (boolean) - t.modules.video = true -- Enable the video module (boolean) + t.modules.touch = false -- Enable the touch module (boolean) + t.modules.video = false -- Enable the video module (boolean) t.modules.window = true -- Enable the window module (boolean) end \ No newline at end of file diff --git a/gpu.lua b/gpu.lua index e69de29..9b6a720 100644 --- a/gpu.lua +++ b/gpu.lua @@ -0,0 +1,11 @@ +local love = assert( love ) + +local canvas = love.graphics.getCanvasFormats( true ) +local limits = love.graphics.getSystemLimits() +local feature= love.graphics.getSupported() + +--[[for k, v in pairs( canvas ) do print( "canvas:", k, v ) end +for k, v in pairs( limits ) do print( "limits:", k, v ) end +for k, v in pairs( feature) do print( "feature", k, v ) end +io.flush()]] +return canvas \ No newline at end of file diff --git a/i18n.lua b/i18n.lua index 01d474a..50dffac 100644 --- a/i18n.lua +++ b/i18n.lua @@ -1,15 +1,29 @@ local t = {} +local love = love + +t._languages = { + "en", + "test", +} + +t._fonts = { + default = love.graphics.newFont( 18 ) +} local fallbackString = function( t, s ) - return "!UNLOCALISED STRING!: "..tostring( s ) + return "!:"..tostring( s ) end -function t.setLanguage( name ) - name = name or "en" +function t._setLanguage( name ) + local lang = name or "en" + local strings = require( "i18n."..lang ) + local fontName = rawget( strings, "_font" ) or "default" setmetatable( t, {__index = - setmetatable( require( "i18n."..name ), {__index = - fallbackString } ) } ) + setmetatable( strings, {__index = + fallbackString } ) } ) + if t._fonts[fontName] then love.graphics.setFont( t._fonts[fontName], 22 ) + else t._fonts[fontName] = love.graphics.setNewFont( fontName, 22 ) end return t end -return t.setLanguage( "en" ) \ No newline at end of file +return t._setLanguage( "en" ) \ No newline at end of file diff --git a/i18n/en.lua b/i18n/en.lua index e9405fc..10cfec7 100644 --- a/i18n/en.lua +++ b/i18n/en.lua @@ -1,23 +1,26 @@ return { title = "ᐊᑯᓕᕕᒃ", - font = "fonts/bjcrus.ttf", + _font = "fonts/bjcrus.ttf", intro = [[ᐊᑯᓕᕕᒃ, 1968 BROTHER JARED HAS BROUGHT THE ROCK OF THE JUDGEMENT, HIS BELOVED FLOCK, TO THE REMAINS OF A REMOTE TRADING POST BEYOND DARKEST THULE. -HERE WE WILL ATTEMPT TO CONJURE ZIMINIAR, THE KING OF THE NORTH. +HERE WE WILL CONJURE ZIMINIAR, THE KING OF THE NORTH. I HAVE VOLUNTEERED TO BE THE FIRST TO ATTEMPT THE RITUAL, THAT I MIGHT BE CROWNED, AMID THE CHAOS LOOSED UPON THE WORLD, JARED'S FOREMOST AND ETERNAL WIFE.]], - loss = "YOU HAVE DIED OF %s", - win = "RICHES TO THE CONJURER", - settingsMenuTitle = "SETTINGS", + loss = "YOU HAVE DIED OF %s", + win = "RICHES TO THE CONJURER", + settingsMenuTitle = "SETTINGS", settingsMenuBackspace = [[ESCAPE TO CANCEL ENTER TO KEEP]], - settingsMenuScroll = "SCROLL TO CHANGE SETTING", - toContinue = "PRESS ENTER TO CONTINUE", - keyForward = "FORWARD", - keyBack = "BACK", - keyLeft = "LEFT", - keyRight = "RIGHT", - mouseSensitivity = "TURN SPEED", + settingsMenuScroll = "SCROLL TO CHANGE SETTING", + toContinue = "PRESS ENTER TO CONTINUE", + keyForward = "FORWARD", + keyBack = "BACK", + keyLeft = "LEFT", + keyRight = "RIGHT", + keyUse = "USE", + mouseSensitivity = "TURN SPEED", + language = "LANGUAGE", + FOV = "FOV", } \ No newline at end of file diff --git a/i18n/test.lua b/i18n/test.lua new file mode 100644 index 0000000..be673ea --- /dev/null +++ b/i18n/test.lua @@ -0,0 +1,3 @@ +return { + title = "test", +} \ No newline at end of file diff --git a/main.lua b/main.lua index 4f39981..7b3713e 100644 --- a/main.lua +++ b/main.lua @@ -3,6 +3,4 @@ local scene = require( "scene" ) local strings = require( "i18n" ) local slideshow = require( "scenes.slideshow" ) local settings = require( "scenes.settings" ) - -love.graphics.setNewFont( strings.font, 20 ) -return slideshow.play( strings.intro, function() return scene.load( settings ) end ) \ No newline at end of file +return scene.load( settings ) \ No newline at end of file diff --git a/mat4.lua b/mat4.lua index b6a2c27..bca1e3f 100644 --- a/mat4.lua +++ b/mat4.lua @@ -1,34 +1,12 @@ --column major! local love = assert( love ) - -local ffi = require('ffi') -ffi.cdef[[ typedef struct{ float m[4][4]; } mat4_t ]] -local ctype = ffi.typeof( "mat4_t*" ) +local math = math local t = {} ---this is actually the argument we need to send to shader:send ---and to newMesh -local data = love.data.newByteData( ffi.sizeof( "mat4_t" ) * 1024 ) -t.data = data -local ptr = data:getFFIPointer() -print( "size", data:getSize() ) -function t.__tostring( idx ) - assert( idx < 1024 ) - local ptr = ffi.cast( ctype, data:getFFIPointer() ) - local m = ptr[ idx ].m - return ([[ - %.2f %.2f %.2f %.2f - %.2f %.2f %.2f %.2f - %.2f %.2f %.2f %.2f - %.2f %.2f %.2f %.2f - ]]):format( - m[0][0], m[1][0], m[2][0], m[3][0], - m[0][1], m[1][1], m[2][1], m[3][1], - m[0][2], m[1][2], m[2][2], m[3][2], - m[0][3], m[1][3], m[2][3], m[3][3]) -end - -function t.lTRS( x, y, z, a, b, g, dx, dy, dz ) +--scale +--rotate +--translate +function t.TRS( x, y, z, a, b, g, dx, dy, dz ) local c, s = math.cos, math.sin local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) return { @@ -38,6 +16,47 @@ function t.lTRS( x, y, z, a, b, g, dx, dy, dz ) {dx, dy, dz, 1}} end +--position of camera x y z +--yaw a +--pitch b +function t.view( x, y, z, a, b ) + local c, s = math.cos, math.sin + local ca, cb, sa, sb = c(a), c(b), s(a), s(b) + return t.__mul( + { + {1, 0, 0, 0}, + {0, cb, sb, 0}, + {0,-sb, cb, 0}, + {0, 0, 0, 1}, + }, + t.__mul( + { + {ca, 0,-sa, 0}, + {0, 1, 0, 0}, + {sa, 0, ca, 0}, + {0, 0, 0, 1}, + }, + { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {-x, -y, z, 1} + })) +end + +function t.projection(n, f, fov) + local r = love.graphics.getWidth() / 2 + local t = love.graphics.getHeight() / 2 + local aspect = r/t + local a = 1.0 / math.tan( fov / 2 ) + return + { {a, 0, 0, 0}, + {0,-a, 0, 0}, + {0, 0, (f+n)/(n-f), -1}, + {0, 0, 2*f*n/(n-f), 0}, + } +end + function t.transpose( A ) for i = 1, 4 do for j = 1, 4 do @@ -46,96 +65,34 @@ function t.transpose( A ) end end -function t.TRS( idx, x, y, z, a, b, g, dx, dy, dz ) - assert( idx < 1024 ) - local ptr = ffi.cast( ctype, data:getFFIPointer() ) - local m = ptr[ idx ].m - - local c, s = math.cos, math.sin - local ca, sa, cb, sb, cg, sg = c(a), s(a), c(b), s(b), c(g), s(g) - m[0][0], m[0][1], m[0][2], m[0][3], - m[1][0], m[1][1], m[1][2], m[1][3], - m[2][0], m[2][1], m[2][2], m[2][3], - m[3][0], m[3][1], m[3][2], m[3][3] = - - x*ca*cb, x*(ca*sb*sg - sa*cg), x*(ca*sb*cg+sa*sg), dx, - y*sa*cb, y*(sa*sb*sg+ca*cg), y*(sa*sb*cg-ca*sg), dy, - z*(-sb), z*(cb*sg), z*cb*cg, dz, - 0, 0, 0, 1 - - - do local p, m = ptr, m end --keep alive - return idx -end function t.__mul( A, B ) - local C = ffi.gc(cmat4(),nil) + local C = {{},{},{},{}} for j = 1, 4 do for i = 1, 4 do - C.x[j][i] = - A.x[1][i] * B.x[j][1] + - A.x[2][i] * B.x[j][2] + - A.x[3][i] * B.x[j][3] + - A.x[4][i] * B.x[j][4] + C[j][i] = + A[1][i] * B[j][1] + + A[2][i] * B[j][2] + + A[3][i] * B[j][3] + + A[4][i] * B[j][4] end end return C end function t.__add( A, B ) - local C = cmat4() + local C = {} for i = 1, 4 do for j = 1, 4 do - C[i][j] = A.x[i][j] + B.x[i][j] + C[i][j] = A[i][j] + B[i][j] end end return C end -function t.randomise( start, len ) - start = start or 0 - len = len or 1023 - for i = start, start + len do - t.TRS( i, - --scale - 1, - 1, - 1, - 0, - 0, - 0, - --pos - 0, - 0, - -4 ) - end -end function t.id() - local ptr = ffi.cast( ctype, data:getFFIPointer() ) - for i = 1, 1024 do - local m = ptr[ i ].m - - m[0][0], m[1][1], m[2][2], m[3][3] = 1, 1, 1, 1 - - do local p, m = ptr, m end --keep alive - end -end - -do --tests - local math = math - --[[ for i = 0, 1023 do - t.TRS( i, - 0.5 + math.random(), - 0.5 + math.random(), - 0.5 + math.random(), - 2 * math.pi * math.random(), - 2 * math.pi * math.random(), - 2 * math.pi * math.random(), - 10 * math.random(), - 10 * math.random(), - 10 * math.random() ) - end]] + return {{ 1, 0, 0, 0 },{ 0, 1, 0, 0 },{0, 0, 1, 0},{0, 0, 0, 1}} end return t \ No newline at end of file diff --git a/models/bell.lua b/models/bell.lua new file mode 100644 index 0000000..e69de29 diff --git a/models/building.lua b/models/building.lua new file mode 100644 index 0000000..e69de29 diff --git a/models/plane.lua b/models/plane.lua new file mode 100644 index 0000000..7fa746c --- /dev/null +++ b/models/plane.lua @@ -0,0 +1,25 @@ +local lg = love.graphics + +return lg.newMesh( + {--attributes + {"VertexPosition", "float", 4}, + {"VertexColor", "float", 3}, + {"VertexTexCoord", "float", 2}, + }, + {--vertices + {-25, 0, -25, 1, + 1, 1, 1, + 0, 0, }, + {25, 0, -25, 1, + 1, 1, 1, + 25, 0, }, + {25, 0, 25, 1, + 1, 1, 1, + 25, 25, }, + { -25, 1, 25, 1, + 1, 1, 1, + 0, 25, }, + }, + "fan", + "static" +) diff --git a/models/sky.lua b/models/sky.lua new file mode 100644 index 0000000..d563ad2 --- /dev/null +++ b/models/sky.lua @@ -0,0 +1,17 @@ +local lg = love.graphics +local mesh = lg.newMesh( + {{ "VertexPosition", 3}}, + { + {-1,-1,9-1}, + {-1,-1,1}, + {-1,1,-1}, + {-1,1,1}, + {1,-1,-1}, + {1,-1,1}, + {1,1,-1}, + {1,1,1} + }, + "strip", + "static") +mesh:setVertexMap{ 4,3,7,8,5,3,1,4,2,7,6,5,2,1 } +return mesh \ No newline at end of file diff --git a/models/spike.lua b/models/spike.lua new file mode 100644 index 0000000..9ec176b --- /dev/null +++ b/models/spike.lua @@ -0,0 +1,23 @@ +local lg = assert( love.graphics ) +local math = math + +local vertices = {{0, 1, 0, 1/2, 3}} + +local c, s = math.cos( math.pi / 8 ), math.sin( math.pi / 8 ) +local x, z = 1, 0 +for i = 1, 17 do + local u, v = i / 17, 1 - i / 17 + vertices[ i + 1 ] = { x, 0, z, u, 0} + x, z = c*x+s*z, c*z-s*x +end + +local mesh = lg.newMesh( + {--attributes + {"VertexPosition", "float", 3}, + {"VertexTexCoord", "float", 2}, + }, + vertices, + "fan", + "static" +) +return mesh \ No newline at end of file diff --git a/models/terrain.lua b/models/terrain.lua new file mode 100644 index 0000000..6573bb0 --- /dev/null +++ b/models/terrain.lua @@ -0,0 +1,26 @@ +local lg = assert( love.graphics ) +local mesh = lg.newMesh( + {--attributes + {"VertexPosition", "float", 3}, + {"VertexColor", "float", 3}, + {"VertexTexCoord", "float", 2}, + }, + {--vertices + { 1, 0, -a, + 1, 1, 1, + 1, 0 }, + { -1, 0, -a, + 1, 0, 0, + 0, 0 }, + { 0, 1, a, + 0, 1, 0, + 1, 1, }, + { 0, -1, a, + 0, 0, 1, + 0, 1, }, + }, + "strip", + "static" +) +mesh:setVertexMap{ 1,2,3,4,1,2 } +return mesh \ No newline at end of file diff --git a/player.lua b/player.lua index 54fd218..28e6fef 100644 --- a/player.lua +++ b/player.lua @@ -1,21 +1,82 @@ +--camera and character controller +local math = assert( math ) +local mat = require( "mat4" ) + +local function logistic( x ) + return 1.0 / ( 1.0 + math.exp( x ) ) +end + local player = { + turnRate = 0, + rate = 0.01, x = 0, - y = 0, + y = 0.5, z = 0, vx = 0, - vy = 0, + vz = 0, yaw = 0, pitch = 0, desx = 0, - desy = 0, + desz = 0, + view = mat.id(), + proj = mat.id(), } -function player.updateDesiredDirection( x, y ) - +function player:updateDesiredDirection( forward, left, right, back ) + local x = (right and 1 or 0) - (left and 1 or 0) + local z = (forward and 1 or 0) - (back and 1 or 0) + local c, s = math.cos( self.yaw ), math.sin( self.yaw ) + local n = math.sqrt( x * x + z * z ) + if n < 0.0001 then n = 1.0 end + x, z = x / n, z / n + self.desx, self.desz = x * c + z * s, -x * s + z * c end -function player.update( dt ) +function player:setFOV( fov ) + self.proj = mat.projection( 0.05, 100, math.rad( fov or 90 ) ) +end + +function player:setTurnRate( sensitivity ) + self.turnRate = 0.001 * logistic( sensitivity ) +end + +function player:turn( dx, dy ) + self.yaw = self.yaw + dx * self.turnRate + self.pitch = self.pitch + dy * self.turnRate +end + +function player:update() + self.vx = self.desx + self.vz = self.desz + self.x = self.x + self.vx * self.rate + self.z = self.z + self.vz * self.rate + + self.view = mat.view( self.x, self.y, self.z, self.yaw, self.pitch ) +end + +function player:tostring() + return ([[ + x: %3.2f + y: %3.2f + z: %3.2f + vx: %3.2f + vz: %3.2f + yaw: %3.2f + pitch:%3.2f + desx: %3.2f + desz: %3.2f + ]]):format( + player.x, + player.y, + player.z, + player.vx, + player.vz, + player.yaw, + player.pitch, + player.desx, + player.desz + ) end return player \ No newline at end of file diff --git a/renderer.lua b/renderer.lua new file mode 100644 index 0000000..2510b4e --- /dev/null +++ b/renderer.lua @@ -0,0 +1,76 @@ +local love = love +local gpu = require( "gpu" ) +local t = {} + +local canvas +local shaders = { + matte = require( "shaders.matte" ), +} + +local meshes = {} +local drawLists = {} +local isDebugging = false +local tf = love.math.newTransform() +local debugTF = love.math.newTransform() + +for k in pairs( shaders ) do drawLists[k] = {} end + +function t.start() + canvas = { + love.graphics.newCanvas(), + stencil = false, + depth = true, + } +end + +function t.debug() + isDebugging = true +end + +function t.draw( view, proj ) + + if isDebugging then + end + + love.graphics.setScissor( 0, 0, love.graphics.getDimensions() ) + love.graphics.setColor( 1, 1, 1, 1 ) + love.graphics.push( "all" ) + love.graphics.setCanvas( canvas ) + love.graphics.clear() + love.graphics.setDepthMode( "less", true ) + + for name, shader in pairs( shaders ) do + love.graphics.setShader( shader ) + shader:send( "view", "column", view ) + shader:send( "proj", "column", proj ) + + for mesh in pairs( drawLists[ name ] ) do + local modelMatrix = meshes[ mesh ] + tf:setMatrix( "column", modelMatrix ) + love.graphics.draw( mesh ) + end + end + + love.graphics.setCanvas() + love.graphics.setDepthMode( "always", false ) + love.graphics.setShader() + love.graphics.draw( canvas[1] ) + love.graphics.pop() + + if isDebugging then + isDebugging = false + io.flush() + end +end + +function t.update( mesh, modelMatrix ) + meshes[mesh] = modelMatrix +end + +function t.add( mesh, shaderName ) + shaderName = shaderName or "matte" + meshes[mesh] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, {0, 0, 1, 0}, {0, 0, 0, 1} } + drawLists[shaderName][mesh] = true +end + +return t \ No newline at end of file diff --git a/scenes/main.lua b/scenes/main.lua index 7e464ae..52d64e6 100644 --- a/scenes/main.lua +++ b/scenes/main.lua @@ -1,31 +1,94 @@ local love = assert( love ) local player = require( "player" ) local settings = require( "settings" ) +local renderer = require( "renderer" ) +local world = require( "scenes.world" ) +local mat = require( "mat4" ) local t = {} +local frameStart = love.timer.getTime() + +local rockTexture = love.graphics.newImage( "tex/rock.png", { mipmaps = true } ) +rockTexture:setWrap( "repeat", "repeat" ) function t.play() + love.graphics.setNewFont( 14 ) + t.mousepressed() --grab window + player:setTurnRate( settings.mouseSensitivity.val ) + player:setFOV( settings.FOV.val ) + renderer.start() +--[[ local terrain = require( "models/terrain" ) + terrain:setTexture( rockTexture ) + renderer.add( terrain ) + renderer.update( terrain, {{1, 0, 0, 0}, {0,1,0,0},{0,0,1,0},{0,0,-3,1}})]] + + local plane = require( "models/plane" ) + plane:setTexture( rockTexture ) + renderer.add( plane ) + + local spike = require( "models/spike" ) + spike:setTexture( rockTexture ) + renderer.add( spike ) + renderer.update( spike, mat.TRS( 0.3, 12, 0.3, 0, 0, 0, 4, 0, 3) ) local scene = require( "scene" ) return scene.load( t ) end function t.draw() - love.graphics.setScissor( ) + --[[love.graphics.setScissor( ) love.graphics.push( "transform" ) - love.graphics.scale( love.graphics.getWidth(), love.graphics.getHeight() ) - love.graphics.rectangle( "fill", player.x, player.y, 6, 6 ) - love.graphics.pop() + love.graphics.scale( love.graphics.getWidth(), -love.graphics.getHeight() ) + love.graphics.translate( 0, -1 ) + love.graphics.translate( player.x, player.y ) + love.graphics.rotate( player.yaw ) + love.graphics.scale( w, h ) + love.graphics.draw( playerMesh ) + love.graphics.pop()]] + + renderer.draw( player.view, player.proj ) + + local y = 0 + for k, v in pairs(love.graphics.getStats()) do + love.graphics.print( k, 0, y ) + love.graphics.print( v, 200, y ) + y = y + 16 + end + + love.graphics.print( player:tostring(), 0, y ) end + +local updateTimeRemaining = 0 function t.update( dt ) + if not love.mouse.getRelativeMode() then return end + + player:updateDesiredDirection( + love.keyboard.isScancodeDown( settings.keyForward.val ), + love.keyboard.isScancodeDown( settings.keyLeft.val ), + love.keyboard.isScancodeDown( settings.keyRight.val ), + love.keyboard.isScancodeDown( settings.keyBack.val ) + ) + + updateTimeRemaining = updateTimeRemaining + dt + while updateTimeRemaining >= player.rate do + updateTimeRemaining = updateTimeRemaining - player.rate + player:update() + end end function t.mousepressed( x, y, button, isTouch, presses ) - + love.mouse.setRelativeMode( true ) + love.mouse.setVisible( false ) end function t.keypressed( key, code, isrepeat ) - + if code == "escape" then + love.mouse.setRelativeMode( false ) + love.mouse.setVisible( true ) + end + if code == settings.keyUse.val then + + end end function t.keyreleased( key, code ) @@ -33,7 +96,8 @@ function t.keyreleased( key, code ) end function t.mousemoved( x, y, dx, dy, isTouch ) - + if not love.mouse.getRelativeMode() then return end + player:turn( dx, dy ) end return t \ No newline at end of file diff --git a/scenes/settings.lua b/scenes/settings.lua index a556c09..76b7a2e 100644 --- a/scenes/settings.lua +++ b/scenes/settings.lua @@ -7,13 +7,25 @@ local currentSetting = false local mouseOverSetting = false local cachedSettingVal = nil local menu = {} +local time = 0 for i, setting in ipairs( settings ) do menu[i] = { x = 410, y = 10 + i * 25, w = love.graphics.getWidth() - 410 , h = 25 } end +local terrain = love.graphics.newMesh( { + { 0, 0, 0, 0, 1, 0.8, 0.8, 0.5, }, + { 0, 1, 0, 0.1, 1, 0.8, 0.8, 0.5, }, + { 1, 1, 0.1, 0.1, 0, 0, 0, 0.01, }, + { 1, 0, 0.1, 0, 0, 0, 0, 0.01, }, + }) + local function restoreCachedSetting() if (not currentSetting) or (cachedSettingVal == nil) then return end + if settings[currentSetting].set then + settings[currentSetting]:set(cachedSettingVal) + else settings[currentSetting].val = cachedSettingVal + end cachedSettingVal = nil end @@ -31,8 +43,9 @@ function t.keypressed( key, code, isRepeat ) end if code == "return" then + local slideshow = require( "scenes.slideshow" ) local main = require( "scenes.main" ) - return main.play() + return slideshow.play( strings.intro, main.play ) end end @@ -44,6 +57,22 @@ function t.wheelmoved(x, y) elseif y < 0 then setting.val = setting.val - 1 end end + if setting.type == "list" then + local list = setting.list + local inc + local next + if y > 0 then + inc = 1 + next = 1 + elseif y < 0 then + inc = -1 + next = #list + end + local idx = setting.idx + inc + if not list[idx] then idx = next end + setting.idx = idx + setting:set( idx ) + end end function t.mousemoved( x, y ) @@ -67,18 +96,37 @@ function t.mousepressed( x, y ) y <= button.y + button.h then restoreCachedSetting() currentSetting = i - cachedSettingVal = settings[i].val + if settings[i].get then cachedSettingVal = settings[i]:get() + else cachedSettingVal = settings[i].val end mouseOverSetting = false end end end -function t.update() - +function t.update( dt ) + time = time + dt + for i = 1, terrain:getVertexCount() do + --2: UV coordinate + local x, y = terrain:getVertexAttribute( i, 1 ) + x = ( x > 0 ) and 0.5 or 0 + y = ( y > 0 ) and 0.5 or 0 + terrain:setVertexAttribute( i, 2, x - 0.04 * time, y - 0.05 * time ) + end end function t.draw() + love.graphics.setScissor( 0, 0, 400, love.graphics.getHeight() ) + + if not terrain:getTexture() then + local tex = love.graphics.newImage( "tex/terrain.png" ) + tex:setFilter( "nearest", "nearest" ) + tex:setWrap( "repeat", "repeat" ) + terrain:setTexture( tex ) + end + + love.graphics.draw( terrain, 0, 0, 0, 400, love.graphics.getHeight() ) + love.graphics.setScissor( 400, 0, love.graphics.getWidth() - 400, love.graphics.getHeight() ) love.graphics.setColor( 1, 0.1, 0.1, 0.2 ) @@ -104,7 +152,7 @@ function t.draw() for i, setting in ipairs( settings ) do local x, y = menu[i].x, menu[i].y --love.graphics.rectangle( "line", x, y, love.graphics.getWidth() / 2, 25 ) - love.graphics.print( setting.name, x + 10, y ) + love.graphics.print( strings[setting.setting], x + 10, y ) love.graphics.print( setting.val, x + 250, y ) end diff --git a/scenes/slideshow.lua b/scenes/slideshow.lua index 7361db3..5b95562 100644 --- a/scenes/slideshow.lua +++ b/scenes/slideshow.lua @@ -12,19 +12,33 @@ local t = {} local len = 0 local time = 0 +local function noop() end +t.mousemoved = noop +t.mousepressed = noop +t.wheelmoved = noop function t.keypressed( key, code, isRepeat ) - if code == "return" then return loadNextScene() end + if code == "return" then + if printString ~= fullString then + printString = fullString + return + else + return loadNextScene() + end + end end function t.draw() + --love.graphics.setScissor( 0, 0, 400, love.graphics.getHeight() ) + love.graphics.setColor( 1, 0.2, 0.2 ) love.graphics.printf( printString, 10, 10, math.min( 400, love.graphics.getWidth() / 2 ), "left" ) love.graphics.print( strings.toContinue, 10, love.graphics.getHeight() - love.graphics.getFont():getHeight() ) end function t.update( dt ) + if printString == fullString then return end time = time + dt - if time > 0.03 then + if time > 0.08 then time = 0 len = len + 1 printString = fullString:sub( 1, ( utf8.offset( fullString, len ) or 0 ) - 1 ) @@ -35,6 +49,8 @@ function t.play( str, nextScene ) loadNextScene = nextScene fullString = str printString = "" + love.graphics.setScissor() + love.graphics.clear( ) return scene.load( t ) end diff --git a/scenes/world.lua b/scenes/world.lua new file mode 100644 index 0000000..666fc53 --- /dev/null +++ b/scenes/world.lua @@ -0,0 +1,2 @@ +local renderer = require( "renderer" ) + diff --git a/settings.lua b/settings.lua index 658db5a..2541519 100644 --- a/settings.lua +++ b/settings.lua @@ -1,12 +1,33 @@ local strings = require( "i18n" ) local settings = { - { setting = "keyForward", type = "keybind", name = strings.keyForward, val = "w" }, - { setting = "keyBack", type = "keybind", name = strings.keyBack, val = "s" }, - { setting = "keyLeft", type = "keybind", name = strings.keyLeft, val = "a" }, - { setting = "keyRight", type = "keybind", name = strings.keyRight, val = "d" }, + { setting = "keyForward", type = "keybind", val = "w" }, + { setting = "keyBack", type = "keybind", val = "s" }, + { setting = "keyLeft", type = "keybind", val = "a" }, + { setting = "keyRight", type = "keybind", val = "d" }, + { setting = "keyUse", type = "keybind", val = "e" }, { setting = "mouseSensitivity", type = "number", - name = strings.mouseSensitivity, - val = 0 }, + val = -12 }, + { setting = "FOV", + type = "number", + val = 65 }, + { setting = "language", + type = "list", + list = strings._languages, + set = function(self, idx) + self.idx = idx + self.val = self.list[idx] + return strings._setLanguage( self.list[idx] ) + end, + get = function( self ) + return self.idx + end, + idx = 1, + val = "en" }, } + +for _, setting in ipairs( settings ) do + settings[setting.setting] = setting +end + return settings \ No newline at end of file diff --git a/shaders/matte.lua b/shaders/matte.lua new file mode 100644 index 0000000..63eae3e --- /dev/null +++ b/shaders/matte.lua @@ -0,0 +1,24 @@ +return love.graphics.newShader[[ + #define fog vec4( 0.85, 0.85, 1.0, 1.0 ) + #define fogHigh vec4( 1.0, 1.0, 0.85, 1.0 ) + varying float depth; + varying float height; +#ifdef VERTEX + uniform mat4 view; + uniform mat4 proj; + vec4 position( mat4 mdl, vec4 pos ){ + vec4 world = mdl * pos; + height = world.y; + vec4 eye = view * world; + depth = -eye.z; + return proj*eye; + } +#endif +#ifdef PIXEL + vec4 effect( vec4 color, Image tex, vec2 texuv, vec2 scruv) { + return mix( mix( color * Texel( tex, texuv ), fog, + clamp( depth / 20.0, 0.0, 1.0)), fogHigh, + clamp( height / 20.0, 0.0, 1.0)) ; + } +#endif +]] \ No newline at end of file diff --git a/shaders/sky.lua b/shaders/sky.lua new file mode 100644 index 0000000..43c1593 --- /dev/null +++ b/shaders/sky.lua @@ -0,0 +1,18 @@ +return love.graphics.newShader[[ +varying vec3 viewDir; +#ifdef VERTEX + uniform mat4 view; + uniform mat4 proj; + vec4 position( mat4 _, vec4 pos ){ + vec4 eye = view * pos; + viewDir = eye.xyz; + return proj*eye; + } +#endif +#ifdef PIXEL + uniform samplerCube cube; + vec4 effect( vec4 color, Image _, vec2 __, vec2 ___) { + return Texel( cube, viewDir ); + } +#endif +]] \ No newline at end of file diff --git a/tex/favicon.png b/tex/favicon.png new file mode 100644 index 0000000..3317108 Binary files /dev/null and b/tex/favicon.png differ diff --git a/tex/terrain.png b/tex/terrain.png new file mode 100644 index 0000000..29da69a Binary files /dev/null and b/tex/terrain.png differ