emulator: Clean up resource files (#4590)

This commit is contained in:
squidbus 2026-06-18 08:52:06 -07:00 committed by GitHub
parent 619e8f5292
commit 1785b98fbf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
77 changed files with 173 additions and 430 deletions

View File

@ -17,5 +17,5 @@ chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
# Build AppImage # Build AppImage
./linuxdeploy-x86_64.AppImage --appdir AppDir ./linuxdeploy-x86_64.AppImage --appdir AppDir
./linuxdeploy-plugin-checkrt-x86_64.sh --appdir AppDir ./linuxdeploy-plugin-checkrt-x86_64.sh --appdir AppDir
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/dist/net.shadps4.shadPS4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/src/images/net.shadps4.shadPS4.svg --output appimage ./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/src/dist/net.shadps4.shadPS4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/src/dist/net.shadps4.shadPS4.svg --output appimage
mv shadPS4-x86_64.AppImage Shadps4-sdl.AppImage mv shadPS4-x86_64.AppImage Shadps4-sdl.AppImage

View File

@ -216,7 +216,7 @@ set(EMULATOR_VERSION_MAJOR "0")
set(EMULATOR_VERSION_MINOR "16") set(EMULATOR_VERSION_MINOR "16")
set(EMULATOR_VERSION_PATCH "1") set(EMULATOR_VERSION_PATCH "1")
set_source_files_properties(src/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}") set_source_files_properties(src/dist/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}")
set(APP_VERSION_NUM "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH}") set(APP_VERSION_NUM "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH}")
set(APP_VERSION "${APP_VERSION_NUM} WIP") set(APP_VERSION "${APP_VERSION_NUM} WIP")
@ -810,10 +810,6 @@ set(COMMON src/common/logging/classes.h
src/common/key_manager.h src/common/key_manager.h
) )
if (APPLE)
list(APPEND COMMON src/common/apple.h src/common/apple.mm)
endif()
if (ENABLE_DISCORD_RPC) if (ENABLE_DISCORD_RPC)
list(APPEND COMMON src/common/discord_rpc_handler.cpp src/common/discord_rpc_handler.h) list(APPEND COMMON src/common/discord_rpc_handler.cpp src/common/discord_rpc_handler.h)
endif() endif()
@ -1168,6 +1164,10 @@ set(EMULATOR src/emulator.cpp
src/sdl_window.cpp src/sdl_window.cpp
) )
if (APPLE)
list(APPEND EMULATOR src/sdl_window_apple.mm)
endif()
if(NOT ENABLE_TESTS) if(NOT ENABLE_TESTS)
add_executable(shadps4 add_executable(shadps4
@ -1252,8 +1252,8 @@ if (APPLE)
target_link_libraries(shadps4 PRIVATE date::date-tz epoll-shim) target_link_libraries(shadps4 PRIVATE date::date-tz epoll-shim)
# Create and embed Info.plist # Create and embed Info.plist
set(INFO_PLIST_PATH ${CMAKE_CURRENT_BINARY_DIR}/dist/Info.plist) set(INFO_PLIST_PATH ${CMAKE_CURRENT_BINARY_DIR}/src/dist/Info.plist)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/dist/MacOSBundleInfo.plist.in ${INFO_PLIST_PATH}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/dist/MacOSBundleInfo.plist.in ${INFO_PLIST_PATH})
target_link_options(shadps4 PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${INFO_PLIST_PATH}) target_link_options(shadps4 PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${INFO_PLIST_PATH})
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
target_link_libraries(shadps4 PRIVATE date::date-tz epoll-shim) target_link_libraries(shadps4 PRIVATE date::date-tz epoll-shim)
@ -1304,7 +1304,7 @@ if (WIN32)
endif() endif()
if (WIN32) if (WIN32)
target_sources(shadps4 PRIVATE src/shadps4.rc) target_sources(shadps4 PRIVATE src/dist/shadps4.rc)
endif() endif()
add_compile_definitions(BOOST_ASIO_STANDALONE) add_compile_definitions(BOOST_ASIO_STANDALONE)
@ -1324,20 +1324,20 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeRC.cmake")
cmrc_add_resource_library(embedded-resources cmrc_add_resource_library(embedded-resources
ALIAS res::embedded ALIAS res::embedded
NAMESPACE res NAMESPACE res
src/images/shadps4.png src/resources/big_picture/controller.png
src/images/big_picture/folder.png src/resources/big_picture/experimental.png
src/images/big_picture/settings.png src/resources/big_picture/folder.png
src/images/big_picture/experimental.png src/resources/big_picture/graphics.png
src/images/big_picture/graphics.png src/resources/big_picture/log.png
src/images/big_picture/controller.png src/resources/big_picture/profiles.png
src/images/big_picture/trophy.png src/resources/big_picture/settings.png
src/images/big_picture/log.png src/resources/big_picture/trophy.png
src/images/big_picture/profiles.png src/resources/bronze.png
src/images/trophy.wav src/resources/gold.png
src/images/bronze.png src/resources/platinum.png
src/images/gold.png src/resources/shadps4.png
src/images/platinum.png src/resources/silver.png
src/images/silver.png) src/resources/trophy.wav)
target_link_libraries(shadps4 PRIVATE res::embedded) target_link_libraries(shadps4 PRIVATE res::embedded)
# ImGui resources # ImGui resources

View File

@ -3,7 +3,6 @@ version = 1
[[annotations]] [[annotations]]
path = [ path = [
"REUSE.toml", "REUSE.toml",
"crowdin.yml",
"CMakeSettings.json", "CMakeSettings.json",
"CMakeDarwinPresets.json", "CMakeDarwinPresets.json",
"CMakeLinuxPresets.json", "CMakeLinuxPresets.json",
@ -12,76 +11,30 @@ path = [
".github/FUNDING.yml", ".github/FUNDING.yml",
".github/shadps4.png", ".github/shadps4.png",
".gitmodules", ".gitmodules",
"dist/MacOSBundleInfo.plist.in",
"dist/net.shadps4.shadPS4.desktop",
"documents/changelog.md",
"documents/Quickstart/2.png",
"documents/Screenshots/*", "documents/Screenshots/*",
"documents/Screenshots/Linux/*", "documents/Screenshots/Linux/*",
"documents/Screenshots/Windows/*", "documents/Screenshots/Windows/*",
"flake.lock", "flake.lock",
"scripts/ps4_names.txt", "scripts/ps4_names.txt",
"src/images/bronze.png", "src/dist/MacOSBundleInfo.plist.in",
"src/images/gold.png", "src/dist/net.shadps4.shadPS4.desktop",
"src/images/platinum.png", "src/dist/net.shadps4.shadPS4.svg",
"src/images/silver.png", "src/dist/shadps4.ico",
"src/images/about_icon.png", "src/dist/shadps4.rc",
"src/images/controller_icon.png", "src/resources/big_picture/controller.png",
"src/images/discord.png", "src/resources/big_picture/experimental.png",
"src/images/dump_icon.png", "src/resources/big_picture/folder.png",
"src/images/exit_icon.png", "src/resources/big_picture/graphics.png",
"src/images/favorite_icon.png", "src/resources/big_picture/log.png",
"src/images/trophy_icon.png", "src/resources/big_picture/profiles.png",
"src/images/flag_china.png", "src/resources/big_picture/settings.png",
"src/images/flag_eu.png", "src/resources/big_picture/trophy.png",
"src/images/flag_jp.png", "src/resources/bronze.png",
"src/images/flag_unk.png", "src/resources/gold.png",
"src/images/flag_us.png", "src/resources/platinum.png",
"src/images/flag_world.png", "src/resources/shadps4.png",
"src/images/folder_icon.png", "src/resources/silver.png",
"src/images/github.png", "src/resources/trophy.wav",
"src/images/grid_icon.png",
"src/images/keyboard_icon.png",
"src/images/iconsize_icon.png",
"src/images/KBM.png",
"src/images/ko-fi.png",
"src/images/list_icon.png",
"src/images/list_mode_icon.png",
"src/images/pause_icon.png",
"src/images/play_icon.png",
"src/images/ps4_controller.png",
"src/images/restart_game_icon.png",
"src/images/refreshlist_icon.png",
"src/images/settings_icon.png",
"src/images/fullscreen_icon.png",
"src/images/stop_icon.png",
"src/images/utils_icon.png",
"src/images/shadPS4.icns",
"src/images/shadps4.ico",
"src/images/shadps4.png",
"src/images/net.shadps4.shadPS4.svg",
"src/images/themes_icon.png",
"src/images/update_icon.png",
"src/images/youtube.png",
"src/images/website.png",
"src/images/discord.svg",
"src/images/github.svg",
"src/images/ko-fi.svg",
"src/images/shadps4.svg",
"src/images/website.svg",
"src/images/youtube.svg",
"src/images/trophy.wav",
"src/images/hotkey.png",
"src/images/game_settings.png",
"src/images/big_picture/controller.png",
"src/images/big_picture/experimental.png",
"src/images/big_picture/folder.png",
"src/images/big_picture/graphics.png",
"src/images/big_picture/log.png",
"src/images/big_picture/settings.png",
"src/images/big_picture/trophy.png",
"src/images/big_picture/profiles.png",
"src/shadps4.rc",
] ]
precedence = "aggregate" precedence = "aggregate"
SPDX-FileCopyrightText = "shadPS4 Emulator Project" SPDX-FileCopyrightText = "shadPS4 Emulator Project"

View File

@ -1,3 +1,8 @@
<!--
SPDX-FileCopyrightText: 2026 shadPS4 Emulator Project
SPDX-License-Identifier: GPL-2.0-or-later
-->
v0.4.0 31/10/2024 - codename divicius v0.4.0 31/10/2024 - codename divicius
================= =================

View File

@ -1,12 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <filesystem>
namespace Common {
void SetAppIcon(const std::filesystem::path& path);
} // namespace Common

View File

@ -1,47 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <filesystem>
#include <Cocoa/Cocoa.h>
#include "common/apple.h"
namespace Common {
void SetAppIcon(const std::filesystem::path& path) {
@autoreleasepool {
NSString* path_str = [NSString stringWithUTF8String:path.native().c_str()];
NSImage* base_icon = [[[NSImage alloc] initWithContentsOfFile:path_str] autorelease];
// Transform the icon to match native look-and-feel.
constexpr double ScaleFactor = 13.0 / 16.0;
constexpr double CornerRadiusFactor = 22.0 / 100.0;
const double base_icon_width = base_icon.size.width;
const double base_icon_height = base_icon.size.height;
const double icon_width = base_icon_width * ScaleFactor;
const double icon_height = base_icon_height * ScaleFactor;
const double icon_x = (base_icon_width - icon_width) / 2.0;
const double icon_y = (base_icon_height - icon_height) / 2.0;
const double corner_radius_x = icon_width * CornerRadiusFactor;
const double corner_radius_y = icon_height * CornerRadiusFactor;
NSRect bounds = NSMakeRect(icon_x, icon_y, icon_width, icon_height);
NSBezierPath* mask_path = [NSBezierPath bezierPathWithRoundedRect:bounds
xRadius:corner_radius_x
yRadius:corner_radius_y];
NSImage* rounded_icon = [[[NSImage alloc] initWithSize:base_icon.size] autorelease];
[rounded_icon lockFocus];
[mask_path addClip];
[base_icon drawInRect:bounds
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1.0f];
[rounded_icon unlockFocus];
[NSApp setApplicationIconImage:rounded_icon];
}
}
} // namespace Common

View File

@ -43,7 +43,7 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin
fmt::UTF(trophyIconPath.u8string())); fmt::UTF(trophyIconPath.u8string()));
} }
std::string pathString = "src/images/"; std::string pathString = "src/resources/";
if (trophy_type == "P") { if (trophy_type == "P") {
pathString += "platinum.png"; pathString += "platinum.png";
@ -151,7 +151,7 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin
file.close(); file.close();
PlayWav(sound_data); PlayWav(sound_data);
} else { } else {
auto soundFile = resource.open("src/images/trophy.wav"); auto soundFile = resource.open("src/resources/trophy.wav");
sound_data = std::vector<unsigned char>(soundFile.begin(), soundFile.end()); sound_data = std::vector<unsigned char>(soundFile.begin(), soundFile.end());
PlayWav(sound_data); PlayWav(sound_data);
} }

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 401 KiB

After

Width:  |  Height:  |  Size: 401 KiB

View File

@ -10,7 +10,7 @@
LANGUAGE LANG_NEUTRAL, 0x8 LANGUAGE LANG_NEUTRAL, 0x8
// ICON // ICON
IDI_ICON1 ICON "images/shadps4.ico" IDI_ICON1 ICON "shadps4.ico"
// VERSION // VERSION
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO

View File

@ -431,9 +431,7 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
g_window = window.get(); g_window = window.get();
std::filesystem::path icon_path = mnt->GetHostPath("/app0/sce_sys/icon0.png"); std::filesystem::path icon_path = mnt->GetHostPath("/app0/sce_sys/icon0.png");
if (std::filesystem::exists(icon_path)) { window->SetIcon(icon_path);
window->SetIcon(icon_path);
}
const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir); const auto& mount_data_dir = Common::FS::GetUserPath(Common::FS::PathType::GameDataDir);
mnt->Mount(mount_data_dir, "/data"); mnt->Mount(mount_data_dir, "/data");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="270.93332mm"
height="270.93332mm"
viewBox="0 0 270.93332 270.93332"
version="1.1"
id="svg1"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><g
id="layer1"><circle
style="fill:#000000;stroke-width:0.333618;fill-opacity:1"
id="path1"
cx="135.46666"
cy="135.46666"
r="135.46666" /><path
d="m 194.12363,81.01373 c -10.93928,-5.11822 -22.63609,-8.83793 -34.86478,-10.95597 -1.50182,2.71524 -3.2564,6.36731 -4.46607,9.27253 -12.99943,-1.95495 -25.87929,-1.95495 -38.63961,0 -1.20947,-2.90522 -3.00389,-6.55729 -4.51915,-9.27253 -12.241889,2.11804 -23.952119,5.85142 -34.891409,10.98307 -22.06463,33.34254 -28.045983,65.85691 -25.055298,97.90961 14.634418,10.92863 28.816948,17.56744 42.760118,21.91169 3.44265,-4.73808 6.513019,-9.77474 9.158059,-15.08293 -5.037579,-1.91418 -9.862539,-4.27637 -14.421539,-7.01873 1.20947,-0.89604 2.39255,-1.83288 3.53556,-2.79678 27.806639,13.00588 58.019289,13.00588 85.493719,0 1.15643,0.9639 2.33926,1.90074 3.53556,2.79678 -4.57246,2.75579 -9.41061,5.11798 -14.4482,7.03241 2.64504,5.29451 5.70223,10.34483 9.15805,15.08268 13.95665,-4.34425 28.1523,-10.98282 42.78675,-21.92512 3.50912,-37.15724 -5.99459,-69.37299 -25.12176,-97.93671 z m -86.72985,78.22459 c -8.347289,0 -15.192739,-7.79268 -15.192739,-17.28227 0,-9.48958 6.69928,-17.29569 15.192739,-17.29569 8.49367,0 15.33891,7.79244 15.19272,17.29569 0.0124,9.48959 -6.69905,17.28227 -15.19272,17.28227 z m 56.14517,0 c -8.34727,0 -15.19272,-7.79268 -15.19272,-17.28227 0,-9.48958 6.69904,-17.29569 15.19272,-17.29569 8.49344,0 15.3389,7.79244 15.19272,17.29569 0,9.48959 -6.69928,17.28227 -15.19272,17.28227 z"
fill="#5865F2"
fill-rule="nonzero"
id="path1-1"
style="fill:#ffffff;stroke-width:0.660131" /></g></svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="270.93332mm"
height="270.93332mm"
viewBox="0 0 270.93332 270.93332"
version="1.1"
id="svg1"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><g
id="layer1"><circle
style="fill:#000000;fill-opacity:1;stroke-width:0.638749"
id="path6"
cx="135.46666"
cy="135.46666"
r="135.46666" /><path
d="m 169.16642,266.41733 0.03,-25.82065 c 0.0275,-14.56818 0.019,-22.82654 -0.0238,-23.70553 -0.45287,-9.28878 -3.18131,-16.59646 -8.00675,-21.44417 -0.51833,-0.52073 -0.93407,-0.95373 -0.92397,-0.96273 0.0101,-0.009 0.44777,-0.0663 0.97255,-0.12764 37.08454,-4.33929 55.61974,-20.97235 59.5452,-53.43395 2.47353,-20.45482 -1.25492,-35.28308 -11.991,-47.687007 -0.441,-0.50949 -0.85644,-0.996495 -0.92294,-1.082105 -0.11924,-0.153612 -0.11632,-0.168083 0.21291,-1.092956 3.48926,-9.801891 3.08146,-21.84476 -1.12293,-33.147331 -0.65397,-1.758042 -0.47565,-1.634201 -2.5709,-1.78077 -7.91812,-0.553905 -20.35359,4.335862 -33.80673,13.293762 l -1.15135,0.766879 -0.52658,-0.150896 c -12.92077,-3.704851 -29.09272,-5.157035 -43.79112,-3.932576 -7.21573,0.601112 -14.83438,1.91638 -21.45193,3.70365 l -1.41438,0.381889 -0.95446,-0.635621 C 86.99336,60.049959 72.837429,54.806634 65.589795,56.343848 l -0.309542,0.06563 -0.326595,0.837675 c -4.332806,11.118399 -4.907871,23.48198 -1.547192,33.270837 0.236072,0.687637 0.444934,1.31371 0.464054,1.39113 0.02704,0.109638 -0.130307,0.328834 -0.711584,0.990637 -9.160582,10.429614 -13.392033,22.887494 -12.958383,38.152714 1.106869,38.96344 19.486075,58.39373 59.852157,63.27469 0.65144,0.0787 1.19093,0.14903 1.19993,0.15503 0.008,0.007 -0.42227,0.45425 -0.95705,0.99477 -3.85869,3.90015 -6.54793,9.80164 -7.46414,16.38039 l -0.0827,0.59221 -0.36174,0.17829 c -1.57996,0.77769 -4.999926,1.92702 -7.319448,2.4598 -12.017875,2.76038 -22.054909,-0.77155 -29.200801,-10.27535 -0.611821,-0.81369 -1.002109,-1.39605 -2.631881,-3.92379 -6.342866,-9.8377 -15.85558,-14.92007 -24.055896,-12.85296 -4.140227,1.04365 -2.520489,4.818 3.538802,8.24704 4.584375,2.59434 11.458806,12.02482 14.328324,19.65565 5.313949,14.13125 20.872615,19.63362 43.89345,15.52308 0.48859,-0.0872 0.93963,-0.15902 1.00303,-0.15916 0.10915,-2.5e-4 0.11524,0.79731 0.11524,15.82539 v 19.35334 a 135.46666,135.46666 0 0 0 33.40882,4.45244 135.46666,135.46666 0 0 0 33.69975,-4.516 z"
style="fill:#ffffff;stroke-width:0.777192"
id="path5" /></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="270.93332mm"
height="270.93332mm"
viewBox="0 0 270.93332 270.93332"
version="1.1"
id="svg1"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><g
id="layer1"><circle
style="fill:#000000;fill-opacity:1;stroke-width:0.638749"
id="path6"
cx="135.46666"
cy="135.46666"
r="135.46666" /><path
d="M 245.29662,112.91788 C 238.59944,77.525962 203.19888,73.124713 203.19888,73.124713 H 44.658761 c -5.232973,0 -5.882763,6.913782 -5.882763,6.913782 0,0 -0.710438,63.454165 -0.190612,102.424225 1.420874,21.00124 22.404764,23.14987 22.404764,23.14987 0,0 71.62419,-0.19923 103.67183,-0.42453 21.12252,-3.69082 23.24517,-22.23147 23.02856,-32.35089 37.70517,2.07933 64.30326,-24.52739 57.60608,-59.91929 z m -95.83971,30.41882 c -10.79518,12.58861 -34.75078,34.44754 -34.75078,34.44754 0,0 -1.04833,1.031 -2.6858,0.19924 -0.65845,-0.49382 -0.93569,-0.77972 -0.93569,-0.77972 -3.83809,-3.82079 -29.179908,-26.41616 -34.950046,-34.25694 -6.14268,-8.36065 -9.019085,-23.39244 -0.788412,-32.14296 8.239342,-8.75052 26.034928,-9.40895 37.800448,3.5262 0,0 13.55896,-15.439026 30.0463,-8.34332 16.49601,7.1044 15.8722,26.0869 6.26398,37.34992 z m 53.48205,4.14135 c -8.04007,1.00499 -14.57263,0.24252 -14.57263,0.24252 V 98.501153 h 15.33506 c 0,0 17.07647,4.773777 17.07647,22.855257 0,16.57399 -8.53391,23.10655 -17.8389,26.12157 z"
id="path1"
style="fill:#ffffff;stroke-width:8.66388" /></g></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

View File

@ -1,105 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
viewBox="0 0 256 256"
xml:space="preserve"
id="svg10"
width="256"
height="256"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs3"><linearGradient
id="linearGradient1"><stop
stop-color="#0b034f"
offset="0"
id="stop1" /><stop
stop-color="#4461f2"
offset="1"
id="stop2" /></linearGradient><linearGradient
id="linearGradient2"
x1="100"
x2="100"
y1="185.84"
y2="14.157"
gradientUnits="userSpaceOnUse"
xlink:href="#linearGradient1"
gradientTransform="matrix(1.4489308,0,0,1.4489308,-16.890188,-16.890188)" /><mask
id="mask9"
maskUnits="userSpaceOnUse"><path
d="m -4.1597,120.43 65.304,22.774 -20.899,59.926 -65.304,-22.774 z"
fill="none"
stroke="#149ffb"
stroke-linecap="square"
stroke-width="11"
style="paint-order:markers fill stroke"
id="path2" /></mask><mask
id="mask10"
maskUnits="userSpaceOnUse"><path
d="M 178.79,52.448 133.386,71.834 139.2995,22.82 Z"
fill="none"
stroke="#149ffb"
stroke-linecap="square"
stroke-width="6.75"
style="paint-order:markers fill stroke"
id="path3" /></mask><linearGradient
xlink:href="#linearGradient1"
id="linearGradient10"
gradientUnits="userSpaceOnUse"
x1="100"
y1="185.84"
x2="100"
y2="14.157"
gradientTransform="matrix(1.4489308,0,0,1.4489308,-16.890188,-16.890188)" /></defs><path
d="M 53.640867,3.6223249 H 202.35913 c 27.70935,0 50.01854,22.3077391 50.01854,50.0185421 V 202.35913 c 0,27.70935 -22.30774,50.01854 -50.01854,50.01854 H 53.640867 c -27.709354,0 -50.0185421,-22.30774 -50.0185421,-50.01854 V 53.640867 c 0,-27.709354 22.3077391,-50.0185421 50.0185421,-50.0185421 z"
fill="url(#linearGradient2)"
stroke="#ffffff"
stroke-linecap="square"
stroke-linejoin="round"
stroke-width="7.24465"
style="fill:url(#linearGradient10);paint-order:markers fill stroke"
id="path4" /><path
d="M 53.640867,3.6223249 H 202.35913 c 27.70935,0 50.01854,22.3077391 50.01854,50.0185421 V 202.35913 c 0,27.70935 -22.30774,50.01854 -50.01854,50.01854 H 53.640867 c -27.709354,0 -50.0185421,-22.30774 -50.0185421,-50.01854 V 53.640867 c 0,-27.709354 22.3077391,-50.0185421 50.0185421,-50.0185421 z"
fill="url(#linearGradient2)"
stroke="#ffffff"
stroke-linecap="square"
stroke-linejoin="round"
stroke-width="7.24465"
style="fill:url(#linearGradient2);paint-order:markers fill stroke"
id="path5" /><path
d="m 50.17,16.403 h 99.848 c 18.603,0 33.58,14.977 33.58,33.58 v 99.848 c 0,18.603 -14.977,33.58 -33.58,33.58 H 50.17 c -18.603,0 -33.58,-14.977 -33.58,-33.58 V 49.983 c 0,-18.603 14.977,-33.58 33.58,-33.58 z"
fill="#00ffff"
mask="url(#mask9)"
style="paint-order:markers fill stroke"
id="path6"
transform="matrix(1.4489308,0,0,1.4489308,-16.890189,-16.890189)" /><path
d="m 50.076,16.496 h 99.848 c 18.603,0 33.58,14.977 33.58,33.58 v 99.848 c 0,18.603 -14.977,33.58 -33.58,33.58 H 50.076 c -18.603,0 -33.58,-14.977 -33.58,-33.58 V 50.076 c 0,-18.603 14.977,-33.58 33.58,-33.58 z"
fill="#00ffff"
mask="url(#mask10)"
style="paint-order:markers fill stroke"
id="path7"
transform="matrix(1.4489308,0,0,1.4489308,-16.890189,-16.890189)" /><g
fill="none"
id="g10"
transform="matrix(1.4489308,0,0,1.4489308,-16.890189,-16.890189)"><path
transform="matrix(0.91041,0.0063593,-0.0063593,0.91041,28.548,42.178)"
d="m 166.13,88.68 -23.677,14.288 13.949,23.879 -14.288,-23.677 -23.879,13.949 23.677,-14.288 -13.949,-23.879 14.288,23.677 z"
stroke="#139ffb"
stroke-linecap="square"
stroke-width="12.43"
style="paint-order:markers fill stroke"
id="path8" /><path
d="M 117.98,135.88 V 47.598 l -65.093,69.568 h 83.807"
stroke="#ffffff"
stroke-linecap="square"
stroke-linejoin="round"
stroke-width="10"
style="font-variation-settings:normal;paint-order:markers fill stroke"
id="path9" /><path
d="M 69.923,56.468 A 20.994,21.009 0 0 1 49.012,77.477 20.994,21.009 0 0 1 27.936,56.634 20.994,21.009 0 0 1 48.68,35.46 20.994,21.009 0 0 1 69.92,56.135"
stop-color="#000000"
stroke="#139ffb"
stroke-linecap="round"
stroke-width="9.4488"
style="paint-order:markers fill stroke"
id="path10" /></g></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="270.93332mm"
height="270.93332mm"
viewBox="0 0 270.93332 270.93332"
version="1.1"
id="svg1"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><g
id="layer1"><circle
style="fill:#000000;fill-opacity:1;stroke-width:0.638749"
id="path6"
cx="135.46666"
cy="135.46666"
r="135.46666" /><g
style="fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
transform="matrix(1.8837557,0,0,1.8837557,50.69765,50.69765)"
id="g1">
<path
d="M 88.119,23.338 C 87.084,19.466 84.034,16.416 80.162,15.381 73.144,13.5 45,13.5 45,13.5 c 0,0 -28.144,0 -35.162,1.881 C 5.966,16.416 2.916,19.466 1.881,23.338 0,30.356 0,45 0,45 0,45 0,59.644 1.881,66.662 2.916,70.534 5.966,73.584 9.838,74.619 16.856,76.5 45,76.5 45,76.5 c 0,0 28.144,0 35.162,-1.881 3.872,-1.035 6.922,-4.085 7.957,-7.957 C 90,59.644 90,45 90,45 90,45 90,30.356 88.119,23.338 Z M 36,58.5 v -27 L 59.382,45 Z"
style="opacity:1;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
stroke-linecap="round"
id="path1" />
</g></g></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -4,17 +4,18 @@
#include <fstream> #include <fstream>
#include <stb_image.h> #include <stb_image.h>
#include "big_picture.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/devtools/layer.h" #include "core/devtools/layer.h"
#include "core/emulator_settings.h" #include "core/emulator_settings.h"
#include "core/file_format/psf.h" #include "core/file_format/psf.h"
#include "emulator.h" #include "emulator.h"
#include "imgui/big_picture/big_picture.h"
#include "imgui/big_picture/imgui_impl_sdl3_big_picture.h"
#include "imgui/big_picture/imgui_impl_sdlrenderer3.h"
#include "imgui/big_picture/settings_dialog_imgui.h"
#include "imgui/imgui_std.h" #include "imgui/imgui_std.h"
#include "imgui/renderer/font_stack.h" #include "imgui/renderer/font_stack.h"
#include "imgui_impl_sdl3_big_picture.h" #include "sdl_window.h"
#include "imgui_impl_sdlrenderer3.h"
#include "settings_dialog_imgui.h"
namespace BigPictureMode { namespace BigPictureMode {
@ -202,15 +203,15 @@ void Launch(char* executableName) {
SDL_Window* window = SDL_Window* window =
SDL_CreateWindow("shadPS4 Big Picture Mode", 1280, 720, SDL_CreateWindow("shadPS4 Big Picture Mode", 1280, 720,
EmulatorSettings.IsFullScreen() ? SDL_WINDOW_FULLSCREEN : 0); EmulatorSettings.IsFullScreen() ? SDL_WINDOW_FULLSCREEN : 0);
renderer = SDL_CreateRenderer(window, nullptr);
if (window == nullptr) { if (window == nullptr) {
LOG_ERROR(ImGui, "SDL Window Creation Error: {}", SDL_GetError()); LOG_ERROR(ImGui, "SDL Window Creation Error: {}", SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_Quit(); SDL_Quit();
return; return;
} }
Frontend::SetDefaultWindowIcon(window);
renderer = SDL_CreateRenderer(window, nullptr);
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();

View File

@ -187,14 +187,14 @@ SettingsWindow::SettingsWindow(bool gameRunning) : isGameRunning(gameRunning) {
: texture = BigPictureMode::LoadSdlTextureData(texData); : texture = BigPictureMode::LoadSdlTextureData(texData);
}; };
loadTexture("src/images/big_picture/settings.png", generalTexture); loadTexture("src/resources/big_picture/settings.png", generalTexture);
loadTexture("src/images/big_picture/experimental.png", experimentalTexture); loadTexture("src/resources/big_picture/experimental.png", experimentalTexture);
loadTexture("src/images/big_picture/graphics.png", graphicsTexture); loadTexture("src/resources/big_picture/graphics.png", graphicsTexture);
loadTexture("src/images/big_picture/controller.png", inputTexture); loadTexture("src/resources/big_picture/controller.png", inputTexture);
loadTexture("src/images/big_picture/trophy.png", trophyTexture); loadTexture("src/resources/big_picture/trophy.png", trophyTexture);
loadTexture("src/images/big_picture/log.png", logTexture); loadTexture("src/resources/big_picture/log.png", logTexture);
loadTexture("src/images/big_picture/folder.png", foldersTexture); loadTexture("src/resources/big_picture/folder.png", foldersTexture);
loadTexture("src/images/big_picture/profiles.png", profilesTexture); loadTexture("src/resources/big_picture/profiles.png", profilesTexture);
auto languageKeys = std::views::keys(languageMap); auto languageKeys = std::views::keys(languageMap);
languageOptions.assign(languageKeys.begin(), languageKeys.end()); languageOptions.assign(languageKeys.begin(), languageKeys.end());

View File

@ -16,10 +16,10 @@ std::queue<NotificationInfo> notif_queue;
std::mutex queueMtx; std::mutex queueMtx;
const std::map<shadNotifications::stockIcons, std::string> iconMap = { const std::map<shadNotifications::stockIcons, std::string> iconMap = {
{shadNotifications::stockIcons::shadPS4, "src/images/shadps4.png"}, {shadNotifications::stockIcons::shadPS4, "src/resources/shadps4.png"},
{shadNotifications::stockIcons::Settings, "src/images/big_picture/settings.png"}, {shadNotifications::stockIcons::Settings, "src/resources/big_picture/settings.png"},
{shadNotifications::stockIcons::Profiles, "src/images/big_picture/profiles.png"}, {shadNotifications::stockIcons::Profiles, "src/resources/big_picture/profiles.png"},
{shadNotifications::stockIcons::Input, "src/images/big_picture/controller.png"}, {shadNotifications::stockIcons::Input, "src/resources/big_picture/controller.png"},
}; };
NotificationsUI::NotificationsUI(NotificationInfo info) { NotificationsUI::NotificationsUI(NotificationInfo info) {

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 993 B

After

Width:  |  Height:  |  Size: 993 B

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -7,6 +7,7 @@
#include <SDL3/SDL_properties.h> #include <SDL3/SDL_properties.h>
#include <SDL3/SDL_timer.h> #include <SDL3/SDL_timer.h>
#include <SDL3/SDL_video.h> #include <SDL3/SDL_video.h>
#include <cmrc/cmrc.hpp>
#include <stb_image.h> #include <stb_image.h>
#include "common/assert.h" #include "common/assert.h"
@ -30,9 +31,10 @@
#ifdef __APPLE__ #ifdef __APPLE__
#include <SDL3/SDL_metal.h> #include <SDL3/SDL_metal.h>
#include "common/apple.h"
#endif #endif
CMRC_DECLARE(res);
namespace Frontend { namespace Frontend {
using namespace Libraries::Pad; using namespace Libraries::Pad;
@ -178,52 +180,33 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameControllers* controller
WindowSDL::~WindowSDL() = default; WindowSDL::~WindowSDL() = default;
void WindowSDL::SetIcon(const std::filesystem::path& path) { void WindowSDL::SetIcon(const std::filesystem::path& path) {
#ifdef __APPLE__ if (!std::filesystem::exists(path)) {
// Use native path which matches system icon look-and-feel. LOG_WARNING(Core, "Could not find icon file '{}', using default icon.",
Common::SetAppIcon(path); fmt::UTF(path.u8string()));
#else SetDefaultWindowIcon(window);
return;
}
Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read, Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read,
Common::FS::FileType::BinaryFile, Common::FS::FileType::BinaryFile,
Common::FS::FileShareFlag::ShareReadWrite}; Common::FS::FileShareFlag::ShareReadWrite};
if (!file.IsOpen()) { if (!file.IsOpen()) {
LOG_ERROR(Core, "Failed to open window icon file '{}'.", fmt::UTF(path.u8string())); LOG_ERROR(Core, "Failed to open window icon file '{}'.", fmt::UTF(path.u8string()));
SetDefaultWindowIcon(window);
return; return;
} }
const u64 file_size = file.GetSize(); const u64 fileSize = file.GetSize();
std::vector<u8> buf(file_size); std::vector<u8> buf(fileSize);
const size_t bytes_read = file.ReadRaw<u8>(buf.data(), file_size); const size_t bytesRead = file.ReadRaw<u8>(buf.data(), fileSize);
file.Close(); file.Close();
if (bytes_read < file_size) { if (bytesRead < fileSize) {
LOG_ERROR(Core, "Failed to read window icon file '{}'.", fmt::UTF(path.u8string())); LOG_ERROR(Core, "Failed to read window icon file '{}'.", fmt::UTF(path.u8string()));
SetDefaultWindowIcon(window);
return; return;
} }
int image_width = 0; SetWindowIcon(window, buf);
int image_height = 0;
constexpr int num_channels = 4;
unsigned char* image_data =
stbi_load_from_memory(buf.data(), static_cast<int>(buf.size()), &image_width, &image_height,
nullptr, num_channels);
if (image_data == nullptr) {
LOG_ERROR(Core, "Failed to load window icon image '{}': {}", fmt::UTF(path.u8string()),
stbi_failure_reason());
return;
}
SCOPE_EXIT {
stbi_image_free(image_data);
};
SDL_Surface* surface = SDL_CreateSurfaceFrom(image_width, image_height, SDL_PIXELFORMAT_RGBA32,
image_data, image_width * num_channels);
if (surface == nullptr) {
LOG_ERROR(Core, "Failed to create SDL surface for window icon: {}", SDL_GetError());
}
if (!SDL_SetWindowIcon(window, surface)) {
LOG_ERROR(Core, "Failed to set SDL window icon: {}", SDL_GetError());
}
SDL_DestroySurface(surface);
#endif
} }
void WindowSDL::WaitEvent() { void WindowSDL::WaitEvent() {
@ -474,4 +457,38 @@ void WindowSDL::OnGamepadEvent(const SDL_Event* event) {
} }
} }
#ifndef __APPLE__
void SetWindowIcon(SDL_Window* window, const std::vector<u8>& png) {
int imageWidth = 0;
int imageHeight = 0;
constexpr int numChannels = 4;
unsigned char* imageData = stbi_load_from_memory(png.data(), png.size(), &imageWidth,
&imageHeight, nullptr, numChannels);
if (imageData == nullptr) {
LOG_ERROR(Core, "Failed to load window icon image: {}", stbi_failure_reason());
return;
}
SCOPE_EXIT {
stbi_image_free(imageData);
};
SDL_Surface* surface = SDL_CreateSurfaceFrom(imageWidth, imageHeight, SDL_PIXELFORMAT_RGBA32,
imageData, imageWidth * numChannels);
if (surface == nullptr) {
LOG_ERROR(Core, "Failed to create SDL surface for window icon: {}", SDL_GetError());
}
if (!SDL_SetWindowIcon(window, surface)) {
LOG_ERROR(Core, "Failed to set SDL window icon: {}", SDL_GetError());
}
SDL_DestroySurface(surface);
}
#endif
void SetDefaultWindowIcon(SDL_Window* window) {
const auto resource = cmrc::res::get_filesystem();
const auto file = resource.open("src/resources/shadps4.png");
const std::vector<u8> texData = std::vector<u8>(file.begin(), file.end());
SetWindowIcon(window, texData);
}
} // namespace Frontend } // namespace Frontend

View File

@ -94,4 +94,7 @@ private:
bool is_open{true}; bool is_open{true};
}; };
void SetWindowIcon(SDL_Window* window, const std::vector<u8>& png);
void SetDefaultWindowIcon(SDL_Window* window);
} // namespace Frontend } // namespace Frontend

48
src/sdl_window_apple.mm Normal file
View File

@ -0,0 +1,48 @@
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <filesystem>
#include <Cocoa/Cocoa.h>
#include <SDL3/SDL_video.h>
#include "sdl_window.h"
namespace Frontend {
void SetWindowIcon(SDL_Window* window, const std::vector<u8>& png) {
@autoreleasepool {
NSData* pngData = [NSData dataWithBytes:png.data() length:png.size()];
NSImage* baseIcon = [[[NSImage alloc] initWithData:pngData] autorelease];
// Transform the icon to match native look-and-feel.
constexpr double ScaleFactor = 13.0 / 16.0;
constexpr double CornerRadiusFactor = 22.0 / 100.0;
const double baseIconWidth = baseIcon.size.width;
const double baseIconHeight = baseIcon.size.height;
const double iconWidth = baseIconWidth * ScaleFactor;
const double iconHeight = baseIconHeight * ScaleFactor;
const double iconX = (baseIconWidth - iconWidth) / 2.0;
const double iconY = (baseIconHeight - iconHeight) / 2.0;
const double cornerRadiusX = iconWidth * CornerRadiusFactor;
const double cornerRadiusY = iconHeight * CornerRadiusFactor;
NSRect bounds = NSMakeRect(iconX, iconY, iconWidth, iconHeight);
NSBezierPath* maskPath = [NSBezierPath bezierPathWithRoundedRect:bounds
xRadius:cornerRadiusX
yRadius:cornerRadiusY];
NSImage* nativeIcon = [[[NSImage alloc] initWithSize:baseIcon.size] autorelease];
[nativeIcon lockFocus];
[maskPath addClip];
[baseIcon drawInRect:bounds
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1.0f];
[nativeIcon unlockFocus];
[NSApp setApplicationIconImage:nativeIcon];
}
}
} // namespace Frontend