2021-01-12 23:39:11 +11:00
-- Copyright (C) 2018-2021 by KittenOS NEO contributors
--
-- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
--
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
-- THIS SOFTWARE.
2018-05-30 23:07:52 +10:00
-- confboot.lua : VM configuration program
-- Authors: 20kdc
2018-05-30 08:50:11 +10:00
-- _MMstartVM(name)
-- _MMcomList(...)
-- _MMserial(str)
-- _MMdeserial(str)
local screen = component.proxy ( component.list ( " screen " , true ) ( ) )
local gpu = component.proxy ( component.list ( " gpu " , true ) ( ) )
local fs = component.proxy ( " world " )
screen.turnOn ( )
gpu.bind ( screen.address )
gpu.setResolution ( 50 , 15 )
gpu.setForeground ( 0 )
gpu.setBackground ( 0xFFFFFF )
local menu
local currentY
local currentVMId
local currentVM
local genMainMenu , genFSSelector , genEditor
function genFSSelector ( cb )
local fsName = " "
menu = {
{ " - Select VFS - " , function ( ) end } ,
{ " Cancel " , cb } ,
{ " New FS: " , function ( )
fs.makeDirectory ( " fs- " .. fsName )
genFSSelector ( cb )
end , function ( text )
if text then fsName = text end
return fsName
end }
}
currentY = 2
local fsl = fs.list ( " " )
table.sort ( fsl )
for k , v in ipairs ( fsl ) do
if v : sub ( # v ) == " / " and v : sub ( 1 , 3 ) == " fs- " then
local id = v : sub ( 4 , # v - 1 )
table.insert ( menu , { id , function ( )
cb ( id )
end } )
table.insert ( menu , { " Delete " , function ( )
fs.remove ( " fs- " .. id )
genFSSelector ( cb )
end } )
end
end
end
local function doVMSave ( )
local f = fs.open ( " vm- " .. currentVMId , " wb " )
if not f then error ( " VM Save failed... " ) end
fs.write ( f , _MMserial ( currentVM ) )
fs.close ( f )
end
function genEditor ( )
menu = {
--01234567890123456789012345678901234567890123456789
{ " - configuring VM: " .. currentVMId , function ( ) end } ,
{ " Save & Return " , function ( )
doVMSave ( )
currentVM , currentVMId = nil
genMainMenu ( )
end } ,
{ " Save & Launch " , function ( )
doVMSave ( )
_MMstartVM ( currentVMId )
computer.shutdown ( )
end } ,
{ " Delete " , function ( )
fs.remove ( " vm- " .. currentVMId )
currentVM , currentVMId = nil
genMainMenu ( )
end } ,
}
currentY = 3
for k , v in pairs ( currentVM ) do
local v1 = tostring ( v )
if type ( v ) ~= " string " then
v1 = " virt. " .. v [ 1 ]
end
table.insert ( menu , { " Del. " .. v1 .. " " .. k , function ( )
currentVM [ k ] = nil
genEditor ( )
end } )
end
2018-05-30 23:07:52 +10:00
if not currentVM [ " k-eeprom " ] then
table.insert ( menu , { " + Virtual EEPROM (R/W, preloaded w/ LUCcABOOT)... " , function ( )
currentVM [ currentVMId .. " -eeprom " ] = { " eeprom " , " /vc- " .. currentVMId .. " .lua " , " /vd- " .. currentVMId .. " .bin " , " VM BIOS " , false }
genEditor ( )
-- do file copy now!
local handleA = fs.open ( " /lucaboot.lua " , " rb " )
local handleB = fs.open ( " /vc- " .. currentVMId .. " .lua " , " wb " )
if not handleA then if handleB then fs.close ( handleB ) end return end
if not handleB then fs.close ( handleA ) return end
while true do
local s = fs.read ( handleA , 2048 )
if not s then break end
fs.write ( handleB , s )
end
fs.close ( handleA )
fs.close ( handleB )
end } )
end
2018-05-30 08:50:11 +10:00
table.insert ( menu , { " + Virtual FS (R/W)... " , function ( )
genFSSelector ( function ( fsa )
if fsa then
currentVM [ " fs- " .. fsa ] = { " filesystem " , " /fs- " .. fsa .. " / " , false }
end
genEditor ( )
end )
end } )
table.insert ( menu , { " + Virtual FS (R/O)... " , function ( )
genFSSelector ( function ( fsa )
if fsa then
currentVM [ fsa .. " -fs " ] = { " filesystem " , fsa , true }
end
genEditor ( )
end )
end } )
local tx = {
" + Screen 50x15: " ,
" + Screen 80x24: " ,
" + Screen 160x49: "
}
local txw = {
50 ,
80 ,
160
}
local txh = {
15 ,
24 ,
49
}
for i = 1 , 3 do
local cName = currentVMId .. " -screen "
local nt = 0
while currentVM [ cName ] do
nt = nt + 1
cName = currentVMId .. " - " .. nt
end
table.insert ( menu , { tx [ i ] , function ( )
currentVM [ cName ] = { " screen " , cName , txw [ i ] , txh [ i ] , 8 }
genEditor ( )
end , function ( text )
if text then cName = text end
return cName
end } )
end
for address , ty in _MMcomList ( " " ) do
if ( not currentVM [ address ] ) and ty ~= " gpu " then
table.insert ( menu , { " + Host " .. ty .. " " .. address , function ( )
currentVM [ address ] = ty
genEditor ( )
end } )
end
end
end
function genMainMenu ( )
local vmName = " "
menu = {
--01234567890123456789012345678901234567890123456789
{ " - metamachine configurator -- use keyboard - " , function ( ) end } ,
{ " Shutdown " , computer.shutdown } ,
{ " New VM: " , function ( )
local f = fs.open ( " vm- " .. vmName , " wb " )
if not f then return end
fs.write ( f , _MMserial ( {
[ vmName .. " -eeprom " ] = { " eeprom " , " /lucaboot.lua " , " /vd- " .. vmName .. " .bin " , " LUCcABOOT VM BIOS " , true } ,
[ vmName .. " -screen " ] = { " screen " , vmName , 50 , 15 , 8 }
} ) )
fs.close ( f )
genMainMenu ( )
end , function ( text )
if text then vmName = text end
return vmName
end }
}
currentY = 3
local fsl = fs.list ( " " )
table.sort ( fsl )
for k , v in ipairs ( fsl ) do
if v : sub ( # v ) == " / " then
elseif v : sub ( 1 , 3 ) == " vm- " then
local id = v : sub ( 4 )
table.insert ( menu , # menu , { id , function ( )
local f = fs.open ( " vm- " .. id , " rb " )
if not f then return end
local str = " "
while true do
local sb = fs.read ( f , 2048 )
if not sb then break end
str = str .. sb
end
currentVM = _MMdeserial ( str ) or { }
fs.close ( f )
currentVMId = id
genEditor ( )
end } )
end
end
end
----
genMainMenu ( )
local function draw ( )
gpu.fill ( 1 , 1 , 50 , 15 , " " )
local camera = math.max ( 0 , math.min ( math.floor ( currentY - 7 ) , # menu - 15 ) )
for i = 1 , # menu do
local pfx = " "
if currentY == i then
pfx = " > "
end
local pox = " "
if menu [ i ] [ 3 ] then
pox = menu [ i ] [ 3 ] ( )
end
gpu.set ( 1 , i - camera , pfx .. menu [ i ] [ 1 ] .. pox )
end
end
-- Final main loop.
draw ( )
while true do
local t = { computer.pullSignal ( ) }
if t [ 1 ] == " key_down " then
if t [ 4 ] == 200 then
currentY = math.max ( 1 , currentY - 1 )
draw ( )
elseif t [ 4 ] == 208 then
currentY = math.min ( currentY + 1 , # menu )
draw ( )
elseif t [ 3 ] == 13 then
menu [ currentY ] [ 2 ] ( )
draw ( )
elseif t [ 3 ] == 8 then
local tx = menu [ currentY ] [ 3 ] ( )
menu [ currentY ] [ 3 ] ( unicode.sub ( tx , 1 , unicode.len ( tx ) - 1 ) )
draw ( )
elseif t [ 3 ] >= 32 then
if menu [ currentY ] [ 3 ] then
menu [ currentY ] [ 3 ] ( menu [ currentY ] [ 3 ] ( ) .. unicode.char ( t [ 3 ] ) )
draw ( )
end
end
end
end