From 99cb58d9fca503f58acf1e43ad31137712245a30 Mon Sep 17 00:00:00 2001 From: 20kdc Date: Wed, 26 Sep 2018 01:46:16 +0100 Subject: [PATCH] Add a tape interface application, 'app-tapedeck' --- claw/repo-claw.lua | 17 ++ repository/apps/app-tapedeck.lua | 206 +++++++++++++++++++++++ repository/docs/repoauthors/app-tapedeck | 2 + 3 files changed, 225 insertions(+) create mode 100644 repository/apps/app-tapedeck.lua create mode 100644 repository/docs/repoauthors/app-tapedeck diff --git a/claw/repo-claw.lua b/claw/repo-claw.lua index 24aeef8..5791869 100644 --- a/claw/repo-claw.lua +++ b/claw/repo-claw.lua @@ -200,6 +200,23 @@ return { "docs/repoauthors/app-nbcompose" }, }, + ["app-tapedeck"] = { + desc = "Computronics Tape Drive interface", + v = 0, + 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, diff --git a/repository/apps/app-tapedeck.lua b/repository/apps/app-tapedeck.lua new file mode 100644 index 0000000..991b1f2 --- /dev/null +++ b/repository/apps/app-tapedeck.lua @@ -0,0 +1,206 @@ +-- 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 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 function genPlayer(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 tapeReadBuf = 8192 + local tapePos = 0 + while tapePos < tapeSize do + if mode then + local data = inst.read(tapeReadBuf) + if not data then break end + tapePos = tapePos + tapeReadBuf + local res, ifo = fh.write(data) + if not res then + neoux.startDialog(tostring(ifo), "issue") + break + end + else + local data = fh.read(tapeReadBuf) + 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 = { + { + x = 1, + y = 5, + w = 20, + h = 1, + selectable = true, + line = function (w, x, y, lined, bg, fg, selected) + local lx = "" + local pos = inst.getPosition() + if inst.isReady() then + -- Show a bar + local tick = inst.getSize() / 13 + for i = 1, 13 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 / 4096 + lx = lx .. string.format(" %03i:%02i", math.floor(sec / 60), math.floor(sec) % 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 = 40960 + 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(14, 3, { + "% Vol. ", + "% Speed" + }), + pcbox(9, 3, 0, 100, "vol", inst.setVolume), + pcbox(9, 4, 25, 200, "spd", inst.setSpeed), + neoux.tcbutton(1, 3, "{", function (w) + inst.seek(-inst.getSize()) + end), + neoux.tcbutton(5, 3, "}", function (w) + inst.seek(inst.getSize()) + end), + neoux.tcbutton(1, 4, ((inst.getState() == "PLAYING") and "Pause") or "Play", function (w) + pausePlay() + end), + -- R/W buttons + neoux.tcbutton(1, 2, "Read", function (w) + rwButton(true) + end), + neoux.tcbutton(8, 2, "Write", function (w) + rwButton(false) + end), + neoux.tcfield(1, 1, 20, function (tx) + if tx then + inst.setLabel(tx) + cachedLabel = tx + end + return cachedLabel + end) + } + updateTick = function () + local lcl = cachedLabel + cachedLabel = inst.getLabel() or "" + elems[1].update(window) + if inst.getState() ~= cachedState then + window.reset(genPlayer(inst)) + elseif lcl ~= cachedLabel then + elems[#elems].update(window) + end + end + local n = neoux.tcwindow(20, 5, elems, function (w) + updateTick = nil + running = false + w.close() + end, 0xFFFFFF, 0) + return 20, 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, function (w) + window.reset(genPlayer(v)) + end) + end + tapes = nil + return 40, #elems, "choose", 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 diff --git a/repository/docs/repoauthors/app-tapedeck b/repository/docs/repoauthors/app-tapedeck new file mode 100644 index 0000000..2d3b037 --- /dev/null +++ b/repository/docs/repoauthors/app-tapedeck @@ -0,0 +1,2 @@ +repository/apps/app-tapedeck.lua: 20kdc, Public Domain +