diff --git a/README.md b/README.md index f3ea317..0d7427a 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,15 @@ Installation Needs luafilesystem, utf8, and luaffi. -luasocket is required for the Internet Component. +luasocket is optional but is required for the Internet Component and higher precision timing. luasec is optional but is required for HTTPS. ``` luarocks-5.2 install luafilesystem luarocks-5.2 install utf8 +luarocks-5.2 install luasocket +luarocks-5.2 install luasec git clone https://github.com/gamax92/luaffi.git cd luaffi make diff --git a/src/component/computer.lua b/src/component/computer.lua index 41d996c..68083f8 100644 --- a/src/component/computer.lua +++ b/src/component/computer.lua @@ -9,13 +9,15 @@ end function obj.beep(frequency, duration) -- Plays a tone, useful to alert users via audible feedback. --STUB cprint("computer.beep", frequency, duration) - compCheckArg(1,frequency,"number","nil") - compCheckArg(2,duration,"number","nil") - frequency = frequency or 440 - duration = duration or 0.1 + if frequency == nil then frequency = 440 end + compCheckArg(1,frequency,"number") + frequency = math.floor(frequency) if frequency < 20 or frequency > 2000 then error("invalid frequency, must be in [20, 2000]",3) end + if duration == nil then duration = 0.1 end + compCheckArg(2,duration,"number") + --local durationInMilliseconds = math.max(50, math.min(5000, math.floor(duration * 1000))) end function obj.stop() -- Stops the computer. Returns true if the state changed. --STUB diff --git a/src/component/screen_sdl2.lua b/src/component/screen_sdl2.lua index cabdfb0..e6d402e 100644 --- a/src/component/screen_sdl2.lua +++ b/src/component/screen_sdl2.lua @@ -9,8 +9,8 @@ local bit = require("bit32") local SDL = elsa.SDL local width, height, tier = maxwidth, maxheight, maxtier -local scrfgc, scrfgp = 0xFFFFFF -local scrbgc, scrfgp = 0x000000 +local scrfgc, scrfgp, scrrfp = 0xFFFFFF +local scrbgc, scrfgp, scrrbp = 0x000000 local scrrfc, srcrbc = scrfgc, scrbgc local palcol = {} @@ -44,11 +44,11 @@ local function loadPalette() for i = 0,15 do palcol[i] = palcopy[i] end - if scrfgp then - scrrfc, scrfgc = palcol[scrfgp], palcol[scrfgp] + if scrrfp then + scrrfc, scrfgc = palcol[scrrfp], palcol[scrrfp] end - if scrbgp then - scrrbc, scrbgc = palcol[scrbgp], palcol[scrbgp] + if scrrbp then + scrrbc, scrbgc = palcol[scrrbp], palcol[scrrbp] end end if tier > 1 then @@ -216,12 +216,15 @@ local function searchPalette(value) return index, score end -local function getColor(value, sel) +local function selectPal(pi, sel) if sel then - scrfgp = nil + scrfgp = pi else - scrbgp = nil + scrbgp = pi end +end +local function getColor(value, sel) + selectPal(nil, sel) if tier == 3 then local pi,ps = searchPalette(value) local r,g,b = extract(value) @@ -233,24 +236,16 @@ local function getColor(value, sel) if defs < ps then return defc else - if sel then - scrfgp = pi - else - scrbgp = pi - end + selectPal(pi, sel) return palcol[pi] end elseif tier == 2 then local pi = searchPalette(value) - if sel then - scrfgp = pi - else - scrbgp = pi - end + selectPal(pi, sel) return palcol[pi] else if value > 0 then - return 0xFFFFFF -- TODO: Configuration color + return settings.monochromeColor else return 0 end @@ -313,35 +308,42 @@ end local cec = {} --- TODO: For (get/set)(Fore/Back)ground, they return what was passed in, rather than the current screen state function cec.getForeground() -- Get the current foreground color and whether it's from the palette or not. cprint("(cec) screen.getForeground") - if scrfgp then - return scrfgp, true + if scrrfp then + return scrrfp, true end - return scrrfc, scrfgp + return scrrfc, false end function cec.setForeground(value, palette) -- Sets the foreground color to the specified value. Optionally takes an explicit palette index. Returns the old value and if it was from the palette its palette index. cprint("(cec) screen.setForeground", value, palette) - local oldc, oldp = scrrfc, scrfgp + local oldc, oldp = scrrfc, scrrfp scrrfc = palette and palcol[value] or value - scrfgp = palette and value - scrfgc = palette and scrrfc or getColor(scrrfc,true) + scrrfp = palette and value + if palette then + scrfgc, scrfgp = scrrfc, scrrfp + else + scrfgc = getColor(scrrfc,true) + end return oldc, oldp end function cec.getBackground() -- Get the current background color and whether it's from the palette or not. cprint("(cec) screen.getBackground") - if scrbgp then - return scrbgp, true + if scrrbp then + return scrrbp, true end - return scrrbc, scrbgp + return scrrbc, false end function cec.setBackground(value, palette) -- Sets the background color to the specified value. Optionally takes an explicit palette index. Returns the old value and if it was from the palette its palette index. cprint("(cec) screen.setBackground", value, palette) - local oldc, oldp = scrrbc, scrbgp + local oldc, oldp = scrrbc, scrrbp scrrbc = palette and palcol[value] or value - scrbgp = palette and value - scrbgc = palette and scrrbc or getColor(scrrbc,false) + scrrbp = palette and value + if palette then + scrbgc, scrbgp = scrrbc, scrrbp + else + scrbgc = getColor(scrrbc,false) + end return oldc, oldp end function cec.getDepth() -- Returns the currently set color depth. @@ -354,9 +356,28 @@ function cec.setDepth(depth) -- Set the color depth. Returns the previous value. if tier > 1 then loadPalette() end - scrfgc = getColor(scrrfc,true) - scrfbc = getColor(scrrbc,false) - -- TODO: Lowering the depth recolors the entire screen + for y = 1,height do + for x = 1,width do + local oldfc,oldbc = screen.fg[y][x],screen.bg[y][x] + screen.fg[y][x] = getColor(screen.fg[y][x],true) + screen.fgp[y][x] = scrfgp + screen.bg[y][x] = getColor(screen.bg[y][x],false) + screen.bgp[y][x] = scrbgp + if screen.fg[y][x] ~= oldfc or screen.bg[y][x] ~= oldbc then + renderChar(utf8.byte(screen.txt[y][x]),(x-1)*8,(y-1)*16,screen.fg[y][x],screen.bg[y][x]) + end + end + end + if scrrfp and tier > 1 then + scrfgc = palcol[scrrfp] + else + scrfgc = getColor(scrrfc,true) + end + if scrrbp and tier > 1 then + scrbgc = palcol[scrrbp] + else + scrbgc = getColor(scrrbc,false) + end end function cec.maxDepth() -- Get the maximum supported color depth. cprint("(cec) screen.maxDepth") diff --git a/src/config.lua b/src/config.lua index 32c955e..85cc515 100644 --- a/src/config.lua +++ b/src/config.lua @@ -2,6 +2,8 @@ local _config local comments = { [1]="OCEmu configuration. Designed to mimic HOCON syntax, but is not exactly HOCON syntax.", +["client"]="Client side settings, presentation and performance related stuff.", +["client.monochromeColor"]="The color of monochrome text (i.e. displayed when in 1-bit color depth, e.g. tier one screens / GPUs, or higher tier set to 1-bit color depth). Defaults to white, feel free to make it some other color, tho!", ["computer"]="Computer related settings, concerns server performance and security.", ["computer.lua"]="Settings specific to the Lua architecture.", ["computer.lua.allowBytecode"]="Whether to allow loading precompiled bytecode via Lua's `load` function, or related functions (`loadfile`, `dofile`). Enable this only if you absolutely trust all users on your server and all Lua code you run. This can be a MASSIVE SECURITY RISK, since precompiled code can easily be used for exploits, running arbitrary code on the real server! I cannot stress this enough: only enable this is you know what you're doing.", diff --git a/src/settings.lua b/src/settings.lua index 39bbc17..eb5ac3c 100644 --- a/src/settings.lua +++ b/src/settings.lua @@ -1,4 +1,6 @@ settings = { + monochromeColor = tonumber(config.get("client.monochromeColor", "0xFFFFFF")), + allowBytecode = config.get("computer.lua.allowBytecode",false), timeout = config.get("computer.timeout",5), @@ -11,3 +13,8 @@ settings = { maxNetworkPacketSize = config.get("misc.maxNetworkPacketSize",8192), maxWirelessRange = config.get("misc.maxWirelessRange",400), } + +if settings.monochromeColor == nil then + settings.monochromeColor = 0xFFFFFF + config.set("client.monochromeColor", "0xFFFFFF") +end