From 2dcb760581675e1ebc3e7cfa0a229199abe968ce Mon Sep 17 00:00:00 2001 From: KubaPro010 Date: Fri, 2 Jan 2026 00:09:21 +0100 Subject: [PATCH] ecc to be completed, and a lot in between --- examples/test.lua | 174 +++++++++++++++++++++++++++++++++++++++++----- plugin.c | 66 +++++++----------- plugin.lua | 4 +- 3 files changed, 187 insertions(+), 57 deletions(-) diff --git a/examples/test.lua b/examples/test.lua index b823ca9..b3d8ce1 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -1,26 +1,130 @@ set_console_mode(true) -set_font_size(24) + +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 oda_string = "" local ert_display = "" -local last_event = -1 +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) - last_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 = {} - oda_string = "" - ert_display = "" + 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 @@ -35,8 +139,13 @@ 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 @@ -44,13 +153,6 @@ function group(stream, b_corr, a, b, c, d) local target_group = (b & 0x1f) >> 1 if odas[target_group] == nil then odas[target_group] = { aid = d, version = (b & 1) } end - - 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 - else local ert_grp, ert_ver = findODAByAID(odas, 0x6552) @@ -60,11 +162,51 @@ function group(stream, b_corr, a, b, c, d) 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 ert_carriage = ert_string:find("\r", 1, true) - if ert_carriage then ert_display = ert_string:sub(1, ert_carriage - 1) + 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 - set_console(string.format("ODAs: %s\r\n\r\nERT: %s\r\n\r\nLast event: %d", oda_string:sub(1, #oda_string-2), ert_display, last_event)) + render_menu() end \ No newline at end of file diff --git a/plugin.c b/plugin.c index 6f67713..f8e2663 100644 --- a/plugin.c +++ b/plugin.c @@ -52,6 +52,22 @@ static HFONT g_hCurrentFont = NULL; #define IDC_MAIN_BUTTON 101 +#define WINDOW_HEIGHT 380 +#define WINDOW_WIDTH 545 +#define BUTTON_COUNT 6 + +#define STRINGIFY(x) #x +#define TOSTRING(x) STRINGIFY(x) + +#define EVENT_BUTTON(I) \ +HWND hButton_event##I = CreateWindowEx( \ + 0, "BUTTON", "Event " TOSTRING(I), \ + WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, \ + 10 + (75 * I), WINDOW_HEIGHT-62, \ + 70, 30, hWnd, \ + (HMENU)(IDC_MAIN_BUTTON + I), hInst, NULL \ +); + static const unsigned char EBU[127] = { 0xE1, 'a', 0xE9, 'e', 0xED, 'i', 0xF3, 'o', 0xFA, 'u', 'N', 0xC7, 0xAA, 0xDF, 'I', 0x00, 0xE2, 0xE4, 'e', 0xEB, 0xEE, 'i', 0xF4, 0xF6, 'u', 0xFC, 'n', 0xE7, 0xBA, 0x00, 'i', 0x00, @@ -94,7 +110,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) int controlId = LOWORD(wParam); if (controlId == IDC_MAIN_BUTTON) InitLua(); - else if (controlId > IDC_MAIN_BUTTON && controlId <= IDC_MAIN_BUTTON + 5) lua_event(controlId - IDC_MAIN_BUTTON); + else if (controlId > IDC_MAIN_BUTTON && controlId <= IDC_MAIN_BUTTON + BUTTON_COUNT) lua_event(controlId - IDC_MAIN_BUTTON); } break; case WM_DESTROY: @@ -119,7 +135,7 @@ void CreatePluginWindow(HWND hOwner) { "Lua Host Console", WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, - 480, 320, + WINDOW_WIDTH, WINDOW_HEIGHT, hOwner, NULL, hInst, @@ -130,53 +146,24 @@ void CreatePluginWindow(HWND hOwner) { WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY, - 10, 10, 480-25, 320-75, + 10, 10, WINDOW_WIDTH-25, WINDOW_HEIGHT-75, hWnd, NULL, hInst, NULL ); HWND hButton = CreateWindowEx( 0, "BUTTON", "Reload", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 10, 258, + 10, WINDOW_HEIGHT-62, 70, 30, hWnd, (HMENU)IDC_MAIN_BUTTON, hInst, NULL ); - HWND hButton_event1 = CreateWindowEx( - 0, "BUTTON", "Event 1", - WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 10+(75*1), 258, - 70, 30, hWnd, - (HMENU)(IDC_MAIN_BUTTON + 1), hInst, NULL - ); - HWND hButton_event2 = CreateWindowEx( - 0, "BUTTON", "Event 2", - WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 10+(75*2), 258, - 70, 30, hWnd, - (HMENU)(IDC_MAIN_BUTTON + 2), hInst, NULL - ); - HWND hButton_event3 = CreateWindowEx( - 0, "BUTTON", "Event 3", - WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 10+(75*3), 258, - 70, 30, hWnd, - (HMENU)(IDC_MAIN_BUTTON + 3), hInst, NULL - ); - HWND hButton_event4 = CreateWindowEx( - 0, "BUTTON", "Event 4", - WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 10+(75*4), 258, - 70, 30, hWnd, - (HMENU)(IDC_MAIN_BUTTON + 4), hInst, NULL - ); - HWND hButton_event5 = CreateWindowEx( - 0, "BUTTON", "Event 5", - WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - 10+(75*5), 258, - 70, 30, hWnd, - (HMENU)(IDC_MAIN_BUTTON + 5), hInst, NULL - ); + EVENT_BUTTON(1) + EVENT_BUTTON(2) + EVENT_BUTTON(3) + EVENT_BUTTON(4) + EVENT_BUTTON(5) + EVENT_BUTTON(6) HFONT hFont = CreateFont(18, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, FONT_NAME); SendMessage(hEditControl, WM_SETFONT, (WPARAM)hFont, TRUE); @@ -186,6 +173,7 @@ void CreatePluginWindow(HWND hOwner) { SendMessage(hButton_event3, WM_SETFONT, (WPARAM)hFont, TRUE); SendMessage(hButton_event4, WM_SETFONT, (WPARAM)hFont, TRUE); SendMessage(hButton_event5, WM_SETFONT, (WPARAM)hFont, TRUE); + SendMessage(hButton_event6, WM_SETFONT, (WPARAM)hFont, TRUE); HICON hIconBig = (HICON)SendMessage(hOwner, WM_GETICON, ICON_BIG, 0); HICON hIconSmall = (HICON)SendMessage(hOwner, WM_GETICON, ICON_SMALL, 0); diff --git a/plugin.lua b/plugin.lua index 96a3504..d2cc29d 100644 --- a/plugin.lua +++ b/plugin.lua @@ -57,8 +57,8 @@ function db.reset_values(key, value) end ---@return integer function db.count_records(key, value) end ----@param ch string ----@return string +---@param ch integer +---@return integer function db.char_conv(ch) end ---@param filename string