diff --git a/Core/Reporting.cpp b/Core/Reporting.cpp index 2a767cdcf1..9e1e053de4 100644 --- a/Core/Reporting.cpp +++ b/Core/Reporting.cpp @@ -330,6 +330,8 @@ namespace Reporting return "Windows 64"; #elif defined(_WIN32) return "Windows"; +#elif PPSSPP_PLATFORM(TVOS) + return "tvOS"; #elif PPSSPP_PLATFORM(IOS) return "iOS"; #elif defined(__APPLE__) diff --git a/ios/Controls.h b/ios/Controls.h index 1783fd2d2d..5e1af38e2d 100644 --- a/ios/Controls.h +++ b/ios/Controls.h @@ -17,10 +17,8 @@ bool InitController(GCController *controller); void ShutdownController(GCController *controller); -#if PPSSPP_PLATFORM(TVOS) // Returns false unless the controller is a Siri Remote (a micro gamepad profile and no extended one). bool InitSiriRemote(GCController *controller); -#endif struct TouchTracker { public: diff --git a/ios/Controls.mm b/ios/Controls.mm index 8a5e41f3b4..a43b5d8240 100644 --- a/ios/Controls.mm +++ b/ios/Controls.mm @@ -204,8 +204,6 @@ void ShutdownController(GCController *controller) { KeyMap::NotifyPadDisconnected(DEVICE_ID_PAD_0); } -#if PPSSPP_PLATFORM(TVOS) - static void remoteButtonPressed(BOOL pressed, InputKeyCode keyCode) { // As keyboard keys, which the UI already understands (arrows, enter, escape), and which have // default in-game mappings. @@ -301,8 +299,6 @@ bool InitSiriRemote(GCController *controller) { return true; } -#endif - void TouchTracker::SendTouchEvent(CGPoint point, UIView *view, int code, int pointerId) { // From points to dp. The view covers the whole display. CGSize size = view.bounds.size; diff --git a/ios/SceneDelegate.mm b/ios/SceneDelegate.mm index 7552a4c8b9..0f7bfeed37 100644 --- a/ios/SceneDelegate.mm +++ b/ios/SceneDelegate.mm @@ -168,12 +168,8 @@ static NSString *ExtractGameInfoScheme(NSURL *url) { break; } -#if PPSSPP_PLATFORM(TVOS) - // No persistent storage on tvOS. The memory stick folder doubles as the documents folder. + // Documents, except on tvOS, which has no persistent storage. See defaultMemoryStickPath(). NSString *documentsPath = @(DarwinFileSystemServices::defaultMemoryStickPath().c_str()); -#else - NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; -#endif NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/assets/"]; // Caches the system may clear when space runs low, and the zips ShareFilesAsZip hands to other apps. NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; diff --git a/ios/ViewController.h b/ios/ViewController.h index 07a7105963..69e2b27701 100644 --- a/ios/ViewController.h +++ b/ios/ViewController.h @@ -55,3 +55,4 @@ extern PPSSPPViewController *sharedViewController; #define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) #define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) +#define IS_TV() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomTV) diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 0f2b1bf64f..0e00e878e8 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -374,11 +374,9 @@ static int GetPickerRequestId(id picker) { { if (![[GCController controllers] containsObject:self.gameController]) self.gameController = nil; -#if PPSSPP_PLATFORM(TVOS) if (InitSiriRemote((GCController *)note.object)) { return; } -#endif if (self.gameController != nil) return; // already have a connected controller @@ -404,11 +402,9 @@ static int GetPickerRequestId(id picker) { // Picks the first gamepad. On tvOS, the Siri Remote is in the list too, and gets set up separately. - (void)setupFirstController { for (GCController *controller in [GCController controllers]) { -#if PPSSPP_PLATFORM(TVOS) if (InitSiriRemote(controller)) { continue; } -#endif if (self.gameController == nil) { [self setupController:controller]; } @@ -665,7 +661,7 @@ extern float g_safeInsetBottom; - (void)shareItems:(NSArray *)items { #if PPSSPP_PLATFORM(TVOS) - // No share sheet on tvOS. SYSPROP_SUPPORTS_SHARE_* is false there, so this shouldn't be reached. + // No share sheet on tvOS. SYSPROP_SUPPORTS_SHARE_* is false there, so this isn't reached. WARN_LOG(Log::System, "Sharing isn't available on tvOS"); #else UIActivityViewController *viewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil]; @@ -799,12 +795,13 @@ extern float g_safeInsetBottom; // The bounds are already corrected for orientation. CGSize size = view.bounds.size; -#if PPSSPP_PLATFORM(TVOS) - // Like a 1080p Android TV, which reports 320 dpi: 1920x1080 points come out as 1440x810 dp. - float dpi = 320.0f * scale; -#else - float dpi = (IS_IPAD() ? 200.0f : 150.0f) * scale; -#endif + float dpi; + if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) == DEVICE_TYPE_TV) { + // Like a 1080p Android TV, which reports 320 dpi: 1920x1080 points come out as 1440x810 dp. + dpi = 320.0f * scale; + } else { + dpi = (IS_IPAD() ? 200.0f : 150.0f) * scale; + } PendingResolution res{ (float)(size.width * scale), (float)(size.height * scale), 240.0f / dpi, diff --git a/ios/main.mm b/ios/main.mm index 16baf21089..85231886f8 100644 --- a/ios/main.mm +++ b/ios/main.mm @@ -285,11 +285,7 @@ int64_t System_GetPropertyInt(SystemProperty prop) { case SYSPROP_AUDIO_SAMPLE_RATE: return 44100; case SYSPROP_DEVICE_TYPE: -#if PPSSPP_PLATFORM(TVOS) - return DEVICE_TYPE_TV; -#else - return DEVICE_TYPE_MOBILE; -#endif + return IS_TV() ? DEVICE_TYPE_TV : DEVICE_TYPE_MOBILE; case SYSPROP_SYSTEMVERSION: return g_iosVersionMajor; #if !PPSSPP_PLATFORM(TVOS) @@ -467,22 +463,6 @@ void System_Notify(SystemNotification notification) { } bool System_MakeRequest(SystemRequestType type, int requestId, const std::string ¶m1, const std::string ¶m2, int64_t param3, int64_t param4) { -#if PPSSPP_PLATFORM(TVOS) - switch (type) { - case SystemRequestType::BROWSE_FOR_FILE: - case SystemRequestType::BROWSE_FOR_FOLDER: - case SystemRequestType::BROWSE_FOR_IMAGE: - case SystemRequestType::CAMERA_COMMAND: - case SystemRequestType::GPS_COMMAND: - case SystemRequestType::MICROPHONE_COMMAND: - case SystemRequestType::SHARE_TEXT: - case SystemRequestType::SHARE_FILE: - case SystemRequestType::COPY_TO_CLIPBOARD: - return false; - default: - break; - } -#endif switch (type) { case SystemRequestType::RESTART_APP: { @@ -515,6 +495,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string break; case SystemRequestType::BROWSE_FOR_FILE: { + if (!System_GetPropertyBool(SYSPROP_HAS_FILE_BROWSER)) { + return false; + } DarwinDirectoryPanelCallback callback = [requestId] (bool success, Path path) { if (success) { g_requestManager.PostSystemSuccess(requestId, path.c_str()); @@ -527,6 +510,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::BROWSE_FOR_FOLDER: { + if (!System_GetPropertyBool(SYSPROP_HAS_FOLDER_BROWSER)) { + return false; + } DarwinDirectoryPanelCallback callback = [requestId] (bool success, Path path) { if (success) { g_requestManager.PostSystemSuccess(requestId, path.c_str()); @@ -539,6 +525,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::BROWSE_FOR_IMAGE: { + if (!System_GetPropertyBool(SYSPROP_HAS_IMAGE_BROWSER)) { + return false; + } NSString *filename = [NSString stringWithUTF8String:param2.c_str()]; dispatch_async(dispatch_get_main_queue(), ^{ [sharedViewController pickPhoto:filename requestId:requestId]; @@ -591,6 +580,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string return true; case SystemRequestType::SHARE_TEXT: { + if (!System_GetPropertyBool(SYSPROP_SUPPORTS_SHARE_TEXT)) { + return false; + } NSString *text = [NSString stringWithUTF8String:param1.c_str()]; dispatch_async(dispatch_get_main_queue(), ^{ [sharedViewController shareText:text]; @@ -599,6 +591,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string } case SystemRequestType::SHARE_FILE: { + if (!System_GetPropertyBool(SYSPROP_SUPPORTS_SHARE_FILE)) { + return false; + } // param2, the MIME type, isn't needed. The share sheet goes by the extension. NSString *path = [NSString stringWithUTF8String:param1.c_str()]; if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {