1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +00:00

Attempts to permit fixed speed multiplication.

This commit is contained in:
Thomas Harte 2020-02-10 23:30:32 -05:00
parent 6624cb7a78
commit 886d923e30
2 changed files with 19 additions and 6 deletions

View File

@ -33,7 +33,7 @@ class ScanSynchroniser {
// Check out the machine's current frame time. // Check out the machine's current frame time.
// If it's within 3% of a non-zero integer multiple of the // If it's within 3% of a non-zero integer multiple of the
// display rate, mark this time window to be split over the sync. // display rate, mark this time window to be split over the sync.
ratio_ = frame_duration / scan_status.field_duration; ratio_ = (frame_duration * base_multiplier_) / scan_status.field_duration;
const double integer_ratio = round(ratio_); const double integer_ratio = round(ratio_);
if(integer_ratio > 0.0) { if(integer_ratio > 0.0) {
ratio_ /= integer_ratio; ratio_ /= integer_ratio;
@ -54,13 +54,21 @@ class ScanSynchroniser {
// //
// ... with one slight caveat, which is that it is desireable to adjust phase here, to align vertical sync points. // ... with one slight caveat, which is that it is desireable to adjust phase here, to align vertical sync points.
// So the set speed multiplier may be adjusted slightly to aim for that. // So the set speed multiplier may be adjusted slightly to aim for that.
double speed_multiplier = 1.0 / ratio_; double speed_multiplier = 1.0 / (ratio_ / base_multiplier_);
if(scan_status.current_position > 0.0) { if(scan_status.current_position > 0.0) {
if(scan_status.current_position < 0.5) speed_multiplier /= phase_adjustment_ratio; if(scan_status.current_position < 0.5) speed_multiplier /= phase_adjustment_ratio;
else speed_multiplier *= phase_adjustment_ratio; else speed_multiplier *= phase_adjustment_ratio;
} }
speed_multiplier_ = (speed_multiplier_ * 0.95) + (speed_multiplier * 0.05); speed_multiplier_ = (speed_multiplier_ * 0.95) + (speed_multiplier * 0.05);
return speed_multiplier_; return speed_multiplier_ * base_multiplier_;
}
void set_base_speed_multiplier(double multiplier) {
base_multiplier_ = multiplier;
}
double get_base_speed_multiplier() {
return base_multiplier_;
} }
private: private:
@ -69,6 +77,7 @@ class ScanSynchroniser {
// Managed local state. // Managed local state.
double speed_multiplier_ = 1.0; double speed_multiplier_ = 1.0;
double base_multiplier_ = 1.0;
// Temporary storage to bridge the can_synchronise -> next_speed_multiplier gap. // Temporary storage to bridge the can_synchronise -> next_speed_multiplier gap.
double ratio_ = 1.0; double ratio_ = 1.0;

View File

@ -74,6 +74,10 @@ struct MachineRunner {
frame_lock_.clear(); frame_lock_.clear();
} }
void set_speed_multiplier(double multiplier) {
scan_synchroniser_.set_base_speed_multiplier(multiplier);
}
std::mutex *machine_mutex; std::mutex *machine_mutex;
Machine::DynamicMachine *machine; Machine::DynamicMachine *machine;
@ -127,6 +131,7 @@ struct MachineRunner {
crt_machine->run_for(double(time_now - vsync_time) / 1e9); crt_machine->run_for(double(time_now - vsync_time) / 1e9);
} else { } else {
crt_machine->set_speed_multiplier(scan_synchroniser_.get_base_speed_multiplier());
crt_machine->run_for(double(time_now - last_time_) / 1e9); crt_machine->run_for(double(time_now - last_time_) / 1e9);
} }
last_time_ = time_now; last_time_ = time_now;
@ -565,13 +570,12 @@ int main(int argc, char *argv[]) {
char *end; char *end;
double speed = strtod(speed_string, &end); double speed = strtod(speed_string, &end);
if(end-speed_string != strlen(speed_string)) { if(size_t(end - speed_string) != strlen(speed_string)) {
std::cerr << "Unable to parse speed: " << speed_string << std::endl; std::cerr << "Unable to parse speed: " << speed_string << std::endl;
} else if(speed <= 0.0) { } else if(speed <= 0.0) {
std::cerr << "Cannot run at speed " << speed_string << "; speeds must be positive." << std::endl; std::cerr << "Cannot run at speed " << speed_string << "; speeds must be positive." << std::endl;
} else { } else {
machine->crt_machine()->set_speed_multiplier(speed); machine_runner.set_speed_multiplier(speed);
// TODO: what if not a 'CRT' machine? Likely rests on resolving this project's machine naming policy.
} }
} }