diff --git a/OSBindings/Mac/Clock Signal/CSAtari2600.mm b/OSBindings/Mac/Clock Signal/CSAtari2600.mm index 90f1596c0..df8059f22 100644 --- a/OSBindings/Mac/Clock Signal/CSAtari2600.mm +++ b/OSBindings/Mac/Clock Signal/CSAtari2600.mm @@ -24,23 +24,39 @@ struct Atari2600CRTDelegate: public Outputs::CRT::CRTDelegate { dispatch_queue_t _serialDispatchQueue; - int _failedVSyncCount; + int _frameCount; + NSTimeInterval _startTimeInterval; + BOOL _didDecideRegion; } - (void)crtDidEndFrame:(CRTFrame *)frame didDetectVSync:(BOOL)didDetectVSync { - if(!didDetectVSync) + if(!_didDecideRegion) { - _failedVSyncCount+=2; - - if(_failedVSyncCount == 60) + if(_startTimeInterval < 1.0) { - _atari2600.switch_region(); + _startTimeInterval = [NSDate timeIntervalSinceReferenceDate]; + } + else + { + _frameCount++; + + if(_frameCount > 30) + { + float fps = (float)_frameCount / (float)([NSDate timeIntervalSinceReferenceDate] - _startTimeInterval); + + if(fabsf(fps - 50.0f) < 5.0f) + { + _atari2600.switch_region(); + _didDecideRegion = YES; + } + + if(fabsf(fps - 60.0f) < 5.0f) + { + _didDecideRegion = YES; + } + } } - } - else - { - _failedVSyncCount = MAX(_failedVSyncCount - 1, 0); } BOOL hasReturn = [self.view pushFrame:frame]; diff --git a/Outputs/CRT.cpp b/Outputs/CRT.cpp index 7a77a90f2..9bd2a50fd 100644 --- a/Outputs/CRT.cpp +++ b/Outputs/CRT.cpp @@ -28,7 +28,7 @@ void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_di height_of_display += (height_of_display / 20); // this is the overrun area we'll use to // store fundamental display configuration properties - _height_of_display = height_of_display + 10; + _height_of_display = height_of_display; _cycles_per_line = cycles_per_line * _time_multiplier; // generate timing values implied by the given arbuments @@ -103,7 +103,7 @@ CRT::SyncEvent CRT::get_next_vertical_sync_event(bool vsync_is_requested, unsign // will an acceptable vertical sync be triggered? if (vsync_is_requested && !_is_in_vsync) { - if (_sync_capacitor_charge_level >= _sync_capacitor_charge_threshold){// && _rasterPosition.y >= (kCRTFixedPointRange * 7) >> 3) { + if (_sync_capacitor_charge_level >= _sync_capacitor_charge_threshold && _rasterPosition.y >= (kCRTFixedPointRange >> 1)) { proposedSyncTime = 0; proposedEvent = SyncEvent::StartVSync; _did_detect_vsync = true; @@ -112,12 +112,12 @@ CRT::SyncEvent CRT::get_next_vertical_sync_event(bool vsync_is_requested, unsign // have we overrun the maximum permitted number of horizontal syncs for this frame? if (!_is_in_vsync) { - unsigned int time_until_end_of_frame = (kCRTFixedPointRange - _rasterPosition.y) / _scanSpeed[0].y; - - if(time_until_end_of_frame < proposedSyncTime) { - proposedSyncTime = time_until_end_of_frame; - proposedEvent = SyncEvent::StartVSync; - } +// unsigned int time_until_end_of_frame = (kCRTFixedPointRange - _rasterPosition.y) / _scanSpeed[0].y; +// +// if(time_until_end_of_frame < proposedSyncTime) { +// proposedSyncTime = time_until_end_of_frame; +// proposedEvent = SyncEvent::StartVSync; +// } } else { unsigned int time_until_start_of_frame = _rasterPosition.y / (uint32_t)(-_scanSpeed[kRetraceYMask].y);