More compatibility mode stuff, also should work

In game I mean
This commit is contained in:
Casey 2023-10-20 02:33:37 +03:00
parent 3543ef9595
commit d84782802f
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
1 changed files with 112 additions and 61 deletions

View File

@ -27,6 +27,54 @@ settings.define("mplayer.colors.status", {
default = 0x80EF80, -- #80EF80
type = number
})
local drive = peripheral.find("disk_drive")
if not drive then
printError("No drive found, starting in dummy mode")
local fp = io.open("noita.dfpwm", "rb")
if fp == nil then
printError("No sample file found, are you running it on a real* computer without a tape drive?")
return
end
local size = fp:seek("end", 0)
fp:seek("set", 0)
drive = {
_pos = 0,
_fp = fp,
_state = "STOPPED",
seek = function(howMuch)
drive._pos = math.min(drive.getSize(), math.max(0, drive._pos + howMuch))
end,
getPosition = function()
return drive._pos
end,
read = function(n)
local out = { drive._fp:read(n) }
drive.seek(n or 1)
return table.unpack(out)
end,
getSize = function()
return size
end,
getState = function()
return drive._state
end,
play = function()
drive._state = "PLAYING"
end,
stop = function()
drive._state = "STOPPED"
end,
isReady = function()
return true
end,
_tick = function()
if drive._state == "PLAYING" then
drive.read(600)
end
end,
}
os.sleep(1)
end
local function time2str(ti)
ti = math.floor(ti)
@ -34,36 +82,15 @@ local function time2str(ti)
return string.format("%02d:%02d", m, s)
end
local function read32(fp)
local function read32()
local v = 0
for i = 1, 4 do
local b = string.byte(fp:read(1), 1)
local b = string.byte(drive.read(1), 1)
v = bit32.bor(bit32.lshift(v, 8), b)
end
return v
end
local drive = peripheral.find("disk_drive")
if not drive then
printError("No drive found, starting in dummy mode")
drive = {
_pos = 0,
seek = function(howMuch)
drive._pos = math.min(drive.getSize(), math.max(0, drive._pos + howMuch))
end,
getPosition = function()
return drive._pos
end,
getSize = function()
return 360000 * 64
end,
_tick = function()
drive._pos = drive._pos + 600
end
}
os.sleep(1)
end
local help = {}
for line in ([[# Movement:
@ -198,6 +225,7 @@ local mplayer = {
elseif key == keys.enter then
drive.seek(-drive.getSize())
drive.seek(self.songs[self.screens[2].cursor].offset)
drive.play()
self.currentSong = self.screens[2].cursor
end
end,
@ -263,21 +291,6 @@ local function setupTerminal()
term.clear()
end
local fp = io.open("noita.dfpwm", "rb")
if fp ~= nil then
for i = 1, 24 do
local offset = read32(fp)
local length = read32(fp)
local title = fp:read(117)
local zero = math.min(64, title:find("\x00") or 0)
title = title:sub(1, zero)
if length > 0 and offset > 0 then
mplayer.songs[i] = { offset = offset, length = length, title = title }
end
end
fp:close()
end
setupTerminal()
local tw, th = term.getSize()
@ -309,31 +322,34 @@ function()
-- Statusline
term.setCursorPos(1, th)
term.clearLine()
term.setTextColor(mplayer.colors.status)
term.write("Playing: ") -- 9 characters
-- Progressbar
local lw = math.floor(tw * time / duration)
term.setCursorPos(1, th - 1)
term.setTextColor(mplayer.colors.current)
term.clearLine()
term.write(string.rep("=", lw))
term.write(">")
term.setTextColor(mplayer.colors.cursor)
term.write(string.rep("-", tw - lw - 1))
-- Statusline text
term.setCursorPos(10, th)
local timeString = string.format("[%s:%s]", time2str(time), time2str(duration))
local w = tw - #timeString - 10 -- "Playing: " plus extra space
if drive.getState() == "PLAYING" then
term.setTextColor(mplayer.colors.status)
term.write("Playing: ") -- 9 characters
term.setTextColor(mplayer.colors.current)
if #title <= w then
term.write(title)
else
local off = (mplayer.statusLineScroll % (#title + 5)) + 1
local txt = title .. " ::: " .. title
term.write(txt:sub(off, off + w - 1))
-- Progressbar
local lw = math.floor(tw * time / duration)
term.setCursorPos(1, th - 1)
term.setTextColor(mplayer.colors.current)
term.clearLine()
term.write(string.rep("=", lw))
term.write(">")
term.setTextColor(mplayer.colors.cursor)
term.write(string.rep("-", tw - lw - 1))
-- Statusline text
term.setCursorPos(10, th)
local w = tw - #timeString - 10 -- "Playing: " plus extra space
term.setTextColor(mplayer.colors.current)
if #title <= w then
term.write(title)
else
local off = (mplayer.statusLineScroll % (#title + 5)) + 1
local txt = title .. " ::: " .. title
term.write(txt:sub(off, off + w - 1))
end
end
term.setTextColor(mplayer.colors.status)
term.setCursorPos(tw - #timeString + 1, th)
@ -396,6 +412,24 @@ function()
end
elseif ev == "term_resize" then
tw, th = term.getSize()
elseif ev == "tape_removed" then
mplayer.songs = {}
elseif ev == "tape_inserted" then
drive.stop()
drive.seek(-drive.getSize())
for i = 1, 48 do
local offset = read32()
local length = read32()
local title = drive.read(117)
title = title:sub(1, title:find("\x00"))
if length > 0 and offset > 0 then
mplayer.songs[i] = {
title = title,
offset = offset,
length = length
}
end
end
elseif ev ~= "timer" then
local m = term.redirect(peripheral.wrap("right"))
io.write(ev .. " ")
@ -413,19 +447,36 @@ function()
end,
function()
local oldSong = nil
local oldDriveState = nil
local oldTapeState = nil
while true do
mplayer.currentSong = 0
if drive._tick then drive._tick() end
if drive._tick then drive._tick() end -- dummy mode
local tapeState = drive.isReady()
if tapeState ~= oldTapeState then
os.queueEvent(tapeState and "tape_inserted" or "tape_removed")
oldTapeState = tapeState
end
local driveState = drive.getState()
if driveState ~= oldDriveState then
os.queueEvent("drive_state", driveState)
oldDriveState = driveState
end
local pos = drive.getPosition()
for i, song in ipairs(mplayer.songs) do
if pos >= song.offset and pos < (song.offset + song.length) then
mplayer.currentSong = i
end
end
if oldSong ~= mplayer.currentSong then
os.queueEvent("song_change")
oldSong = mplayer.currentSong
end
os.sleep(0.1)
end
end