Files
rdsspy-lua-host/examples/test.lua

212 lines
7.5 KiB
Lua

set_console_mode(true)
local last_pi = 0
local last_super_pi = 0
local ert_string = string.rep("_", 128)
local rt_a = string.rep("_", 64)
local rt_b = string.rep("_", 64)
local ptyn_toggle = false
local ptyn = string.rep(" ", 8)
local odas = {}
local ert_display = ""
local last_rt = false
local rta_display = ""
local rtb_display = ""
local current_menu = 1
local pty_rds = {
"None", "News", "Current Affairs",
"Information", "Sport", "Education",
"Drama", "Culture", "Science",
"Varied speech", "Pop", "Rock",
"Easy listening", "Light classic", "Classic",
"Other", "Weather", "Finance",
"Children's", "Social", "Religion",
"Phone in", "Travel", "Leisure",
"Jazz", "Country", "National",
"Oldies", "Folk", "Documentary",
"Alarm Test", "Alarm !",
}
local pty_rbds = {
"None", "News", "Information",
"Sports", "Talk", "Rock",
"Classic Rock", "Adult Hits", "Soft Rock",
"Top 40", "Country", "Oldies",
"Soft", "Nostalgia", "Jazz",
"Classical", "R&B", "Soft R&B",
"Foreign Language", "Religious Music", "Religious Talk",
"Personality", "Public", "College",
"Spanish Talk", "Spanish Music", "Hip-Hop",
"???", "???", "Weather",
"Emergency Test", "ALERT !",
}
local pty = 0
local tp = false
local ta = false
local dpty = false
local last_render_hash = 0
local function crc(data)
local crc = 0xFF
for i = 1, #data do
crc = crc ~ data:byte(i)
for _ = 1, 8 do
if (crc & 0x80) ~= 0 then crc = (crc << 1) ~ 0x7
else crc = crc << 1 end
crc = crc & 0xFF
end
end
return crc
end
function render_menu()
out = string.format("Menu %d\r\n------\r\n", current_menu)
if current_menu == 1 then
set_font_size(64) -- largest as i can do, this is directly from the public's wants (https://pira.cz/forum/index.php?topic=1124.0)
out = out .. string.format("PI: %X (SPI: %X)\r\n", last_pi, last_super_pi)
out = out .. string.format("PS: %s", db.read_value("PS"))
elseif current_menu == 2 then
set_font_size(24)
out = out .. string.format("PTY: %d (%s / %s)\r\n", pty, pty_rds[pty+1], pty_rbds[pty+1])
out = out .. string.format("TP %s | TA %s | DPTY %s\r\n", tp and "+" or "-", ta and "+" or "-", dpty and "+" or "-")
out = out .. string.format("PTYN: %s\r\n\r\n", ptyn)
out = out .. string.format("RT[A]: %s%s\r\n", last_rt and ">" or " ", rta_display)
out = out .. string.format("RT[B]: %s%s\r\n\r\n", (not last_rt) and ">" or " ", rtb_display)
out = out .. string.format("ERT: %s\r\n", ert_display)
elseif current_menu == 3 then
set_font_size(24)
local oda_string = ""
for grp, data in pairs(odas) do
local ver_char = (data.version == 0) and "A" or "B"
oda_string = oda_string .. string.format("%d%s - %04X | ", grp, ver_char, data.aid)
end
out = out .. string.format("ODA: %s\r\n", oda_string:sub(1, #oda_string-2))
end
local hash = crc(out)
if hash ~= last_render_hash then
set_console(out)
last_render_hash = hash
end
end
function event(event)
current_menu = event
end
function command(cmd, param)
if cmd:lower() == "request" and param:lower() == "decoderdata" then
db.add_value("RT.A", rta_display)
db.add_value("RT.B", rtb_display)
db.add_value("RT.Type", "0" and last_rt or "1")
db.add_value("PTYN", ptyn)
db.add_value("ERT", ert_display)
elseif cmd:lower() == "resetdata" then
ert_string = string.rep("_", 128)
rt_a = string.rep("_", 64)
rt_b = string.rep("_", 64)
odas = {}
last_pi = 0
last_super_pi = 0
pty = 0
tp = false
ta = false
dpty = false
ptyn = string.rep(" ", 8)
ptyn_toggle = false
elseif cmd:lower() == "superpi" then
last_super_pi = tonumber(param, 16)
end
end
local function findODAByAID(t, targetAID)
for grp, data in pairs(t) do
if data.aid == targetAID then return grp, data.version end
end
return nil, nil
end
function group(stream, b_corr, a, b, c, d)
if stream ~= 0 and a ~= 0 then return
elseif stream ~= 0 and not db.load_boolean("rdsspy.ini", "General", "Tunnelling", false) then return end
if a ~= 0 then last_pi = a end
if b_corr or b < 0 or c < 0 or d < 0 then return end
pty = (b >> 5) & 0x1f
tp = ((b >> 10) & 1) ~= 0
local group_type = (b & 0xf000) >> 12
local group_version = (b & 0x800) >> 11
if group_type == 3 and group_version == 0 then
local target_group = (b & 0x1f) >> 1
if odas[target_group] == nil then odas[target_group] = { aid = d, version = (b & 1) } end
else
local ert_grp, ert_ver = findODAByAID(odas, 0x6552)
if ert_grp and group_type == ert_grp and group_version == ert_ver then
local ert_state = b & 0x1f
local new_chars = string.char((c >> 8) & 0xff) .. string.char(c & 0xff) .. string.char((d >> 8) & 0xff) .. string.char(d & 0xff)
local start_pos = (ert_state * 4) + 1
ert_string = ert_string:sub(1, start_pos - 1) .. new_chars .. ert_string:sub(start_pos + 4)
local carriage = ert_string:find("\r", 1, true)
if carriage then ert_display = ert_string:sub(1, carriage - 1)
else ert_display = ert_string:gsub("%s+$", "") end
else
if group_type == 0 then
ta = ((b & 0x10) >> 4) ~= 0
local di_bit = ((b & 0x4) >> 2) ~= 0
local segment = b & 0x3
if di_bit and segment == 0 then dpty = true
elseif segment == 0 then dpty = false end
elseif group_type == 10 and group_version == 0 then
local toggle = ((b & 0x10) >> 4) ~= 0
if toggle ~= ptyn_toggle then
ptyn = string.rep(" ", 8)
ptyn_toggle = toggle
end
local segment = b & 1
local new_chars = string.char(db.char_conv((c >> 8) & 0xff)) .. string.char(db.char_conv(c & 0xff)) .. string.char(db.char_conv((d >> 8) & 0xff)) .. string.char(db.char_conv(d & 0xff))
local start_pos = (segment * 4) + 1
ptyn = rt_a:sub(1, ptyn - 1) .. new_chars .. rt_a:sub(ptyn + 4)
elseif group_type == 2 and group_version == 0 then -- TODO 2B
local rt_state = b & 0xF
local rt_toggle = (b >> 4) & 1
local new_chars = string.char(db.char_conv((c >> 8) & 0xff)) .. string.char(db.char_conv(c & 0xff)) .. string.char(db.char_conv((d >> 8) & 0xff)) .. string.char(db.char_conv(d & 0xff))
local start_pos = (rt_state * 4) + 1
if rt_toggle == 0 then
last_rt = true
rt_a = rt_a:sub(1, start_pos - 1) .. new_chars .. rt_a:sub(start_pos + 4)
local carriage = rt_a:find("\r", 1, true)
if carriage then rta_display = rt_a:sub(1, carriage - 1)
else rta_display = rt_a:gsub("%s+$", "") end
else
last_rt = false
rt_b = rt_b:sub(1, start_pos - 1) .. new_chars .. rt_b:sub(start_pos + 4)
local carriage = rt_b:find("\r", 1, true)
if carriage then rtb_display = rt_b:sub(1, carriage - 1)
else rtb_display = rt_b:gsub("%s+$", "") end
end
end
end
end
render_menu()
end