From 7cd8dc3197bfff8389786f71bde5b81e4012591c Mon Sep 17 00:00:00 2001 From: gamax92 Date: Sun, 21 Jun 2015 21:04:39 -0600 Subject: [PATCH] Descriptive Commit Name Here Add some more checks into component.connect Add component.disconnect Send signals component_added/removed when adding/removing components, except on boot Add some checks to eeprom component Add checks to filesystem component Add checks to gpu component Add checks to screen component Remove showWindow, causing issues in linux and doing nothing in windows Remove a useless renderchange calculation Fix internet.request for response codes 400 and above, oppm now works Add a ocemu component, which will be used to control the emulator from inside Add a basic configuration program, allowing to insert and delete components Add ocemu component to the list --- src/apis/component.lua | 25 ++++- src/component/eeprom.lua | 6 +- src/component/filesystem.lua | 4 +- src/component/gpu.lua | 5 +- src/component/internet.lua | 17 ++- src/component/ocemu.lua | 31 ++++++ src/component/screen_sdl2.lua | 8 +- src/customlua/ocemu/.autorun.lua | 29 +++++ src/customlua/ocemu/bin/cfgemu.lua | 169 +++++++++++++++++++++++++++++ src/main.lua | 1 + 10 files changed, 285 insertions(+), 10 deletions(-) create mode 100644 src/component/ocemu.lua create mode 100644 src/customlua/ocemu/.autorun.lua create mode 100644 src/customlua/ocemu/bin/cfgemu.lua diff --git a/src/apis/component.lua b/src/apis/component.lua index 8ebc8ee..2e6b070 100644 --- a/src/apis/component.lua +++ b/src/apis/component.lua @@ -27,18 +27,41 @@ function component.connect(...) math.randomseed(info[2]) address = gen_uuid() end + if proxylist[address] ~= nil then + return nil, "component already at address" + end info[2] = address local fn, err = elsa.filesystem.load("component/" .. info[1] .. ".lua") if not fn then - error(err,0) + return nil, err end local proxy, cec, doc = fn(table.unpack(info,2)) + if not proxy then + return nil, cec or "no component added" + end proxy.address = address proxy.type = proxy.type or info[1] proxylist[address] = proxy emuicc[address] = cec doclist[address] = doc slotlist[address] = info[3] + if boot_machine then + table.insert(machine.signals,{"component_added",address,proxy.type}) + end + return true +end +function component.disconnect(address) + checkArg(1,address,"string") + if proxylist[address] == nil then + return nil, "no component at address" + end + local thetype = proxylist[address].type + proxylist[address] = nil + emuicc[address] = nil + doclist[address] = nil + slotlist[address] = nil + table.insert(machine.signals,{"component_removed",address,thetype}) + return true end function component.exists(address) checkArg(1,address,"string") diff --git a/src/component/eeprom.lua b/src/component/eeprom.lua index 80cc4ab..47a684b 100644 --- a/src/component/eeprom.lua +++ b/src/component/eeprom.lua @@ -1,4 +1,8 @@ -local address, slot, filename = ... +local address, _, filename = ... +compCheckArg(1,filename,"string") +if not elsa.filesystem.exists(filename) then + error("no such file",3) +end local crc32 = require("support.crc32") diff --git a/src/component/filesystem.lua b/src/component/filesystem.lua index 38c0d81..f0e9693 100644 --- a/src/component/filesystem.lua +++ b/src/component/filesystem.lua @@ -1,4 +1,6 @@ -local address, slot, directory, readonly = ... +local address, _, directory, readonly = ... +compCheckArg(1,directory,"string","nil") +compCheckArg(2,readonly,"boolean") if directory == nil then directory = elsa.filesystem.getSaveDirectory() .. "/" .. address diff --git a/src/component/gpu.lua b/src/component/gpu.lua index 325d2ed..00ce2cc 100644 --- a/src/component/gpu.lua +++ b/src/component/gpu.lua @@ -1,4 +1,7 @@ -local address, slot, maxwidth, maxheight, maxtier = ... +local address, _, maxwidth, maxheight, maxtier = ... +compCheckArg(1,maxwidth,"number") +compCheckArg(2,maxheight,"number") +compCheckArg(3,maxtier,"number") local lua_utf8 = require("utf8") diff --git a/src/component/internet.lua b/src/component/internet.lua index b60a7b7..07eb9c7 100644 --- a/src/component/internet.lua +++ b/src/component/internet.lua @@ -3,7 +3,7 @@ local okay, socket = pcall(require, "socket") if not okay then cprint("Cannot use internet component: " .. socket) - return + return nil, "missing socket library" end require("support.http_patch") local url = require("socket.url") @@ -145,9 +145,18 @@ function obj.request(url, postData) -- Starts an HTTP request. If this returns t end end local procotol, code, message + local bad = false if status then protocol, code, message = status:match("(.-) (.-) (.*)") code = tonumber(code) + if code >= 400 then + bad = true + if code == 404 or code == 410 then + page = url + else + page = "Server returned HTTP response code: " .. code .. " for URL: " .. url + end + end end local closed = false local fakesocket = { @@ -160,6 +169,8 @@ function obj.request(url, postData) -- Starts an HTTP request. If this returns t return nil, "Connection refused" elseif page == "" then return nil + elseif bad then + return nil, page else -- Return up to 8192 bytes local data = page:sub(1,8192) @@ -169,7 +180,7 @@ function obj.request(url, postData) -- Starts an HTTP request. If this returns t end, response = function() cprint("(socket) response") - if headers == nil then + if headers == nil or bad then return nil end return code, message, headers @@ -185,6 +196,8 @@ function obj.request(url, postData) -- Starts an HTTP request. If this returns t return nil, "connection lost" elseif headers == nil then return nil, "Connection refused" + elseif bad then + return nil, page end return true end diff --git a/src/component/ocemu.lua b/src/component/ocemu.lua new file mode 100644 index 0000000..68c6eaf --- /dev/null +++ b/src/component/ocemu.lua @@ -0,0 +1,31 @@ +-- ocemu component + +component.connect("filesystem",gen_uuid(),nil,"customlua/ocemu",true) + +local obj = {} + +function obj.connect(kind, address, slot, ...) + cprint("screen.isTouchModeInverted") + compCheckArg(1,kind,"string") + compCheckArg(2,address,"string","number","nil") + compCheckArg(3,slot,"number","nil") + if address == nil then + if elsa.SDL then + math.randomseed(elsa.SDL.getTicks()) + else + math.randomseed(os.clock()*1000000) + end + address=gen_uuid() + end + return component.connect(kind, address, slot, ...) +end +function obj.disconnect(address) + checkArg(1,address,"string") + return component.disconnect(address) +end + +local cec = {} + +local doc = {} + +return obj,cec,doc diff --git a/src/component/screen_sdl2.lua b/src/component/screen_sdl2.lua index a51e075..ac7c06c 100644 --- a/src/component/screen_sdl2.lua +++ b/src/component/screen_sdl2.lua @@ -1,4 +1,7 @@ -local address, slot, maxwidth, maxheight, maxtier = ... +local address, _, maxwidth, maxheight, maxtier = ... +compCheckArg(1,maxwidth,"number") +compCheckArg(2,maxheight,"number") +compCheckArg(3,maxtier,"number") local ffi = require("ffi") local utf8 = require("utf8") @@ -106,8 +109,6 @@ SDL.renderFillRect(renderer, ffi.C.NULL) SDL.setRenderTarget(renderer, ffi.C.NULL); function elsa.draw() - -- TODO: This causes issues in linux, test if it's necessary in windows or not - SDL.showWindow(window) SDL.renderCopy(renderer, texture, ffi.C.NULL, ffi.C.NULL) SDL.renderPresent(renderer) end @@ -359,7 +360,6 @@ function cec.copy(x1, y1, w, h, tx, ty) -- Copies a portion of the screen from t end for y = math.max(math.min(y1+ty, height), 1), math.max(math.min(y2+ty, height), 1) do for x = math.max(math.min(x1+tx, width), 1), math.max(math.min(x2+tx, width), 1) do - local renderchange = screen.txt[y][x] ~= copy.txt[y-y1-ty][x-x1-tx] or screen.bg[y][x] ~= copy.bg[y-y1-ty][x-x1-tx] or (screen.txt[y][x] ~= " " and screen.fg[y][x] ~= copy.fg[y-y1-ty][x-x1-tx]) screen.txt[y][x] = copy.txt[y-y1-ty][x-x1-tx] screen.fg[y][x] = copy.fg[y-y1-ty][x-x1-tx] screen.bg[y][x] = copy.bg[y-y1-ty][x-x1-tx] diff --git a/src/customlua/ocemu/.autorun.lua b/src/customlua/ocemu/.autorun.lua new file mode 100644 index 0000000..8cbee59 --- /dev/null +++ b/src/customlua/ocemu/.autorun.lua @@ -0,0 +1,29 @@ +local event = require("event") +local fs = require("filesystem") +local process = require("process") + +local proxy = ... + +-- Install symlinks if they don't already exist. +local links = {} +local fsroot = fs.path(process.running()) +local function inject(path) + for file in fs.list(fs.concat(fsroot, path)) do + local source = fs.concat(fsroot, path, file) + local target = fs.concat(path, file) + if fs.link(source, target) then + table.insert(links, target) + end + end +end +inject("bin") + +-- Delete symlinks on removal. +event.listen("component_removed", function(_, address) + if address == proxy.address then + for _, link in ipairs(links) do + fs.remove(link) + end + return false -- remove listener + end +end) diff --git a/src/customlua/ocemu/bin/cfgemu.lua b/src/customlua/ocemu/bin/cfgemu.lua new file mode 100644 index 0000000..34ea8d1 --- /dev/null +++ b/src/customlua/ocemu/bin/cfgemu.lua @@ -0,0 +1,169 @@ +local component = require("component") +local kbd = require("keyboard") +local event = require("event") +local term = require("term") + +if not component.isAvailable("ocemu") then + io.stderr:write("This program requires OCEmu to run.") + return +end + +local ocemu = component.ocemu +local gpu = component.gpu +local keys = kbd.keys + +local gpuW,gpuH = gpu.getResolution() + +gpu.setForeground(0xFFFFFF) +gpu.setBackground(0x000000) + +local function setTitle(title) + gpu.set((gpuW-#title)/2,1,title) +end + +local function setStatus(status) + gpu.fill(1,gpuH,gpuW,1," ") + gpu.set((gpuW-#status)/2,gpuH,status) +end + +local function componentConfig() + setTitle("Component Configuration Utility") + local list = {} + for address, kind in component.list() do + list[#list+1] = {address, kind} + end + table.sort(list, function(a, b) return a[1] < b[1] end) + local listX = 1 + + local function drawList() + gpu.fill(1,3,gpuW,gpuH-3," ") + for i = 1,#list do + gpu.set(4,i+2,string.format("%s - %s",list[i][1],list[i][2])) + end + gpu.set(2,listX+2,"▶") + end + local function prompt(msg) + gpu.fill(1,gpuH-3,gpuW,1," ") + term.setCursor(1,gpuH-3) + io.stdout:write(msg) + return term.read(nil, false):gsub("[\r\n]","") + end + drawList() + + while true do + local evnt = table.pack(event.pull()) + if evnt[1] == "key_down" then + if evnt[4] == keys.up and listX > 1 then + gpu.set(2,listX+2," ") + listX = listX - 1 + gpu.set(2,listX+2,"▶") + elseif evnt[4] == keys.down and listX < #list then + gpu.set(2,listX+2," ") + listX = listX + 1 + gpu.set(2,listX+2,"▶") + elseif evnt[4] == keys.delete then + local ok, err = ocemu.disconnect(list[listX][1]) + if ok then + table.remove(list, listX) + listX = math.min(listX,#list) + drawList() + else + setStatus(err or "unknown error") + end + elseif evnt[4] == keys.insert then + setStatus("") + local kind = prompt("Component type: ") + local address = prompt("Component address: ") + local slot = prompt("Component slot: ") + local args = prompt("Component arguments: ") + + local bad = false + if kind == "" or kind == nil then + bad = true + setStatus("Invalid type") + end + if address == "" or address == nil then + address = nil + elseif tonumber(address) ~= nil then + address = tonumber(address) + elseif address ~= address:gsub("[^%x-]","") or address:match("........%-....%-4...%-[89abAB]...%-............") == nil then + bad = true + setStatus("Invalid address") + end + if slot == "" or slot == nil then + slot = nil + elseif tonumber(slot) ~= nil then + slot = tonumber(slot) + else + bad = true + setStatus("Invalid slot") + end + if not bad then + local fn, err = load("return " .. args,"=arguments","t",{}) + if not fn then + setStatus(err) + else + local args = table.pack(pcall(fn)) + if not args[1] then + setStatus(args[2]) + else + local rok, ok, err = pcall(ocemu.connect, kind, address, slot, table.unpack(args, 2)) + if not rok then + if ok:match("^.-:.-: .*") then + ok = ok:match("^.-:.-: (.*)") + end + setStatus(ok) + elseif not ok then + setStatus(err) + else + list = {} + for address, kind in component.list() do + list[#list+1] = {address, kind} + end + table.sort(list, function(a, b) return a[1] < b[1] end) + end + end + end + end + drawList() + elseif evnt[3] == string.byte("q") then + return + end + end + end +end + +local menu = { + {"Configure Components",componentConfig}, + {"Exit",os.exit} +} +local menuX = 1 + +local function drawMenu() + gpu.fill(1,1,gpuW,gpuH," ") + setTitle("OCEmu Setup Utility") + for i = 1,#menu do + gpu.set(4,i+2,menu[i][1]) + end + gpu.set(2,menuX+2,"▶") +end +drawMenu() + +while true do + local evnt = table.pack(event.pull()) + if evnt[1] == "key_down" then + if evnt[4] == keys.up and menuX > 1 then + gpu.set(2,menuX+2," ") + menuX = menuX - 1 + gpu.set(2,menuX+2,"▶") + elseif evnt[4] == keys.down and menuX < #menu then + gpu.set(2,menuX+2," ") + menuX = menuX + 1 + gpu.set(2,menuX+2,"▶") + elseif evnt[4] == keys.enter then + gpu.fill(1,1,gpuW,gpuH," ") + menu[menuX][2]() + drawMenu() + end + end +end diff --git a/src/main.lua b/src/main.lua index d50339a..dbc588d 100644 --- a/src/main.lua +++ b/src/main.lua @@ -30,6 +30,7 @@ conf = { {"filesystem",nil,5,nil,false}, {"internet"}, {"computer"}, + {"ocemu"}, } } if elsa.SDL then