mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-03 04:12:42 +02:00
Merge pull request #642 from logicalmoody/master
This commit is contained in:
@@ -52,6 +52,10 @@
|
|||||||
NSTimer *_disableCameraTimer;
|
NSTimer *_disableCameraTimer;
|
||||||
AVCaptureDevicePosition _cameraPosition;
|
AVCaptureDevicePosition _cameraPosition;
|
||||||
UIButton *_cameraPositionButton;
|
UIButton *_cameraPositionButton;
|
||||||
|
UIButton *_changeCameraButton;
|
||||||
|
NSArray *_allCaptureDevices;
|
||||||
|
NSArray *_backCaptureDevices;
|
||||||
|
AVCaptureDevice *_selectedBackCaptureDevice;
|
||||||
|
|
||||||
__weak GCController *_lastController;
|
__weak GCController *_lastController;
|
||||||
|
|
||||||
@@ -241,8 +245,36 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
|
|||||||
|
|
||||||
_motionManager = [[CMMotionManager alloc] init];
|
_motionManager = [[CMMotionManager alloc] init];
|
||||||
_cameraPosition = AVCaptureDevicePositionBack;
|
_cameraPosition = AVCaptureDevicePositionBack;
|
||||||
_cameraPositionButton = [[UIButton alloc] initWithFrame:CGRectMake(8,
|
_selectedBackCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
|
||||||
0,
|
|
||||||
|
// Back camera setup
|
||||||
|
NSArray *deviceTypes = @[AVCaptureDeviceTypeBuiltInWideAngleCamera,
|
||||||
|
AVCaptureDeviceTypeBuiltInTelephotoCamera];
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
// AVCaptureDeviceTypeBuiltInUltraWideCamera is only available in iOS 13+
|
||||||
|
deviceTypes = @[AVCaptureDeviceTypeBuiltInWideAngleCamera,
|
||||||
|
AVCaptureDeviceTypeBuiltInUltraWideCamera,
|
||||||
|
AVCaptureDeviceTypeBuiltInTelephotoCamera];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
if ([device position] == AVCaptureDevicePositionBack) {
|
||||||
|
[filteredBackCameras addObject:device];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_backCaptureDevices = filteredBackCameras;
|
||||||
|
|
||||||
|
UIEdgeInsets insets = self.window.safeAreaInsets;
|
||||||
|
_cameraPositionButton = [[UIButton alloc] initWithFrame:CGRectMake(insets.left + 8,
|
||||||
|
_backgroundView.bounds.size.height - 8 - insets.bottom - 32,
|
||||||
32,
|
32,
|
||||||
32)];
|
32)];
|
||||||
[self didRotateFromInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation];
|
[self didRotateFromInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation];
|
||||||
@@ -251,20 +283,41 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
|
|||||||
withConfiguration:[UIImageSymbolConfiguration configurationWithScale:UIImageSymbolScaleLarge]]
|
withConfiguration:[UIImageSymbolConfiguration configurationWithScale:UIImageSymbolScaleLarge]]
|
||||||
forState:UIControlStateNormal];
|
forState:UIControlStateNormal];
|
||||||
_cameraPositionButton.backgroundColor = [UIColor systemBackgroundColor];
|
_cameraPositionButton.backgroundColor = [UIColor systemBackgroundColor];
|
||||||
|
|
||||||
|
// Configure the change camera button stacked on top of the camera position button
|
||||||
|
_changeCameraButton = [[UIButton alloc] initWithFrame:CGRectMake(insets.left + 8,
|
||||||
|
_backgroundView.bounds.size.height - 8 - insets.bottom - 32 - 32 - 8,
|
||||||
|
32,
|
||||||
|
32)];
|
||||||
|
[_changeCameraButton setImage:[UIImage systemImageNamed:@"camera.aperture"
|
||||||
|
withConfiguration:[UIImageSymbolConfiguration configurationWithScale:UIImageSymbolScaleLarge]]
|
||||||
|
forState:UIControlStateNormal];
|
||||||
|
_changeCameraButton.backgroundColor = [UIColor systemBackgroundColor];
|
||||||
|
_changeCameraButton.layer.cornerRadius = 6;
|
||||||
|
_changeCameraButton.alpha = 0;
|
||||||
|
[_changeCameraButton addTarget:self
|
||||||
|
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) {
|
||||||
|
[_backgroundView addSubview:_changeCameraButton];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
UIImage *image = [[UIImage imageNamed:@"CameraRotateTemplate"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
UIImage *rotateImage = [[UIImage imageNamed:@"CameraRotateTemplate"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
|
||||||
[_cameraPositionButton setImage:image
|
[_cameraPositionButton setImage:rotateImage
|
||||||
forState:UIControlStateNormal];
|
forState:UIControlStateNormal];
|
||||||
_cameraPositionButton.backgroundColor = [UIColor whiteColor];
|
_cameraPositionButton.backgroundColor = [UIColor whiteColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
_cameraPositionButton.layer.cornerRadius = 6;
|
_cameraPositionButton.layer.cornerRadius = 6;
|
||||||
_cameraPositionButton.alpha = 0;
|
_cameraPositionButton.alpha = 0;
|
||||||
[_cameraPositionButton addTarget:self
|
[_cameraPositionButton addTarget:self
|
||||||
action:@selector(rotateCamera)
|
action:@selector(rotateCamera)
|
||||||
forControlEvents:UIControlEventTouchUpInside];
|
forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
|
||||||
[_backgroundView addSubview:_cameraPositionButton];
|
[_backgroundView addSubview:_cameraPositionButton];
|
||||||
|
|
||||||
_cameraQueue = dispatch_queue_create("SameBoy Camera Queue", NULL);
|
_cameraQueue = dispatch_queue_create("SameBoy Camera Queue", NULL);
|
||||||
|
|
||||||
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||||
@@ -685,7 +738,16 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
|
|||||||
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
|
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
|
||||||
{
|
{
|
||||||
UIEdgeInsets insets = self.window.safeAreaInsets;
|
UIEdgeInsets insets = self.window.safeAreaInsets;
|
||||||
_cameraPositionButton.frame = CGRectMake(insets.left + 8, _backgroundView.bounds.size.height - 8 - insets.bottom - 32, 32, 32);
|
_cameraPositionButton.frame = CGRectMake(insets.left + 8,
|
||||||
|
_backgroundView.bounds.size.height - 8 - insets.bottom - 32,
|
||||||
|
32,
|
||||||
|
32);
|
||||||
|
if (_changeCameraButton) {
|
||||||
|
_changeCameraButton.frame = CGRectMake(insets.left + 8,
|
||||||
|
_backgroundView.bounds.size.height - 8 - insets.bottom - 32 - 32 - 8,
|
||||||
|
32,
|
||||||
|
32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
||||||
@@ -1123,12 +1185,20 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|||||||
|
|
||||||
- (AVCaptureDevice *)captureDevice
|
- (AVCaptureDevice *)captureDevice
|
||||||
{
|
{
|
||||||
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
for (AVCaptureDevice *device in _allCaptureDevices) {
|
||||||
for (AVCaptureDevice *device in devices) {
|
|
||||||
if ([device position] == _cameraPosition) {
|
if ([device position] == _cameraPosition) {
|
||||||
return device;
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Return the default camera
|
||||||
return [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
|
return [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1179,6 +1249,16 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|||||||
_cameraPositionButton.alpha = 1;
|
_cameraPositionButton.alpha = 1;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
if (_changeCameraButton) {
|
||||||
|
// The change camera button is only available when we are using a capture device on the back of the device
|
||||||
|
double changeCameraButtonAlpha = (_cameraPosition == AVCaptureDevicePositionFront) ? 0 : 1;
|
||||||
|
if (changeCameraButtonAlpha != _changeCameraButton.alpha) {
|
||||||
|
[UIView animateWithDuration:0.25 animations:^{
|
||||||
|
_changeCameraButton.alpha = changeCameraButtonAlpha;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_disableCameraTimer = [NSTimer scheduledTimerWithTimeInterval:1
|
_disableCameraTimer = [NSTimer scheduledTimerWithTimeInterval:1
|
||||||
repeats:false
|
repeats:false
|
||||||
block:^(NSTimer *timer) {
|
block:^(NSTimer *timer) {
|
||||||
@@ -1187,6 +1267,11 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
|||||||
_cameraPositionButton.alpha = 0;
|
_cameraPositionButton.alpha = 0;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
if (_changeCameraButton.alpha) {
|
||||||
|
[UIView animateWithDuration:0.25 animations:^{
|
||||||
|
_changeCameraButton.alpha = 0;
|
||||||
|
}];
|
||||||
|
}
|
||||||
dispatch_async(_cameraQueue, ^{
|
dispatch_async(_cameraQueue, ^{
|
||||||
[_cameraSession stopRunning];
|
[_cameraSession stopRunning];
|
||||||
_cameraSession = nil;
|
_cameraSession = nil;
|
||||||
@@ -1292,4 +1377,23 @@ 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Reference in New Issue
Block a user