mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-31 22:21:51 +02:00
Improved AirPlay mirroring
This commit is contained in:
@@ -32,5 +32,5 @@ typedef enum {
|
||||
- (void) createInternalView;
|
||||
- (uint32_t *)currentBuffer;
|
||||
- (uint32_t *)previousBuffer;
|
||||
|
||||
- (instancetype)mirroredView;
|
||||
@end
|
||||
|
@@ -6,10 +6,13 @@
|
||||
unsigned _currentBuffer;
|
||||
GB_frame_blending_mode_t _frameBlendingMode;
|
||||
bool _oddFrame;
|
||||
GBViewBase *_parent;
|
||||
__weak GBViewBase *_child;
|
||||
}
|
||||
|
||||
- (void)screenSizeChanged
|
||||
{
|
||||
if (_parent) return;
|
||||
if (_imageBuffers[0]) free(_imageBuffers[0]);
|
||||
if (_imageBuffers[1]) free(_imageBuffers[1]);
|
||||
if (_imageBuffers[2]) free(_imageBuffers[2]);
|
||||
@@ -23,12 +26,15 @@
|
||||
|
||||
- (void)flip
|
||||
{
|
||||
if (_parent) return;
|
||||
_currentBuffer = (_currentBuffer + 1) % self.numberOfBuffers;
|
||||
_oddFrame = GB_is_odd_frame(_gb);
|
||||
[_child flip];
|
||||
}
|
||||
|
||||
- (unsigned) numberOfBuffers
|
||||
{
|
||||
assert(!_parent);
|
||||
return _frameBlendingMode? 3 : 2;
|
||||
}
|
||||
|
||||
@@ -39,16 +45,23 @@
|
||||
|
||||
- (uint32_t *)currentBuffer
|
||||
{
|
||||
if (unlikely(_parent)) {
|
||||
return [_parent currentBuffer];
|
||||
}
|
||||
return _imageBuffers[_currentBuffer];
|
||||
}
|
||||
|
||||
- (uint32_t *)previousBuffer
|
||||
{
|
||||
if (unlikely(_parent)) {
|
||||
return [_parent previousBuffer];
|
||||
}
|
||||
return _imageBuffers[(_currentBuffer + 2) % self.numberOfBuffers];
|
||||
}
|
||||
|
||||
- (uint32_t *) pixels
|
||||
{
|
||||
assert(!_parent);
|
||||
return _imageBuffers[(_currentBuffer + 1) % self.numberOfBuffers];
|
||||
}
|
||||
|
||||
@@ -56,10 +69,14 @@
|
||||
{
|
||||
_frameBlendingMode = frameBlendingMode;
|
||||
[self setNeedsDisplay];
|
||||
[_child setNeedsDisplay];
|
||||
}
|
||||
|
||||
- (GB_frame_blending_mode_t)frameBlendingMode
|
||||
{
|
||||
if (unlikely(_parent)) {
|
||||
return [_parent frameBlendingMode];
|
||||
}
|
||||
if (_frameBlendingMode == GB_FRAME_BLENDING_MODE_ACCURATE) {
|
||||
if (!_gb || GB_is_sgb(_gb)) {
|
||||
return GB_FRAME_BLENDING_MODE_SIMPLE;
|
||||
@@ -71,6 +88,7 @@
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_parent) return;
|
||||
free(_imageBuffers[0]);
|
||||
free(_imageBuffers[1]);
|
||||
free(_imageBuffers[2]);
|
||||
@@ -82,4 +100,22 @@
|
||||
[self setNeedsDisplay:true];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)setGb:(GB_gameboy_t *)gb
|
||||
{
|
||||
assert(!_parent);
|
||||
_gb = gb;
|
||||
if (_child) {
|
||||
_child->_gb = gb;
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)mirroredView
|
||||
{
|
||||
if (_child) return _child;
|
||||
GBViewBase *ret = [[self.class alloc] initWithFrame:self.bounds];
|
||||
ret->_parent = self;
|
||||
ret->_gb = _gb;
|
||||
return _child = ret;
|
||||
}
|
||||
@end
|
||||
|
@@ -25,6 +25,7 @@ static const vector_float2 rect[] =
|
||||
vector_float2 _outputResolution;
|
||||
id<MTLCommandBuffer> _commandBuffer;
|
||||
bool _waitedForFrame;
|
||||
_Atomic unsigned _pendingFrames;
|
||||
}
|
||||
|
||||
+ (bool)isSupported
|
||||
@@ -236,8 +237,11 @@ static const vector_float2 rect[] =
|
||||
- (void)flip
|
||||
{
|
||||
[super flip];
|
||||
if (_pendingFrames == 2) return;
|
||||
_pendingFrames++;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[(MTKView *)self.internalView draw];
|
||||
_pendingFrames--;
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -64,6 +64,9 @@
|
||||
dispatch_queue_t _cameraQueue;
|
||||
|
||||
bool _runModeFromController;
|
||||
|
||||
UIWindow *_mirrorWindow;
|
||||
GBView *_mirrorView;
|
||||
}
|
||||
|
||||
static void loadBootROM(GB_gameboy_t *gb, GB_boot_rom_t type)
|
||||
@@ -333,9 +336,51 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
|
||||
name:GCControllerDidConnectNotification
|
||||
object:nil];
|
||||
|
||||
for (NSString *name in @[UIScreenDidConnectNotification,
|
||||
UIScreenDidDisconnectNotification,
|
||||
UIScreenModeDidChangeNotification]) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(updateMirrorWindow)
|
||||
name:name
|
||||
object:nil];
|
||||
}
|
||||
|
||||
|
||||
|
||||
[self updateMirrorWindow];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void)updateMirrorWindow
|
||||
{
|
||||
if ([UIScreen screens].count == 1) {
|
||||
_mirrorWindow = nil;
|
||||
_mirrorView = nil;
|
||||
return;
|
||||
}
|
||||
if (_mirrorWindow && ![[UIScreen screens] containsObject:_mirrorWindow.screen]) {
|
||||
_mirrorWindow = nil;
|
||||
_mirrorView = nil;
|
||||
}
|
||||
for (UIScreen *screen in [UIScreen screens]) {
|
||||
if (screen == UIScreen.mainScreen) continue;
|
||||
CGRect rect = screen.bounds;
|
||||
rect.size.height = floor(rect.size.height / 144) * 144;
|
||||
rect.size.width = rect.size.height / 144 * 160;
|
||||
rect.origin.x = (screen.bounds.size.width - rect.size.width) / 2;
|
||||
rect.origin.y = (screen.bounds.size.height - rect.size.height) / 2;
|
||||
_mirrorWindow = [[UIWindow alloc] initWithFrame:screen.bounds];
|
||||
_mirrorWindow.screen = screen;
|
||||
_mirrorView = [_gbView mirroredView];
|
||||
_mirrorView.frame = rect;
|
||||
_mirrorWindow.backgroundColor = [UIColor blackColor];
|
||||
[_mirrorWindow addSubview:_mirrorView];
|
||||
[_mirrorWindow setHidden:false];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setControllerHandlers
|
||||
{
|
||||
|
Reference in New Issue
Block a user