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