Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
build:
# runs-on: macos-12
runs-on: [self-hosted, macOS]
runs-on: macos-latest

env:
XCODE_COMMON_BUILD_ARGS: -project Source/iOS/App/DolphiniOS.xcodeproj -derivedDataPath "${{ github.workspace }}/build-Xcode" -sdk iphoneos -destination generic/platform=iOS DOL_PBID_ORGANIZATION_IDENTIFIER="me.oatmealdome" DOL_BUILD_SOURCE="development" CODE_SIGNING_ALLOWED="NO" CODE_SIGNING_REQUIRED="NO"
Expand Down Expand Up @@ -52,4 +52,4 @@ jobs:
run: |
"${{ github.workspace }}/Source/iOS/App/Project/Scripts/CreateDeb.sh" "${{ github.workspace }}/archives/Jailbroken.xcarchive/Products/Applications/DolphiniOS.app" "OatmealDome Software" "${{ github.workspace }}/Source/iOS/App/Project/Entitlements/Private.entitlements" "${{ github.workspace }}/Source/iOS/App/Project/Package/Deb/${{ env.DEB_CONTROL_NAME }}.in" "${{ github.workspace }}/Source/iOS/App/Project/Package/Deb/postinst.sh" "${{ github.workspace }}/Source/iOS/App/Project/Package/Deb/postrm.sh" "Applications" "${{ github.workspace }}/products/Jailbroken-Rootful.deb"
"${{ github.workspace }}/Source/iOS/App/Project/Scripts/CreateDeb.sh" "${{ github.workspace }}/archives/Jailbroken.xcarchive/Products/Applications/DolphiniOS.app" "OatmealDome Software" "${{ github.workspace }}/Source/iOS/App/Project/Entitlements/Private.entitlements" "${{ github.workspace }}/Source/iOS/App/Project/Package/Deb/${{ env.DEB_CONTROL_NAME }}-rootless.in" "${{ github.workspace }}/Source/iOS/App/Project/Package/Deb/postinst.sh" "${{ github.workspace }}/Source/iOS/App/Project/Package/Deb/postrm.sh" "var/jb/Applications" "${{ github.workspace }}/products/Jailbroken-Rootless.deb"


119 changes: 119 additions & 0 deletions .github/workflows/dsu-client-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: DSU Client CI

# Workflow de validacion en runners hosteados por GitHub (sin infraestructura
# propia, sin necesidad de una Mac local).
#
# El workflow existente del repo (`build.yml`) hace el archive/IPA/DEB
# completo pero requiere `runs-on: [self-hosted, macOS]` con el toolchain de
# jailbreak ya instalado. Este workflow es mas liviano: solo COMPILA (no
# archiva) el scheme "DiOS (NJB)" en Debug, con firma de codigo deshabilitada,
# para detectar errores de compilacion en cada push/PR. Pensado especialmente
# para validar los cambios de la pantalla DSU Client (Controllers/Controllers
# DsuClient*, Controllers/DsuServerCell*, Controllers/ControllersAddDsuServer*)
# y cualquier otro cambio en el arbol de iOS.
#
# Sobre el runner y la version de Xcode:
# - `runs-on:` en GitHub Actions usa etiquetas por VERSION DE macOS, no por
# version de Xcode: macos-26 (Apple Silicon, la mas nueva), macos-15,
# macos-14 (en baja: deprecada desde el 6/jul/2026, se apaga el 2/nov/2026
# - no usar). No existe "runs-on: xcode-27".
# - Xcode se selecciona con un paso dentro del job (`xcode-select` o la
# action `maxim-lobanov/setup-xcode`), porque cada imagen trae varias
# versiones de Xcode preinstaladas en paralelo.
# - Las versiones beta/RC de Xcode (como Xcode 27, en preview publico) solo
# se instalan en la imagen de macOS mas nueva (macos-26) - por eso el
# runner tiene que ser macos-26 si se quiere probar contra Xcode 27.
#
# Por eso hay DOS jobs:
# - build-stable: Xcode estable mas reciente -> senal confiable de "esto
# compila con lo que compilaria un usuario comun hoy".
# - build-xcode27-preview: Xcode 27 (preview publico) -> para adelantarse a
# roturas de SDK/toolchain, como haces otros proyectos de emuladores.
# No bloquea el PR si falla (continue-on-error), porque un preview puede
# romper por cosas ajenas a este cambio.

on:
push:
branches: [ master ]
paths:
- 'Source/iOS/**'
- 'Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/**'
- '.github/workflows/dsu-client-ci.yml'
pull_request:
branches: [ master ]
paths:
- 'Source/iOS/**'
- 'Source/Core/InputCommon/ControllerInterface/DualShockUDPClient/**'
- '.github/workflows/dsu-client-ci.yml'
workflow_dispatch: {}

env:
XCODE_COMMON_BUILD_ARGS: -project Source/iOS/App/DolphiniOS.xcodeproj -derivedDataPath "${{ github.workspace }}/build-Xcode" -sdk iphoneos -destination generic/platform=iOS DOL_PBID_ORGANIZATION_IDENTIFIER="me.oatmealdome" DOL_BUILD_SOURCE="development" CODE_SIGNING_ALLOWED="NO" CODE_SIGNING_REQUIRED="NO"

jobs:
build-stable:
name: Build (Xcode estable)
runs-on: macos-26

steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Seleccionar Xcode estable mas reciente
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable

- name: Mostrar version de Xcode seleccionada
run: xcodebuild -version

- name: Compilar DiOS (NJB) - Debug
run: |
xcodebuild build \
-configuration "Debug (Non-Jailbroken)" \
-scheme "DiOS (NJB)" \
${{ env.XCODE_COMMON_BUILD_ARGS }}

- name: Subir el .app compilado (sin firmar) como artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: DolphiniOS-NJB-Debug-xcode-estable
path: ${{ github.workspace }}/build-Xcode/Build/Products/Debug*iphoneos/DolphiniOS.app
if-no-files-found: ignore
retention-days: 14

build-xcode27-preview:
name: Build (Xcode 27 preview)
runs-on: macos-26
continue-on-error: true

steps:
- uses: actions/checkout@v4
with:
submodules: 'recursive'

- name: Seleccionar Xcode 27 (preview publico, incluye betas)
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest

- name: Mostrar version de Xcode seleccionada
run: xcodebuild -version

- name: Compilar DiOS (NJB) - Debug
run: |
xcodebuild build \
-configuration "Debug (Non-Jailbroken)" \
-scheme "DiOS (NJB)" \
${{ env.XCODE_COMMON_BUILD_ARGS }}

- name: Subir el .app compilado (sin firmar) como artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: DolphiniOS-NJB-Debug-xcode27-preview
path: ${{ github.workspace }}/build-Xcode/Build/Products/Debug*iphoneos/DolphiniOS.app
if-no-files-found: ignore
retention-days: 14
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,7 @@ Would you like to ignore this line and continue parsing?";
"Enable" = "Enable";
"Add..." = "Add...";
"Remove" = "Remove";
"Please enter a valid server address and port." = "Please enter a valid server address and port.";
"DSU protocol enables the use of input and motion data from compatible sources, like PlayStation, Nintendo Switch and Steam controllers.<br><br>For setup instructions, <a href=\"https://wiki.dolphin-emu.org/index.php?title=DSU_Client\">refer to this page</a>." = "DSU protocol enables the use of input and motion data from compatible sources, like PlayStation, Nintendo Switch and Steam controllers.<br><br>For setup instructions, <a href=\"https://wiki.dolphin-emu.org/index.php?title=DSU_Client\">refer to this page</a>.";
"Size" = "Size";
"Disc" = "Disc";
Expand Down
20 changes: 20 additions & 0 deletions Source/iOS/App/DolphiniOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@
B9DC5FB92884CB7C004BD94A /* GraphicsChoiceCell.mm in Sources */ = {isa = PBXBuildFile; fileRef = B9DC5FB82884CB7C004BD94A /* GraphicsChoiceCell.mm */; };
B9EC1A43295FFFD30013EBE4 /* SoftwareListiOSViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = B9EC1A42295FFFD30013EBE4 /* SoftwareListiOSViewController.mm */; };
B9EC28382D21D429000FAE09 /* ControllersTouchscreenViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = B9EC28372D21D429000FAE09 /* ControllersTouchscreenViewController.mm */; };
CFCE2A026C13DB1B9B62AD4B /* ControllersDsuClientViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE99DB7E010EF4A5584CB5DA /* ControllersDsuClientViewController.mm */; };
CEAC14FEE3BC2980C98DB85F /* DsuServerCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EDA3BEE4FE789DBD3CFDF55 /* DsuServerCell.m */; };
73169C33207036903039304A /* ControllersAddDsuServerViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = FC8D428F66DEF8467F8DF51C /* ControllersAddDsuServerViewController.mm */; };
B9EC283A2D21DA56000FAE09 /* TCWiiTouchIRMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9EC28392D21DA56000FAE09 /* TCWiiTouchIRMode.swift */; };
B9EC283D2D21DE2F000FAE09 /* ControllersTouchscreenIRModeViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = B9EC283C2D21DE2F000FAE09 /* ControllersTouchscreenIRModeViewController.mm */; };
B9EFF8532E7F56790029F016 /* AppIcon_Glass.icon in Resources */ = {isa = PBXBuildFile; fileRef = B9EFF8522E7F56790029F016 /* AppIcon_Glass.icon */; };
Expand Down Expand Up @@ -548,6 +551,13 @@
B9EC1A42295FFFD30013EBE4 /* SoftwareListiOSViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SoftwareListiOSViewController.mm; sourceTree = "<group>"; };
B9EC28362D21D429000FAE09 /* ControllersTouchscreenViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControllersTouchscreenViewController.h; sourceTree = "<group>"; };
B9EC28372D21D429000FAE09 /* ControllersTouchscreenViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ControllersTouchscreenViewController.mm; sourceTree = "<group>"; };
E723480BA2A352B04E8FD38E /* ControllersDsuClientViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControllersDsuClientViewController.h; sourceTree = "<group>"; };
CE99DB7E010EF4A5584CB5DA /* ControllersDsuClientViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ControllersDsuClientViewController.mm; sourceTree = "<group>"; };
C623440D4EF2976092F76843 /* DsuServerCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DsuServerCell.h; sourceTree = "<group>"; };
4EDA3BEE4FE789DBD3CFDF55 /* DsuServerCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DsuServerCell.m; sourceTree = "<group>"; };
BA352A1E6E317A3FBBBC4A87 /* ControllersAddDsuServerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControllersAddDsuServerViewController.h; sourceTree = "<group>"; };
FC8D428F66DEF8467F8DF51C /* ControllersAddDsuServerViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ControllersAddDsuServerViewController.mm; sourceTree = "<group>"; };
088316AAD0B43DC1AB1ED40C /* ControllersAddDsuServerViewControllerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControllersAddDsuServerViewControllerDelegate.h; sourceTree = "<group>"; };
B9EC28392D21DA56000FAE09 /* TCWiiTouchIRMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TCWiiTouchIRMode.swift; sourceTree = "<group>"; };
B9EC283B2D21DE2F000FAE09 /* ControllersTouchscreenIRModeViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ControllersTouchscreenIRModeViewController.h; sourceTree = "<group>"; };
B9EC283C2D21DE2F000FAE09 /* ControllersTouchscreenIRModeViewController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ControllersTouchscreenIRModeViewController.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -770,6 +780,13 @@
B9EC28372D21D429000FAE09 /* ControllersTouchscreenViewController.mm */,
B9EC283B2D21DE2F000FAE09 /* ControllersTouchscreenIRModeViewController.h */,
B9EC283C2D21DE2F000FAE09 /* ControllersTouchscreenIRModeViewController.mm */,
E723480BA2A352B04E8FD38E /* ControllersDsuClientViewController.h */,
CE99DB7E010EF4A5584CB5DA /* ControllersDsuClientViewController.mm */,
C623440D4EF2976092F76843 /* DsuServerCell.h */,
4EDA3BEE4FE789DBD3CFDF55 /* DsuServerCell.m */,
BA352A1E6E317A3FBBBC4A87 /* ControllersAddDsuServerViewController.h */,
FC8D428F66DEF8467F8DF51C /* ControllersAddDsuServerViewController.mm */,
088316AAD0B43DC1AB1ED40C /* ControllersAddDsuServerViewControllerDelegate.h */,
);
path = Controllers;
sourceTree = "<group>";
Expand Down Expand Up @@ -2135,6 +2152,9 @@
B9B2C661288E569E00CB6569 /* ExternalDisplayEmulationViewController.mm in Sources */,
B950CFA32961696100197719 /* BootNoticeNavigationViewController.m in Sources */,
B9EC28382D21D429000FAE09 /* ControllersTouchscreenViewController.mm in Sources */,
CFCE2A026C13DB1B9B62AD4B /* ControllersDsuClientViewController.mm in Sources */,
CEAC14FEE3BC2980C98DB85F /* DsuServerCell.m in Sources */,
73169C33207036903039304A /* ControllersAddDsuServerViewController.mm in Sources */,
B9B1483C29642CB8002C4BE7 /* UpdateRequiredNoticeViewController.m in Sources */,
B900A7B027F2866D000361DD /* UserFolderUtil.swift in Sources */,
B974923C2960096C00794509 /* ImportFileManager.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2026 DolphiniOS Project
// SPDX-License-Identifier: GPL-2.0-or-later

#import <UIKit/UIKit.h>

@protocol ControllersAddDsuServerViewControllerDelegate;

NS_ASSUME_NONNULL_BEGIN

@interface ControllersAddDsuServerViewController : UITableViewController

@property (weak, nonatomic, nullable) id<ControllersAddDsuServerViewControllerDelegate> delegate;

@property (weak, nonatomic) IBOutlet UITextField* descriptionField;
@property (weak, nonatomic) IBOutlet UITextField* addressField;
@property (weak, nonatomic) IBOutlet UITextField* portField;

- (IBAction)addPressed:(id)sender;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright 2026 DolphiniOS Project
// SPDX-License-Identifier: GPL-2.0-or-later

#import "ControllersAddDsuServerViewController.h"

#import <string>

#import "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h"

#import "ControllersAddDsuServerViewControllerDelegate.h"
#import "FoundationStringUtil.h"
#import "LocalizationUtil.h"

@interface ControllersAddDsuServerViewController () <UITextFieldDelegate>

@end

@implementation ControllersAddDsuServerViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.navigationItem.title = DOLCoreLocalizedString(@"Add New DSU Server");

self.descriptionField.placeholder = DOLCoreLocalizedString(@"BetterJoy, DS4Windows, etc");
self.addressField.text = CppToFoundationString(std::string(ciface::DualShockUDPClient::DEFAULT_SERVER_ADDRESS));
self.portField.text = [NSString stringWithFormat:@"%d", ciface::DualShockUDPClient::DEFAULT_SERVER_PORT];
}

// Mirrors ServerStringValidator: the description and address fields are
// used as fields in a "description:address:port;" serialized entry, so
// ':' and ';' can never be allowed in them.
- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string {
if (textField != self.descriptionField && textField != self.addressField) {
return true;
}

return [string rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@":;"]].location == NSNotFound;
}

- (void)showInvalidInputAlert {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:DOLCoreLocalizedString(@"Error")
message:DOLCoreLocalizedString(@"Please enter a valid server address and port.")
preferredStyle:UIAlertControllerStyleAlert];

[alert addAction:[UIAlertAction actionWithTitle:DOLCoreLocalizedString(@"OK") style:UIAlertActionStyleDefault handler:nil]];

[self presentViewController:alert animated:true completion:nil];
}

- (IBAction)addPressed:(id)sender {
NSString* description = [self.descriptionField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString* address = [self.addressField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

if (description.length == 0 || address.length == 0) {
[self showInvalidInputAlert];
return;
}

NSInteger port = [self.portField.text integerValue];
if (port <= 0 || port > 0xFFFF) {
[self showInvalidInputAlert];
return;
}

[self.delegate addDsuServerViewController:self
didAddServerWithDescription:description
address:address
port:(uint16_t)port];

[self.navigationController popViewControllerAnimated:true];
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2026 DolphiniOS Project
// SPDX-License-Identifier: GPL-2.0-or-later

#import <Foundation/Foundation.h>

@class ControllersAddDsuServerViewController;

NS_ASSUME_NONNULL_BEGIN

@protocol ControllersAddDsuServerViewControllerDelegate <NSObject>

- (void)addDsuServerViewController:(ControllersAddDsuServerViewController*)viewController
didAddServerWithDescription:(NSString*)description
address:(NSString*)address
port:(uint16_t)port;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2026 DolphiniOS Project
// SPDX-License-Identifier: GPL-2.0-or-later

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ControllersDsuClientViewController : UITableViewController

@property (weak, nonatomic) IBOutlet UISwitch* enabledSwitch;
@property (weak, nonatomic) IBOutlet UITextView* descriptionTextView;

- (IBAction)enabledSwitchChanged:(id)sender;

@end

NS_ASSUME_NONNULL_END
Loading