Compare commits

...

9 Commits

Author SHA1 Message Date
Nico 073fb10abb revert to old method of graphics 2021-11-02 10:47:49 +00:00
Nico 90be393276 Merge branch 'master' into varvara 2021-10-30 19:09:37 +01:00
Nico 23dd0c0e59 cleanup 2021-10-30 19:08:31 +01:00
Nico 16fa1f1990 ignore varvara roms 2021-10-30 19:07:57 +01:00
Nico 8b022f1a27 initial g 2021-10-30 19:07:46 +01:00
Nico e051ac2c48 add screen vector and first test program 2021-10-29 09:03:45 +01:00
William Wilgus dc24a18cef PLUGINBROWSER make resumable
make the plugin browser remember the last item between invocations

this has bugged me for the longest time dealing with the plugin_menu

Fix a very old bug fix for reloading lang strings in the lang menu
FS#8117, sending multiple ENTER_MENU_ITEM callbacks from different
areas of the code makes it hard to keep track of where your callback
is originating

Change-Id: Ib0a61558c11ee4c772134378a7020ac0e10fc4ee
2021-10-29 03:07:42 -04:00
William Wilgus 8ee24d8cb4 onplay calls plugins to run other plugins
Change-Id: I7c1593c93debc0ac5c0f1b2e839ec0eb1bd375b7
2021-10-27 22:44:35 -04:00
William Wilgus f1ef5ab8a6 menu.c do_menu code cleanup
no functional changes here just removal of cruft

Change-Id: Id16c3607608d8f1ddcaf219dcd346f7a996aec5d
2021-10-27 15:44:38 -04:00
8 changed files with 323 additions and 112 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@
*.o
*.a
*~
*.bin
__pycache__
# Intermediate language files

View File

@ -67,6 +67,12 @@ static int current_subitems[MAX_MENU_SUBITEMS];
static int current_subitems_count = 0;
static int talk_menu_item(int selected_item, void *data);
struct menu_data_t
{
const struct menu_item_ex *menu;
int selected;
};
static void get_menu_callback(const struct menu_item_ex *m,
menu_callback_type *menu_callback)
{
@ -76,6 +82,19 @@ static void get_menu_callback(const struct menu_item_ex *m,
*menu_callback = m->menu_callback;
}
static bool query_audio_status(int *old_audio_status)
{
bool redraw_list = false;
/* query audio status to see if it changed */
int new_audio_status = audio_status();
if (*old_audio_status != new_audio_status)
{ /* force a redraw if anything changed the audio status from outside */
*old_audio_status = new_audio_status;
redraw_list = true;
}
return redraw_list;
}
static int get_menu_selection(int selected_item, const struct menu_item_ex *menu)
{
int type = (menu->flags&MENU_TYPE_MASK);
@ -128,8 +147,7 @@ static const char* get_menu_item_name(int selected_item,
type = (menu->flags&MENU_TYPE_MASK);
if ((type == MT_SETTING) || (type == MT_SETTING_W_TEXT))
{
const struct settings_list *v
= find_setting(menu->variable, NULL);
const struct settings_list *v = find_setting(menu->variable, NULL);
if (v)
return str(v->lang_id);
else return "Not Done yet!";
@ -158,35 +176,29 @@ static enum themable_icons menu_get_icon(int selected_item, void * data)
if (menu_icon == Icon_NOICON)
{
switch (menu->flags&MENU_TYPE_MASK)
{
case MT_SETTING:
case MT_SETTING_W_TEXT:
menu_icon = Icon_Menu_setting;
break;
case MT_MENU:
menu_icon = Icon_Submenu;
break;
case MT_FUNCTION_CALL:
case MT_RETURN_VALUE:
menu_icon = Icon_Menu_functioncall;
break;
}
unsigned int flags = (menu->flags&MENU_TYPE_MASK);
if(flags == MT_MENU)
menu_icon = Icon_Submenu;
else if (flags == MT_SETTING || flags == MT_SETTING_W_TEXT)
menu_icon = Icon_Menu_setting;
else if (flags == MT_FUNCTION_CALL || flags == MT_RETURN_VALUE)
menu_icon = Icon_Menu_functioncall;
}
return menu_icon;
}
static void init_menu_lists(const struct menu_item_ex *menu,
static int init_menu_lists(const struct menu_item_ex *menu,
struct gui_synclist *lists, int selected, bool callback,
struct viewport parent[NB_SCREENS])
{
if (!menu || !lists)
{
panicf("init_menu_lists, NULL pointer");
return;
return 0;
}
int i;
int start_action = ACTION_ENTER_MENUITEM;
int count = MIN(MENU_GET_COUNT(menu->flags), MAX_MENU_SUBITEMS);
int type = (menu->flags&MENU_TYPE_MASK);
menu_callback_type menu_callback = NULL;
@ -253,7 +265,9 @@ static void init_menu_lists(const struct menu_item_ex *menu,
get_menu_callback(menu,&menu_callback);
if (callback && menu_callback)
menu_callback(ACTION_ENTER_MENUITEM, menu, lists);
start_action = menu_callback(start_action, menu, lists);
return start_action;
}
static int talk_menu_item(int selected_item, void *data)
@ -368,12 +382,16 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
struct viewport parent[NB_SCREENS], bool hide_theme)
{
int selected = start_selected? *start_selected : 0;
int ret = 0;
int action;
int start_action;
struct gui_synclist lists;
const struct menu_item_ex *temp = NULL;
const struct menu_item_ex *menu = start_menu;
int ret = 0;
bool in_stringlist, done = false;
bool redraw_lists;
int old_audio_status = audio_status();
#ifdef HAVE_TOUCHSCREEN
@ -386,16 +404,17 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
FOR_NB_SCREENS(i)
viewportmanager_theme_enable(i, !hide_theme, NULL);
const struct menu_item_ex *menu_stack[MAX_MENUS];
int menu_stack_selected_item[MAX_MENUS];
struct menu_data_t mstack[MAX_MENUS]; /* menu, selected */
int stack_top = 0;
bool in_stringlist, done = false;
struct viewport *vps = NULL;
menu_callback_type menu_callback = NULL;
/* if hide_theme is true, assume parent has been fixed before passed into
* this function, e.g. with viewport_set_defaults(parent, screen) */
init_menu_lists(menu, &lists, selected, true, parent);
* this function, e.g. with viewport_set_defaults(parent, screen)
* start_action allows an action to be processed
* by menu logic by bypassing get_action on the initial run */
start_action = init_menu_lists(menu, &lists, selected, true, parent);
vps = *(lists.parent);
in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID);
/* load the callback, and only reload it if menu changes */
@ -403,42 +422,36 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
gui_synclist_draw(&lists);
gui_synclist_speak_item(&lists);
while (!done)
{
int new_audio_status;
redraw_lists = false;
keyclick_set_callback(gui_synclist_keyclick_callback, &lists);
action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK,
list_do_action_timeout(&lists, HZ));
if (UNLIKELY(start_action != ACTION_ENTER_MENUITEM))
{
action = start_action;
start_action = ACTION_ENTER_MENUITEM;
}
else
action = get_action(CONTEXT_MAINMENU|ALLOW_SOFTLOCK,
list_do_action_timeout(&lists, HZ));
/* HZ so the status bar redraws corectly */
/* query audio status to see if it changed */
new_audio_status = audio_status();
if (old_audio_status != new_audio_status)
{ /* force a redraw if anything changed the audio status
* from outside */
redraw_lists = true;
old_audio_status = new_audio_status;
}
/* HZ so the status bar redraws corectly */
redraw_lists = query_audio_status(&old_audio_status);
if (menu_callback)
{
int old_action = action;
action = menu_callback(action, menu, &lists);
if (action == ACTION_EXIT_AFTER_THIS_MENUITEM)
{
action = old_action;
ret = MENU_SELECTED_EXIT; /* will exit after returning
from selection */
}
else if (action == ACTION_REDRAW)
{
action = old_action;
int new_action = menu_callback(action, menu, &lists);
if (new_action == ACTION_EXIT_AFTER_THIS_MENUITEM)
ret = MENU_SELECTED_EXIT; /* exit after return from selection */
else if (new_action == ACTION_REDRAW)
redraw_lists = true;
}
else
action = new_action;
}
if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
if (LIKELY(gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD)))
continue;
#ifdef HAVE_QUICKSCREEN
else if (action == ACTION_STD_QUICKSCREEN)
@ -505,7 +518,6 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
ID2P(LANG_ONPLAY_MENU_TITLE), NULL,
ID2P(LANG_RESET_SETTING));
const struct menu_item_ex *menu;
int menu_selection = 0;
const struct settings_list *setting =
find_setting(temp->variable, NULL);
#ifdef HAVE_QUICKSCREEN
@ -514,7 +526,10 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
else
#endif
menu = &notquickscreen_able_option;
switch (do_menu(menu, &menu_selection, NULL, false))
int msel = do_menu(menu, NULL, NULL, false);
switch (msel)
{
case GO_TO_PREVIOUS:
break;
@ -556,10 +571,12 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
}
else if (action == ACTION_STD_CANCEL)
{
bool exiting_menu = false;
in_stringlist = false;
/* might be leaving list, so stop scrolling */
gui_synclist_scroll_stop(&lists);
bool exiting_menu = false;
in_stringlist = false;
if (menu_callback)
menu_callback(ACTION_EXIT_MENUITEM, menu, &lists);
@ -567,15 +584,16 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
done = true;
else if ((menu->flags&MENU_TYPE_MASK) == MT_MENU)
exiting_menu = true;
if (stack_top > 0)
{
stack_top--;
menu = menu_stack[stack_top];
menu = mstack[stack_top].menu;
int msel = mstack[stack_top].selected;
if (!exiting_menu && (menu->flags&MENU_EXITAFTERTHISMENU))
done = true;
else
init_menu_lists(menu, &lists,
menu_stack_selected_item[stack_top], false, vps);
init_menu_lists(menu, &lists, msel, false, vps);
redraw_lists = true;
/* new menu, so reload the callback */
get_menu_callback(menu, &menu_callback);
@ -588,19 +606,18 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
}
else if (action == ACTION_STD_OK)
{
int type = (menu->flags&MENU_TYPE_MASK);
/* entering an item that may not be a list, so stop scrolling */
gui_synclist_scroll_stop(&lists);
redraw_lists = true;
int type = (menu->flags&MENU_TYPE_MASK);
selected = get_menu_selection(gui_synclist_get_sel_pos(&lists), menu);
if (type == MT_MENU)
temp = menu->submenus[selected];
else
else if (!in_stringlist)
type = -1;
redraw_lists = true;
if (in_stringlist)
type = (menu->flags&MENU_TYPE_MASK);
else if (temp)
if (!in_stringlist && temp)
{
type = (temp->flags&MENU_TYPE_MASK);
get_menu_callback(temp, &menu_callback);
@ -616,8 +633,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
case MT_MENU:
if (stack_top < MAX_MENUS)
{
menu_stack[stack_top] = menu;
menu_stack_selected_item[stack_top] = selected;
mstack[stack_top].menu = menu;
mstack[stack_top].selected = selected;
stack_top++;
menu = temp;
init_menu_lists(menu, &lists, 0, true, vps);
@ -634,7 +651,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
if (!(menu->flags&MENU_EXITAFTERTHISMENU) ||
(temp->flags&MENU_EXITAFTERTHISMENU))
{
init_menu_lists(menu, &lists, selected, true, vps);
/* Reload menu but don't run the calback again FS#8117 */
init_menu_lists(menu, &lists, selected, false, vps);
}
if (temp->flags&MENU_FUNC_CHECK_RETVAL)
{
@ -661,8 +679,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
}
else if (stack_top < MAX_MENUS)
{
menu_stack[stack_top] = menu;
menu_stack_selected_item[stack_top] = selected;
mstack[stack_top].menu = menu;
mstack[stack_top].selected = selected;
stack_top++;
menu = temp;
init_menu_lists(menu,&lists,0,false, vps);
@ -731,8 +749,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
the selected item from the menu do_menu() was called from */
if (stack_top > 0)
{
menu = menu_stack[0];
init_menu_lists(menu,&lists,menu_stack_selected_item[0],true, vps);
menu = mstack[0].menu;
init_menu_lists(menu,&lists,mstack[0].selected,true, vps);
}
*start_selected = get_menu_selection(
gui_synclist_get_sel_pos(&lists), menu);
@ -748,6 +766,5 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
tsm == old_global_mode))
touchscreen_set_mode(tsm);
#endif
return ret;
}

View File

@ -24,11 +24,12 @@
#include "config.h"
#include "lang.h"
#include "menu.h"
#include "action.h"
#include "settings.h"
#include "rbpaths.h"
#include "root_menu.h"
#include "tree.h"
static int reenter = 0;
enum {
GAMES,
@ -53,13 +54,36 @@ static int plugins_menu(void* param)
browse_context_init(&browse, SHOW_PLUGINS, 0, str(items[item].id),
Icon_Plugin, items[item].path, NULL);
ret = rockbox_browse(&browse);
if (ret == GO_TO_PREVIOUS)
return 0;
if (ret == GO_TO_PLUGIN)
reenter = 1;
return ret;
}
static int menu_callback(int action,
const struct menu_item_ex *this_item,
struct gui_synclist *this_list)
{
(void)this_item;
static int selected = 0;
if (action == ACTION_ENTER_MENUITEM)
{
this_list->selected_item = selected;
if (reenter-- > 0)
action = ACTION_STD_OK;
}
else if (action == ACTION_STD_OK)
{
selected = gui_synclist_get_sel_pos(this_list);
}
return action;
}
#define ITEM_FLAG (MENU_FUNC_USEPARAM|MENU_FUNC_CHECK_RETVAL)
MENUITEM_FUNCTION(games_item, ITEM_FLAG, ID2P(LANG_PLUGIN_GAMES),
@ -69,6 +93,6 @@ MENUITEM_FUNCTION(apps_item, ITEM_FLAG, ID2P(LANG_PLUGIN_APPS),
MENUITEM_FUNCTION(demos_item, ITEM_FLAG, ID2P(LANG_PLUGIN_DEMOS),
plugins_menu, (void*)DEMOS, NULL, Icon_Folder);
MAKE_MENU(plugin_menu, ID2P(LANG_PLUGINS), NULL,
MAKE_MENU(plugin_menu, ID2P(LANG_PLUGINS), &menu_callback,
Icon_Plugin,
&games_item, &apps_item, &demos_item);

View File

@ -1576,6 +1576,8 @@ static bool onplay_load_plugin(void *param)
int ret = filetype_load_plugin((const char*)param, selected_file);
if (ret == PLUGIN_USB_CONNECTED)
onplay_result = ONPLAY_RELOAD_DIR;
else if (ret == PLUGIN_GOTO_PLUGIN)
onplay_result = ONPLAY_PLUGIN;
return false;
}

View File

@ -0,0 +1,69 @@
( dev/screen )
%RTN { JMP2r }
%2/ { #01 SFT }
%4/ { #02 SFT }
( devices )
|00 @System [ &vector $2 &wst $1 &rst $1 &pad $4 &r $2 &g $2 &b $2 &debug $1 &halt $1 ]
|20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 ]
( variables )
|0000
@count $2
@center
&x $2 &y $2
( init )
|0100 ( -> )
( vector )
;on-frame .Screen/vector DEO2
( theme )
#0f7f .System/r DEO2
#0fe0 .System/g DEO2
#0fc0 .System/b DEO2
BRK
@on-frame ( -> )
.count LDZ2 INC2 [ DUP2 ] .count STZ2
#0000 .Screen/x DEO2
#0000 .Screen/y DEO2
( color ) #01 STH
SWP
DUP #04 SFT [ #00 SWP ] #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
( draw ) STHkr .Screen/sprite DEO
#0f AND [ #00 SWP ] #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw ) STHkr .Screen/sprite DEO
DUP #04 SFT [ #00 SWP ] #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw ) STHkr .Screen/sprite DEO
#0f AND [ #00 SWP ] #30 SFT2 ;font-hex ADD2 .Screen/addr DEO2
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
( draw ) STHr .Screen/sprite DEO
BRK
@preview_icn
0f38 675f dfbf bfbf 0007 1820 2344 4848
@font-hex
007c 8282 8282 827c 0030 1010 1010 1010
007c 8202 7c80 80fe 007c 8202 1c02 827c
000c 1424 4484 fe04 00fe 8080 7c02 827c
007c 8280 fc82 827c 007c 8202 1e02 0202
007c 8282 7c82 827c 007c 8282 7e02 827c
007c 8202 7e82 827e 00fc 8282 fc82 82fc
007c 8280 8080 827c 00fc 8282 8282 82fc
007c 8280 f080 827c 007c 8280 f080 8080

View File

@ -1,6 +1,7 @@
/* Varvara plugin for rockbox. I have no idea what I'm doing.
Functions taken from uxnemu.c and uxncli.c are copyright (c) 2021 Devine Lu Linvega.
copyright (c) 2021 Devine Lu Linvega
copyright (c) 2021 nihilazo
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@ -9,15 +10,16 @@ copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
TODO screen vector, de-janking display code, support for greyscale displays
TODO proper support for greyscale displays
TODO rom loading
TODO other varvara devices
TODO hardware builds
TODO clean up
*/
#include "uxn.h"
#include "devices/ppu.h"
#include "plugin.h"
#include "lib/pluginlib_actions.h"
#include <stdio.h>
#include <stdint.h>
#include <time.h>
@ -25,14 +27,14 @@ TODO clean up
const uint8_t hwrom[] = { /* hello world ROM */
const Uint8 hwrom[] = { /* hello world ROM */
0x20, 0x01, 0x0e, 0x94, 0x80, 0x18, 0x17, 0x21,
0x94, 0x80, 0xf7, 0x0d, 0x22, 0x00, 0x48, 0x65,
0x6c, 0x6c, 0x6f, 0x20, 0x55, 0x78, 0x6e, 0x21,
0x21,
};
const uint8_t uxn_rom[] = { /* screen test ROM */
const Uint8 uxn_rom[] = { /* screen test ROM */
0x20, 0x01, 0x43, 0x80, 0x20, 0x37, 0x20, 0xf0,
0x7f, 0x80, 0x08, 0x37, 0x20, 0xf0, 0xe0, 0x80,
0x0a, 0x37, 0x20, 0xf0, 0xc0, 0x80, 0x0c, 0x37,
@ -134,12 +136,55 @@ const uint8_t uxn_rom[] = { /* screen test ROM */
0x80, 0x80,
};
const Uint8 vector_rom[] = { // screen vector test ROM
0x20, 0x01, 0x19, 0x80, 0x20, 0x37, 0x20, 0x0f,
0x7f, 0x80, 0x08, 0x37, 0x20, 0x0f, 0xe0, 0x80,
0x0a, 0x37, 0x20, 0x0f, 0xc0, 0x80, 0x0c, 0x37,
0x00, 0x80, 0x00, 0x30, 0x21, 0x23, 0x80, 0x00,
0x31, 0x20, 0x00, 0x00, 0x80, 0x28, 0x37, 0x20,
0x00, 0x00, 0x80, 0x2a, 0x37, 0x80, 0x01, 0x0f,
0x05, 0x03, 0x80, 0x04, 0x1f, 0x80, 0x00, 0x05,
0x80, 0x30, 0x3f, 0x20, 0x01, 0xb2, 0x38, 0x80,
0x2c, 0x37, 0xcf, 0x80, 0x2f, 0x17, 0x80, 0x0f,
0x1c, 0x80, 0x00, 0x05, 0x80, 0x30, 0x3f, 0x20,
0x01, 0xb2, 0x38, 0x80, 0x2c, 0x37, 0x80, 0x28,
0x36, 0x20, 0x00, 0x08, 0x38, 0x80, 0x28, 0x37,
0xcf, 0x80, 0x2f, 0x17, 0x03, 0x80, 0x04, 0x1f,
0x80, 0x00, 0x05, 0x80, 0x30, 0x3f, 0x20, 0x01,
0xb2, 0x38, 0x80, 0x2c, 0x37, 0x80, 0x28, 0x36,
0x20, 0x00, 0x08, 0x38, 0x80, 0x28, 0x37, 0xcf,
0x80, 0x2f, 0x17, 0x80, 0x0f, 0x1c, 0x80, 0x00,
0x05, 0x80, 0x30, 0x3f, 0x20, 0x01, 0xb2, 0x38,
0x80, 0x2c, 0x37, 0x80, 0x28, 0x36, 0x20, 0x00,
0x08, 0x38, 0x80, 0x28, 0x37, 0x4f, 0x80, 0x2f,
0x17, 0x00, 0x0f, 0x38, 0x67, 0x5f, 0xdf, 0xbf,
0xbf, 0xbf, 0x00, 0x07, 0x18, 0x20, 0x23, 0x44,
0x48, 0x48, 0x00, 0x7c, 0x82, 0x82, 0x82, 0x82,
0x82, 0x7c, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x00, 0x7c, 0x82, 0x02, 0x7c, 0x80,
0x80, 0xfe, 0x00, 0x7c, 0x82, 0x02, 0x1c, 0x02,
0x82, 0x7c, 0x00, 0x0c, 0x14, 0x24, 0x44, 0x84,
0xfe, 0x04, 0x00, 0xfe, 0x80, 0x80, 0x7c, 0x02,
0x82, 0x7c, 0x00, 0x7c, 0x82, 0x80, 0xfc, 0x82,
0x82, 0x7c, 0x00, 0x7c, 0x82, 0x02, 0x1e, 0x02,
0x02, 0x02, 0x00, 0x7c, 0x82, 0x82, 0x7c, 0x82,
0x82, 0x7c, 0x00, 0x7c, 0x82, 0x82, 0x7e, 0x02,
0x82, 0x7c, 0x00, 0x7c, 0x82, 0x02, 0x7e, 0x82,
0x82, 0x7e, 0x00, 0xfc, 0x82, 0x82, 0xfc, 0x82,
0x82, 0xfc, 0x00, 0x7c, 0x82, 0x80, 0x80, 0x80,
0x82, 0x7c, 0x00, 0xfc, 0x82, 0x82, 0x82, 0x82,
0x82, 0xfc, 0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80,
0x82, 0x7c, 0x00, 0x7c, 0x82, 0x80, 0xf0, 0x80,
0x80, 0x80, 0x80,
};
static Uxn u;
static Ppu ppu;
static Device *devsystem, *devconsole, *devscreen;
static Device *devctrl, *devsystem, *devconsole, *devscreen;
unsigned int palette[3];
static uint8_t framebuffer[LCD_HEIGHT * LCD_WIDTH * 4];
static Uint8 framebuffer[LCD_HEIGHT * LCD_WIDTH * 4];
static void
memzero8(void *src, uint64_t n)
@ -169,7 +214,7 @@ inspect(Stack *s, char *name)
static void
set_palette(Uint8 *addr)
{
#if LCD_DEPTH > 1
#if LCD_DEPTH > 4
int i;
for(i = 0; i < 4; ++i) {
Uint8
@ -181,8 +226,7 @@ set_palette(Uint8 *addr)
#else
int i;
for(i = 0; i < 4; ++i) {
Uint8
sum = (*(addr + i / 2) >> (!(i % 2) << 2)) & 0x0f;
Uint8 sum = (*(addr + i / 2) >> (!(i % 2) << 2)) & 0x0f;
sum += (*(addr + 2 + i / 2) >> (!(i % 2) << 2)) & 0x0f;
sum += (*(addr + 4 + i / 2) >> (!(i % 2) << 2)) & 0x0f;
palette[i] = sum > 0x17;
@ -279,14 +323,14 @@ nil_talk(Device *d, Uint8 b0, Uint8 w)
return 1;
}
// TODO optimise, make build on non-color devices
// TODO optimise, proper greyscale
static void redraw(void)
{
rb->lcd_clear_display();
Uint16 x, y;
for(y = 0; y < ppu.height; ++y)
for(x = 0; x < ppu.width; ++x) {
#if LCD_DEPTH > 1
#if LCD_DEPTH > 4
rb->lcd_set_foreground(palette[ppu_read(&ppu, x, y)]);
rb->lcd_drawpixel(x, y);
#else
@ -303,10 +347,23 @@ static void redraw(void)
int
uxn_halt(Uxn *u, Uint8 error, char *name, int id)
{
DEBUGF("Halted");
rb->splash(HZ, "Halted\n");
return 0;
}
static void run() {
while(!devsystem->dat[0xf]) {
uxn_eval(&u, devscreen->vector);
if(ppu.reqdraw || devsystem->dat[0xe])
redraw();
switch(rb->button_get(false)) { // TODO implement other buttons
case BUTTON_NONE: break;
default: return;
}
rb->sleep(HZ/60);
}
}
/* this is the plugin entry point */
enum plugin_status plugin_start(const void* parameter)
@ -332,7 +389,7 @@ enum plugin_status plugin_start(const void* parameter)
/* audio2 */ uxn_port(&u, 0x5, nil_talk);
/* audio3 */ uxn_port(&u, 0x6, nil_talk);
/* empty */ uxn_port(&u, 0x7, nil_talk);
/* control */ uxn_port(&u, 0x8, nil_talk);
/* control */ devctrl = uxn_port(&u, 0x8, nil_talk);
/* mouse */ uxn_port(&u, 0x9, nil_talk);
/* file */ uxn_port(&u, 0xa, nil_talk);
/* datetime */ uxn_port(&u, 0xb, nil_talk);
@ -342,9 +399,7 @@ enum plugin_status plugin_start(const void* parameter)
/* empty */ uxn_port(&u, 0xf, nil_talk);
DEBUGF("eval\n");
uxn_eval(&u, 0x0100);
redraw();
rb->button_get(true);
run();
return PLUGIN_OK;
}

View File

@ -634,6 +634,7 @@ static int item_callback(int action,
}
return action;
}
static int get_selection(int last_screen)
{
int i;
@ -683,6 +684,7 @@ static inline int load_screen(int screen)
last_screen = old_previous;
return ret_val;
}
static int load_context_screen(int selection)
{
const struct menu_item_ex *context_menu = NULL;
@ -709,13 +711,12 @@ static int load_plugin_screen(char *key)
{
int ret_val;
int old_previous = last_screen;
int old_global = global_status.last_screen;
last_screen = next_screen;
global_status.last_screen = (char)next_screen;
status_save();
int opret = open_plugin_get_entry(key, &open_plugin_entry);
bool flush = (opret == OPEN_PLUGIN_NEEDS_FLUSHED);
char *path = open_plugin_entry.path;
char *param = open_plugin_entry.param;
if (param[0] == '\0')
@ -723,6 +724,9 @@ static int load_plugin_screen(char *key)
switch (plugin_load(path, param))
{
case PLUGIN_USB_CONNECTED:
ret_val = GO_TO_ROOT;
break;
case PLUGIN_GOTO_WPS:
ret_val = GO_TO_WPS;
break;
@ -730,18 +734,30 @@ static int load_plugin_screen(char *key)
ret_val = GO_TO_PLUGIN;
break;
case PLUGIN_OK:
ret_val = audio_status() ? GO_TO_PREVIOUS : GO_TO_ROOT;
break;
/* Prevents infinite loop with WPS & Plugins*/
if (old_global == GO_TO_WPS && !audio_status())
{
ret_val = GO_TO_ROOT;
break;
}
/*fallthrough*/
default:
ret_val = GO_TO_PREVIOUS;
last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous;
break;
}
if (!flush && ret_val != GO_TO_PLUGIN)
open_plugin_add_path(NULL, NULL, NULL);
if (ret_val == GO_TO_PREVIOUS)
last_screen = (old_previous == next_screen) ? GO_TO_ROOT : old_previous;
if (ret_val != GO_TO_PLUGIN)
{
if (opret != OPEN_PLUGIN_NEEDS_FLUSHED || last_screen != GO_TO_WPS)
{
/* Keep the entry in case of GO_TO_PREVIOUS */
open_plugin_entry.hash = 0; /*remove hash -- prevents flush to disk */
open_plugin_entry.lang_id = LANG_PREVIOUS_SCREEN;
/*open_plugin_add_path(NULL, NULL, NULL);// clear entry */
}
}
return ret_val;
}
@ -858,8 +874,12 @@ void root_menu(void)
#endif /* With !CONFIG_TUNER previous_music is always GO_TO_WPS */
case GO_TO_PREVIOUS:
{
next_screen = last_screen;
if (last_screen == GO_TO_PLUGIN)/* for WPS */
last_screen = GO_TO_PREVIOUS;
break;
}
case GO_TO_PREVIOUS_BROWSER:
next_screen = previous_browser;
@ -874,7 +894,8 @@ void root_menu(void)
case GO_TO_PLUGIN:
{
char *key;
if (global_status.last_screen == GO_TO_SHORTCUTMENU)
if (global_status.last_screen == GO_TO_SHORTCUTMENU &&
last_screen != GO_TO_ROOT)
{
shortcut_origin = last_screen;
key = ID2P(LANG_SHORTCUTS);
@ -892,6 +913,9 @@ void root_menu(void)
case GO_TO_SHORTCUTMENU:
key = ID2P(LANG_SHORTCUTS);
break;
case GO_TO_PREVIOUS:
key = ID2P(LANG_PREVIOUS_SCREEN);
break;
default:
key = ID2P(LANG_OPEN_PLUGIN);
break;
@ -900,15 +924,23 @@ void root_menu(void)
next_screen = load_plugin_screen(key);
/* shortcuts may take several trips through the GO_TO_PLUGIN case
make sure we preserve and restore the origin */
if (next_screen == GO_TO_PREVIOUS && shortcut_origin != GO_TO_ROOT)
if (next_screen == GO_TO_PREVIOUS)
{
if (shortcut_origin != GO_TO_WPS)
next_screen = shortcut_origin;
shortcut_origin = GO_TO_ROOT;
/* shortcuts may take several trips through the GO_TO_PLUGIN
case make sure we preserve and restore the origin */
if (shortcut_origin != GO_TO_ROOT)
{
if (shortcut_origin != GO_TO_WPS)
next_screen = shortcut_origin;
shortcut_origin = GO_TO_ROOT;
}
/* skip GO_TO_PREVIOUS */
if (last_screen == GO_TO_BROWSEPLUGINS)
{
next_screen = last_screen;
last_screen = GO_TO_PLUGIN;
}
}
previous_browser = (next_screen != GO_TO_WPS) ? GO_TO_FILEBROWSER : GO_TO_PLUGIN;
break;
}

View File

@ -805,6 +805,7 @@ static int dirbrowse(void)
{
case ONPLAY_MAINMENU:
return GO_TO_ROOT;
break;
case ONPLAY_OK:
restore = true;
@ -817,6 +818,10 @@ static int dirbrowse(void)
case ONPLAY_START_PLAY:
return GO_TO_WPS;
break;
case ONPLAY_PLUGIN:
return GO_TO_PLUGIN;
break;
}
break;
}
@ -962,11 +967,17 @@ int rockbox_browse(struct browse_context *browse)
if (*tc.dirfilter >= NUM_FILTER_MODES)
{
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.browse = browse;
tc.selected_item = 0;
tc.dirlevel = 0;
strlcpy(tc.currdir, browse->root, sizeof(tc.currdir));
}
tc.browse = browse;
tc.selected_item = 0;
tc.dirlevel = 0;
strlcpy(tc.currdir, browse->root, sizeof(tc.currdir));
start_wps = false;
last_context = curr_context;