tvOS: Fewer ifdefs, capability checks instead

The Siri Remote setup builds on iOS too, the device type comes from the
interface idiom, and requests for things the platform says it lacks are
refused by checking the property. What's left ifdeffed is API tvOS doesn't
have at all. Reports say tvOS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-13 02:21:14 +02:00
1 parent 5ce0eb58fd
commit 5b05b34b4e
7 files changed
+28 -43

No files matched your search

+2
View File
@@ -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__)
-2
View File
@@ -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:
-4
View File
@@ -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;
+1 -5
View File
@@ -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];
+1
View File
@@ -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)
+8 -11
View File
@@ -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,
+16 -21
View File
@@ -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 &param1, const std::string &param2, 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]) {