diff --git a/MiSTer.ini b/MiSTer.ini
index cb1f63e..118b8de 100644
--- a/MiSTer.ini
+++ b/MiSTer.ini
@@ -18,6 +18,7 @@ rbf_hide_datecode=0 ; 1 - hides datecodes from rbf file names. Press F2 for q
menu_pal=0 ; 1 - PAL mode for menu core
hdmi_limited=0 ; 1 - use limited (16..235) color range over HDMI
fb_size=0 ; 0 - automatic, 1 - full size, 2 - 1/2 of resolution, 4 - 1/4 of resolution.
+fb_terminal=1 ; 1 - enabled (default), 0 - disabled
; lastcore - Autoboot the last loaded core (corename autosaved in CONFIG/lastcore.dat) first found on the SD/USB
; lastexactcore - Autoboot the last loaded exact core (corename_yyyymmdd.rbf autosaved in CONFIG/lastcore.dat) first found on the SD/USB
diff --git a/cfg.cpp b/cfg.cpp
index 71ea168..2a011df 100644
--- a/cfg.cpp
+++ b/cfg.cpp
@@ -13,6 +13,7 @@ void MiSTer_ini_parse()
{
memset(&cfg, 0, sizeof(cfg));
cfg.bootscreen = 1;
+ cfg.fb_terminal = 1;
ini_parse(&ini_cfg);
}
@@ -51,6 +52,7 @@ const ini_var_t ini_vars[] = {
{ "BOOTCORE_TIMEOUT", (void*)(&(cfg.bootcore_timeout)), INT16, 10, 30, 1 },
{ "FONT", (void*)(&(cfg.font)), STRING, 0, sizeof(cfg.font) - 1, 1 },
{ "FB_SIZE", (void*)(&(cfg.fb_size)), UINT8, 1, 4, 1 },
+ { "FB_TERMINAL", (void*)(&(cfg.fb_terminal)), UINT8, 0, 1, 1 },
};
// mist ini config
diff --git a/cfg.h b/cfg.h
index e4e457d..9a09325 100644
--- a/cfg.h
+++ b/cfg.h
@@ -35,6 +35,7 @@ typedef struct {
uint8_t menu_pal;
int16_t bootcore_timeout;
uint8_t fb_size;
+ uint8_t fb_terminal;
char bootcore[256];
char video_conf[1024];
char video_conf_pal[1024];
diff --git a/menu.cpp b/menu.cpp
index c4e5e4b..c4dfa3d 100644
--- a/menu.cpp
+++ b/menu.cpp
@@ -38,6 +38,10 @@ along with this program. If not, see .
#include
#include
#include
+#include
+#include
+#include
+
#include "file_io.h"
#include "osd.h"
#include "hardware.h"
@@ -110,6 +114,8 @@ enum MENU
MENU_SCRIPTS_PRE1,
MENU_SCRIPTS,
MENU_SCRIPTS1,
+ MENU_SCRIPTS_FB,
+ MENU_SCRIPTS_FB2,
MENU_BTPAIR,
MENU_WMPAIR,
MENU_WMPAIR1,
@@ -760,7 +766,7 @@ void HandleUI(void)
// No UI in unknown cores.
return;
}
-
+
struct RigidDiskBlock *rdb = nullptr;
static char opensave;
@@ -778,6 +784,7 @@ void HandleUI(void)
static uint32_t cheatsub = 0;
static uint8_t card_cid[32];
static uint32_t hdmask = 0;
+ static pid_t ttypid = 0;
static char cp_MenuCancel;
@@ -799,80 +806,88 @@ void HandleUI(void)
cfg.bootcore[0] = '\0';
}
- switch (c)
+ //prevent OSD control while script is executing on framebuffer
+ if (!video_fb_state() || video_chvt(0) != 2)
{
- case KEY_F12:
- menu = true;
- menu_key_set(KEY_F12 | UPSTROKE);
- video_fb_enable(0);
- break;
- case KEY_F1:
- if (is_menu_core())
+ switch (c)
{
- unsigned long status = ((user_io_8bit_set_status(0, 0)>>1)&7)+1;
- status <<= 1;
- user_io_8bit_set_status(status, 0xE);
- FileSaveConfig(user_io_create_config_name(), &status, 4);
- video_menu_bg((status >> 1) & 7);
- }
- break;
-
- case KEY_F11:
- if (user_io_osd_is_visible())
- {
- menustate = MENU_BTPAIR;
- }
- break;
-
- case KEY_F10:
- if (user_io_osd_is_visible() && !access("/bin/wminput", F_OK))
- {
- menustate = MENU_WMPAIR;
- }
- else if(input_has_lightgun())
- {
- menustate = MENU_LGCAL;
- }
- break;
-
- case KEY_F9:
- video_fb_enable(!video_fb_state());
- if(video_fb_state() || !is_menu_core()) menustate = MENU_NONE1;
- break;
-
- // Within the menu the esc key acts as the menu key. problem:
- // if the menu is left with a press of ESC, then the follwing
- // break code for the ESC key when the key is released will
- // reach the core which never saw the make code. Simple solution:
- // react on break code instead of make code
- case KEY_ESC | UPSTROKE:
- if (menustate != MENU_NONE2)
+ case KEY_F12:
menu = true;
- break;
- case KEY_ENTER:
- case KEY_SPACE:
- select = true;
- break;
- case KEY_UP:
- up = true;
- break;
- case KEY_DOWN:
- down = true;
- break;
- case KEY_LEFT:
- left = true;
- break;
- case KEY_RIGHT:
- right = true;
- break;
- case KEY_KPPLUS:
- case KEY_EQUAL: // =/+
- plus = true;
- break;
- case KEY_KPMINUS:
- case KEY_MINUS: // -/_
- minus = true;
- break;
+ menu_key_set(KEY_F12 | UPSTROKE);
+ video_fb_enable(0);
+ break;
+
+ case KEY_F1:
+ if (is_menu_core())
+ {
+ unsigned long status = ((user_io_8bit_set_status(0, 0) >> 1) & 7) + 1;
+ status <<= 1;
+ user_io_8bit_set_status(status, 0xE);
+ FileSaveConfig(user_io_create_config_name(), &status, 4);
+ video_menu_bg((status >> 1) & 7);
+ }
+ break;
+
+ case KEY_F11:
+ if (user_io_osd_is_visible())
+ {
+ menustate = MENU_BTPAIR;
+ }
+ break;
+
+ case KEY_F10:
+ if (user_io_osd_is_visible() && !access("/bin/wminput", F_OK))
+ {
+ menustate = MENU_WMPAIR;
+ }
+ else if (input_has_lightgun())
+ {
+ menustate = MENU_LGCAL;
+ }
+ break;
+
+ case KEY_F9:
+ if (is_menu_core() && cfg.fb_terminal)
+ {
+ video_chvt(1);
+ video_fb_enable(!video_fb_state());
+ if (video_fb_state()) menustate = MENU_NONE1;
+ }
+ break;
+
+ // Within the menu the esc key acts as the menu key. problem:
+ // if the menu is left with a press of ESC, then the follwing
+ // break code for the ESC key when the key is released will
+ // reach the core which never saw the make code. Simple solution:
+ // react on break code instead of make code
+ case KEY_ESC | UPSTROKE:
+ if (menustate != MENU_NONE2) menu = true;
+ break;
+ case KEY_ENTER:
+ case KEY_SPACE:
+ select = true;
+ break;
+ case KEY_UP:
+ up = true;
+ break;
+ case KEY_DOWN:
+ down = true;
+ break;
+ case KEY_LEFT:
+ left = true;
+ break;
+ case KEY_RIGHT:
+ right = true;
+ break;
+ case KEY_KPPLUS:
+ case KEY_EQUAL: // =/+
+ plus = true;
+ break;
+ case KEY_KPMINUS:
+ case KEY_MINUS: // -/_
+ minus = true;
+ break;
+ }
}
if (menu || select || up || down || left || right)
@@ -3688,6 +3703,7 @@ void HandleUI(void)
break;
}
+ OsdSetSize(16);
helptext = helptexts[HELPTEXT_NONE];
parentstate = menustate;
@@ -3798,7 +3814,7 @@ void HandleUI(void)
}
}
- if(match) SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_SYSTEM1);
+ if(match) SelectFile("SH", SCANO_DIR, MENU_SCRIPTS_FB, MENU_SYSTEM1);
else
{
menustate = MENU_SCRIPTS_PRE;
@@ -3916,12 +3932,58 @@ void HandleUI(void)
// fall through
case 1:
- SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_SYSTEM1);
+ SelectFile("SH", SCANO_DIR, MENU_SCRIPTS_FB, MENU_SYSTEM1);
break;
}
}
break;
+ case MENU_SCRIPTS_FB:
+ if (cfg.fb_terminal)
+ {
+ menustate = MENU_SCRIPTS_FB2;
+ OsdDisable();
+ video_chvt(2);
+ video_fb_enable(1);
+ static char cmd[1024 * 2];
+ sprintf(cmd, "#!/bin/bash\nexport LC_ALL=en_US.UTF-8\ncd $(dirname %s)\n%s\necho \"Press any key to continue\"\n", getFullPath(SelectedPath), getFullPath(SelectedPath));
+ unlink("/tmp/script");
+ FileSave("/tmp/script", cmd, strlen(cmd), 1);
+ ttypid = fork();
+ if (!ttypid)
+ {
+ system("/sbin/agetty -a root -l /tmp/script --nohostname -L tty2 xterm");
+ exit(0);
+ }
+ }
+ else
+ {
+ menustate = MENU_SCRIPTS;
+ }
+ break;
+
+ case MENU_SCRIPTS_FB2:
+ if (ttypid)
+ {
+ if (waitpid(ttypid, 0, WNOHANG) > 0)
+ {
+ ttypid = 0;
+ user_io_osd_key_enable(1);
+ }
+ }
+ else
+ {
+ if (c & UPSTROKE)
+ {
+ video_fb_enable(0);
+ menustate = MENU_SYSTEM1;
+ menusub = 3;
+ OsdClear();
+ OsdEnable(DISABLE_KEYBOARD);
+ }
+ }
+ break;
+
case MENU_BTPAIR:
OsdSetSize(16);
OsdEnable(DISABLE_KEYBOARD);
@@ -4445,11 +4507,6 @@ void Info(const char *message, int timeout, int width, int height, int frame)
}
}
-void menu_bt_pair()
-{
- menustate = MENU_BTPAIR;
-}
-
int menu_lightgun_cb(uint16_t type, uint16_t code, int value)
{
if (type == EV_ABS)
diff --git a/menu.h b/menu.h
index 3cec841..bc63e18 100644
--- a/menu.h
+++ b/menu.h
@@ -28,8 +28,6 @@ extern char joy_bnames[32][32];
extern int joy_bcount;
void open_joystick_setup();
-void menu_bt_pair();
-
int menu_lightgun_cb(uint16_t type, uint16_t code, int value);
#endif
diff --git a/video.cpp b/video.cpp
index f15051d..187ffa9 100644
--- a/video.cpp
+++ b/video.cpp
@@ -5,6 +5,8 @@
#include
#include
#include
+#include
+#include
#include "hardware.h"
#include "user_io.h"
@@ -1010,3 +1012,21 @@ void video_menu_bg(int n)
video_fb_enable(0);
}
+
+int video_chvt(int num)
+{
+ static int cur_vt = 0;
+ if (num)
+ {
+ cur_vt = num;
+ int fd;
+ if ((fd = open("/dev/tty0", O_RDONLY)) >= 0)
+ {
+ if (ioctl(fd, VT_ACTIVATE, cur_vt)) printf("ioctl VT_ACTIVATE fails\n");
+ if (ioctl(fd, VT_WAITACTIVE, cur_vt)) printf("ioctl VT_WAITACTIVE fails\n");
+ close(fd);
+ }
+ }
+
+ return cur_vt ? cur_vt : 1;
+}
diff --git a/video.h b/video.h
index 67015ea..b2257a5 100644
--- a/video.h
+++ b/video.h
@@ -14,5 +14,6 @@ int hasAPI1_5();
void video_fb_enable(int enable, int n = 0);
int video_fb_state();
void video_menu_bg(int n);
+int video_chvt(int num);
#endif // VIDEO_H