1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Merge pull request #853 from TomHarte/AppleIIReset

Improves Apple II keyboard input, especially under SDL.
This commit is contained in:
Thomas Harte 2020-11-28 12:43:32 -05:00 committed by GitHub
commit c9ca1fc7a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 67 additions and 30 deletions

View File

@ -804,38 +804,62 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
m6502_.run_for(cycles); m6502_.run_for(cycles);
} }
void reset_all_keys(Inputs::Keyboard *) final { void reset_all_keys() final {
open_apple_is_pressed_ = closed_apple_is_pressed_ = key_is_down_ = false; open_apple_is_pressed_ = closed_apple_is_pressed_ = key_is_down_ = false;
} }
bool prefers_logical_input() final {
return true;
}
bool set_key_pressed(Key key, char value, bool is_pressed) final { bool set_key_pressed(Key key, char value, bool is_pressed) final {
// If no ASCII value is supplied, look for a few special cases.
switch(key) { switch(key) {
default: break; case Key::Left: value = 0x08; break;
case Key::F12: case Key::Right: value = 0x15; break;
m6502_.set_reset_line(is_pressed); case Key::Down: value = 0x0a; break;
return true; case Key::Up: value = 0x0b; break;
case Key::Backspace: value = 0x7f; break;
case Key::Enter: value = 0x0d; break;
case Key::Tab: value = '\t'; break;
case Key::Escape: value = 0x1b; break;
case Key::LeftOption: case Key::LeftOption:
case Key::RightMeta:
open_apple_is_pressed_ = is_pressed; open_apple_is_pressed_ = is_pressed;
return true; return true;
case Key::RightOption: case Key::RightOption:
case Key::LeftMeta:
closed_apple_is_pressed_ = is_pressed; closed_apple_is_pressed_ = is_pressed;
return true; return true;
}
// If no ASCII value is supplied, look for a few special cases. case Key::F1: case Key::F2: case Key::F3: case Key::F4:
if(!value) { case Key::F5: case Key::F6: case Key::F7: case Key::F8:
switch(key) { case Key::F9: case Key::F10: case Key::F11: case Key::F12:
case Key::Left: value = 0x08; break; case Key::PrintScreen:
case Key::Right: value = 0x15; break; case Key::ScrollLock:
case Key::Down: value = 0x0a; break; case Key::Pause:
case Key::Up: value = 0x0b; break; case Key::Insert:
case Key::Backspace: value = 0x7f; break; case Key::Home:
default: return false; case Key::PageUp:
} case Key::PageDown:
} case Key::End:
// Accept a bunch non-symbolic other keys, as
// reset, in the hope that the user can find
// at least one usable key.
m6502_.set_reset_line(is_pressed);
return true;
// Prior to the IIe, the keyboard could produce uppercase only. default:
if(!is_iie()) value = char(toupper(value)); if(!value) {
return false;
}
// Prior to the IIe, the keyboard could produce uppercase only.
if(!is_iie()) value = char(toupper(value));
break;
}
if(is_pressed) { if(is_pressed) {
keyboard_input_ = uint8_t(value | 0x80); keyboard_input_ = uint8_t(value | 0x80);

View File

@ -32,6 +32,11 @@ struct KeyActions {
Instructs that all keys should now be treated as released. Instructs that all keys should now be treated as released.
*/ */
virtual void clear_all_keys() {} virtual void clear_all_keys() {}
/*!
Indicates whether a machine most naturally accepts logical rather than physical input.
*/
virtual bool prefers_logical_input() { return false; }
}; };
/*! /*!

View File

@ -5175,6 +5175,7 @@
"$(USER_LIBRARY_DIR)/Frameworks", "$(USER_LIBRARY_DIR)/Frameworks",
); );
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
MACOSX_DEPLOYMENT_TARGET = 10.13;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };
name = Debug; name = Debug;
@ -5197,6 +5198,8 @@
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_OPTIMIZATION_LEVEL = 2; GCC_OPTIMIZATION_LEVEL = 2;
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG; GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
MACOSX_DEPLOYMENT_TARGET = 10.13;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
}; };
name = Release; name = Release;

View File

@ -31,7 +31,7 @@
</Testables> </Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Release" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
disableMainThreadChecker = "YES" disableMainThreadChecker = "YES"
@ -58,8 +58,16 @@
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "&quot;/Users/thomasharte/Library/Mobile Documents/com~apple~CloudDocs/Desktop/Soft/Macintosh/MusicWorks 0.42.image&quot;" argument = "&quot;/Users/thomasharte/Library/Mobile Documents/com~apple~CloudDocs/Desktop/Soft/Macintosh/MusicWorks 0.42.image&quot;"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "/Users/thomasharte/Library/Mobile\ Documents/com\~apple\~CloudDocs/Desktop/Soft/Apple\ II/Keplermatik.dsk"
isEnabled = "YES"> isEnabled = "YES">
</CommandLineArgument> </CommandLineArgument>
<CommandLineArgument
argument = "/Users/thomasharte/Library/Mobile\ Documents/com\~apple\~CloudDocs/Desktop/Soft/Apple\ II/WOZs/Prince\ of\ Persia\ side\ A.woz"
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument <CommandLineArgument
argument = "--volume=0.001" argument = "--volume=0.001"
isEnabled = "NO"> isEnabled = "NO">

View File

@ -783,8 +783,10 @@ int main(int argc, char *argv[]) {
} }
} }
// Check whether a 'logical' keyboard has been requested. // Check whether a 'logical' keyboard has been requested, or the machine would prefer one anyway.
const bool logical_keyboard = arguments.selections.find("logical-keyboard") != arguments.selections.end(); const bool logical_keyboard =
(arguments.selections.find("logical-keyboard") != arguments.selections.end()) ||
(machine->keyboard_machine() && machine->keyboard_machine()->prefers_logical_input());
if(logical_keyboard) { if(logical_keyboard) {
SDL_StartTextInput(); SDL_StartTextInput();
} }
@ -1162,13 +1164,8 @@ int main(int argc, char *argv[]) {
} else { } else {
// This is a slightly terrible way of obtaining a symbol for the key, e.g. for letters it will always return // This is a slightly terrible way of obtaining a symbol for the key, e.g. for letters it will always return
// the capital letter version, at least empirically. But it'll have to do for now. // the capital letter version, at least empirically. But it'll have to do for now.
//
// TODO: ideally have a keyboard machine declare whether it wants either key events or text input? But that
// doesn't match machines like the IIe that, to some extent, expose both. So then eliding as attempted above,
// and keeping ephemeral track of which symbols have been tied to which keys for the benefit of future key up
// events is probably the way forward?
const char *key_name = SDL_GetKeyName(keypress.keycode); const char *key_name = SDL_GetKeyName(keypress.keycode);
if(keyboard_machine->get_keyboard().set_key_pressed(key, key_name[0], keypress.is_down)) { if(keyboard_machine->get_keyboard().set_key_pressed(key, (strlen(key_name) == 1) ? key_name[0] : 0, keypress.is_down)) {
continue; continue;
} }
} }

View File

@ -194,8 +194,9 @@ std::vector<std::string> ScanTarget::bindings(ShaderType type) const {
std::string ScanTarget::sampling_function() const { std::string ScanTarget::sampling_function() const {
std::string fragment_shader; std::string fragment_shader;
const auto modals = BufferingScanTarget::modals(); const auto modals = BufferingScanTarget::modals();
const bool is_svideo = modals.display_type == DisplayType::SVideo;
if(modals.display_type == DisplayType::SVideo) { if(is_svideo) {
fragment_shader += fragment_shader +=
"vec2 svideo_sample(vec2 coordinate, float angle) {"; "vec2 svideo_sample(vec2 coordinate, float angle) {";
} else { } else {
@ -203,7 +204,6 @@ std::string ScanTarget::sampling_function() const {
"float composite_sample(vec2 coordinate, float angle) {"; "float composite_sample(vec2 coordinate, float angle) {";
} }
const bool is_svideo = modals.display_type == DisplayType::SVideo;
switch(modals.input_data_type) { switch(modals.input_data_type) {
case InputDataType::Luminance1: case InputDataType::Luminance1:
case InputDataType::Luminance8: case InputDataType::Luminance8: