mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-12 15:31:09 +00:00
Rejigs the typing relationship so that use of a typer is not strongly implied by the interface.
Simultaneously implements typing on the MSX by direct insertion into the key buffer.
This commit is contained in:
parent
d5b1a9d918
commit
e349161a53
@ -27,3 +27,6 @@ void Machine::reset_all_keys(Inputs::Keyboard *keyboard) {
|
||||
Inputs::Keyboard &Machine::get_keyboard() {
|
||||
return keyboard_;
|
||||
}
|
||||
|
||||
void Machine::type_string(const std::string &) {
|
||||
}
|
||||
|
@ -30,6 +30,13 @@ class Machine: public Inputs::Keyboard::Delegate {
|
||||
*/
|
||||
virtual void clear_all_keys() = 0;
|
||||
|
||||
/*!
|
||||
Causes the machine to attempt to type the supplied string.
|
||||
|
||||
This is best effort. Success or failure is permitted to be a function of machine and current state.
|
||||
*/
|
||||
virtual void type_string(const std::string &);
|
||||
|
||||
/*!
|
||||
Provides a destination for keyboard input.
|
||||
*/
|
||||
|
@ -139,6 +139,10 @@ class ConcreteMachine:
|
||||
|
||||
void configure_as_target(const StaticAnalyser::Target &target) override {
|
||||
insert_media(target.media);
|
||||
|
||||
if(target.loading_command.length()) {
|
||||
type_string(target.loading_command);
|
||||
}
|
||||
}
|
||||
|
||||
bool insert_media(const StaticAnalyser::Media &media) override {
|
||||
@ -160,6 +164,10 @@ class ConcreteMachine:
|
||||
return true;
|
||||
}
|
||||
|
||||
void type_string(const std::string &string) override final {
|
||||
input_text_ += string;
|
||||
}
|
||||
|
||||
void page_memory(uint8_t value) {
|
||||
for(size_t c = 0; c < 4; ++c) {
|
||||
read_pointers_[c] = memory_slots_[value & 3].read_pointers[c];
|
||||
@ -296,6 +304,32 @@ class ConcreteMachine:
|
||||
|
||||
case CPU::Z80::PartialMachineCycle::Interrupt:
|
||||
*cycle.value = 0xff;
|
||||
|
||||
// Take this as a convenient moment to jump into the keyboard buffer, if desired.
|
||||
if(!input_text_.empty()) {
|
||||
// TODO: is it safe to assume these addresses?
|
||||
const int buffer_start = 0xfbf0;
|
||||
const int buffer_end = 0xfb18;
|
||||
|
||||
int read_address = ram_[0xf3fa] | (ram_[0xf3fb] << 8);
|
||||
int write_address = ram_[0xf3f8] | (ram_[0xf3f9] << 8);
|
||||
|
||||
const int buffer_size = buffer_end - buffer_start;
|
||||
int available_space = write_address + buffer_size - read_address - 1;
|
||||
|
||||
const std::size_t characters_to_write = std::min(static_cast<std::size_t>(available_space), input_text_.size());
|
||||
write_address -= buffer_start;
|
||||
for(std::size_t c = 0; c < characters_to_write; ++c) {
|
||||
char character = input_text_[c];
|
||||
ram_[write_address + buffer_start] = static_cast<uint8_t>(character);
|
||||
write_address = (write_address + 1) % buffer_size;
|
||||
}
|
||||
write_address += buffer_start;
|
||||
input_text_.erase(input_text_.begin(), input_text_.begin() + static_cast<std::string::difference_type>(characters_to_write));
|
||||
|
||||
ram_[0xf3f8] = static_cast<uint8_t>(write_address);
|
||||
ram_[0xf3f9] = static_cast<uint8_t>(write_address >> 8);
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
@ -457,6 +491,7 @@ class ConcreteMachine:
|
||||
|
||||
uint8_t key_states_[16];
|
||||
int selected_key_line_ = 0;
|
||||
std::string input_text_;
|
||||
|
||||
MSX::KeyboardMapper keyboard_mapper_;
|
||||
};
|
||||
|
@ -87,12 +87,6 @@ class TypeRecipient: public Typer::Delegate {
|
||||
typer_.reset(new Typer(string, get_typer_delay(), get_typer_frequency(), std::move(character_mapper), this));
|
||||
}
|
||||
|
||||
/*!
|
||||
Provided as a hook for subclasses to implement so that external callers can install a typer
|
||||
without needing inside knowledge as to where the character mapper comes from.
|
||||
*/
|
||||
virtual void type_string(const std::string &) = 0;
|
||||
|
||||
/*!
|
||||
Provided in order to conform to that part of the Typer::Delegate interface that goes above and
|
||||
beyond KeyboardMachine::Machine; responds to the end of typing by clearing all keys.
|
||||
|
@ -188,9 +188,9 @@ struct MachineDelegate: CRTMachine::Machine::Delegate, public LockProtectedDeleg
|
||||
}
|
||||
|
||||
- (void)paste:(NSString *)paste {
|
||||
Utility::TypeRecipient *typeRecipient = _machine->type_recipient();
|
||||
if(typeRecipient)
|
||||
typeRecipient->type_string([paste UTF8String]);
|
||||
KeyboardMachine::Machine *keyboardMachine = _machine->type_recipient();
|
||||
if(keyboardMachine)
|
||||
keyboardMachine->type_string([paste UTF8String]);
|
||||
}
|
||||
|
||||
- (void)applyTarget:(const StaticAnalyser::Target &)target {
|
||||
|
@ -439,9 +439,9 @@ int main(int argc, char *argv[]) {
|
||||
case SDL_KEYDOWN:
|
||||
// Syphon off the key-press if it's control+shift+V (paste).
|
||||
if(event.key.keysym.sym == SDLK_v && (SDL_GetModState()&KMOD_CTRL) && (SDL_GetModState()&KMOD_SHIFT)) {
|
||||
Utility::TypeRecipient *type_recipient = machine->type_recipient();
|
||||
KeyboardMachine::Machine *keyboard_machine = machine->keyboard_machine()();
|
||||
if(type_recipient) {
|
||||
type_recipient->type_string(SDL_GetClipboardText());
|
||||
keyboard_machine->type_string(SDL_GetClipboardText());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ void StaticAnalyser::MSX::AddTargets(const Media &media, std::list<Target> &dest
|
||||
std::vector<File> files_on_tape = GetFiles(tape);
|
||||
if(!files_on_tape.empty()) {
|
||||
switch(files_on_tape.front().type) {
|
||||
case File::Type::ASCII: target.loading_command = "RUN\"CAS:\n"; break;
|
||||
case File::Type::TokenisedBASIC: target.loading_command = "CLOAD\nRUN\n"; break;
|
||||
case File::Type::Binary: target.loading_command = "BLOAD\"CAS:\",R\n"; break;
|
||||
case File::Type::ASCII: target.loading_command = "RUN\"CAS:\r"; break;
|
||||
case File::Type::TokenisedBASIC: target.loading_command = "CLOAD\rRUN\r"; break;
|
||||
case File::Type::Binary: target.loading_command = "BLOAD\"CAS:\",R\r"; break;
|
||||
default: break;
|
||||
}
|
||||
target.media.tapes.push_back(tape);
|
||||
|
Loading…
x
Reference in New Issue
Block a user