SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 150f0fcad40d2e26361bf482df7d80a4a5876aa5 parent a39b1913b8adc69fb287dd5479a49cdc1e602d4a Author: Lior Halphon <LIJI32@gmail.com> Date: Sat, 23 Nov 2024 20:55:44 +0200 Add a fourth, virtual zoom factor for triple camera iPhones that have a large difference between their zoom factors. Closes #663 Diffstat:
| M | iOS/GBViewController.m | 74 | ++++++++++++++++++++++++++++++++++---------------------------------------- |
1 file changed, 34 insertions(+), 40 deletions(-)
diff --git a/iOS/GBViewController.m b/iOS/GBViewController.m @@ -61,9 +61,10 @@ AVCaptureDevicePosition _cameraPosition; UIButton *_cameraPositionButton; UIButton *_changeCameraButton; - NSArray *_allCaptureDevices; - NSArray *_backCaptureDevices; - AVCaptureDevice *_selectedBackCaptureDevice; + AVCaptureDevice *_frontCaptureDevice; + AVCaptureDevice *_backCaptureDevice; + NSMutableArray<NSNumber *> *_zoomLevels; + unsigned _currentZoomIndex; __weak GCController *_lastController; @@ -285,32 +286,42 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp) _motionManager = [[CMMotionManager alloc] init]; _cameraPosition = AVCaptureDevicePositionBack; - _selectedBackCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; // Back camera setup NSArray *deviceTypes = @[AVCaptureDeviceTypeBuiltInWideAngleCamera, - AVCaptureDeviceTypeBuiltInTelephotoCamera]; + AVCaptureDeviceTypeBuiltInTelephotoCamera, + AVCaptureDeviceTypeBuiltInDualCamera]; if (@available(iOS 13.0, *)) { // AVCaptureDeviceTypeBuiltInUltraWideCamera is only available in iOS 13+ deviceTypes = @[AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeBuiltInUltraWideCamera, - AVCaptureDeviceTypeBuiltInTelephotoCamera]; + AVCaptureDeviceTypeBuiltInTelephotoCamera, + AVCaptureDeviceTypeBuiltInTripleCamera, + AVCaptureDeviceTypeBuiltInDualWideCamera, + AVCaptureDeviceTypeBuiltInDualCamera]; } // Use a discovery session to gather the capture devices (all back cameras as well as the front camera) AVCaptureDeviceDiscoverySession *cameraDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:deviceTypes mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified]; - _allCaptureDevices = cameraDiscoverySession.devices; - - // Filter only the back cameras into a list used for switching between them - NSMutableArray *filteredBackCameras = [NSMutableArray array]; - for (AVCaptureDevice *device in _allCaptureDevices) { + for (AVCaptureDevice *device in cameraDiscoverySession.devices) { if ([device position] == AVCaptureDevicePositionBack) { - [filteredBackCameras addObject:device]; + if (!_backCaptureDevice || + _backCaptureDevice.virtualDeviceSwitchOverVideoZoomFactors.count < device.virtualDeviceSwitchOverVideoZoomFactors.count) { + _backCaptureDevice = device; + } + } + else if ([device position] == AVCaptureDevicePositionFront) { + _frontCaptureDevice = device; } } - _backCaptureDevices = filteredBackCameras; + + _zoomLevels = _backCaptureDevice.virtualDeviceSwitchOverVideoZoomFactors.mutableCopy; + [_zoomLevels insertObject:@1 atIndex:0]; + if (_zoomLevels.count == 3 && _zoomLevels[2].doubleValue > 5.5 && _zoomLevels[1].doubleValue < 3.5) { + [_zoomLevels insertObject:@4 atIndex:2]; + } _cameraPositionButton = [[UIButton alloc] init]; [self didRotateFromInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation]; @@ -332,7 +343,7 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp) action:@selector(changeCamera) forControlEvents:UIControlEventTouchUpInside]; // Only show the change camera button if we have more than one back camera to swap between. - if ([_backCaptureDevices count] > 1) { + if (_zoomLevels.count > 1) { [_backgroundView addSubview:_changeCameraButton]; } } @@ -1561,21 +1572,10 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response - (AVCaptureDevice *)captureDevice { - for (AVCaptureDevice *device in _allCaptureDevices) { - if ([device position] == _cameraPosition) { - // There is only one front camera, return it - if (_cameraPosition == AVCaptureDevicePositionFront) { - return device; - } - - // There may be several back cameras, return the one with the matching type - if ([device deviceType] == [_selectedBackCaptureDevice deviceType]) { - return device; - } - } + if (_cameraPosition == AVCaptureDevicePositionFront) { + return _frontCaptureDevice ?: [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; } - // Return the default camera - return [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; + return _backCaptureDevice ?: [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo]; } - (void)cameraRequestUpdate @@ -1756,19 +1756,13 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response - (void)changeCamera { dispatch_async(_cameraQueue, ^{ - // Get index of selected camera and select the next one, wrapping to the beginning - NSUInteger i = [_backCaptureDevices indexOfObject:_selectedBackCaptureDevice]; - int nextIndex = (i + 1) % _backCaptureDevices.count; - _selectedBackCaptureDevice = _backCaptureDevices[nextIndex]; - - [_cameraSession stopRunning]; - _cameraSession = nil; - _cameraConnection = nil; - _cameraOutput = nil; - if (_cameraNeedsUpdate) { - _cameraNeedsUpdate = false; - GB_camera_updated(&_gb); + if (![_backCaptureDevice lockForConfiguration:nil]) return; + _currentZoomIndex++; + if (_currentZoomIndex == _zoomLevels.count) { + _currentZoomIndex = 0; } + [_backCaptureDevice rampToVideoZoomFactor:_zoomLevels[_currentZoomIndex].doubleValue withRate:2]; + [_backCaptureDevice unlockForConfiguration]; }); }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.