From 8c3c28e29a3178451c03cea3cdd6dd9942f343ed Mon Sep 17 00:00:00 2001 From: Alexey Melnikov Date: Thu, 3 Aug 2023 15:03:47 +0800 Subject: [PATCH] OSD Locking (#794) Add osd_lock and osd_lock_time config options When osd_lock is set it specifies a sequence of button pressed that must be pressed in order to gain access to the OSD while running a core. osd_lock_time is the time (in seconds) before you will be prompted again for the unlock code after you have closes the OSD. Co-authored-by: Martin Donlon --- MiSTer.ini | 11 ++++++++ cfg.cpp | 2 ++ cfg.h | 2 ++ menu.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/MiSTer.ini b/MiSTer.ini index 8b88b36..961a2d9 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -319,3 +319,14 @@ disable_autofire=0 ; You may use several controller_unique_mapping instances to assign several VID:PID. ;controller_unique_mapping=0x23418037 ; example for Arduino Micro controller_unique_mapping=0 + + +; Protect access to the OSD when a core is running +; When attempting to access the OSD players will be prompted for an unlock code. +; U = Up, D = Down, L = Left, R = Right, A = Select, B = Back +; Setting osd_lock to DUUUD would require entering the sequence Down, Up, Up, Up, Down +;osd_lock=DUUUD + +; If osd_lock is enabled, allow the OSD to be opened without entering the unlock +; code if less than osd_lock_time seconds have passed since the OSD was closed. +osd_lock_time=5 diff --git a/cfg.cpp b/cfg.cpp index e024e79..1cfb1a8 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -122,6 +122,8 @@ static const ini_var_t ini_vars[] = { "VGA_MODE", (void*)(&(cfg.vga_mode)), STRING, 0, sizeof(cfg.vga_mode) - 1 }, { "NTSC_MODE", (void *)(&(cfg.ntsc_mode)), UINT8, 0, 2}, { "CONTROLLER_UNIQUE_MAPPING", (void *)(cfg.controller_unique_mapping), UINT32ARR, 0, 0xFFFFFFFF }, + { "OSD_LOCK", (void*)(&(cfg.osd_lock)), STRING, 0, sizeof(cfg.osd_lock) - 1 }, + { "OSD_LOCK_TIME", (void*)(&(cfg.osd_lock_time)), UINT16, 0, 60}, }; static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t)); diff --git a/cfg.h b/cfg.h index be041fb..c06aa06 100644 --- a/cfg.h +++ b/cfg.h @@ -92,6 +92,8 @@ typedef struct { char vga_mode_int; char ntsc_mode; uint32_t controller_unique_mapping[256]; + char osd_lock[25]; + uint16_t osd_lock_time; } cfg_t; extern cfg_t cfg; diff --git a/menu.cpp b/menu.cpp index 25bda69..db83694 100644 --- a/menu.cpp +++ b/menu.cpp @@ -95,6 +95,8 @@ enum MENU MENU_ABOUT2, MENU_RESET1, MENU_RESET2, + MENU_UNLOCK1, + MENU_UNLOCK2, MENU_JOYSYSMAP, MENU_JOYDIGMAP, @@ -206,6 +208,11 @@ static uint32_t menu_save_timer = 0; static uint32_t load_addr = 0; static int32_t bt_timer = 0; +static bool osd_unlocked = false; +static char osd_code_entry[32]; +static uint32_t osd_lock_timer = 0; + + extern const char *version; const char *config_tos_wrprot[] = { "None", "A:", "B:", "A: and B:" }; @@ -934,6 +941,8 @@ void HandleUI(void) } } + if (osd_lock_timer == 0) osd_lock_timer = GetTimer(cfg.osd_lock_time * 1000); + switch (user_io_core_type()) { case CORE_TYPE_8BIT: @@ -1346,6 +1355,8 @@ void HandleUI(void) menumask = 0; menustate = MENU_NONE2; firstmenu = 0; + osd_unlocked = false; + osd_lock_timer = GetTimer(cfg.osd_lock_time * 1000); vga_nag(); OsdSetSize(8); break; @@ -1355,7 +1366,11 @@ void HandleUI(void) // fall through case MENU_NONE2: - if (menu || (is_menu() && !video_fb_state()) || (menustate == MENU_NONE2 && !mgl->done && mgl->state == 1)) + if (menu && cfg.osd_lock[0] && !osd_unlocked && CheckTimer(osd_lock_timer) && !is_menu() && mgl->done) + { + menustate = MENU_UNLOCK1; + } + else if (menu || osd_unlocked || (is_menu() && !video_fb_state()) || (menustate == MENU_NONE2 && !mgl->done && mgl->state == 1)) { OsdSetSize(16); menusub = 0; @@ -4055,6 +4070,64 @@ void HandleUI(void) } break; + case MENU_UNLOCK1: + osd_code_entry[0] = '\0'; + menumask = 0; + helptext_idx = 0; + menustate = MENU_UNLOCK2; + parentstate = MENU_UNLOCK1; + OsdSetSize(16); + OsdEnable(DISABLE_KEYBOARD); + OsdSetTitle("Menu Locked", 0); + for (int r = 0; r < OsdGetSize(); r++) + OsdWrite(r); + break; + + case MENU_UNLOCK2: + { + const char *append = ""; + if (up) append = "U"; + else if (down) append = "D"; + else if (left) append = "L"; + else if (right) append = "R"; + else if (select) append = "A"; + else if (back) append = "B"; + else if (menu) menustate = MENU_NONE1; + + strcat(osd_code_entry, append); + + if (strlen(osd_code_entry) >= strlen(cfg.osd_lock)) + { + if (!strcmp(osd_code_entry, cfg.osd_lock)) + { + osd_unlocked = true; + menustate = MENU_NONE2; + } + else + { + osd_code_entry[0] = '\0'; + } + } + + int maxlen = strlen(cfg.osd_lock); + int count = strlen(osd_code_entry); + + m = 5; + OsdWrite(m++, " Enter Unlock Code", 0, 0, 1); + OsdWrite(m++, "", 0, 0, 1); + OsdWrite(m++, "", 0, 0, 1); + int i; + for( i = 0; i < ( 29 - maxlen ) / 2; i++ ) + s[i] = ' '; + for( int j = 0; j < maxlen; j++, i++ ) + { + s[i] = j < count ? '*' : '-'; + } + + s[i] = '\0'; + OsdWrite(m++, s, 0, 0, 1); + break; + } /******************************************************************/ /* st main menu */