From b064d06efd181e55c79dffdc453543b15b1f60e6 Mon Sep 17 00:00:00 2001 From: "Christopher A. Mosher" Date: Mon, 12 Dec 2022 13:03:30 -0500 Subject: [PATCH] add wx menu handling for F1,F7,F9; fix initial value (random) of keyboard latch --- src/E2wxApp.cpp | 7 ++++- src/E2wxApp.h | 1 + src/E2wxFrame.cpp | 16 +++++++++-- src/E2wxFrame.h | 1 + src/apple2.cpp | 1 + src/emulator.cpp | 47 +++++++++++++++--------------- src/emulator.h | 14 ++++----- src/keyboard.cpp | 73 ++++++++++++++++++++++++----------------------- src/keyboard.h | 7 ++--- 9 files changed, 91 insertions(+), 76 deletions(-) diff --git a/src/E2wxApp.cpp b/src/E2wxApp.cpp index 32a6a66..a6473a9 100644 --- a/src/E2wxApp.cpp +++ b/src/E2wxApp.cpp @@ -360,7 +360,6 @@ void E2wxApp::StartEmulator() { this->emu = new Emulator(); E2Config cfg{this->arg_configfile, this->opt_config_from_prefs_only}; this->emu->config(cfg); - this->emu->init(); this->emu_timer = new EmuTimer{this->emu}; this->emu_timer->begin(); @@ -373,3 +372,9 @@ bool E2wxApp::EnsureCanQuit() { } return ok; } + +void E2wxApp::Paste() { + if (this->emu) { + this->emu->handlePaste(); + } +} \ No newline at end of file diff --git a/src/E2wxApp.h b/src/E2wxApp.h index 0adf651..53361cc 100644 --- a/src/E2wxApp.h +++ b/src/E2wxApp.h @@ -83,6 +83,7 @@ public: bool CloseMainFrame(); bool EnsureCanQuit(); + void Paste(); virtual bool OnInit() override; virtual int OnExit() override; diff --git a/src/E2wxFrame.cpp b/src/E2wxFrame.cpp index 946f462..71a3030 100644 --- a/src/E2wxFrame.cpp +++ b/src/E2wxFrame.cpp @@ -23,18 +23,19 @@ #include "PreferencesDialog.h" #include "gui.h" #include +#include #include #include #include - enum E2MenuID { ID_MENUITEM_POWER = wxID_HIGHEST+1 }; wxBEGIN_EVENT_TABLE(E2wxFrame, wxFrame) EVT_MENU(wxID_EXIT, E2wxFrame::OnExit) + EVT_MENU(wxID_PASTE, E2wxFrame::OnPaste) EVT_MENU(wxID_PREFERENCES, E2wxFrame::OnPreferences) EVT_MENU(wxID_ABOUT, E2wxFrame::OnAbout) EVT_MENU(ID_MENUITEM_POWER, E2wxFrame::OnTogglePower) @@ -65,15 +66,20 @@ void E2wxFrame::InitMenuBar() { wxMenu *menuFile = new wxMenu(); menuBar->Append(menuFile, "&File"); - menuFile->Append(wxID_EXIT); + wxMenuItem *miExit = menuFile->Append(wxID_EXIT); + miExit->AddExtraAccel(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F9)); wxMenu *menuEdit = new wxMenu(); menuBar->Append(menuEdit, "&Edit"); + wxMenuItem *miPaste = menuEdit->Append(wxID_PASTE); + miPaste->AddExtraAccel(wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F7)); + menuEdit->AppendSeparator(); menuEdit->Append(wxID_PREFERENCES); wxMenu *menuMachine = new wxMenu(); menuBar->Append(menuMachine, "&Machine"); - menuMachine->Append(ID_MENUITEM_POWER, "Toggle Power"); + wxMenuItem *miPower = menuMachine->Append(ID_MENUITEM_POWER, "Toggle Power"); + miPower->SetAccel(new wxAcceleratorEntry(wxACCEL_NORMAL, WXK_F1)); wxMenu *menuHelp = new wxMenu(); menuBar->Append(menuHelp, "&Help"); @@ -104,6 +110,10 @@ void E2wxFrame::OnAbout(wxCommandEvent& event) { wxMessageBox(msg, "About "+wxGetApp().GetID(), wxOK | wxICON_INFORMATION); } +void E2wxFrame::OnPaste(wxCommandEvent& event) { + wxGetApp().Paste(); +} + void E2wxFrame::OnPreferences(wxCommandEvent& event) { PreferencesDialog *dlg = new PreferencesDialog(this); dlg->OnInit(); diff --git a/src/E2wxFrame.h b/src/E2wxFrame.h index ed09c6a..f3ca51b 100644 --- a/src/E2wxFrame.h +++ b/src/E2wxFrame.h @@ -34,6 +34,7 @@ public: private: void OnExit(wxCommandEvent& event); + void OnPaste(wxCommandEvent& event); void OnPreferences(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); void OnTogglePower(wxCommandEvent& event); diff --git a/src/apple2.cpp b/src/apple2.cpp index 01c188c..5d21eba 100644 --- a/src/apple2.cpp +++ b/src/apple2.cpp @@ -94,6 +94,7 @@ void Apple2::powerOn() { this->video.powerOn(); this->picgen.powerOn(); this->powerUpReset.powerOn(); + this->kbd.powerOn(); } void Apple2::powerOff() { diff --git a/src/emulator.cpp b/src/emulator.cpp index a5d662c..5776787 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -52,11 +52,6 @@ void Emulator::toggleComputerPower() { } void Emulator::powerOnComputer() { - if (this->apple2.revision == 0) { - unsigned char key = 33u + rand()%94; - this->keypresses.push(key); - this->lastKeyDown = key; - } this->apple2.powerOn(); this->screenImage.drawPower(true); this->display.setNoise(false); @@ -78,9 +73,6 @@ void Emulator::powerOffComputer() { void Emulator::config(E2Config& cfg) { cfg.parse(this->apple2.ram, this->apple2.rom, this->apple2.slts, this->apple2.revision, this->screenImage, this->apple2.cassetteIn, this->apple2.cassetteOut, &this->apple2); this->apple2.ram.dump_config(); -} - -void Emulator::init() { powerOffComputer(); this->display.powerOn(true); } @@ -299,23 +291,15 @@ void Emulator::dispatchKeypress(const SDL_KeyboardEvent& keyEvent) { * First handle the key presses that are for commands, as opposed to * simple key-presses that we send to the apple. */ - + // TODO remove all function key handling from here, and + // instead redirect them to the main frame, which will call back + // our appropriate handler functions + // Note: REPT key is special (need to track key-up event) if (sym == SDLK_F6) { this->apple2.reset(); return; } else if (sym == SDLK_F7) { - // Feed input from the clipboard to the Apple keyboard - std::string s = this->clip.getText(); - for (unsigned int i = 0; i < s.length(); ++i) { - unsigned char key = s[i]; - // TODO fix pasting line-endings - if (key == '\n') - key = '\r'; - if ('a' <= key && key <= 'z') { - key -= 32; - } - this->keypresses.push(key); - } + handlePaste(); return; }// ...else if this is the emulated REPT key on the Apple keyboard... else if (sym == SDLK_F10) { @@ -325,7 +309,7 @@ void Emulator::dispatchKeypress(const SDL_KeyboardEvent& keyEvent) { return; }// ...else if the user wants to run at full speed instead of emulating // the Apple's speed... - else if (sym == SDLK_F11) { + else if (sym == SDLK_F11) { // TODO remove hyper this->fhyper.toggleHyper(); this->screenImage.toggleHyperLabel(); return; @@ -350,12 +334,12 @@ void Emulator::dispatchKeypress(const SDL_KeyboardEvent& keyEvent) { return; }// ...else if the user wants to switch between the interlaced extension // of the display and the non-interlaced historically correct display... - else if (sym == SDLK_F4) { + else if (sym == SDLK_F4) { // TODO remove bleed-down this->display.toggleBleedDown(); this->screenImage.toggleFillLinesLabel(); return; }// ...else initiate command line entry at the bottom of the emulator window - else if (sym == SDLK_F5) { + else if (sym == SDLK_F5) { // TODO re-do user-entered command line this->command = true; this->screenImage.enterCommandMode(); return; @@ -474,3 +458,18 @@ bool Emulator::isSafeToQuit() { void Emulator::handleUserQuitRequest() { wxGetApp().CloseMainFrame(); } + +void Emulator::handlePaste() { + // Feed input from the clipboard to the Apple keyboard + std::string s = this->clip.getText(); + for (unsigned int i = 0; i < s.length(); ++i) { + unsigned char key = s[i]; + // TODO fix pasting line-endings + if (key == '\n') + key = '\r'; + if ('a' <= key && key <= 'z') { + key -= 32; + } + this->keypresses.push(key); + } +} diff --git a/src/emulator.h b/src/emulator.h index fe690d3..fd29c0e 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -61,6 +61,8 @@ class Emulator { void dispatchKeyUp(const SDL_KeyboardEvent& keyEvent); void cmdKey(const SDL_KeyboardEvent& keyEvent); void processCommand(); + void powerOnComputer(); + void powerOffComputer(); void handleRepeatKey(); void handleAnyPendingEvents(); @@ -72,15 +74,11 @@ public: void config(E2Config& cfg); - void init(); - - void powerOnComputer(); - void powerOffComputer(); - void toggleComputerPower(); - void cycleDisplayType(); - bool isSafeToQuit(); - void tick50ms(); + + void toggleComputerPower(); + void handlePaste(); + bool isSafeToQuit(); }; #endif diff --git a/src/keyboard.cpp b/src/keyboard.cpp index c953b1b..0cf739c 100644 --- a/src/keyboard.cpp +++ b/src/keyboard.cpp @@ -14,32 +14,34 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #include "keyboard.h" #include "hypermode.h" #include "keyboardbuffermode.h" +#include -Keyboard::Keyboard(KeypressQueue& q, HyperMode& fhyper, KeyboardBufferMode& buffered): + + +Keyboard::Keyboard(KeypressQueue& q, HyperMode& fhyper, KeyboardBufferMode& buffered) : keys(q), fhyper(fhyper), buffered(buffered), - latch(0xC1u), // TODO: randomize this a little - cGet(0) -{ + latch(0), + cGet(0) { } -void Keyboard::clear() -{ +void Keyboard::powerOn() { + this->latch = 0xA1u + std::rand() % (0xFEu-0xA1+1u); +} + +void Keyboard::clear() { this->latch &= 0x7F; } -unsigned char Keyboard::get() -{ +unsigned char Keyboard::get() { waitIfTooFast(); - if (!this->buffered.isBuffered() || !(this->latch & 0x80)) - { - if (!this->keys.empty()) - { + if (!this->buffered.isBuffered() || !(this->latch & 0x80)) { + if (!this->keys.empty()) { this->latch = this->keys.front() | 0x80; this->keys.pop(); } @@ -47,28 +49,27 @@ unsigned char Keyboard::get() return this->latch; } -void Keyboard::waitIfTooFast() -{ - if (this->fhyper.isHyper()) - { - return; - } +void Keyboard::waitIfTooFast() { + // TODO remove all hyper stuff; it doesn't do anything anymore, + // since the new architecture with wxTimer - ++this->cGet; - if (!this->cGet) - { - if (SDL_GetTicks() - this->lastGet <= 1000) - { - /* - * Check every 256 gets to see if they are - * happening too fast (within one second). - * If so, it means we are probably just - * looping waiting for a keypress, so - * wait a millisecond (or so) just to - * prevent us from using 100% of CPU time. - */ - SDL_Delay(1); - } - } - this->lastGet = SDL_GetTicks(); +// if (this->fhyper.isHyper()) { +// return; +// } +// +// ++this->cGet; +// if (!this->cGet) { +// if (SDL_GetTicks() - this->lastGet <= 1000) { +// /* +// * Check every 256 gets to see if they are +// * happening too fast (within one second). +// * If so, it means we are probably just +// * looping waiting for a keypress, so +// * wait a millisecond (or so) just to +// * prevent us from using 100% of CPU time. +// */ +// SDL_Delay(1); +// } +// } +// this->lastGet = SDL_GetTicks(); } diff --git a/src/keyboard.h b/src/keyboard.h index 9d05d46..c2d1ead 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ + */ #ifndef KEYBOARD_H #define KEYBOARD_H @@ -26,9 +26,7 @@ typedef std::queue KeypressQueue; class HyperMode; class KeyboardBufferMode; -class Keyboard -{ -private: +class Keyboard { KeypressQueue& keys; HyperMode& fhyper; KeyboardBufferMode& buffered; @@ -41,6 +39,7 @@ private: public: Keyboard(KeypressQueue& q, HyperMode& fhyper, KeyboardBufferMode& buffered); + void powerOn(); void clear(); unsigned char get(); };