summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Wilgus <wilgus.william@gmail.com>2024-05-04 08:41:16 -0400
committerWilliam Wilgus <wilgus.william@gmail.com>2024-05-05 14:01:43 -0400
commitd7c541742f5e6ec07dbcc8e1346efde9d807437e (patch)
tree2c3325b652999bd9b2443eb96d8d32035d3c4c18
parentefcea6628024c5f6796c3850c3779801db4b6874 (diff)
downloadrockbox-d7c541742f.tar.gz
rockbox-d7c541742f.zip
Allow first level folders in plugin menu
add sorting directories as files move picross files to a hidden folder use directory for lua_scripts, sgt_puzzles make plugin browser able to handle 1st level directories Change-Id: I30852d71dc992c378d5790756e94f06f5a2e9bef
-rw-r--r--apps/filetree.c68
-rw-r--r--apps/plugins/CATEGORIES1
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/lua/include_lua/dbgettags.lua119
-rwxr-xr-xapps/plugins/lua/include_lua/filebrowse.lua241
-rwxr-xr-xapps/plugins/lua/include_lua/fileviewers.lua468
-rw-r--r--apps/plugins/lua/lua.make12
-rw-r--r--apps/plugins/lua_scripts/lua_scripts.lua172
-rw-r--r--apps/plugins/lua_scripts/lua_scripts.make4
-rw-r--r--apps/plugins/picross.lua8
-rw-r--r--apps/plugins/picross/picross.make4
-rw-r--r--apps/settings.h2
-rw-r--r--apps/tree.c9
-rwxr-xr-xtools/buildzip.pl28
14 files changed, 1079 insertions, 58 deletions
diff --git a/apps/filetree.c b/apps/filetree.c
index b5f5dece5a..594a0bd6f1 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -224,7 +224,11 @@ static int compare(const void* p1, const void* p2)
struct entry* e2 = (struct entry*)p2;
int criteria;
- if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY)
+ if (cmp_data.sort_dir == SORT_AS_FILE)
+ { /* treat as two files */
+ criteria = global_settings.sort_file;
+ }
+ else if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY)
{ /* two directories */
criteria = cmp_data.sort_dir;
@@ -326,18 +330,17 @@ int ft_load(struct tree_context* c, const char* tempdir)
info = dir_get_info(dir, entry);
len = strlen((char *)entry->d_name);
- /* skip directories . and .. */
- if ((info.attribute & ATTR_DIRECTORY) &&
- (((len == 1) && (!strncmp((char *)entry->d_name, ".", 1))) ||
- ((len == 2) && (!strncmp((char *)entry->d_name, "..", 2))))) {
- continue;
- }
-
/* Skip FAT volume ID */
if (info.attribute & ATTR_VOLUME_ID) {
continue;
}
+ dptr->attr = info.attribute;
+ int dir_attr = (dptr->attr & ATTR_DIRECTORY);
+ /* skip directories . and .. */
+ if (dir_attr && is_dotdir_name(entry->d_name))
+ continue;
+
/* filter out dotfiles and hidden files */
if (*c->dirfilter != SHOW_ALL &&
((entry->d_name[0]=='.') ||
@@ -345,48 +348,45 @@ int ft_load(struct tree_context* c, const char* tempdir)
continue;
}
- dptr->attr = info.attribute;
- int dir_attr = (dptr->attr & ATTR_DIRECTORY);
-
/* check for known file types */
if ( !(dir_attr) )
dptr->attr |= filetype_get_attr((char *)entry->d_name);
int file_attr = (dptr->attr & FILE_ATTR_MASK);
+#define CHK_FT(show,attr) (*c->dirfilter == (show) && file_attr != (attr))
/* filter out non-visible files */
- if ((!(dir_attr) && ((*c->dirfilter == SHOW_PLAYLIST &&
- file_attr != FILE_ATTR_M3U) ||
- ((*c->dirfilter == SHOW_MUSIC && file_attr != FILE_ATTR_AUDIO) &&
- file_attr != FILE_ATTR_M3U) ||
+ if ((!(dir_attr) && (CHK_FT(SHOW_PLAYLIST, FILE_ATTR_M3U) ||
+ (CHK_FT(SHOW_MUSIC, FILE_ATTR_AUDIO) && file_attr != FILE_ATTR_M3U) ||
(*c->dirfilter == SHOW_SUPPORTED && !filetype_supported(dptr->attr)))) ||
- (*c->dirfilter == SHOW_WPS && file_attr != FILE_ATTR_WPS) ||
- (*c->dirfilter == SHOW_FONT && file_attr != FILE_ATTR_FONT) ||
- (*c->dirfilter == SHOW_SBS && file_attr != FILE_ATTR_SBS) ||
+ CHK_FT(SHOW_WPS, FILE_ATTR_WPS) ||
+ CHK_FT(SHOW_FONT, FILE_ATTR_FONT) ||
+ CHK_FT(SHOW_SBS, FILE_ATTR_SBS) ||
#if CONFIG_TUNER
- (*c->dirfilter == SHOW_FMS && file_attr != FILE_ATTR_FMS) ||
+ CHK_FT(SHOW_FMS, FILE_ATTR_FMS) ||
+ CHK_FT(SHOW_FMR, FILE_ATTR_FMR) ||
#endif
#ifdef HAVE_REMOTE_LCD
- (*c->dirfilter == SHOW_RWPS && file_attr != FILE_ATTR_RWPS) ||
- (*c->dirfilter == SHOW_RSBS && file_attr != FILE_ATTR_RSBS) ||
+ CHK_FT(SHOW_RWPS, FILE_ATTR_RWPS) ||
+ CHK_FT(SHOW_RSBS, FILE_ATTR_RSBS) ||
#if CONFIG_TUNER
- (*c->dirfilter == SHOW_RFMS && file_attr != FILE_ATTR_RFMS) ||
-#endif
+ CHK_FT(SHOW_RFMS, FILE_ATTR_RFMS) ||
#endif
-#if CONFIG_TUNER
- (*c->dirfilter == SHOW_FMR && file_attr != FILE_ATTR_FMR) ||
#endif
- (*c->dirfilter == SHOW_M3U && file_attr != FILE_ATTR_M3U) ||
- (*c->dirfilter == SHOW_CFG && file_attr != FILE_ATTR_CFG) ||
- (*c->dirfilter == SHOW_LNG && file_attr != FILE_ATTR_LNG) ||
- (*c->dirfilter == SHOW_MOD && file_attr != FILE_ATTR_MOD) ||
- (*c->dirfilter == SHOW_PLUGINS && file_attr != FILE_ATTR_ROCK &&
- file_attr != FILE_ATTR_LUA &&
- file_attr != FILE_ATTR_OPX) ||
+ CHK_FT(SHOW_M3U, FILE_ATTR_M3U) ||
+ CHK_FT(SHOW_CFG, FILE_ATTR_CFG) ||
+ CHK_FT(SHOW_LNG, FILE_ATTR_LNG) ||
+ CHK_FT(SHOW_MOD, FILE_ATTR_MOD) ||
+ /* show first level directories */
+ ((!(dir_attr) || c->dirlevel > 0) &&
+ CHK_FT(SHOW_PLUGINS, FILE_ATTR_ROCK) &&
+ file_attr != FILE_ATTR_LUA &&
+ file_attr != FILE_ATTR_OPX) ||
(callback_show_item && !callback_show_item(entry->d_name, dptr->attr, c)))
{
continue;
}
+#undef CHK_FT
if (len > c->cache.name_buffer_size - name_buffer_used - 1) {
/* Tell the world that we ran out of buffer space */
@@ -408,7 +408,9 @@ int ft_load(struct tree_context* c, const char* tempdir)
c->dirlength = files_in_dir;
closedir(dir);
- cmp_data.sort_dir = c->sort_dir;
+ /* allow directories to be sorted into file list */
+ cmp_data.sort_dir = (*c->dirfilter == SHOW_PLUGINS) ? SORT_AS_FILE : c->sort_dir;
+
if (global_settings.sort_case)
{
if (global_settings.interpret_numbers == SORT_INTERPRET_AS_NUMBER)
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES
index db0eb70fc4..c91d02ade8 100644
--- a/apps/plugins/CATEGORIES
+++ b/apps/plugins/CATEGORIES
@@ -57,7 +57,6 @@ lastfm_scrobbler_viewer,viewers
logo,demos
lrcplayer,apps
lua,viewers
-lua_scripts,demos
fractals,demos
main_menu_config,apps
matrix,demos
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index ff08074f82..8028758ef0 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -117,7 +117,6 @@ metronome.c
#if PLUGIN_BUFFER_SIZE >= 0x80000
boomshine.lua
picross.lua
-lua_scripts.lua
#ifdef HAVE_LCD_COLOR
pixel-painter.lua
#endif /* HAVE_LCD_COLOR */
diff --git a/apps/plugins/lua/include_lua/dbgettags.lua b/apps/plugins/lua/include_lua/dbgettags.lua
new file mode 100644
index 0000000000..8e9f26393d
--- /dev/null
+++ b/apps/plugins/lua/include_lua/dbgettags.lua
@@ -0,0 +1,119 @@
+-- dbgettags.lua Bilgus 2017
+--[[
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2017 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.
+ *
+ ****************************************************************************/
+]]
+
+require("actions")
+local CANCEL_BUTTON = rb.actions.PLA_CANCEL
+
+local sINVALIDDATABASE = "Invalid Database"
+local sERROROPENING = "Error opening"
+
+-- tag cache header
+sTCVERSION = string.char(0x10)
+sTCHEADER = string.reverse("TCH" .. sTCVERSION)
+DATASZ = 4 -- int32_t
+TCHSIZE = 3 * DATASZ -- 3 x int32_t
+
+-- Converts array of bytes to proper endian
+function bytesLE_n(str)
+ str = str or ""
+ local tbyte={str:byte(1, -1)}
+ local bpos = 1
+ local num = 0
+ for k = 1,#tbyte do -- (k = #t, 1, -1 for BE)
+ num = num + tbyte[k] * bpos
+ bpos = bpos * 256
+ end
+ return num
+end
+
+-- uses database files to retrieve database tags
+-- adds all unique tags into a lua table
+-- ftable is optional
+function get_tags(filename, hstr, ftable)
+
+ if not filename then return end
+ if not ftable then ftable = {} end
+ hstr = hstr or filename
+
+ local file = io.open('/' .. filename or "", "r") --read
+ if not file then rb.splash(100, sERROROPENING .. " " .. filename) return end
+
+ local fsz = file:seek("end")
+
+ local posln = 0
+ local tag_len = TCHSIZE
+ local idx
+
+ local function readchrs(count)
+ if posln >= fsz then return nil end
+ file:seek("set", posln)
+ posln = posln + count
+ return file:read(count)
+ end
+
+ -- check the header and get size + #entries
+ local tagcache_header = readchrs(DATASZ) or ""
+ local tagcache_sz = readchrs(DATASZ) or ""
+ local tagcache_entries = readchrs(DATASZ) or ""
+
+ if tagcache_header ~= sTCHEADER or
+ bytesLE_n(tagcache_sz) ~= (fsz - TCHSIZE) then
+ rb.splash(100, sINVALIDDATABASE .. " " .. filename)
+ return
+ end
+
+ -- local tag_entries = bytesLE_n(tagcache_entries)
+
+ for k, v in pairs(ftable) do ftable[k] = nil end -- clear table
+ ftable[1] = hstr
+
+ local tline = #ftable + 1
+ ftable[tline] = ""
+
+ local str = ""
+
+ while true do
+ tag_len = bytesLE_n(readchrs(DATASZ))
+ readchrs(DATASZ) -- idx = bytesLE_n(readchrs(DATASZ))
+ str = readchrs(tag_len) or ""
+ str = string.match(str, "(%Z+)%z") -- \0 terminated string
+
+ if str then
+ if ftable[tline - 1] ~= str then -- Remove dupes
+ ftable[tline] = str
+ tline = tline + 1
+ end
+ elseif posln >= fsz then
+ break
+ end
+
+ if rb.get_plugin_action(0) == CANCEL_BUTTON then
+ break
+ end
+ end
+
+ file:close()
+
+ return ftable
+end -- get_tags
diff --git a/apps/plugins/lua/include_lua/filebrowse.lua b/apps/plugins/lua/include_lua/filebrowse.lua
new file mode 100755
index 0000000000..0640ec3764
--- /dev/null
+++ b/apps/plugins/lua/include_lua/filebrowse.lua
@@ -0,0 +1,241 @@
+--[[
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2017 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.
+ *
+ ****************************************************************************/
+]]
+if ... == nil then rb.splash(rb.HZ * 3, "use 'require'") end
+require("printtable")
+local _lcd = require("lcd")
+local _timer = require("timer")
+
+--------------------------------------------------------------------------------
+--[[ returns a sorted tables of directories and (another) of files
+-- path is the starting path; norecurse == true.. only that path will be searched
+-- findfile & finddir are definable search functions
+-- if not defined all files/dirs are returned if false is passed.. none
+-- or you can provide your own function see below..
+-- f_t and d_t allow you to pass your own tables for re-use but isn't necessary
+]]
+local function get_files(path, norecurse, finddir, findfile, sort_by, f_t, d_t)
+ local quit = false
+ local sort_by_function -- forward declaration
+ local filepath_function -- forward declaration
+ local files = f_t or {}
+ local dirs = d_t or {}
+
+ local function f_filedir(name)
+ --default find function
+ -- example: return name:find(".mp3", 1, true) ~= nil
+ if name:len() <= 2 and (name == "." or name == "..") then
+ return false
+ end
+ return true
+ end
+ local function d_filedir(name)
+ --default discard function
+ return false
+ end
+
+ if finddir == nil then
+ finddir = f_filedir
+ elseif type(finddir) ~= "function" then
+ finddir = d_filedir
+ end
+
+ if findfile == nil then
+ findfile = f_filedir
+ elseif type(findfile) ~= "function" then
+ findfile = d_filedir
+ end
+
+ local function _get_files(path, cancelbtn)
+ local sep = ""
+ local filepath
+ local finfo_t
+ if string.sub(path, - 1) ~= "/" then sep = "/" end
+ for fname, isdir, finfo_t in luadir.dir(path, true) do
+ if isdir and finddir(fname) then
+ table.insert(dirs, path .. sep ..fname)
+ elseif not isdir and findfile(fname) then
+ filepath = filepath_function(path, sep, fname, finfo_t.attribute, finfo_t.size, finfo_t.time)
+ table.insert(files, filepath)
+ end
+
+ if rb.get_plugin_action(0) == cancelbtn then
+ return true
+ end
+ end
+ end
+
+
+
+ local function cmp_alphanum (op1, op2)
+ local type1= type(op1)
+ local type2 = type(op2)
+
+ if type1 ~= type2 then
+ return type1 < type2
+ else
+ if type1 == "string" then
+ op1 = op1:upper()
+ op2 = op2:upper()
+ return sort_by_function(op1, op2)
+ end
+ return op1 < op2
+ end
+ end
+
+ _lcd:splashf(1, "Searching for Files")
+
+ if sort_by == "name" then
+ sort_by_function = function(s1, s2) return s1 < s2 end
+ filepath_function = function(path, sep, fname, fattrib, fsize, ftime)
+ return string.format("%s%s%s;", path, sep, fname)
+ end
+ elseif sort_by == "size" then
+ filepath_function = function(path, sep, fname, fattrib, fsize, ftime)
+ return string.format("%s%s%s; At:%d, Sz:%d, Tm:%d", path, sep, fname, fattrib, fsize, ftime)
+ end
+ sort_by_function = function(s1, s2)
+ local v1, v2
+ v1 = string.match(s1, "SZ:(%d+)")
+ v2 = string.match(s2, "SZ:(%d+)")
+ if v1 or v2 then
+ return tonumber(v1 or 0) < tonumber(v2 or 0)
+ end
+ return s1 < s2
+ end
+ elseif sort_by == "date" then
+ filepath_function = function(path, sep, fname, fattrib, fsize, ftime)
+ return string.format("%s%s%s; At:%d, Sz:%d, Tm:%d", path, sep, fname, fattrib, fsize, ftime)
+ end
+ sort_by_function = function(s1, s2)
+ local v1, v2
+ v1 = string.match(s1, "TM:(%d+)")
+ v2 = string.match(s2, "TM:(%d+)")
+ if v1 or v2 then
+ return tonumber(v1 or 0) < tonumber(v2 or 0)
+ end
+ return s1 < s2
+ end
+ end
+
+ table.insert(dirs, path) -- root
+
+ for key,value in pairs(dirs) do
+ --luadir.dir may error out so we need to do the call protected
+ -- _get_files(value, CANCEL_BUTTON)
+ _, quit = pcall(_get_files, value, CANCEL_BUTTON)
+
+ if quit == true or norecurse then
+ break;
+ end
+ end
+
+ table.sort(files, cmp_alphanum)
+ table.sort(dirs, cmp_alphanum)
+
+ return dirs, files
+end -- get_files
+--------------------------------------------------------------------------------
+
+-- uses print_table and get_files to display simple file browser
+-- sort_by "date" "name" "size"
+-- descending true/false
+function file_choose(dir, title, sort_by, descending)
+ local dstr, hstr = ""
+ if not title then
+ dstr = "%d items found in %0d.%02d seconds"
+ else
+ hstr = title
+ end
+
+ if not sort_by then sort_by = "name" end
+ sort_by = sort_by:lower()
+
+ -- returns whole seconds and remainder
+ local function tick2seconds(ticks)
+ local secs = (ticks / rb.HZ)
+ local csecs = (ticks - (secs * rb.HZ))
+ return secs, csecs
+ end
+
+ local norecurse = true
+ local f_finddir = nil -- function to match directories; nil all, false none
+ local f_findfile = nil -- function to match files; nil all, false none
+
+ local p_settings = {wrap = true, hasheader = true}
+
+ local timer
+ local files = {}
+ local dirs = {}
+ local item = 1
+ _lcd:clear()
+
+ while item > 0 do
+ if not title then
+ timer = _timer()
+ end
+
+ dirs, files = get_files(dir, norecurse, f_finddir, f_findfile, sort_by, dirs, files)
+
+ local parentdir = dirs[1]
+ for i = 1, #dirs do
+ dirs[i] = "\t" .. dirs[i]
+ end
+
+ if not descending then
+ for i = 1, #files do
+ -- only store file name .. strip attributes from end
+ table.insert(dirs, "\t" .. string.match(files[i], "[^;]+") or "?")
+ end
+ else
+ for i = #files, 1, -1 do
+ -- only store file name .. strip attributes from end
+ table.insert(dirs, "\t" .. string.match(files[i], "[^;]+") or "?")
+ end
+ end
+ for i=1, #files do files[i] = nil end -- empty table for reuse
+
+ if not title then
+ hstr = string.format(dstr, #dirs - 1, tick2seconds(timer:stop()))
+ end
+
+ table.insert(dirs, 1, hstr)
+
+ item = print_table(dirs, #dirs, p_settings)
+
+ -- If item was selected follow directory or return filename
+ if item > 0 then
+ dir = string.gsub(dirs[item], "%c+","")
+ if not rb.dir_exists("/" .. dir) then
+ return dir
+ end
+ end
+
+ if dir == parentdir then
+ dir = dir:sub(1, dir:match(".*()/") - 1)
+ if dir == "" then dir = "/" end
+ end
+ for i=1, #dirs do dirs[i] = nil end -- empty table for reuse
+
+ end
+end -- file_choose
+--------------------------------------------------------------------------------
diff --git a/apps/plugins/lua/include_lua/fileviewers.lua b/apps/plugins/lua/include_lua/fileviewers.lua
new file mode 100755
index 0000000000..c686f3eeda
--- /dev/null
+++ b/apps/plugins/lua/include_lua/fileviewers.lua
@@ -0,0 +1,468 @@
+--[[
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2017 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.
+ *
+ ****************************************************************************/
+]]
+if ... == nil then rb.splash(rb.HZ * 3, "use 'require'") end
+require("printtable")
+local _clr = require("color")
+local _lcd = require("lcd")
+local _print = require("print")
+local _timer = require("timer")
+
+require("actions")
+local CANCEL_BUTTON = rb.actions.PLA_CANCEL
+--------------------------------------------------------------------------------
+-- builds an index of byte position of every line at each bufsz increment
+-- in filename; bufsz == 1 would be every line; saves to filename.ext.idx_ext
+-- lnbyte should be nil for text files and number of bytes per line for binary
+local function build_file_index(filename, idx_ext, bufsz, lnbyte)
+
+ if not filename then return end
+ local file = io.open('/' .. filename, "r") --read
+ if not file then _lcd:splashf(100, "Can't open %s", filename) return end
+ local fsz = file:seek("end")
+ local fsz_kb = fsz / 1024
+ local count
+ local ltable = {0} --first index is the beginning of the file
+ local timer = _timer()
+ local fread
+ _lcd:splashf(100, "Indexing file %d Kb", (fsz / 1024))
+
+ if lnbyte then
+ fread = function(f) return f:read(lnbyte) end
+ else
+ lnbyte = -1
+ fread = function(f) return f:read("*l") end
+ end
+
+ file:seek("set", 0)
+ for i = 1, fsz do
+ if i % bufsz == 0 then
+ local loc = file:seek()
+ ltable[#ltable + 1] = loc
+ _lcd:splashf(1, "Parsing %d of %d Kb", loc / 1024, fsz_kb)
+ end
+ if rb.get_plugin_action(0) == CANCEL_BUTTON then
+ return
+ end
+ if not fread(file) then
+ count = i
+ break
+ end
+ end
+
+ local fileidx = io.open('/' .. filename .. idx_ext, "w+") -- write/erase
+ if fileidx then
+ fileidx:write(fsz .. "\n")
+ fileidx:write(count .. "\n")
+ fileidx:write(bufsz .. "\n")
+ fileidx:write(lnbyte .. "\n")
+ fileidx:write(table.concat(ltable, "\n"))
+ fileidx:close()
+ _lcd:splashf(100, "Finished in %d seconds", timer.stop() / rb.HZ)
+ collectgarbage("collect")
+ else
+ error("unable to save index file")
+ end
+end -- build_file_index
+--------------------------------------------------------------------------------
+
+--- returns size of original file, total lines buffersize, and table filled
+-- with line offsets in index file -> filename
+local function load_index_file(filename)
+ local filesz, count, bufsz, lnbyte
+ local ltable
+ local fileidx = io.open('/' .. filename, "r") --read
+ if fileidx then
+ local idx = -3
+ ltable = {}
+ fileidx:seek("set", 0)
+ for line in fileidx:lines() do
+ if idx == -3 then
+ filesz = tonumber(line)
+ elseif idx == -2 then
+ count = tonumber(line)
+ elseif idx == -1 then
+ bufsz = tonumber(line)
+ elseif idx == 0 then
+ lnbyte = tonumber(line)
+ else
+ ltable[idx] = tonumber(line)
+ end
+ idx = idx + 1
+ end
+ fileidx:close()
+ end
+ return lnbyte, filesz, count, bufsz, ltable
+end -- load_index_file
+--------------------------------------------------------------------------------
+
+-- creates a fixed index with fixed line lengths, perfect for viewing hex files
+-- not so great for reading text files but works as a fallback
+local function load_fixed_index(bytesperline, filesz, bufsz)
+ local lnbyte = bytesperline
+ local count = (filesz + lnbyte - 1) / lnbyte + 1
+ local idx_t = {} -- build index
+ for i = 0, filesz, bufsz do
+ idx_t[#idx_t + 1] = lnbyte * i
+ end
+ return lnbyte, filesz, count, bufsz, idx_t
+end -- load_fixed_index
+--------------------------------------------------------------------------------
+
+-- uses print_table to display a whole file
+function print_file(filename, maxlinelen, settings)
+
+ if not filename then return end
+ local file = io.open('/' .. filename or "", "r") --read
+ if not file then _lcd:splashf(100, "Can't open %s", filename) return end
+ maxlinelen = 33
+ local hstr = filename
+ local ftable = {}
+ table.insert(ftable, 1, hstr)
+
+ local tline = #ftable + 1
+ local remln = maxlinelen
+ local posln = 1
+
+ for line in file:lines() do
+ if line then
+ if maxlinelen then
+ if line == "" then
+ ftable[tline] = ftable[tline] or ""
+ tline = tline + 1
+ remln = maxlinelen
+ else
+ line = line:match("%w.+") or ""
+ end
+ local linelen = line:len()
+ while linelen > 0 do
+
+ local fsp = line:find("%s", posln + remln - 5) or 0x0
+ fsp = fsp - (posln + remln)
+ if fsp >= 0 then
+ local fspr = fsp
+ fsp = line:find("%s", posln + remln) or linelen
+ fsp = fsp - (posln + remln)
+ if math.abs(fspr) < fsp then fsp = fspr end
+ end
+ if fsp > 5 or fsp < -5 then fsp = 0 end
+
+ local str = line:sub(posln, posln + remln + fsp)
+ local slen = str:len()
+ ftable[tline] = ftable[tline] or ""
+ ftable[tline] = ftable[tline] .. str
+ linelen = linelen - slen
+ if linelen > 0 then
+ tline = tline + 1
+ posln = posln + slen
+ remln = maxlinelen
+ --loop continues
+ else
+ ftable[tline] = ftable[tline] .. " "
+ remln = maxlinelen - slen
+ posln = 1
+ --loop ends
+ end
+
+ end
+ else
+ ftable[#ftable + 1] = line
+ end
+
+
+ end
+ end
+
+ file:close()
+
+ _lcd:clear()
+ _print.clear()
+
+ if not settings then
+ settings = {}
+ settings.justify = "center"
+ settings.wrap = true
+ settings.msel = true
+ end
+ settings.hasheader = true
+ settings.co_routine = nil
+ settings.ovfl = "manual"
+
+ local sel =
+ print_table(ftable, #ftable, settings)
+
+ _lcd:splashf(rb.HZ * 2, "%d items {%s}", #sel, table.concat(sel, ", "))
+ ftable = nil
+end -- print_file
+--------------------------------------------------------------------------------
+
+-- uses print_table to display a portion of a file
+function print_file_increment(filename, settings)
+
+ if not filename then return end
+ local file = io.open('/' .. filename, "r") --read
+ if not file then _lcd:splashf(100, "Can't open %s", filename) return end
+ local fsz = file:seek("end")
+ local bsz = 1023
+ --if small file do it the easier way and load whole file to table
+ if fsz < 60 * 1024 then
+ file:close()
+ print_file(filename, settings)
+ return
+ end
+
+ local ext = ".idx"
+ local lnbyte, filesz, count, bufsz, idx_t = load_index_file(filename .. ext)
+
+ if not idx_t or fsz ~= filesz then -- build file index
+ build_file_index(filename, ext, bsz)
+ lnbyte, filesz, count, bufsz, idx_t = load_index_file(filename .. ext)
+ end
+
+ -- if invalid or user canceled creation fallback to a fixed index
+ if not idx_t or fsz ~= filesz or count <= 0 then
+ _lcd:splashf(rb.HZ * 5, "Unable to read file index %s", filename .. ext)
+ lnbyte, filesz, count, bufsz, idx_t = load_fixed_index(32, fsz, bsz)
+ end
+
+ if not idx_t or fsz ~= filesz or count <= 0 then
+ _lcd:splashf(rb.HZ * 5, "Unable to load file %s", filename)
+ return
+ end
+
+ local hstr = filename
+ local file_t = setmetatable({},{__mode = "kv"}) --weak keys and values
+ -- this allows them to be garbage collected as space is needed
+ -- rebuilds when needed
+ local ovf = 0
+ local lpos = 1
+ local timer = _timer()
+ file:seek("set", 0)
+
+ function print_co()
+ while true do
+ collectgarbage("step")
+ file_t[1] = hstr --position 1 is ALWAYS header/title
+
+ for i = 1, bufsz + ovf do
+ file_t[lpos + i] = file:read ("*l")
+ end
+ ovf = 0
+ lpos = lpos + bufsz
+
+ local bpos = coroutine.yield()
+
+ if bpos <= lpos then -- roll over or scroll up
+ bpos = (bpos - bufsz) + bpos % bufsz
+ timer:check(true)
+ end
+
+ lpos = bpos - bpos % bufsz
+
+ if lpos < 1 then
+ lpos = 1
+ elseif lpos > count - bufsz then -- partial fill
+ ovf = count - bufsz - lpos
+ end
+ --get position in file of the nearest indexed line
+ file:seek("set", idx_t[bpos / bufsz + 1])
+
+ -- on really large files if it has been more than 10 minutes
+ -- since the user scrolled up the screen wipe out the prior
+ -- items to free memory
+ if lpos % 5000 == 0 and timer:check() > rb.HZ * 600 then
+ for i = 1, lpos - 100 do
+ file_t[i] = nil
+ end
+ end
+
+ end
+ end
+
+ co = coroutine.create(print_co)
+ _lcd:clear()
+ _print.clear()
+
+ if not settings then
+ settings = {}
+ settings.justify = "center"
+ settings.wrap = true
+ end
+ settings.hasheader = true
+ settings.co_routine = co
+ settings.msel = false
+ settings.ovfl = "manual"
+
+ table.insert(file_t, 1, hstr) --position 1 is header/title
+ local sel =
+ print_table(file_t, count, settings)
+ file:close()
+ idx_t = nil
+ file_t = nil
+ return sel
+end --print_file_increment
+--------------------------------------------------------------------------------
+function print_file_hex(filename, bytesperline, settings)
+
+ if not filename then return end
+ local file = io.open('/' .. filename, "r") --read
+ if not file then _lcd:splashf(100, "Can't open %s", filename) return end
+ local hstr = filename
+ local bpl = bytesperline
+ local fsz = file:seek("end")
+--[[
+ local filesz = file:seek("end")
+ local bufsz = 1023
+ local lnbyte = bytesperline
+ local count = (filesz + lnbyte - 1) / lnbyte + 1
+
+ local idx_t = {} -- build index
+ for i = 0, filesz, bufsz do
+ idx_t[#idx_t + 1] = lnbyte * i
+ end]]
+
+ local lnbyte, filesz, count, bufsz, idx_t = load_fixed_index(bpl, fsz, 1023)
+
+ local file_t = setmetatable({},{__mode = "kv"}) --weak keys and values
+ -- this allows them to be garbage collected as space is needed
+ -- rebuilds when needed
+ local ovf = 0
+ local lpos = 1
+ local timer = _timer()
+ file:seek("set", 0)
+
+ function hex_co()
+ while true do
+ collectgarbage("step")
+ file_t[1] = hstr --position 1 is ALWAYS header/title
+
+ for i = 1, bufsz + ovf do
+ local pos = file:seek()
+ local s = file:read (lnbyte)
+ if not s then -- EOF
+ file_t[lpos + i] = ""
+ break;
+ end
+ local s_len = s:len()
+
+ if s_len > 0 then
+ local fmt = "0x%04X: " .. string.rep("%02X ", s_len)
+ local schrs = " " .. s:gsub("(%c)", " . ")
+ file_t[lpos + i] = string.format(fmt, pos, s:byte(1, s_len)) ..
+ schrs
+ else
+ file_t[lpos + i] = string.format("0x%04X: ", pos)
+ end
+ end
+ ovf = 0
+ lpos = lpos + bufsz
+
+ local bpos = coroutine.yield()
+
+ if bpos < lpos then -- roll over or scroll up
+ bpos = (bpos - bufsz) + bpos % bufsz
+ timer:check(true)
+ end
+
+ lpos = bpos - bpos % bufsz
+
+ if lpos < 1 then
+ lpos = 1
+ elseif lpos > count - bufsz then -- partial fill
+ ovf = count - bufsz - lpos
+ end
+ --get position in file of the nearest indexed line
+ file:seek("set", idx_t[bpos / bufsz + 1])
+
+ -- on really large files if it has been more than 10 minutes
+ -- since the user scrolled up the screen wipe out the prior
+ -- items to free memory
+ if lpos % 10000 == 0 and timer:check() > rb.HZ * 600 then
+ for i = 1, lpos - 100 do
+ file_t[i] = nil
+ end
+ end
+
+ end
+ end
+
+ co = coroutine.create(hex_co)
+
+ local function repl(char)
+ local ret = ""
+ if char:sub(1,2) == "0x" then
+ return string.format("%dd:", tonumber(char:sub(3, -2), 16))
+ else
+ return string.format("%03d ", tonumber(char, 16))
+ end
+ end
+
+
+ _lcd:clear()
+ _print.clear()
+
+ local sel, start, vcur = 1
+ table.insert(file_t, 1, hstr) --position 1 is header/title
+
+ if not settings then
+ settings = {}
+ settings.justify = "left"
+ settings.wrap = true
+ settings.msel = false
+ settings.hfgc = _clr.set( 0, 000, 000, 000)
+ settings.hbgc = _clr.set(-1, 255, 255, 255)
+ settings.ifgc = _clr.set(-1, 255, 255, 255)
+ settings.ibgc = _clr.set( 0, 000, 000, 000)
+ settings.iselc = _clr.set( 1, 000, 200, 100)
+ end
+
+ settings.hasheader = true
+ settings.co_routine = co
+ settings.start = start
+ settings.curpos = vcur
+ settings.ovfl = "manual"
+
+ while sel > 0 do
+ settings.start = start
+ settings.curpos = vcur
+
+ sel, start, vcur = print_table(file_t, count, settings)
+
+ if sel > 1 and file_t[sel] then -- flips between hex and decimal
+ local s = file_t[sel]
+ if s:sub(-1) == "\b" then
+ file_t[sel] = nil
+ ovf = -(bufsz - 1)
+ coroutine.resume(co, sel) --rebuild this item
+ else
+ s = s:gsub("(0x%x+:)", repl) .. "\b"
+ file_t[sel] = s:gsub("(%x%x%s)", repl) .. "\b"
+ end
+ end
+ end
+
+ file:close()
+ idx_t = nil
+ file_t = nil
+ return sel
+end -- print_file_hex
+--------------------------------------------------------------------------------
diff --git a/apps/plugins/lua/lua.make b/apps/plugins/lua/lua.make
index 60dfd24cdd..c85182880b 100644
--- a/apps/plugins/lua/lua.make
+++ b/apps/plugins/lua/lua.make
@@ -16,14 +16,7 @@ LUA_OBJ := $(call c2obj, $(LUA_SRC))
OTHER_SRC += $(LUA_SRC)
LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua
-LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua \
- draw.lua draw_floodfill.lua draw_poly.lua draw_num.lua \
- draw_text.lua files.lua image.lua image_save.lua lcd.lua \
- math_ex.lua print.lua timer.lua playlist.lua pcm.lua \
- sound.lua rbcompat.lua rbsettings.lua poly_points.lua \
- printtable.lua printmenus.lua printsubmenu.lua \
- menubuttons.lua menucoresettings.lua create_kbd_layout.lua \
- temploader.lua)
+LUA_INCLUDELIST := $(wildcard $(LUA_INCLUDEDIR)/*.lua)
ifndef APP_TYPE
ROCKS += $(LUA_BUILDDIR)/lua.rock
@@ -31,6 +24,7 @@ else
### simulator
ROCKS += $(LUA_BUILDDIR)/lua.rock
endif
+all: $(subst $(LUA_INCLUDEDIR)/,$(LUA_BUILDDIR)/,$(LUA_INCLUDELIST))
$(LUA_BUILDDIR)/lua.rock: $(LUA_OBJ) $(TLSFLIB) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/buttons.lua $(LUA_BUILDDIR)/settings.lua \
$(LUA_BUILDDIR)/rocklib_aux.o $(LUA_BUILDDIR)/rb_defines.lua $(LUA_BUILDDIR)/sound_defines.lua \
@@ -66,7 +60,7 @@ $(LUA_BUILDDIR)/rocklib_aux.o: $(LUA_BUILDDIR)/rocklib_aux.c
$(call PRINTS,CC $(<F))$(CC) $(INCLUDES) $(PLUGINFLAGS) -I $(LUA_SRCDIR) -c $< -o $@
$(LUA_BUILDDIR)/%.lua: $(LUA_INCLUDEDIR)/%.lua | $(LUA_BUILDDIR)
- $(call PRINTS,CP $(subst $(LUA_INCLUDEDIR)/,,$<))cp $< $@
+ $(call PRINTS,CP $(notdir $<))cp $< $@
$(LUA_BUILDDIR)/lua.refmap: $(LUA_OBJ) $(TLSFLIB)
diff --git a/apps/plugins/lua_scripts/lua_scripts.lua b/apps/plugins/lua_scripts/lua_scripts.lua
new file mode 100644
index 0000000000..331611d389
--- /dev/null
+++ b/apps/plugins/lua_scripts/lua_scripts.lua
@@ -0,0 +1,172 @@
+--[[
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2017 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.
+ *
+ ****************************************************************************/
+]]
+
+local scrpath = rb.current_path()
+
+package.path = scrpath .. "/?.lua;" .. package.path --add lua_scripts directory to path
+require("printmenus")
+
+rb.actions = nil
+package.loaded["actions"] = nil
+
+--------------------------------------------------------------------------------
+local Icon_Plugin = 0x9
+
+
+local function get_files(path, norecurse, finddir, findfile, f_t, d_t)
+
+ local quit = false
+
+ local files = f_t or {}
+ local dirs = d_t or {}
+
+ local function f_filedir(name)
+ --default find function
+ -- example: return name:find(".mp3", 1, true) ~= nil
+ if name:len() <= 2 and (name == "." or name == "..") then
+ return false
+ end
+ if string.sub(name, 1, 1) == '.' then
+ return false
+ end
+ if string.sub(name, -4) == ".lua" then
+ return true
+ end
+ return false
+ end
+ local function d_filedir(name)
+ --default discard function
+ return false
+ end
+
+ if finddir == nil then
+ finddir = f_filedir
+ elseif type(finddir) ~= "function" then
+ finddir = d_filedir
+ end
+
+ if findfile == nil then
+ findfile = f_filedir
+ elseif type(findfile) ~= "function" then
+ findfile = d_filedir
+ end
+
+ local function _get_files(path, cancelbtn)
+ local sep = ""
+ if string.sub(path, - 1) ~= "/" then sep = "/" end
+ for fname, isdir in luadir.dir(path) do
+
+ if isdir and finddir(fname) then
+ table.insert(dirs, path .. sep ..fname)
+ elseif not isdir and findfile(fname) then
+ table.insert(files, path .. sep ..fname)
+ end
+
+ if rb.get_plugin_action(0) == cancelbtn then
+ return true
+ end
+ end
+ end
+
+ local function cmp_alphanum (op1, op2)
+ local type1= type(op1)
+ local type2 = type(op2)
+
+ if type1 ~= type2 then
+ return type1 < type2
+ else
+ if type1 == "string" then
+ op1 = op1:upper()
+ op2 = op2:upper()
+ end
+ return op1 < op2
+ end
+ end
+
+ table.insert(dirs, path) -- root
+
+ for key,value in pairs(dirs) do
+ --luadir.dir may error out so we need to do the call protected
+ _, quit = pcall(_get_files, value, CANCEL_BUTTON)
+
+ if quit == true or norecurse then
+ break;
+ end
+ end
+
+ table.sort(files, cmp_alphanum)
+ table.sort(dirs, cmp_alphanum)
+
+ return dirs, files
+end -- get_files
+--------------------------------------------------------------------------------
+
+function icon_fn(item, icon)
+ if item ~= 0 then
+ icon = Icon_Plugin
+ else
+ icon = -1
+ end
+ return icon
+end
+
+-- uses print_table and get_files to display simple file browser
+function script_choose(dir, title)
+ local dstr
+ local hstr = title
+
+ local norecurse = true
+ local f_finddir = false -- function to match directories; nil all, false none
+ local f_findfile = nil -- function to match files; nil all, false none
+ local t_linedesc = {show_icons = true, icon_fn = icon_fn}
+ local p_settings = {wrap = true, hasheader = true, justify = "left", linedesc = t_linedesc}
+ local files = {}
+ local dirs = {}
+ local item = 1
+ rb.lcd_clear_display()
+
+ while item > 0 do
+ dirs, files = get_files(dir, norecurse, f_finddir, f_findfile, dirs, files)
+ for i=1, #dirs do dirs[i] = nil end -- empty table for reuse
+ table.insert(dirs, 1, hstr)
+ for i = 1, #files do
+ table.insert(dirs, "\t" .. string.gsub(files[i], ".*/",""))
+ end
+ --print_menu(menu_t, func_t, selected, settings, copy_screen)
+ _, item = print_menu(dirs, nil, 0, p_settings)
+
+ -- If item was selected follow directory or return filename
+ item = item or -1
+ if item > 0 then
+ dir = files[item - 1]
+ if not rb.dir_exists("/" .. dir) then
+ return dir
+ end
+ end
+
+ end
+end -- file_choose
+--------------------------------------------------------------------------------
+
+local script_path = script_choose(scrpath, "lua scripts")
+if script_path then rb.restart_lua(script_path) end
diff --git a/apps/plugins/lua_scripts/lua_scripts.make b/apps/plugins/lua_scripts/lua_scripts.make
index 2f46f9d74a..9151ab6d1c 100644
--- a/apps/plugins/lua_scripts/lua_scripts.make
+++ b/apps/plugins/lua_scripts/lua_scripts.make
@@ -10,7 +10,6 @@
LUASCR_SRCDIR := $(APPSDIR)/plugins/lua_scripts
LUASCR_BUILDDIR := $(BUILDDIR)/apps/plugins/lua_scripts
LUASCRS := $(wildcard $(LUASCR_SRCDIR)/*.lua)
-
#DUMMY := $(info [${LUASCRS}])
DUMMY : all
@@ -18,7 +17,6 @@ DUMMY : all
all: $(subst $(LUASCR_SRCDIR)/,$(LUASCR_BUILDDIR)/,$(LUASCRS))
$(LUASCR_BUILDDIR)/%.lua: $(LUASCR_SRCDIR)/%.lua | $(LUASCR_BUILDDIR)
- $(call PRINTS,CP $(subst $(LUASCR_SRCDIR)/,,$<))cp $< $@
-
+ $(call PRINTS,CP $(subst $(APPSDIR)/,,$<))cp $< $@
$(LUASCR_BUILDDIR):
$(call PRINTS,MKDIR $@)mkdir -p $(LUASCR_BUILDDIR)/
diff --git a/apps/plugins/picross.lua b/apps/plugins/picross.lua
index 26ad57ee74..ec9b6ef7a9 100644
--- a/apps/plugins/picross.lua
+++ b/apps/plugins/picross.lua
@@ -24,7 +24,7 @@ local _clr = require("color") -- clrset, clrinc provides device independent co
local _lcd = require("lcd") -- lcd helper functions
local plugindir = rb.PLUGIN_GAMES_DATA_DIR
-local userdir = plugindir .. "/picross"
+local userdir = plugindir .. "/.picross"
local wrap = rb.settings.read('global_settings', rb.system.global_settings.list_wraparound)
wrap = (wrap or 1) == 1
@@ -371,7 +371,7 @@ function State:loadSave()
end
function State:loadDefault()
- self:loadFile(userdir .. '/picross_default.picross')
+ return self:loadFile(userdir .. '/picross_default.picross')
end
function State:loadFile(path)
@@ -763,7 +763,9 @@ function viewPicture()
end
if not State:loadSave() then
- State:loadDefault()
+ if not State:loadDefault() then
+ return;
+ end
end
local act = rb.actions
diff --git a/apps/plugins/picross/picross.make b/apps/plugins/picross/picross.make
index d34b251dac..ead5ba482a 100644
--- a/apps/plugins/picross/picross.make
+++ b/apps/plugins/picross/picross.make
@@ -8,7 +8,7 @@
#
PICRSCR_SRCDIR := $(APPSDIR)/plugins/picross
-PICRSCR_BUILDDIR := $(BUILDDIR)/apps/plugins/picross
+PICRSCR_BUILDDIR := $(BUILDDIR)/apps/plugins/.picross
PICRSCRS := $(wildcard $(PICRSCR_SRCDIR)/*.picross)
#DUMMY := $(info [${PICRSCRS}])
@@ -18,7 +18,7 @@ DUMMY : all
all: $(subst $(PICRSCR_SRCDIR)/,$(PICRSCR_BUILDDIR)/,$(PICRSCRS))
$(PICRSCR_BUILDDIR)/%.picross: $(PICRSCR_SRCDIR)/%.picross | $(PICRSCR_BUILDDIR)
- $(call PRINTS,CP $(subst $(PICRSCR_SRCDIR)/,,$<))cp $< $@
+ $(call PRINTS,CP $(subst $(APPSDIR)/,,$<))cp $< $@
$(PICRSCR_BUILDDIR):
$(call PRINTS,MKDIR $@)mkdir -p $(PICRSCR_BUILDDIR)/
diff --git a/apps/settings.h b/apps/settings.h
index 2277805fec..e3b11430cd 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -163,7 +163,7 @@ enum { SHOW_ALL, SHOW_SUPPORTED, SHOW_MUSIC, SHOW_PLAYLIST, SHOW_ID3DB,
/* file and dir sort options */
enum { SORT_ALPHA, SORT_DATE, SORT_DATE_REVERSED, SORT_TYPE, /* available as settings */
- SORT_ALPHA_REVERSED, SORT_TYPE_REVERSED }; /* internal use only */
+ SORT_ALPHA_REVERSED, SORT_TYPE_REVERSED, SORT_AS_FILE }; /* internal use only */
enum { SORT_INTERPRET_AS_DIGIT, SORT_INTERPRET_AS_NUMBER };
/* recursive dir insert options */
diff --git a/apps/tree.c b/apps/tree.c
index 2e82b165af..58457c2d71 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -466,6 +466,13 @@ static int update_dir(void)
icon = tc.browse->icon;
if (icon == NOICON)
icon = filetype_get_icon(ATTR_DIRECTORY);
+ /* display sub directories in the title of plugin browser */
+ if (tc.dirlevel > 0 && *tc.dirfilter == SHOW_PLUGINS)
+ {
+ char *subdir = strrchr(tc.currdir, '/');
+ if (subdir)
+ title = subdir + 1; /* step past the separator */
+ }
}
else
{
@@ -1056,7 +1063,7 @@ int rockbox_browse(struct browse_context *browse)
int last_context;
/* don't reset if its the same browse already loaded */
if (tc.browse != browse ||
- !(tc.currdir[1] && strcmp(tc.currdir, browse->root) == 0))
+ !(tc.currdir[1] && strstr(tc.currdir, browse->root) != NULL))
{
tc.browse = browse;
tc.selected_item = 0;
diff --git a/tools/buildzip.pl b/tools/buildzip.pl
index 2956b49492..59c32d3e3d 100755
--- a/tools/buildzip.pl
+++ b/tools/buildzip.pl
@@ -167,6 +167,13 @@ sub make_install {
glob_install("$src/rocks/$t/*", "$libdir/rocks/$t", "-m 0755");
}
+ if(-e "$src/rocks/games/sgt_puzzles") {
+ unless (glob_mkdir("$libdir/rocks/games/sgt_puzzles")) {
+ return 0;
+ }
+ glob_install("$src/rocks/games/sgt_puzzles/*", "$libdir/rocks/games/sgt_puzzles", "-m 0755");
+ }
+
# rocks/viewers/lua
unless (glob_mkdir("$libdir/rocks/viewers/lua")) {
return 0;
@@ -182,12 +189,13 @@ sub make_install {
#glob_mkdir("$temp_dir/rocks/demos/lua_scripts");
#glob_copy("$ROOT/apps/plugins/lua_scripts/*.lua", "$temp_dir/rocks/demos/lua_scripts/");
}
- #lua picross puzzles
+
+ #lua picross puzzles
if(-e "$ROOT/apps/plugins/picross") {
- unless (glob_mkdir("$libdir/rocks/games/picross")) {
+ unless (glob_mkdir("$libdir/rocks/games/.picross")) {
return 0;
}
- glob_install("$ROOT/apps/plugins/picross/*.picross", "$libdir/rocks/games/picross");
+ glob_install("$ROOT/apps/plugins/picross/*.picross", "$libdir/rocks/games/.picross");
}
# all the rest directories
@@ -451,6 +459,12 @@ sub buildzip {
glob_copy("$ROOT/apps/plugins/lua_scripts/*.lua", "$temp_dir/rocks/demos/lua_scripts/");
}
+ #lua picross puzzles
+ if(-e "$ROOT/apps/plugins/picross") {
+ glob_mkdir("$temp_dir/rocks/games/.picross");
+ glob_copy("$ROOT/apps/plugins/picross/*.picross", "$temp_dir/rocks/games/.picross/");
+ }
+
# exclude entries for the image file types not supported by the imageviewer for the target.
my $viewers = "$ROOT/apps/plugins/viewers.config";
my $c="cat $viewers | gcc $cppdef -I. -I$firmdir/export -E -P -include config.h -";
@@ -512,7 +526,13 @@ sub buildzip {
foreach my $line (@rock_targetdirs) {
if ($line =~ /([^,]*),(.*)/) {
my ($plugin, $dir)=($1, $2);
- move("$temp_dir/rocks/${plugin}.rock", "$temp_dir/rocks/$dir/${plugin}.rock");
+ if($dir eq 'games' and substr(${plugin}, 0, 4) eq "sgt-") {
+ glob_mkdir("$temp_dir/rocks/$dir/sgt_puzzles");
+ move("$temp_dir/rocks/${plugin}.rock", "$temp_dir/rocks/$dir/sgt_puzzles/${plugin}.rock");
+ }
+ else {
+ move("$temp_dir/rocks/${plugin}.rock", "$temp_dir/rocks/$dir/${plugin}.rock");
+ }
if(-e "$temp_dir/rocks/${plugin}.ovl") {
# if there's an "overlay" file for the .rock, move that as
# well