local logger = require("utils/logger") local lovehandler = require("utils/love_file_handler") local zip = require("utils/zip") local multi, thread = require("multi"):init({priority=true}) multi.setClock(require("socket").gettime) -- When on linux os.clock doesn't reture actual seconds the program has elapsed for local GLOBAL, THREAD = require("multi.integration.loveManager"):init() local fileHandler, logCtrl = lovehandler.new("logs/jeopardy.log", { max_size = 512 * 1024, -- rotate at 512 KB max_files = 3, buffered = false, -- write every line immediately (safest for games) }) lovehandler.auto_flush_on_quit(logCtrl) log = logger.new("jeopardy", { level = logger.LEVELS.INFO, handlers = { logger.handlers.ConsoleHandler({ colours = true }), fileHandler, }, }) local gui = require("gui") local color = require("gui.core.color") local title = require("menus.title") local menu = require("gui.core.menus") color.indexColor("bg","#2b348b") color.indexColor("tile_bg","#5459e4") color.indexColor("header_tile","#2a2e91") color.indexColor("status_font", "#e4b82a") color.indexColor("title_font","#b16d24") color.indexColor("question_bg","#363ac8") color.indexColor("tile_font","#ffffff") color.indexColor("header_font","#fef6eeda") color.indexColor("correct", "#52b11b") color.indexColor("skip", "#5d5d5d") color.indexColor("wrong", "#bd2626") color.indexColor("shaderColA","rgb01(0.10, 0.12, 0.38)") color.indexColor("shaderColB","rgb01(0.20, 0.22, 0.58)") color.indexColor("shaderColC","rgb01(0.55, 0.58, 0.78)") require("gui.addons") gui:setHotKey({"f11"})(function() fullscreen, fstype = love.window.getFullscreen() love.window.setFullscreen(not fullscreen, "desktop") end) local loadLog = log:child("load") local old = multi.error multi.error = function(self, err) loadLog:error("Error: %s", err) loadLog:error(debug.traceback()) love.quit() end function readFileData(path) return io.open(path,"r"):read("*a") end function love.load() -- local z = zip.new() -- z:add("main.lua",readFileData("main.lua")) -- z:add("package.bat",readFileData("package.bat")) -- local data = z:build() -- local file = io.open("test.zip","wb") -- file:write(data) -- file:close() loadLog:info("Starting Jeopardy Game") loadLog:debug("Setting game identity to jeopardy") for i,v in ipairs(color.listColors(showAllColors)) do loadLog:debug("Indexed color %s",v) end love.filesystem.setIdentity("jeopardy") loadLog:trace("Creating save directory") success = love.filesystem.createDirectory("") if not success then loadLog:fatal("Unable to create save directory") love.quit() end loadLog:trace("Creating save directory") gui:cacheImage({"assets/images/checked.png","assets/images/unchecked.png","assets/images/speaker.png"}) gui:setAspectSize(1920, 1080) gui.aspect_ratio = true loadLog:debug("Creating main background image") local bg = gui:newImageLabel("assets/images/background.png") bg:fullFrame() loadLog:debug("Init menu module") menu.init(bg) loadLog:debug("Displaying title menu") title:visible(true) end function love.update(dt) gui.update(dt) multi:uManager(dt) end function love.draw() gui.draw() end -- custom shaders gui.NewShader("background", [[ extern float time; extern vec2 size; extern vec3 colA; extern vec3 colB; extern vec3 colC; // Hash function (pseudo-random from 2D input) float hash(vec2 p) { p = fract(p * vec2(127.1, 311.7)); p += dot(p, p + 19.19); return fract(p.x * p.y); } // Smooth value noise float noise(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); // Quintic smoothstep vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0); float a = hash(i); float b = hash(i + vec2(1.0, 0.0)); float c = hash(i + vec2(0.0, 1.0)); float d = hash(i + vec2(1.0, 1.0)); return mix(mix(a, b, u.x), mix(c, d, u.x), u.y); } // Fractional Brownian Motion – layers of noise at different scales float fbm(vec2 p) { float value = 0.0; float amplitude = 0.5; float frequency = 1.0; for (int i = 0; i < 6; i++) { value += amplitude * noise(p * frequency); frequency *= 2.0; amplitude *= 0.5; } return value; } vec4 effect(vec4 color, Image tex, vec2 texCoord, vec2 screenCoord) { // Normalized UV with aspect ratio correction vec2 uv = screenCoord / size; // Slow, asymmetric time offsets per axis for lava-lamp feel float t1 = time * 0.008; float t2 = time * 0.005; // Domain-warped FBM: feed FBM output back into itself // This creates the bulging, self-folding blob shapes. vec2 q = vec2( fbm(uv + vec2(0.0, 0.0) + t1), fbm(uv + vec2(5.2, 1.3) + t2) ); vec2 r = vec2( fbm(uv + 4.0 * q + vec2(1.7, 9.2) + t1 * 0.7), fbm(uv + 4.0 * q + vec2(8.3, 2.8) + t2 * 0.9) ); float n = fbm(uv + 4.0 * r + t1 * 0.4); vec3 col = mix(colA, colB, clamp(n * 2.0, 0.0, 1.0)); col = mix(col, colC, clamp(n * 2.0 - 0.6, 0.0, 1.0)); return vec4(col, 1.0); } ]])