release
dev builds
extras
themes manual
wiki
device status forums
mailing lists
IRC bugs
patches
dev guide



Wiki > Main > PluginLua (compare)

Difference: PluginLua (r9 vs. r8)

Lua scripting language

Introduction

This plugin is an interpreter for the Lua language. To quote from the Lua website ( http://www.lua.org), Lua is a “powerful, fast, lightweight, embeddable scripting language”. Select a .lua file in the File Browser to run it. For more information on programming in Lua, please see http://www.lua.org/manual/5.1/ and http://www.lua.org/pil/.

There are a few exceptions/additions to the Lua support in Rockbox:

  • No floating point support.
    • The number type in Lua is usually float, however in the Rockbox implementation it is integer.
  • Non-supported libraries.
    • The coroutine and debug libraries are not supported.
  • Partially-supported libraries.
    • The math, os and package libraries are only partially supported.
  • Additional libraries.

Documentation of the API is still a work in progress, and the API itself is not finalised. For the latest information, see PluginLua?.

Note: Please note that if a script does not provide a way to exit, then the only way to exit will be to reset the player.

API

The plugin API and some Rockbox C functions are directly exposed in the rb table. Have a look at the source code for more info (like plugin.h and others).

To generate a /rb.txt file containing the keys of the rb object, you can run this code:

rb_obj = {}
for k, v in pairs(rb) do
    local the_type = type(v)..'s'
    if not rb_obj[the_type] then
        rb_obj[the_type] = {}
        end
    table.insert(rb_obj[the_type], k)
    end

local list = {}
for rb_type, rb_table in pairs(rb_obj) do
    table.insert(list, string.format('* %s *', rb_type))
    table.sort(rb_table)
    for _, v in ipairs(rb_table) do
        table.insert(list, v)
        end
    -- jump a line
    table.insert(list, '')
    end
local file = io.open('/rb.txt', "w+")
file:write(table.concat(list, '\n'))
file:close()

API list

As of Rockbox 3.9, the following are available:

Example

Note that the following example may not be up to date with the current version of the Lua plugin.

function sayhello(seconds)
  local message = string.format("Hello from LUA for %d seconds", 5)
  rb.splash(seconds, message)
end

-- Drawn an X on the screen
rb.lcd_clear_display()
rb.lcd_drawline(0, 0, rb.LCD_WIDTH, rb.LCD_HEIGHT)
rb.lcd_drawline(rb.LCD_WIDTH, 0, 0, rb.LCD_HEIGHT)
rb.lcd_update()

local seconds = 5

rb.sleep(5 * rb.HZ)

sayhello(seconds)

The following example will display a menu with four items. When the user selects the first item, he will enter a submenu with three items. You can go back to the main menu or exit out of the script either by selecting "Exit" (or "Return") on the menu, or by pressing the key that on your DAP returns to the last menu (on iPods is the left key). All the needed comments are done on the code.

It's a good example to learn how to work with the menu API, fundamental part of almost any Rockbox plugin.

-- Example script to demonstrate the development of a simple Rockbox plugin in LUA.
-- Written by Gabriel Maia (gbl08ma on the Rockbox community).
-- Licensed under GNU GPL v2 or, at your choice, any later version.

-- Function to display the main menu of this script
function ShowMainMenu() -- we invoke this function every time we want to display the main menu of the script
    mainmenu = {"Item 1", "Item 2", "Item 3", "Exit"} -- define the items of the menu

    while true do -- don't exit of program until user selects Exit
        s = rb.do_menu("Test", mainmenu, nil, false) -- actually tell Rockbox to draw the menu
        
        -- In the line above: "Test" is the title of the menu, mainmenu is an array with the items
        -- of the menu, nil is a null value that needs to be there, and the last parameter is
        -- whether the theme should be drawn on the menu or not.
        -- the variable s will hold the index of the selected item on the menu.
        -- the index is zero based. This means that the first item is 0, the second one is 1, etc.
        if     s == 0 then ShowSubmenu1()
        elseif s == 1 then rb.splash(2 * rb.HZ, "You selected Item 2") --show a message for two seconds
        elseif s == 2 then rb.splash(2 * rb.HZ, "You selected Item 3")
        elseif s == 3 then os.exit() -- User selected to exit
        elseif s == -2 then os.exit() -- -2 index is returned from do_menu() when user presses the key to exit the menu (on iPods, it's the left key).
                                      -- In this case, user probably wants to exit (or go back to last menu).
        else rb.splash(2 * rb.HZ, "Error! Selected index: " .. s) -- something strange happened. The program shows this message when
                                                                  -- the selected item is not on the index from 0 to 3 (in this case), and displays
                                                                  -- the selected index. Having this type of error handling is not
                                                                  -- required, but it might be nice to have specially while you're still
                                                                  -- developing the plugin.
        end
    end
end

-- Submenu 1
function ShowSubmenu1() -- function to draw the submenu 1, which will be displayed when
                        -- user selects Item 1 on main menu
    submenu1 = {"Sub Item 1", "Sub Item 2", "Return"} -- define the items of the menu

    while true do -- don't exit of program until user selects Exit
        s1 = rb.do_menu("Item 1 menu", submenu1, nil, false)

        if     s1 == 0 then rb.splash(2 * rb.HZ, "You selected Sub Item 1") --show a message for two seconds
        elseif s1 == 1 then rb.splash(2 * rb.HZ, "You selected Sub Item 2")
        elseif s1 == 2 then ShowMainMenu() -- return to the main menu, display it again
        elseif s1 == -2 then ShowMainMenu() -- user seems to want to go back
        else rb.splash(2 * rb.HZ, "Error! Selected index: " .. s) 
        end
    end
end

-- code written out of any function will be executed when the file is "played" on the file browser.
-- if you don't put anything out of a function (not even a call to the main function, like we do here),
-- the script will simply do nothing.
ShowMainMenu() -- start the program by displaying the main menu of the script.

There's also a helloworld example script in SVN, see apps/plugins/helloworld.lua

Most if not all the functions listed in plugins.h will work in a LUA program, take note that some of the functions are dedicated to certain ports 
only. Here's an example script of playing an MP3 file in a LUA program(This will work only on ports with software decoding, unlike the 
Archos port with a dedicated DSP chip):


-- Helper function which reads the contents of a file(This function is from the helloworld.lua example above)
function file_get_contents(filename)
    local file = io.open(filename, "r")
    if not file then
        return nil
    end

    local contents = file:read("*all") -- See Lua manual for more information
    file:close() -- GC takes care of this if you would've forgotten it

    return contents
end

rb.lcd_clear_display()
file_put_contents("/temp.m3u8","/test.mp3")
rb.playlist_create("/","temp.m3u8")
rb.playlist_start(0,0)
rb.sleep(3 * rb.HZ)
repeat
   BtnInput = rb.get_action(rb.contexts.CONTEXT_STD, rb.HZ)
until BtnInput == rb.actions.ACTION_STD_OK

This takes advantage of the playlist functions and plays the mp3 in the background, by writing a temporary playlist file and then playing the playlist. 
You can rewrite the playlist file over an over just by including the path/file-name of the song file in the playlist and then loading and starting the playlist.


CategoryPlugin: Lua interpreter [Sansa ClipDONE, Sansa FuzeDONE, Sansa e200DONE, Sansa c200DONE, iPod 1G2GDONE, iPod 3GDONE, iPod 4GDONE, iPod ColorDONE, iPod VideoDONE, iPod MiniDONE, iPod NanoDONE, GigabeatDONE, MR-100DONE, iAudio M5DONE, iAudio X5DONE, H100DONE, H300DONE, H10DONE]

r9 - 11 Aug 2011 - 00:34:11 - NickWinston?

Revision r9 - 11 Aug 2011 - 00:34 - NickWinston?
Revision r8 - 24 Jul 2011 - 17:13 - StevenDick?
Copyright by the contributing authors.