diff options
author | FeralChild64 <unknown> | 2022-11-06 14:30:43 +0300 |
---|---|---|
committer | kcgen <1557255+kcgen@users.noreply.github.com> | 2022-11-07 08:43:55 +0300 |
commit | 35b2eec923545b6087dc622c0546807852fe041d (patch) | |
tree | 4d7e010ecdff09c0d989f24885abe458417fe428 | |
parent | c9351ab7768b5230440404fdeb4faf16f6f6985b (diff) |
Add general DOS user request functions
-rw-r--r-- | include/dos_inc.h | 9 | ||||
-rw-r--r-- | src/dos/dos.cpp | 68 | ||||
-rw-r--r-- | src/dos/program_more.cpp | 51 | ||||
-rw-r--r-- | src/dos/program_more.h | 10 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_manymouse.cpp | 27 | ||||
-rw-r--r-- | src/hardware/mouse/mouse_manymouse.h | 1 |
6 files changed, 95 insertions, 71 deletions
diff --git a/include/dos_inc.h b/include/dos_inc.h index caddb9b06..8fbcd7637 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -179,7 +179,8 @@ bool DOS_CreateTempFile(char * const name,uint16_t * entry); bool DOS_FileExists(char const * const name); /* Helper Functions */ -bool DOS_MakeName(char const * const name,char * const fullname,uint8_t * drive); +bool DOS_MakeName(char const *const name, char *const fullname, uint8_t *drive); + /* Drive Handing Routines */ uint8_t DOS_GetDefaultDrive(void); void DOS_SetDefaultDrive(uint8_t drive); @@ -290,6 +291,12 @@ static inline uint16_t long2para(uint32_t size) { #define DOSERR_NO_MORE_FILES 18 #define DOSERR_FILE_ALREADY_EXISTS 80 +/* Wait/check user input */ +enum class UserDecision { Cancel, Continue, Next }; +bool DOS_IsCancelRequest(); +UserDecision DOS_WaitForCancelContinue(); +UserDecision DOS_WaitForCancelContinueNext(); + /* Macros SSET_* and SGET_* are used to safely access fields in memory-mapped * DOS structures represented via classes inheriting from MemStruct class. * diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 6081899ec..f8fba87b9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -1440,6 +1440,74 @@ static Bitu DOS_26Handler(void) { return CBRET_NONE; } +constexpr uint8_t code_ctrl_c = 0x03; +constexpr uint8_t code_return = 0x0d; +constexpr uint8_t code_esc = 0x1b; + +bool DOS_IsCancelRequest() +{ + if (shutdown_requested) + return true; + + CALLBACK_Idle(); + while (!(Files[STDIN]->GetInformation() & (1 << 6))) { + // A key is waiting, read it + uint16_t count = 1; + uint8_t code = 0; + DOS_ReadFile(STDIN, &code, &count); + + // Check if user requested to cancel + if (shutdown_requested || count == 0 || + code == 'q' || code == 'Q' || + code == code_ctrl_c || code == code_esc) + return true; + } + + // Return control if no key pressed + return shutdown_requested; +} + +UserDecision DOS_WaitForCancelContinue() +{ + auto decision = UserDecision::Next; + while (decision == UserDecision::Next) + decision = DOS_WaitForCancelContinueNext(); + + return decision; +} + +UserDecision DOS_WaitForCancelContinueNext() +{ + auto decision = UserDecision::Cancel; + while (!shutdown_requested) { + CALLBACK_Idle(); + + // Try to read the key + uint16_t count = 1; + uint8_t code = 0; + DOS_ReadFile(STDIN, &code, &count); + + if (shutdown_requested || count == 0 || + code == 'q' || code == 'Q' || + code == code_ctrl_c || code == code_esc) { + decision = UserDecision::Cancel; + break; + } + + if (code == code_return || code == ' ') { + decision = UserDecision::Continue; + break; + } + + if (code == 'n' || code == 'N') { + decision = UserDecision::Next; + break; + } + } + + return decision; +} + DOS_Version DOS_ParseVersion(const char *word, const char *args) { DOS_Version new_version = {5, 0, 0}; // Default to 5.0 diff --git a/src/dos/program_more.cpp b/src/dos/program_more.cpp index 84864d6e1..76d6015a9 100644 --- a/src/dos/program_more.cpp +++ b/src/dos/program_more.cpp @@ -36,7 +36,6 @@ CHECK_NARROWING(); constexpr char code_ctrl_c = 0x03; // end of text constexpr char code_lf = 0x0a; // line feed constexpr char code_cr = 0x0d; // carriage return -constexpr char code_esc = 0x1b; // escape void MORE::Run() { @@ -220,7 +219,7 @@ void MORE::DisplayInputFiles() bool first = true; for (const auto &input_file : input_files) { - if (!first && Decision::Terminate == PromptUser()) + if (!first && UserDecision::Cancel == PromptUser()) break; first = false; @@ -252,7 +251,7 @@ void MORE::DisplayInputFiles() const auto decision = DisplaySingleStream(); DOS_CloseFile(input_handle); - if (decision == Decision::Terminate) { + if (decision == UserDecision::Cancel) { break; } } @@ -278,7 +277,7 @@ void MORE::DisplayInputStream() DisplaySingleStream(); } -MORE::Decision MORE::DisplaySingleStream() +UserDecision MORE::DisplaySingleStream() { auto previous_column = GetCurrentColumn(); @@ -286,17 +285,17 @@ MORE::Decision MORE::DisplaySingleStream() skip_next_cr = false; skip_next_lf = false; - auto decision = Decision::NextFile; + auto decision = UserDecision::Next; while (true) { if (shutdown_requested) { - decision = Decision::Terminate; + decision = UserDecision::Cancel; break; } // Read character char code = 0; if (!GetCharacter(code)) { - decision = Decision::NextFile; // end of file + decision = UserDecision::Next; // end of current file break; } @@ -340,7 +339,8 @@ MORE::Decision MORE::DisplaySingleStream() // New line occured just enough times for a pause decision = PromptUser(); - if (decision == Decision::Terminate || decision == Decision::NextFile) { + if (decision == UserDecision::Cancel || + decision == UserDecision::Next) { break; } } @@ -353,7 +353,7 @@ MORE::Decision MORE::DisplaySingleStream() return decision; } -MORE::Decision MORE::PromptUser() +UserDecision MORE::PromptUser() { line_counter = 0; const bool multiple_files = input_files.size() > 1; @@ -366,35 +366,14 @@ MORE::Decision MORE::PromptUser() else WriteOut(MSG_Get("PROGRAM_MORE_PROMPT_SINGLE")); - auto decision = Decision::Terminate; - while (!shutdown_requested) { - CALLBACK_Idle(); + auto decision = UserDecision::Cancel; - uint16_t count = 1; - char choice = 0; - DOS_ReadFile(STDIN, reinterpret_cast<uint8_t *>(&choice), &count); - - if (count == 0 || choice == code_ctrl_c || choice == code_esc || - choice == 'q' || choice == 'Q') { - decision = Decision::Terminate; - break; - } - - if (choice == code_cr || choice == ' ') { - decision = Decision::More; - break; - } - - if (!multiple_files) - continue; - - if (choice == 'n' || choice == 'N') { - decision = Decision::NextFile; - break; - } - } + if (multiple_files) + decision = DOS_WaitForCancelContinueNext(); + else + decision = DOS_WaitForCancelContinue(); - if (decision == Decision::Terminate || decision == Decision::NextFile) { + if (decision == UserDecision::Cancel || decision == UserDecision::Next) { WriteOut(" "); WriteOut(MSG_Get("PROGRAM_MORE_TERMINATE")); WriteOut("\n"); diff --git a/src/dos/program_more.h b/src/dos/program_more.h index e5266a929..ff3431087 100644 --- a/src/dos/program_more.h +++ b/src/dos/program_more.h @@ -38,19 +38,13 @@ public: void Run(); private: - enum class Decision { - More, - Terminate, - NextFile, - }; - bool ParseCommandLine(); bool FindInputFiles(const std::vector<std::string> ¶ms); void DisplayInputFiles(); void DisplayInputStream(); - Decision DisplaySingleStream(); - Decision PromptUser(); + UserDecision DisplaySingleStream(); + UserDecision PromptUser(); std::string GetShortName(const std::string &file_name, const char *msg_id); static uint8_t GetCurrentColumn(); diff --git a/src/hardware/mouse/mouse_manymouse.cpp b/src/hardware/mouse/mouse_manymouse.cpp index 46f9c03a2..4f50fb4ee 100644 --- a/src/hardware/mouse/mouse_manymouse.cpp +++ b/src/hardware/mouse/mouse_manymouse.cpp @@ -254,15 +254,10 @@ bool ManyMouseGlue::ProbeForMapping(uint8_t &physical_device_idx) HandleEvent(event, true); // handle critical events bool success = false; - while (!shutdown_requested) { - if (IsCancelRequested()) - break; // user cancelled using a keyboard - + while (!DOS_IsCancelRequest()) { // Poll mouse events, handle critical ones - if (!ManyMouse_PollEvent(&event)) { - CALLBACK_Idle(); + if (!ManyMouse_PollEvent(&event)) continue; - } if (event.device >= max_mice) continue; HandleEvent(event, true); @@ -297,24 +292,6 @@ bool ManyMouseGlue::ProbeForMapping(uint8_t &physical_device_idx) return success; } -bool ManyMouseGlue::IsCancelRequested() -{ - constexpr uint8_t code_ctrl_c = 0x03; - constexpr uint8_t code_esc = 0x1b; - - while (!(Files[STDIN]->GetInformation() & (1 << 6))) { - // A key is waiting, read it - uint16_t count = 1; - uint8_t code = 0; - DOS_ReadFile(STDIN, &code, &count); - // Check if requested to cancel - if (code == code_ctrl_c || code == code_esc || code == 'q' || code == 'Q') - return true; - } - - return false; -} - uint8_t ManyMouseGlue::GetIdx(const std::regex ®ex) { assert(max_mice < UINT8_MAX); diff --git a/src/hardware/mouse/mouse_manymouse.h b/src/hardware/mouse/mouse_manymouse.h index f9b0a0fc1..69753e145 100644 --- a/src/hardware/mouse/mouse_manymouse.h +++ b/src/hardware/mouse/mouse_manymouse.h @@ -73,7 +73,6 @@ private: ManyMouseGlue(const ManyMouseGlue &) = delete; ManyMouseGlue &operator=(const ManyMouseGlue &) = delete; - bool IsCancelRequested(); void Tick(); friend void manymouse_tick(uint32_t); |