Add a gold icon to alternate icons. NOTE: It must not be named AppIconGold!

This commit is contained in:
Henrik Rydgård
2025-05-22 23:42:20 +02:00
parent 758dcf6afc
commit cd21f6a526
55 changed files with 600 additions and 50 deletions
+8 -7
View File
@@ -2887,7 +2887,7 @@ if(TargetBin)
if(IOS)
set(AssetCatalog "${CMAKE_SOURCE_DIR}/ios/assets.xcassets")
add_executable(${TargetBin} MACOSX_BUNDLE ${ICON_PATH_ABS} ${NativeAssets} ${BigFontAssets} ${AssetCatalog} ${SHADER_FILES} ${THEME_FILE} ${DEBUGGER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource} "ios/Settings.bundle" "ios/Launch Screen.storyboard")
add_executable(${TargetBin} MACOSX_BUNDLE ${NativeAssets} ${BigFontAssets} ${AssetCatalog} ${SHADER_FILES} ${THEME_FILE} ${DEBUGGER_FILES} ${FLASH0_FILES} ${LANG_FILES} ${NativeAppSource} "ios/Settings.bundle" "ios/Launch Screen.storyboard")
if(NOT IOS_APP_STORE)
file(INSTALL "${CMAKE_SOURCE_DIR}/ext/vulkan/iOS/Frameworks/libMoltenVK.dylib" DESTINATION "${CMAKE_BINARY_DIR}/PPSSPP.app/Frameworks/")
endif()
@@ -2958,7 +2958,7 @@ if(IOS AND NOT LIBRETRO)
else()
set(BUNDLE_IDENTIFIER "org.ppsspp.ppssppgold")
endif()
set(ICON_NAME "AppIconGold")
set(ICON_NAME "GoldIcon")
set(DISPLAY_NAME "PPSSPP Gold")
else()
if(IOS_APP_STORE)
@@ -2998,13 +2998,12 @@ if(IOS AND NOT LIBRETRO)
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER ${BUNDLE_IDENTIFIER}
XCODE_ATTRIBUTE_PRODUCT_NAME ${PRODUCT_NAME}
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME ${ICON_NAME}
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME ""
BUILD_WITH_INSTALL_RPATH YES
MACOSX_BUNDLE_INFO_PLIST ${BUNDLE_PLIST}
# Some sources say we should generate the PLIST. There's stuff in it that
# I don't know how to generate, though.
#XCODE_ATTRIBUTE_GENERATE_INFOPLIST_FILE "YES"
#XCODE_ATTRIBUTE_INFOPLIST_KEY_UIRequiredDeviceCapabilities arm64
# Some sources say we should generate the PLIST. There's stuff in it that
# I don't know how to generate, though.
#XCODE_ATTRIBUTE_GENERATE_INFOPLIST_FILE "YES"
#XCODE_ATTRIBUTE_INFOPLIST_KEY_UIRequiredDeviceCapabilities arm64
XCODE_ATTRIBUTE_INFOPLIST_KEY_UIFileSharingEnabled YES
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES
@@ -3015,6 +3014,8 @@ if(IOS AND NOT LIBRETRO)
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${DEVELOPMENT_TEAM_ID}
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development"
XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Automatic"
# The following one was hallucinated by ChatGPT
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS "YES"
#XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${BUNDLE_ENTITLEMENTS}
XCODE_ATTRIBUTE_SKIP_INSTALL NO
XCODE_ATTRIBUTE_INSTALL_PATH "$(LOCAL_APPS_DIR)"
+3 -2
View File
@@ -138,7 +138,7 @@
- (void)updateIcon {
NSString *desiredIcon = nil;
if ([self isGoldUnlocked]) {
desiredIcon = @"AppIconGold";
desiredIcon = @"GoldIcon";
}
NSLog(@"updateIcon called with %@", desiredIcon);
@@ -156,7 +156,7 @@
NSLog(@"IAPManager about to reset the icon");
}
// Useful for debugging.
// Useful to set to true for debugging.
const bool force = false;
if ([[UIApplication sharedApplication] supportsAlternateIcons]) {
if (force || ![[UIApplication sharedApplication].alternateIconName isEqualToString:desiredIcon]) {
@@ -167,6 +167,7 @@
NSLog(@"[IAPManager] Failed to set Gold icon to %@: %@", desiredIcon, error.localizedDescription);
} else {
NSLog(@"Icon update succeeded.");
NSLog(@"Current icon name: %@", [[UIApplication sharedApplication] alternateIconName]);
// Here we need to call hideKeyboard.
}
}];
+8 -3
View File
@@ -19,7 +19,7 @@
<key>CFBundleExecutable</key>
<string>PPSSPP</string>
<key>CFBundleIdentifier</key>
<string>org.ppsspp.ppsspp</string>
<string>org.ppsspp.ppsspp-free</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@@ -34,12 +34,17 @@
<string>1.0</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconName</key>
<string>AppIcon</string>
</dict>
<key>CFBundleAlternateIcons</key>
<dict>
<key>AppIconGold</key>
<key>GoldIcon</key>
<dict>
<key>CFBundleIconName</key>
<string>AppIconGold</string>
<string>GoldIcon</string>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
+1
View File
@@ -730,6 +730,7 @@ extern float g_safeInsetBottom;
-(void) showKeyboard {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"becomeFirstResponder");
[self becomeFirstResponder];
});
}
@@ -1,38 +0,0 @@
{
"images" : [
{
"filename" : "icon_gold_backfill_1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances": [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "dark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances": [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "tinted.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

@@ -0,0 +1,503 @@
{
"images": [
{
"idiom": "universal",
"size": "20x20",
"scale": "1x",
"filename": "icon_20x20@1x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "20x20",
"scale": "2x",
"filename": "icon_20x20@2x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "20x20",
"scale": "3x",
"filename": "icon_20x20@3x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "29x29",
"scale": "1x",
"filename": "icon_29x29@1x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "29x29",
"scale": "2x",
"filename": "icon_29x29@2x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "29x29",
"scale": "3x",
"filename": "icon_29x29@3x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "40x40",
"scale": "1x",
"filename": "icon_40x40@1x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "40x40",
"scale": "2x",
"filename": "icon_40x40@2x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "40x40",
"scale": "3x",
"filename": "icon_40x40@3x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "60x60",
"scale": "2x",
"filename": "icon_60x60@2x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "60x60",
"scale": "3x",
"filename": "icon_60x60@3x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "76x76",
"scale": "1x",
"filename": "icon_76x76@1x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "76x76",
"scale": "2x",
"filename": "icon_76x76@2x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "83.5x83.5",
"scale": "2x",
"filename": "icon_83x83@2x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "1024x1024",
"scale": "1x",
"filename": "icon_1024x1024@1x_light.png",
"platform": "ios"
},
{
"idiom": "universal",
"size": "20x20",
"scale": "1x",
"filename": "icon_20x20@1x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "20x20",
"scale": "2x",
"filename": "icon_20x20@2x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "20x20",
"scale": "3x",
"filename": "icon_20x20@3x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "29x29",
"scale": "1x",
"filename": "icon_29x29@1x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "29x29",
"scale": "2x",
"filename": "icon_29x29@2x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "29x29",
"scale": "3x",
"filename": "icon_29x29@3x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "40x40",
"scale": "1x",
"filename": "icon_40x40@1x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "40x40",
"scale": "2x",
"filename": "icon_40x40@2x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "40x40",
"scale": "3x",
"filename": "icon_40x40@3x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "60x60",
"scale": "2x",
"filename": "icon_60x60@2x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "60x60",
"scale": "3x",
"filename": "icon_60x60@3x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "76x76",
"scale": "1x",
"filename": "icon_76x76@1x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "76x76",
"scale": "2x",
"filename": "icon_76x76@2x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "83.5x83.5",
"scale": "2x",
"filename": "icon_83x83@2x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "1024x1024",
"scale": "1x",
"filename": "icon_1024x1024@1x_dark.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
]
},
{
"idiom": "universal",
"size": "20x20",
"scale": "1x",
"filename": "icon_20x20@1x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "20x20",
"scale": "2x",
"filename": "icon_20x20@2x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "20x20",
"scale": "3x",
"filename": "icon_20x20@3x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "29x29",
"scale": "1x",
"filename": "icon_29x29@1x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "29x29",
"scale": "2x",
"filename": "icon_29x29@2x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "29x29",
"scale": "3x",
"filename": "icon_29x29@3x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "40x40",
"scale": "1x",
"filename": "icon_40x40@1x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "40x40",
"scale": "2x",
"filename": "icon_40x40@2x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "40x40",
"scale": "3x",
"filename": "icon_40x40@3x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "60x60",
"scale": "2x",
"filename": "icon_60x60@2x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "60x60",
"scale": "3x",
"filename": "icon_60x60@3x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "76x76",
"scale": "1x",
"filename": "icon_76x76@1x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "76x76",
"scale": "2x",
"filename": "icon_76x76@2x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "83.5x83.5",
"scale": "2x",
"filename": "icon_83x83@2x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
},
{
"idiom": "universal",
"size": "1024x1024",
"scale": "1x",
"filename": "icon_1024x1024@1x_tinted.png",
"platform": "ios",
"appearances": [
{
"appearance": "luminosity",
"value": "tinted"
}
]
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+77
View File
@@ -0,0 +1,77 @@
import os
from PIL import Image
import json
# Input files
icons = {
"light": "icon_gold_backfill_1024.png",
"dark": "dark.png",
"tinted": "tinted.png"
}
output_dir = "AppIconGold.appiconset"
os.makedirs(output_dir, exist_ok=True)
# Sizes and scales required by iOS
icon_sizes = [
(20, [1, 2, 3]),
(29, [1, 2, 3]),
(40, [1, 2, 3]),
(60, [2, 3]),
(76, [1, 2]),
(83.5, [2]),
(1024, [1]),
]
# Appearance tags for Contents.json, none for light
appearance_tags = {
"light": None,
"dark": [{"appearance": "luminosity", "value": "dark"}],
"tinted": [{"appearance": "luminosity", "value": "tinted"}]
}
def save_icon(image, size_pt, scale, appearance):
px = int(size_pt * scale)
# file name like: icon_20x20@2x_light.png
suffix = appearance
filename = f"icon_{int(size_pt)}x{int(size_pt)}@{scale}x_{suffix}.png"
filepath = os.path.join(output_dir, filename)
resized = image.resize((px, px), Image.LANCZOS)
resized.save(filepath)
return filename
def generate_images_for_appearance(img_path, appearance):
image = Image.open(img_path)
images = []
for size, scales in icon_sizes:
for scale in scales:
filename = save_icon(image, size, scale, appearance)
entry = {
"idiom": "universal",
"size": f"{size}x{size}",
"scale": f"{scale}x",
"filename": filename,
"platform": "ios",
}
if appearance_tags[appearance]:
entry["appearances"] = appearance_tags[appearance]
images.append(entry)
return images
# Generate all images and JSON entries
all_images = []
for appearance, filepath in icons.items():
all_images.extend(generate_images_for_appearance(filepath, appearance))
contents = {
"images": all_images,
"info": {
"version": 1,
"author": "xcode"
}
}
with open(os.path.join(output_dir, "Contents.json"), "w") as f:
json.dump(contents, f, indent=4)
print("✅ AppIconGold asset catalog with light, dark and tinted appearances generated.")