SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 52de44049c16928cb61b29c8e977f84f52212e05 parent db5fa8df4c48b71db1ad8ca466eb27cec7522184 Author: Lior Halphon <LIJI32@gmail.com> Date: Sun, 22 Sep 2024 14:58:51 +0300 Better horizontal layouts on notched iPhones Diffstat:
| M | iOS/GBHorizontalLayout.h | 2 | +- |
| M | iOS/GBHorizontalLayout.m | 39 | ++++++++++++++++----------------------- |
| M | iOS/GBLayout.h | 2 | +- |
| M | iOS/GBLayout.m | 5 | +++++ |
| M | iOS/GBTheme.m | 2 | +- |
| M | iOS/GBThemePreviewController.m | 26 | +++++++++++++++++++++----- |
| M | iOS/GBViewController.m | 26 | +++++++++++++++++++++----- |
7 files changed, 66 insertions(+), 36 deletions(-)
diff --git a/iOS/GBHorizontalLayout.h b/iOS/GBHorizontalLayout.h @@ -1,5 +1,5 @@ #import "GBLayout.h" @interface GBHorizontalLayout : GBLayout - +- (instancetype)initWithTheme:(GBTheme *)theme cutoutOnRight:(bool)cutoutOnRight; @end diff --git a/iOS/GBHorizontalLayout.m b/iOS/GBHorizontalLayout.m @@ -3,12 +3,12 @@ @implementation GBHorizontalLayout -- (instancetype)initWithTheme:(GBTheme *)theme +- (instancetype)initWithTheme:(GBTheme *)theme cutoutOnRight:(bool)cutoutOnRight { self = [super initWithTheme:theme]; if (!self) return nil; - CGSize resolution = {self.resolution.height - self.cutout, self.resolution.width}; + CGSize resolution = {self.resolution.height, self.resolution.width}; CGRect screenRect = {0,}; screenRect.size.height = self.hasFractionalPixels? (resolution.height - self.homeBar) : floor((resolution.height - self.homeBar) / 144) * 144; @@ -46,19 +46,20 @@ else { screenRect.origin.y = (resolution.height - self.homeBar - screenRect.size.height) / 2; } - + self.screenRect = screenRect; self.dpadLocation = (CGPoint){ - round((screenRect.origin.x - screenBorderWidth) / 2), + round((screenRect.origin.x - screenBorderWidth) / 2) + (cutoutOnRight? 0 : self.cutout / 2), round(resolution.height * 3 / 8) }; - - double wingWidth = (resolution.width - screenRect.size.width) / 2 - screenBorderWidth * 5; + + double longWing = (resolution.width - screenRect.size.width) / 2 - screenBorderWidth * 5; + double shortWing = longWing - self.cutout; double buttonRadius = 36 * self.factor; - CGSize buttonsDelta = [self buttonDeltaForMaxHorizontalDistance:wingWidth - buttonRadius * 2]; + CGSize buttonsDelta = [self buttonDeltaForMaxHorizontalDistance:(cutoutOnRight? shortWing : longWing) - buttonRadius * 2]; CGPoint buttonsCenter = { - resolution.width - self.dpadLocation.x, + (resolution.width + screenRect.size.width + screenRect.origin.x) / 2 - (cutoutOnRight? self.cutout / 2 : 0), self.dpadLocation.y, }; @@ -73,24 +74,14 @@ }; self.selectLocation = (CGPoint){ - self.dpadLocation.x, + self.dpadLocation.x + (cutoutOnRight? self.cutout / 2 : 0), MIN(round(resolution.height * 3 / 4), self.dpadLocation.y + 180 * self.factor) }; self.startLocation = (CGPoint){ - buttonsCenter.x, + buttonsCenter.x - (cutoutOnRight? 0 : self.cutout / 2 ), self.selectLocation.y }; - - resolution.width += self.cutout * 2; - self.screenRect = (CGRect){{self.screenRect.origin.x + self.cutout, self.screenRect.origin.y}, self.screenRect.size}; - self.dpadLocation = (CGPoint){self.dpadLocation.x + self.cutout, self.dpadLocation.y}; - self.aLocation = (CGPoint){self.aLocation.x + self.cutout, self.aLocation.y}; - self.bLocation = (CGPoint){self.bLocation.x + self.cutout, self.bLocation.y}; - self.startLocation = (CGPoint){self.startLocation.x + self.cutout, self.startLocation.y}; - self.selectLocation = (CGPoint){self.selectLocation.x + self.cutout, self.selectLocation.y}; - self.abComboLocation = (CGPoint){(self.aLocation.x + self.bLocation.x) / 2, - (self.aLocation.y + self.bLocation.y) / 2}; if (theme.renderingPreview) { @@ -118,11 +109,13 @@ return self; } +- (instancetype)initWithTheme:(GBTheme *)theme +{ + assert(false); +} + - (CGRect)viewRectForOrientation:(UIInterfaceOrientation)orientation { - if (orientation == UIInterfaceOrientationLandscapeLeft) { - return CGRectMake(-(signed)self.cutout / (signed)self.factor, 0, self.background.size.width / self.factor, self.background.size.height / self.factor); - } return CGRectMake(0, 0, self.background.size.width / self.factor, self.background.size.height / self.factor); } diff --git a/iOS/GBLayout.h b/iOS/GBLayout.h @@ -15,6 +15,7 @@ @property (readonly) CGPoint abComboLocation; @property (readonly) CGPoint startLocation; @property (readonly) CGPoint selectLocation; +@property (readonly) unsigned cutout; - (CGRect)viewRectForOrientation:(UIInterfaceOrientation)orientation; @end @@ -36,7 +37,6 @@ @property (readonly) unsigned factor; @property (readonly) unsigned minY; @property (readonly) unsigned homeBar; -@property (readonly) unsigned cutout; @property (readonly) bool hasFractionalPixels; - (void)drawBackground; diff --git a/iOS/GBLayout.m b/iOS/GBLayout.m @@ -99,6 +99,11 @@ static bool HasHomeBar(void) bezelRect.origin.y -= borderWidth; bezelRect.size.width += borderWidth * 2; bezelRect.size.height += borderWidth * 2; + + if (bezelRect.origin.y + bezelRect.size.height >= self.size.height - _homeBar) { + bezelRect.origin.y = -32; + bezelRect.size.height = self.size.height + 32; + } UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:bezelRect cornerRadius:borderWidth]; CGContextSaveGState(context); CGContextSetShadowWithColor(context, (CGSize){0, _factor}, _factor, [UIColor colorWithWhite:1 alpha:0.25].CGColor); diff --git a/iOS/GBTheme.m b/iOS/GBTheme.m @@ -183,7 +183,7 @@ __attribute__((objc_direct_members)) { if (_horizontalPreview) return _horizontalPreview; _renderingPreview = true; - GBLayout *layout = [[GBHorizontalLayout alloc] initWithTheme:self]; + GBLayout *layout = [[GBHorizontalLayout alloc] initWithTheme:self cutoutOnRight:false]; _renderingPreview = false; GBBackgroundView *view = [[GBBackgroundView alloc] initWithLayout:layout]; [view enterPreviewMode:false]; diff --git a/iOS/GBThemePreviewController.m b/iOS/GBThemePreviewController.m @@ -5,7 +5,8 @@ @implementation GBThemePreviewController { - GBHorizontalLayout *_horizontalLayout; + GBHorizontalLayout *_horizontalLayoutLeft; + GBHorizontalLayout *_horizontalLayoutRight; GBVerticalLayout *_verticalLayout; GBBackgroundView *_backgroundView; } @@ -13,7 +14,10 @@ - (instancetype)initWithTheme:(GBTheme *)theme { self = [super init]; - _horizontalLayout = [[GBHorizontalLayout alloc] initWithTheme:theme]; + _horizontalLayoutLeft = [[GBHorizontalLayout alloc] initWithTheme:theme cutoutOnRight:false]; + _horizontalLayoutRight = _horizontalLayoutLeft.cutout? + [[GBHorizontalLayout alloc] initWithTheme:theme cutoutOnRight:true] : + _horizontalLayoutLeft; _verticalLayout = [[GBVerticalLayout alloc] initWithTheme:theme]; return self; } @@ -39,10 +43,22 @@ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration { - GBLayout *layout = _horizontalLayout; - if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) { - layout = _verticalLayout; + GBLayout *layout = nil; + switch (orientation) { + default: + case UIInterfaceOrientationUnknown: + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + layout = _verticalLayout; + break; + case UIInterfaceOrientationLandscapeRight: + layout = _horizontalLayoutLeft; + break; + case UIInterfaceOrientationLandscapeLeft: + layout = _horizontalLayoutRight; + break; } + _backgroundView.frame = [layout viewRectForOrientation:orientation]; _backgroundView.layout = layout; } diff --git a/iOS/GBViewController.m b/iOS/GBViewController.m @@ -36,7 +36,8 @@ bool _skipAutoLoad; UIInterfaceOrientation _orientation; - GBHorizontalLayout *_horizontalLayout; + GBHorizontalLayout *_horizontalLayoutLeft; + GBHorizontalLayout *_horizontalLayoutRight; GBVerticalLayout *_verticalLayout; GBBackgroundView *_backgroundView; @@ -223,7 +224,10 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp) #pragma clang diagnostic ignored "-Warc-retain-cycles" [self addDefaultObserver:^(id newValue) { GBTheme *theme = [GBSettingsViewController themeNamed:newValue]; - _horizontalLayout = [[GBHorizontalLayout alloc] initWithTheme:theme]; + _horizontalLayoutLeft = [[GBHorizontalLayout alloc] initWithTheme:theme cutoutOnRight:false]; + _horizontalLayoutRight = _horizontalLayoutLeft.cutout? + [[GBHorizontalLayout alloc] initWithTheme:theme cutoutOnRight:true] : + _horizontalLayoutLeft; _verticalLayout = [[GBVerticalLayout alloc] initWithTheme:theme]; _printerSpinner.color = theme.brandColor; @@ -870,11 +874,23 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp) - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration { - GBLayout *layout = _horizontalLayout; + GBLayout *layout = nil; _orientation = orientation; - if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) { - layout = _verticalLayout; + switch (orientation) { + default: + case UIInterfaceOrientationUnknown: + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + layout = _verticalLayout; + break; + case UIInterfaceOrientationLandscapeRight: + layout = _horizontalLayoutLeft; + break; + case UIInterfaceOrientationLandscapeLeft: + layout = _horizontalLayoutRight; + break; } + _backgroundView.frame = [layout viewRectForOrientation:orientation]; _backgroundView.layout = layout; if (!self.presentedViewController) {
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.