Something went wrong. Try again.
A modern, network-enabled music player platform built on Rockbox technology. rockboxd.tsiry-sandratraina.com
rust deno navidrome airplay libadwaita zig mpris snapcast mpd rockbox audio subsonic
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287--[[ Lua rb settings reader / writer/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * * Copyright (C) 2026 William Wilgus * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/see https://www.rockbox.org/forums/index.php/topic,55820.0.html for an examplesee rocklib.c for definitive list of supported settingsrb.global_settings()rb.global_status()rb.audio_next_track()rb.audio_current_track()
NOTES:Not all settings are accessible from lua, for instance you can read char_ptrsbut writing them is not supported since we cannot guarantee the lifetime oncelua terminates, or settigns containing unions since its not possible to discernwhat the value is at compile time these items will be an opaque pointer to thestructure in memory but lua does not know how to decode it
If you are writing settings that you want to persist do not forget to callrb.settings_save() though not calling it does NOT guarantee a changed settingwon't be written behind your back so be sure to save the old valueand restore it when you are finished and call rb.settings_save()to ensure the old value gets saved
To Write stucts and arrays it is recommended to first make a call tonewval = settings_read('global_settings', 'setting.foo', 'system')and make changes to the returned table newval.foo = barfollowed by setting_writesettings_read('global_settings', 'rb.foo', 'system', newval)with the altered table.]]
rb.settings = rb.settings or {}
local var = {offset = 1, size = 2, type = 3, fields = 3}
local function bytesLE_n(str) str = str or "" local tbyte={str:byte(1, -1)} local bpos, num = 1, 0 for k = 1,#tbyte do -- (k = #t, 1, -1 for BE) num = num + tbyte[k] * bpos bpos = bpos * 256 --1<<8 end return numend
local function get_var_fields(s_var) -- converts member string into table -- var = {offset, size, "type"} s_var = s_var or "" local o, s, t = string.match(s_var, "(0x%x+),%s*(%d+),%s*(.+)") local tvar = {o, s, t}
return #tvar == var.fields and tvar or nilend
local function format_val(val, var_type) local ret, num
if var_type == nil then return nil elseif var_type == "str" then -- stop at first null byte, return nil if str doesn't exist return val and string.match(val, "^%Z+") or nil end
num = bytesLE_n(val) if string.find(var_type, "^b") then if(num <= 0) then ret = false else ret = true end elseif string.find(var_type, "^u_[cil]") then -- Lua integers are signed so we need to do a bit of extra processing ret = (string.format("%u", num)) else ret = num end
return retend
--[[ ex. dump_struct(rb.global_settings, rb.system.replaygain_settings, 0, [0x2c, 12, s_replaygain_settings])]]
local function dump_struct(t_settings, t_struct, n_elems, t_var) --Internal function dumps structs local tdata = {}
local function struct_get_elem(v, elem_offset) local val, offset, tvar1 tvar1 = get_var_fields(v) offset = t_var[var.offset] + tvar1[var.offset] + elem_offset val = t_settings(offset, tvar1[var.size]) return format_val(val, tvar1[var.type]) end
if n_elems > 0 then -- Array of structs, struct[elems]; local elemsize = (t_var[var.size] / n_elems) for i = 0, n_elems - 1 do tdata[i] = tdata[i] or {} for k1, v1 in pairs(t_struct) do tdata[i][k1] = struct_get_elem(v1, (elemsize * i)) end end else -- single struct, struct; for k1, v1 in pairs(t_struct) do tdata[k1] = struct_get_elem(v1, 0) end end return tdataend
--[[ ex. write_struct(rb.global_settings, rb.system.eq_band_setting, 10, [ 0x54, 120, s_eq_band_setting[10] ])]]local function write_struct(t_settings, t_struct, n_elems, t_var, tdata) --Internal function writes structs local function struct_write_elem(v, elem_offset, newval) local offset, tvar1 tvar1 = get_var_fields(v) offset = t_var[var.offset] + tvar1[var.offset] + elem_offset return t_settings(offset, tvar1[var.size], newval) == 1 end
if n_elems > 0 then -- Array of structs, struct[elems]; local elemsize = (t_var[var.size] / n_elems) for i = 0, n_elems - 1 do tdata[i] = tdata[i] or {} for k1, v1 in pairs(t_struct) do --tdata[i][k1] = struct_get_elem(v1, (elemsize * i)) if tdata[i][k1] ~= nil then if not struct_write_elem(v1, (elemsize * i), tdata[i][k1]) then return false end end end end else -- single struct, struct; for k1, v1 in pairs(t_struct) do if tdata[k1] ~= nil then if not struct_write_elem(v1, 0, tdata[k1]) then return false end end end end return trueend
local function get_array_elems(var_type) --extract the number of elements, returns 0 if not found local elems = string.match(var_type,".*%[(%d+)%]") return tonumber(elems) or 0end
local function get_struct_name(var_type) --extract the name of a struct, returns nil if not found return string.match(var_type,"^s_([^%[%]%s]+)")end
function rb.settings.read(s_settings, s_var, s_groupname) local data, val local tvar = get_var_fields(s_var) if tvar == nil then return nil end
local elems = get_array_elems(tvar[var.type]) local structname = get_struct_name(tvar[var.type])
local tsettings = rb[s_settings] if not tsettings then error(s_settings .. " does not exist") end
if structname and rb[s_groupname] then return dump_struct(tsettings, rb[s_groupname][structname], elems, tvar) end
local voffset, vsize, vtype = tvar[var.offset], tvar[var.size], tvar[var.type] if elems > 0 then -- Arrays of values, val[elems]; data = {} local elemsize = (vsize / elems)
for i = 0, elems - 1 do val = tsettings(voffset + (elemsize * i), elemsize) data[i] = format_val(val, vtype) end else -- Single value, val; if vtype == "ptr_char" then -- (**char) vtype = "str" val = tsettings(voffset, vsize, nil, true) else val = tsettings(voffset, vsize) end data = format_val(val, vtype) end return dataend
function rb.settings.write(s_settings, s_var, s_groupname, newval) local data, val local res = 0 local tvar = get_var_fields(s_var) if tvar == nil then return nil end
local elems = get_array_elems(tvar[var.type]) local structname = get_struct_name(tvar[var.type])
local tsettings = rb[s_settings] if not tsettings then error(s_settings .. " does not exist") end if not newval then error(s_settings .. " nothing to write") end
if structname and rb[s_groupname] then -- rb.splash(300, "struct " .. structname .. " - " .. s_groupname) if type (newval) ~= "table" then error("newval table expected got " .. type(newval)) end if not write_struct(tsettings, rb[s_groupname][structname], elems, tvar, newval) then error(s_groupname .. " writing failed") end return 1 end
local voffset, vsize, vtype = tvar[var.offset], tvar[var.size], tvar[var.type] if elems > 0 then if type (newval) ~= "table" then error("newval table expected got " .. type(newval)) end -- Arrays of values, val[elems]; local elemsize = (vsize / elems)
for i = 0, elems - 1 do if newval[i] ~= nil then if tsettings(voffset + (elemsize * i), elemsize, newval[i]) ~= 1 then res = 0 break end end end else -- Single value, val; if vtype == "ptr_char" then -- (**char) error(s_var .. " is a string pointer") else res = tsettings(voffset, vsize, newval) end end return resend
function rb.settings.dump(s_settings, s_groupname, s_structname, t_output, fn_filter) t_output = t_output or {} fn_filter = fn_filter or function(s,k) return true end local tgroup = rb[s_groupname] s_structname = s_structname or s_settings for k, v in pairs(tgroup[s_structname]) do if fn_filter(s_structname, k) then t_output[k] = rb.settings.read(s_settings, v, s_groupname) end end return t_outputend
return true