mirror of
https://github.com/20kdc/OC-KittenOS.git
synced 2024-11-27 04:48:05 +11:00
Merge branch 'repository'
This commit is contained in:
commit
3502cdedc2
@ -91,7 +91,7 @@ return {
|
||||
},
|
||||
["app-kmt"] = {
|
||||
desc = "Line-terminal for MUDs & such",
|
||||
v = 0,
|
||||
v = 1,
|
||||
deps = {
|
||||
"neo",
|
||||
"zzz-license-pd"
|
||||
@ -200,6 +200,23 @@ return {
|
||||
"docs/repoauthors/app-nbcompose"
|
||||
},
|
||||
},
|
||||
["app-tapedeck"] = {
|
||||
desc = "Computronics Tape Drive interface",
|
||||
v = 1,
|
||||
deps = {
|
||||
"neo",
|
||||
"zzz-license-pd"
|
||||
},
|
||||
dirs = {
|
||||
"apps",
|
||||
"docs",
|
||||
"docs/repoauthors"
|
||||
},
|
||||
files = {
|
||||
"apps/app-tapedeck.lua",
|
||||
"docs/repoauthors/app-tapedeck"
|
||||
},
|
||||
},
|
||||
["app-launchbar"] = {
|
||||
desc = "Application launcher bar",
|
||||
v = 0,
|
||||
|
@ -113,7 +113,7 @@ while true do
|
||||
local e = {coroutine.yield()}
|
||||
if e[1] == "k.timer" then
|
||||
while true do
|
||||
local b, e = tcp.read(1)
|
||||
local b, e = tcp.read(neo.readBufSize)
|
||||
if not b then
|
||||
if e then
|
||||
incoming(":Warning: " .. e)
|
||||
@ -123,12 +123,16 @@ while true do
|
||||
break
|
||||
elseif b == "" then
|
||||
break
|
||||
elseif b ~= "\r" then
|
||||
if b == "\n" then
|
||||
incoming("<" .. tcpBuf)
|
||||
tcpBuf = ""
|
||||
else
|
||||
tcpBuf = tcpBuf .. b
|
||||
tcpBuf = tcpBuf .. b:gsub("\r", "")
|
||||
while true do
|
||||
local nlp = tcpBuf:find("\n")
|
||||
if nlp then
|
||||
incoming("<" .. tcpBuf:sub(1, nlp - 1))
|
||||
tcpBuf = tcpBuf:sub(nlp + 1)
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
308
repository/apps/app-tapedeck.lua
Normal file
308
repository/apps/app-tapedeck.lua
Normal file
@ -0,0 +1,308 @@
|
||||
-- This is released into the public domain.
|
||||
-- No warranty is provided, implied or otherwise.
|
||||
|
||||
-- app-tapedeck.lua : Computronics Tape interface.
|
||||
-- Added note: Computerized record discs aren't available, so it can't be called vinylscratch.
|
||||
-- Authors: 20kdc
|
||||
|
||||
local tapes = {}
|
||||
for v in neo.requireAccess("c.tape_drive", "tapedrives").list() do
|
||||
table.insert(tapes, v)
|
||||
end
|
||||
|
||||
local tapeRate = 4096
|
||||
|
||||
local event = require("event")(neo)
|
||||
local neoux = require("neoux")(event, neo)
|
||||
|
||||
-- There's no way to get these, so they get reset
|
||||
local pcvals = {vol = 100, spd = 100}
|
||||
local function pcbox(x, y, low, high, id, fun)
|
||||
return neoux.tcfield(x, y, 5, function (tx)
|
||||
if tx then
|
||||
pcvals[id] = math.min(math.max(0, math.floor(tonumber(tx) or 0)), high)
|
||||
fun(math.max(pcvals[id], low) / 100)
|
||||
end
|
||||
return tostring(pcvals[id])
|
||||
end)
|
||||
end
|
||||
|
||||
local window
|
||||
local running = true
|
||||
local focused = true
|
||||
|
||||
local updateTick
|
||||
|
||||
local downloadCancelled = false
|
||||
|
||||
local genPlayer -- used to return to player
|
||||
|
||||
local function genDownloading(inst)
|
||||
local lclLabelText = {"downloading..."}
|
||||
local lclLabel = neoux.tcrawview(1, 1, lclLabelText)
|
||||
local thr = {
|
||||
"/",
|
||||
"-",
|
||||
"\\",
|
||||
"|"
|
||||
}
|
||||
local thri = 0
|
||||
updateTick = function ()
|
||||
lclLabelText[1] = "downloading... " .. (inst.getPosition() / (1024 * 1024)) .. "MB " .. thr[(thri % #thr) + 1]
|
||||
thri = thri + 1
|
||||
lclLabel.update(window)
|
||||
end
|
||||
return 40, 1, nil, neoux.tcwindow(40, 1, {
|
||||
lclLabel
|
||||
}, function (w)
|
||||
downloadCancelled = true
|
||||
end, 0xFFFFFF, 0)
|
||||
end
|
||||
|
||||
local function doINetThing(inet, url, inst)
|
||||
inet = inet.list()()
|
||||
assert(inet, "No available card")
|
||||
inst.stop()
|
||||
inst.seek(-inst.getSize())
|
||||
downloadCancelled = false
|
||||
downloadPercent = 0
|
||||
window.reset(genDownloading(inst))
|
||||
local req = assert(inet.request(url))
|
||||
req.finishConnect()
|
||||
local tapePos = 0
|
||||
local tapeSize = inst.getSize()
|
||||
while (not downloadCancelled) and tapePos < tapeSize do
|
||||
local n, n2 = req.read(neo.readBufSize)
|
||||
if not n then
|
||||
if n2 then
|
||||
req.close()
|
||||
error(n2)
|
||||
end
|
||||
break
|
||||
elseif n == "" then
|
||||
event.sleepTo(os.uptime() + 0.05)
|
||||
else
|
||||
inst.write(n)
|
||||
tapePos = tapePos + #n
|
||||
end
|
||||
end
|
||||
req.close()
|
||||
inst.seek(-inst.getSize())
|
||||
end
|
||||
|
||||
local function genWeb(inst)
|
||||
updateTick = nil
|
||||
local url = ""
|
||||
local lockout = false
|
||||
return 40, 3, nil, neoux.tcwindow(40, 3, {
|
||||
neoux.tcrawview(1, 1, {"URL to write to tape?"}),
|
||||
neoux.tcfield(1, 2, 40, function (t)
|
||||
url = t or url
|
||||
return url
|
||||
end),
|
||||
neoux.tcbutton(1, 3, "Download & Write", function (w)
|
||||
lockout = true
|
||||
local inet = neo.requestAccess("c.internet")
|
||||
lockout = false
|
||||
if inet then
|
||||
local ok, err = pcall(doINetThing, inet, url, inst)
|
||||
if not ok then
|
||||
neoux.startDialog("Couldn't download: " .. tostring(err), "error")
|
||||
end
|
||||
end
|
||||
w.reset(genPlayer(inst))
|
||||
end)
|
||||
}, function (w)
|
||||
w.reset(genPlayer(inst))
|
||||
end, 0xFFFFFF, 0)
|
||||
end
|
||||
|
||||
-- The actual main UI --
|
||||
genPlayer = function (inst)
|
||||
local cachedLabel = inst.getLabel() or ""
|
||||
local cachedState = inst.getState()
|
||||
local function pausePlay()
|
||||
if inst.getState() == "PLAYING" then
|
||||
inst.stop()
|
||||
else
|
||||
inst.play()
|
||||
end
|
||||
window.reset(genPlayer(inst))
|
||||
end
|
||||
-- Common code for reading/writing tapes.
|
||||
-- Note that it tries to allow playback to resume later.
|
||||
local function rwButton(mode)
|
||||
local fh = neoux.fileDialog(mode)
|
||||
if not fh then return end
|
||||
inst.stop()
|
||||
local sp = inst.getPosition()
|
||||
local tapeSize = inst.getSize()
|
||||
inst.seek(-tapeSize)
|
||||
local tapePos = 0
|
||||
while tapePos < tapeSize do
|
||||
if mode then
|
||||
local data = inst.read(neo.readBufSize)
|
||||
if not data then break end
|
||||
tapePos = tapePos + #data
|
||||
local res, ifo = fh.write(data)
|
||||
if not res then
|
||||
neoux.startDialog(tostring(ifo), "issue")
|
||||
break
|
||||
end
|
||||
else
|
||||
local data = fh.read(neo.readBufSize)
|
||||
if not data then break end
|
||||
tapePos = tapePos + #data
|
||||
inst.write(data)
|
||||
end
|
||||
end
|
||||
inst.seek(-tapeSize)
|
||||
inst.seek(sp)
|
||||
fh.close()
|
||||
end
|
||||
local elems = {
|
||||
neoux.tcrawview(1, 1, {
|
||||
"Label:",
|
||||
"Contents:"
|
||||
}),
|
||||
neoux.tcfield(7, 1, 34, function (tx)
|
||||
if tx then
|
||||
inst.setLabel(tx)
|
||||
cachedLabel = tx
|
||||
end
|
||||
return cachedLabel
|
||||
end),
|
||||
{
|
||||
x = 1,
|
||||
y = 5,
|
||||
w = 40,
|
||||
h = 1,
|
||||
selectable = true,
|
||||
line = function (w, x, y, lined, bg, fg, selected)
|
||||
local lx = ""
|
||||
local pos = inst.getPosition()
|
||||
local sz = inst.getSize()
|
||||
if inst.isReady() then
|
||||
-- Show a bar
|
||||
local tick = sz / 23
|
||||
for i = 1, 23 do
|
||||
local alpos = (tick * i) - (tick / 2)
|
||||
if pos > alpos then
|
||||
lx = lx .. "="
|
||||
else
|
||||
lx = lx .. "-"
|
||||
end
|
||||
end
|
||||
else
|
||||
lx = "NO TAPE HERE."
|
||||
end
|
||||
local sec = pos / tapeRate
|
||||
local secz = sz / tapeRate
|
||||
lx = lx .. string.format(" %03i:%02i / %03i:%02i ",
|
||||
math.floor(sec / 60), math.floor(sec) % 60,
|
||||
math.floor(secz / 60), math.floor(secz) % 60)
|
||||
if selected then bg, fg = fg, bg end
|
||||
window.span(x, y, lx, bg, fg)
|
||||
end,
|
||||
key = function (w, update, a, b, c, kf)
|
||||
local amount = tapeRate * 10
|
||||
if kf.shift or kf.rshift then
|
||||
amount = amount * 24
|
||||
end
|
||||
if c then
|
||||
if a == 32 then
|
||||
pausePlay()
|
||||
elseif b == 203 then
|
||||
inst.seek(-amount)
|
||||
update()
|
||||
return true
|
||||
elseif b == 205 then
|
||||
inst.seek(amount)
|
||||
update()
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
neoux.tcrawview(33, 3, {
|
||||
"% Volume"
|
||||
}),
|
||||
neoux.tcrawview(20, 3, {
|
||||
"% Speed"
|
||||
}),
|
||||
pcbox(15, 3, 25, 200, "spd", inst.setSpeed),
|
||||
pcbox(28, 3, 0, 100, "vol", inst.setVolume),
|
||||
neoux.tcrawview(1, 4, {
|
||||
"Seeker: use ◃/▹ (shift goes faster)"
|
||||
}),
|
||||
neoux.tcbutton(1, 3, "«", function (w)
|
||||
inst.seek(-inst.getSize())
|
||||
end),
|
||||
neoux.tcbutton(11, 3, "»", function (w)
|
||||
inst.seek(inst.getSize())
|
||||
end),
|
||||
neoux.tcbutton(4, 3, ((inst.getState() == "PLAYING") and "Pause") or "Play", function (w)
|
||||
pausePlay()
|
||||
end),
|
||||
-- R/W buttons
|
||||
neoux.tcbutton(11, 2, "Read", function (w)
|
||||
rwButton(true)
|
||||
end),
|
||||
neoux.tcbutton(17, 2, "Write", function (w)
|
||||
rwButton(false)
|
||||
end),
|
||||
neoux.tcbutton(24, 2, "Write From Web", function (w)
|
||||
w.reset(genWeb(inst))
|
||||
end)
|
||||
}
|
||||
updateTick = function ()
|
||||
local lcl = cachedLabel
|
||||
cachedLabel = inst.getLabel() or ""
|
||||
elems[3].update(window)
|
||||
if inst.getState() ~= cachedState then
|
||||
window.reset(genPlayer(inst))
|
||||
elseif lcl ~= cachedLabel then
|
||||
elems[2].update(window)
|
||||
end
|
||||
end
|
||||
local n = neoux.tcwindow(40, 5, elems, function (w)
|
||||
updateTick = nil
|
||||
running = false
|
||||
w.close()
|
||||
end, 0xFFFFFF, 0)
|
||||
return 40, 5, inst.address, function (a, ...)
|
||||
if a == "focus" then
|
||||
focused = (...) or true
|
||||
end
|
||||
return n(a, ...)
|
||||
end
|
||||
end
|
||||
local function genList()
|
||||
local elems = {}
|
||||
for k, v in ipairs(tapes) do
|
||||
elems[k] = neoux.tcbutton(1, k, v.address:sub(1, 38), function (w)
|
||||
window.reset(genPlayer(v))
|
||||
end)
|
||||
end
|
||||
tapes = nil
|
||||
return 40, #elems, nil, neoux.tcwindow(40, #elems, elems, function (w)
|
||||
running = false
|
||||
w.close()
|
||||
end, 0xFFFFFF, 0)
|
||||
end
|
||||
|
||||
|
||||
window = neoux.create(genList())
|
||||
|
||||
-- Timer for time update
|
||||
local function tick()
|
||||
if updateTick then
|
||||
updateTick()
|
||||
end
|
||||
event.runAt(os.uptime() + ((focused and 1) or 10), tick)
|
||||
end
|
||||
event.runAt(0, tick)
|
||||
|
||||
while running do
|
||||
event.pull()
|
||||
end
|
2
repository/docs/repoauthors/app-tapedeck
Normal file
2
repository/docs/repoauthors/app-tapedeck
Normal file
@ -0,0 +1,2 @@
|
||||
repository/apps/app-tapedeck.lua: 20kdc, Public Domain
|
||||
|
Loading…
Reference in New Issue
Block a user