Test pull request - #2
Open
j92580498-max wants to merge 1276 commits into
Open
Conversation
Port the CGFont/CGGlyph rasterisation path from
touchHLE@38d09d4 so that apps that ship their own TrueType/OpenType fonts
via CoreGraphics (CGFontCreateWithDataProvider) can actually render
glyphs into a CGBitmapContext.
font.rs:
- Add glyph_id_for_char(), from_vec() and draw_glyphs() to the rusttype
wrapper Font. draw_glyphs() takes raw glyph ids and lays them out
with horizontal kerning, mirroring the y axis to match CG's
bottom-left-origin coordinate space.
cg_font.rs:
- Add the private _touchHLE_CGFont host class backing CGFontRef when
the font is created from raw bytes.
- Implement CGFontCreateWithDataProvider by parsing the provider's
bytes into a rusttype Font.
- Implement CGFontGetGlyphsForUnichars.
- Make CGFontRetain/Release use CFRetain/CFRelease so both CGFont
flavours (UIFont-backed and rusttype-backed) work uniformly.
- Make CGFontCopy{PostScript,Full}Name and CGFontGet{Ascent,Descent,
Leading} dispatch on the underlying CGFont kind so calls on the new
rusttype-backed objects no longer hit msg dispatch on UIFont
selectors.
cg_context.rs:
- Add font/font_size to CGContextHostObject and to the gstate stack,
with proper retain/release on save/restore/dealloc.
- Replace the no-op CGContextSetFont/CGContextSetFontSize stubs with
real implementations.
- Implement CGContextShowGlyphsAtPoint by reusing the existing
CGBitmapContextDrawer/draw_font_glyph rasterisation path.
cg_bitmap_context.rs:
- Initialise font (null) and font_size (17.0) for new bitmap contexts.
core_graphics.rs:
- Expose cg_font::CLASSES so _touchHLE_CGFont is registered.
ui_font.rs:
- Make draw_font_glyph pub so cg_context can reuse the rasteriser.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
feat(uikit): Full UIKit implementation - gesture recognizers, autoresizing, UICollectionView
- Enhanced Font struct with raw_data storage for TrueType table access - Added real per-glyph metrics: glyph_advance(), glyph_bbox(), glyph_left_side_bearing() using rusttype h_metrics - Implemented TrueType/OpenType table parsing (parse_table_from_raw, parse_table_tags_from_raw) for direct font table access - Added PostScript 'post' table name lookup (glyph_for_name, glyph_name) supporting format 1.0 and 2.0 with standard Mac glyph names - Added 'name' table parsing for CGFontCopyPostScriptName/CGFontCopyFullName - Implemented CGFontGetNumberOfGlyphs, CGFontGetTypeID, CGFontGetItalicAngle - Real CGFontGetCapHeight/CGFontGetXHeight from OS/2 table - Real CGFontGetFontBBox from head table (xMin/yMin/xMax/yMax) - Real CGFontGetUnitsPerEm from head table - Real CGFontCopyTableTags returns all font table tags as CFArray - Real CGFontCopyTableForTag returns raw table bytes as CFData - CGFontGetGlyphWithGlyphName uses 'post' table lookup - CGFontCopyGlyphNameForGlyph returns PostScript name from 'post' table - Added CGContextShowGlyphsAtPositions for positioned glyph rendering - Added CGContextShowGlyphsWithAdvances for advance-based glyph rendering - Added CGContextShowGlyphs wrapper function - All implementations backed by real font data, no stubs Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…lementation feat: Full CGFont/CGGlyph implementation with real metrics
…anic, UITabBarController host object chain - Add preferredContentSize/setPreferredContentSize and deprecated contentSizeForViewInPopover to UIViewController. Fixes panic in UIPopoverController.initWithContentViewController: which calls msg![env; view_controller preferredContentSize] on the passed VC. (Crash seen with Enigmo Deluxe HD) - Handle AlreadyExists (os error 17) gracefully in Fs::create_dir instead of panicking via handle_open_err. The host directory may already exist on disk from a previous run while the in-memory filesystem tree was rebuilt fresh. (Crash seen with Rabbids Go Phone Again / Unity .wapi directory) - Add superclass UIViewControllerHostObject to UITabBarControllerHostObject and use impl_HostObject_with_superclass! macro so that borrow::<UIViewControllerHostObject>() properly walks the host object chain. Previously UITabBarController loaded from NIB (via UIClassSwapper) produced phantom object warnings because the borrow could not find UIViewControllerHostObject fields. (Warnings seen with PapiJump Cave, PapiJump Land Lite) Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
Fix crashes: UIPopoverController selector, fs AlreadyExists, TabBar host object
- Fix allocWithZone: recursion causing nil textures (RedBall2P, etc.) When objc_msgSend recursion limit is hit for allocWithZone:, perform the allocation directly instead of returning nil. This prevents the cascading 'texture cannot be nil!' failures in games. - Add _UIScrollViewDecelerationRateFast/Normal constants (UIKit) Exported as CGFloat values 0.99/0.998 per Apple docs. Fixes unhandled symbol in Monster Hunter Dynamic Hunting. - Add _kCATransition constant (Core Animation) NSString constant 'transition' used as animation key. Fixes unhandled symbol in RedBall2P and Resident Evil 4. - Implement pthread_getname_np and pthread_setname_np (Darwin extensions) Full implementation with thread name storage. Fixes unhandled symbol in Sonic Dash. - Implement _dyld_get_image_header and related dyld API functions Added _dyld_image_count, _dyld_get_image_header, _dyld_get_image_name, _dyld_get_image_vmaddr_slide with proper MachO text_base tracking. Fixes return-0 stub warning in Sonic Dash. Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
Fix multiple runtime bugs affecting game compatibility
…rrors - Add Accelerate.framework with real vDSP FFT implementation (radix-2 Cooley-Tukey algorithm) including: vDSP_create_fftsetup, vDSP_destroy_fftsetup, vDSP_fft_zip, vDSP_fft_zrip, vDSP_fft_zop, vDSP_ctoz, vDSP_ztoc, vDSP_vsmul, vDSP_zvmags, vDSP_meanv, vDSP_maxv, vDSP_minv, vDSP_rmsqv, vDSP_vadd, vDSP_vmul, vDSP_vfill, vDSP_vclr - Fix AudioFormatGetPropertyInfo: return success with size=0 instead of paramErr (-50). Apps querying kAudioFormatProperty_Encoders now get an empty list (valid response) instead of an error. Also add AudioFormatGetProperty function. - Implement MPMediaLibrary.defaultMediaLibrary: return proper singleton with beginGenerating/endGenerating/lastModifiedDate methods instead of nil. - Implement MPMediaQuery: playlistsQuery/songsQuery/albumsQuery/ artistsQuery now return valid query objects with empty arrays for items/collections (empty library on emulated device). - Fix NSKeyedArchiver initForWritingWithMutableData: properly stores the mutable data reference and finishEncoding writes serialized plist into it (was previously a no-op stub). - Harden memmove: early-reject sizes >= 0x80000000 (likely negative i32 cast to u32) and NULL source with non-zero size. Prevents Geometry Dash crashes from corrupted std::string internals. Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
…che, video playback - Implement UIViewController setWantsFullScreenLayout: as a proper no-op (touchHLE always renders full-screen) with getter returning true. Removes the TODO log. - Implement full CFStringNormalize with real Unicode NFC/NFD/NFKC/NFKD normalization. Fast path for ASCII (no-op). Includes canonical decomposition/composition tables for Latin precomposed characters and Hangul syllables. Canonical ordering by combining class. - Implement ___srget: BSD/Darwin internal stdio slow-path character read function, mapped to fgetc. Apps compiled against the iOS SDK call this when the getc() macro's inline buffer is empty. - Implement NSURLCache properly: setSharedURLCache: now retains the cache object and stores it in Foundation state singleton. sharedURLCache returns the stored cache (creates a default empty one if none set). Removed all 'stubbed' log spam. - Fix video playback performSelectorOnMainThread: now forwards play/startMovie:/stopMovie: selectors to the receiver instead of silently dropping them. MPMoviePlayerController's play/stop methods post MPMoviePlayerPlaybackDidFinishNotification so apps correctly transition from intro video to main menu.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
feat: implement Accelerate/vDSP, fix audio/media/archiver errors
…ple docs - UIFont: Add fontName and familyName property getters - NSMutableArray: Add sortUsingDescriptors: method + NSArray sortedArrayUsingDescriptors: - UIViewController: Replace todo_objc_setter with real editing state storage + isEditing getter - UIApplication: Replace todo_objc_setter with real statusBarStyle storage + getter - UIButton: Fix setTitleShadowOffset: parameter type (CGSize) and accept silently - UIActivityIndicatorView: Store style in host object + add getter - UIApplication: Handle orientation 0 (UIDeviceOrientationUnknown) gracefully - sscanf: Handle 'l' length modifier for %ld/%li/%lx/%lu (32-bit long on ARM) - MPMoviePlayerController: Remove misleading TODO logs, replace stubs with proper no-ops - CFRunLoopStop: Implement real stop flag checked by run loop iteration - CGImageCreate: Full implementation supporting RGBA/RGBX/grayscale pixel data - NSHost: New class with currentHost, name, address, names, addresses methods Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Fix 12 errors from log files — real implementations per Apple docs
…ocking
Replaces three stubbed/incorrect host-side implementations with real ones
per Apple's documentation. All three were called by Minecraft PE 0.10.x and
turned up either as 'return-0' dyld stubs or as 'TODO: locking ignored' log
lines in user logs.
1) src/libc/unistd.rs: implement rmdir(2). Previously the symbol was not
exported, so dyld installed a return-0 stub. The new function follows
Apple man rmdir(2): checks the path exists, refuses non-directories with
ENOTDIR, and translates Fs::remove errors (DirectoryNotEmpty -> ENOTEMPTY,
etc.) to the documented errno values. Also tightens unlink(2) to reject
directories with EPERM as Darwin specifies, and to translate Fs::remove
errors instead of generically returning -1.
2) src/gles/gles2_native.rs + src/frameworks/opengles/gles_guest.rs:
delegate glGetShaderPrecisionFormat and glShaderBinary to the native
GLES 2.0 driver, and add the missing guest export for
glGetShaderPrecisionFormat. Previously the symbol fell through to the
generic 'GetShaderPrecisionFormat ... [stubbed]' implementation and dyld
installed a return-0 stub, breaking shader-precision probes done by
Minecraft PE before linking.
3) src/libc/posix_io.rs: replace the three 'TODO: locking ignored' lines for
fcntl F_SETLK / F_SETLKW / F_GETLK and the 'TODO: flock' stub with real
advisory locking. Locks are stored as byte ranges on each
PosixFileHostObject (LockRange { start, end, lock_type }). New requests
are checked for conflicts against locks held by *other* fds on the same
guest path (POSIX advisory locks are per-process; HyperHLE is single
process). flock(2) is implemented in terms of a whole-file lock entry on
the descriptor. F_GETLK now reports the actual conflicting lock with
start/len/whence/pid set per Apple man fcntl(2), and locks are released
automatically on close(2) (the PosixFileHostObject is dropped).
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Advisory locks under POSIX are owned by the *process*, not the file descriptor (Apple 'man 2 fcntl', section 'File Locking', and POSIX.1 3.4.2). Locks held by the same process never conflict with each other. The previous commit treated two fds opened by the guest on the same path as separate lock holders and rejected overlapping requests with EAGAIN, which can break apps (notably ones that use LevelDB-style 'LOCK' files or open the same world database from multiple threads via separate file descriptors). This commit makes fcntl(F_SETLK/F_SETLKW) and flock(2) match real POSIX semantics for a single-process emulator: - F_SETLK / F_SETLKW: validate the flock struct, record the byte-range lock on the fd for diagnostics, and return success. No same-process conflict checks (POSIX never conflicts within a process). F_UNLCK correctly releases overlapping sub-ranges. - F_GETLK: validate the request, then always report F_UNLCK \u2014 there is no other process to contend for the lock. - flock(2): identical reasoning; track the whole-file lock state but never reject a same-process request. stdio remove(3) now logs the actual guest path and FsError instead of an opaque pointer, and translates errors to POSIX errno values per Apple 'man 3 remove' / 'man 2 unlink' / 'man 2 rmdir' (DirectoryNotEmpty -> ENOTEMPTY, DoesNotExist -> ENOENT, AccessDenied -> EACCES, etc.). This makes the existing 'remove(0x303a3f30) failed' log line actionable on the next iteration. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Real impls: rmdir, glGetShaderPrecisionFormat, advisory file locking, remove(3) diagnostics
…re, MPMediaItemProperty* - mem.rs: replace double-unwrap in wcstr_at with chunks_exact + U+FFFD replacement so invalid UTF-32 (e.g. surrogate halves, >U+10FFFF) no longer panics the host. Previous code panicked Vatican.ipa on startup. - libsqlite3.rs: add sqlite3_prepare (legacy V1) per Apple/SQLite docs as a thin wrapper around sqlite3_prepare_v2; HitNRun.ipa links against the deprecated symbol. - core_graphics/cg_pattern.rs (new): real CGPattern CFType backed by a touchHLE class. CGPatternCreate stores bounds/matrix/step/tiling/ callbacks/info; CGPatternRetain/Release participate in normal CF refcounting; the releaseInfo callback is invoked on dealloc as documented in CGPattern.h. Wired into the CoreGraphics dylib. - media_player/music_player.rs: export the full set of MPMediaItemProperty* / MPMusicPlayerControllerVolumeDidChange* constants from Apple's MPMediaItem.h so non-lazy symbol fixups for e.g. _MPMediaItemPropertyTitle succeed. - cf_http_message.rs (new) + cf_network wiring: real CFHTTPMessage implementation. Stores method/URL/version/headers/body, parses on-the-wire bytes appended via CFHTTPMessageAppendBytes, and produces a properly framed RFC 7230 byte buffer from CFHTTPMessageCopySerializedMessage. Retain/Release are real CFType ops; ASIHTTPRequest no longer hits unimplemented_function on CFHTTPMessageCreateRequest. - ns_object.rs: add explicit +initialize no-op on NSObject so '[super initialize]' chains (e.g. ASIHTTPRequest) stop hitting the superclass-does-not-respond warning. - libc/mach/message.rs: stop busy-looping in mach_msg. Now honours MACH_RCV_TIMEOUT and sleeps the requested duration (capped at 5s) per <mach/message.h>; Mono's exception thread no longer pegs a CPU core. - libc/mach/arm/task.rs: demote task_set_exception_ports stub from log! to log_dbg! and document why a no-op return is correct on a single-process emulator with no Mach port delivery. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ch_msg busy-loop Fix log-derived crashes: wcstr_at panic,
audio_toolbox/media_player: real implementations replacing logged TODO stubs
Closes the gap from PR #107 with a complete, real CATransform3D
implementation and the supporting plumbing it needs.
- src/matrix.rs: add Matrix<4>::determinant and Matrix<4>::inverse
(MESA-style cofactor formula) plus unit tests.
- src/frameworks/core_animation/ca_transform3d.rs: rewrite the module.
Provides the complete C API documented in <QuartzCore/CATransform3D.h>
(CATransform3DIsIdentity / EqualToTransform / Make{Translation,Scale,
Rotation} / Translate / Scale / Rotate / Concat / Invert /
MakeAffineTransform / IsAffine / GetAffineTransform), uses
Matrix<4>::inverse for CATransform3DInvert, and ships unit tests
covering the documented semantics (translate-then-scale, Apple's
CATransform3DTranslate = translate*t convention, singular fallback,
affine round-trips).
- src/frameworks/core_animation/ca_layer.rs: route the local affine
bridge through the new CATransform3D::from_affine/to_affine; add
-[CALayer sublayerTransform] / -setSublayerTransform: so the property
round-trips like Apple's.
- src/frameworks/foundation/ns_value.rs: add the QuartzCore category
+valueWithCATransform3D: / -CATransform3DValue plus matching isEqual:
and -description handling so apps can box transforms in NSValue.
core_animation: full CATransform3D implementation
Replace the previous custom XML parser stub of libxml2.2.dylib with a full host shim that delegates to the real GNOME libxml2 (v2.12.10) compiled statically from a new vendored submodule. New components: - vendor/libxml2: GNOME libxml2 source tree as a git submodule. - src/frameworks/libxml2_wrapper/: new Rust crate that builds libxml2 via CMake, exposes a raw FFI surface, and a small C shim for safe struct access and quiet error handlers. - src/frameworks/libxml2.rs: rewritten host shim. Provides handle-based identity for opaque libxml2 objects, copies xmlChar * results into guest memory, and dispatches parser/tree/reader/writer/XPath/HTML/URI entry points to the real library. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
clang (used by macOS CI) rejects passing a 'void(void*, void*)' to a parameter typed 'void(*)(void*, const xmlError*)'. Change the no-op structured error handler signature to match xmlStructuredErrorFunc. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The Android Gradle build uses --no-default-features, so the new touchHLE_libxml2_wrapper crate falls back to /usr/include/libxml2 on the runner instead of building the vendored sources. Add the static feature explicitly so cargo-ndk builds libxml2 from vendor/libxml2 like the desktop targets. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Fix crashes and implement missing runtime APIs found in logs
- bundle: don't panic on non-string MinimumOSVersion (number/real); return Option<String>
- font: make Font::from_vec fallible; CGFontCreateWithDataProvider returns NULL on bad data (per Apple docs)
- NSPropertyListSerialization: implement +propertyListWithData:options:format:error: (iOS 4.0+) with real NSError
- objc runtime: implement objc_alloc and objc_autorelease (libobjc ARC fast paths) and export them
* objc: implement missing objc_retainBlock (fixes pre-existing trunk build break)
objc_retainBlock was imported and exported in src/objc.rs but never
defined, so the crate failed to compile (E0432). Per Apple's objc4
runtime, objc_retainBlock(x) wraps _Block_copy(x); mirror touchHLE's
_Block_copy behaviour (returns the same pointer).
* Implement more documented runtime stubs from logs (real, per Apple docs)
- GCD: real dispatch_queue_set_specific / dispatch_queue_get_specific /
dispatch_get_specific backed by a (queue,key)->value store + current-queue
tracking (was: call to unimplemented _dispatch_queue_set_specific)
- objc: objc_unsafeClaimAutoreleasedReturnValue ARC fast path (was: return-0 stub)
- UIViewController: real extendedLayoutIncludesOpaqueBars property + setter
(was: 'does not respond to selector setExtendedLayoutIncludesOpaqueBars:')
* Implement remaining documented runtime stubs (real, per Apple docs)
- Foundation: real NSIndexSet class (indexSetWithIndexesInRange:, indexSetWithIndex:,
count, containsIndex:, firstIndex/lastIndex, indexGreater/LessThanIndex:, equality,
copy) — was 'Class NSIndexSet is unimplemented'
- CoreText: CTFontManagerRegisterGraphicsFont(font, error) — was return-0 stub
- CoreFoundation: CFErrorCopyDescription forwards to NSError -localizedDescription
(toll-free bridged) — was return-0 stub
* Fix two guest-triggered hard crashes (GameStop, Reckless Getaway)
- objc/classes.rs: a class and its metaclass always share the same name in
Apple's runtime (class_getName). The previous code only harmonized the two
names when one was a synthetic placeholder for an unreadable name, and
asserted otherwise — which aborted the whole VM for GameStop_iOS, whose
class/metaclass names were both readable yet mismatched. Make harmonization
unconditional (class side canonical) and drop the assert.
- foundation/ns_string.rs: NSMutableString -setString:nil and -appendFormat:nil
asserted on nil and crashed the emulator (e.g. Reckless Getaway hit
'assertion left != right'). Apple raises NSInvalidArgumentException but never
aborts the process; log a warning and no-op instead, matching the lenient
handling already used for the other NSMutableString implementation.
* Foundation: add missing framework constants and real NSSet member:/setWithObjects:count:
- Register ~55 previously-unhandled host constants in foundation STUB_CONSTANTS
with documented Apple values: UIKeyInput* arrows/Escape, kCAAlignment*,
AVAudioTimePitchAlgorithm*, kCMFormatDescriptionExtension_Depth, CVPixelBuffer
pool keys, VTDecompression keys, kCTFontPostScriptNameKey, kCGPDFContext*,
GKSessionErrorDomain, PKPaymentNetwork*, MKLaunchOptions*, MKMapRectNull,
UIActivityTypePostToTencentWeibo, NSExtensionHost*/UIScene* notifications,
NSMetadata/NSURL ubiquitous-item keys, MPNowPlayingInfoProperty*, AVMetadata*,
kCGColorSpaceExtended(Linear)SRGB, AVCaptureExposureDurationCurrent (CMTime
invalid), AVCaptureISOCurrent (-1.0f), and __NSArray0__/__NSDictionary0__
empty-collection singletons backed by real retained objects.
- NSSet/NSMutableSet: implement -member: (real isEqual: lookup per Apple docs),
+setWithObjects:count: and -initWithObjects:count: (C-array initialisers),
mirroring the existing NSArray implementations.
* dyld constants: fix leading-underscore symbol keys + add CAEmitterLayer/UITableViewIndexSearch/AVEncoder constants
Constant export keys are matched against raw Mach-O symbol names, which
carry a leading underscore (e.g. _matrix_identity_float4x4). Many entries
in foundation/avfoundation STUB_CONSTANTS were written without it and so
never resolved (logs still showed them as unhandled). Prefix all such keys
with '_', fix ___NSArray0__/___NSDictionary0__ (triple underscore), and add
CAEmitterLayer shape/render-mode keys, UITableViewIndexSearch and
AVEncoderBitRatePerChannelKey.
* feat: Replace stubs with real implementations in AudioFile and socket ioctl
- AudioFileCreateWithURL: Real implementation creating virtual writable
audio files in memory instead of returning kAudioFileOperationNotSupportedError.
Apps that record/cache audio can now create files, write PCM data, and
read it back.
- AudioFileInitializeWithCallbacks: Real implementation matching
AudioFileCreateWithURL behavior for callback-based file creation.
- AudioFileWriteBytes: Now actually stores written bytes in the Writable
file's memory buffer instead of silently discarding them.
- AudioFileWritePackets: Now actually stores written packet data in memory
with correct offset calculation for CBR formats.
- AudioFileGetProperty: Full support for Writable variant including
DataFormat, ByteCount, PacketCount, Duration, PacketTableInfo.
- AudioFileReadBytes/ReadPackets: Full support for reading back data from
Writable files.
- AudioFile UserData API (Count/GetSize/GetSize64/Get/GetAtOffset/Set/Remove):
Complete real implementation using in-memory storage. Previously all
functions were stubbed returning kAudioFileUnsupportedPropertyError.
- ioctl() for sockets: Implement FIONBIO (set non-blocking mode) and
FIONREAD (bytes available) instead of returning -1 for all requests.
Unknown ioctl requests now return 0 (success) instead of -1 to prevent
apps from crashing on unsupported requests.
All changes follow Apple's Audio File Services Reference documentation
and POSIX ioctl(2) semantics.
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* fix: Resolve all compilation errors and fix CI workflow
- Fix E0793 (packed field references): Copy packed struct fields to local
variables before passing to format macros in AudioFileCreateWithURL and
AudioFileInitializeWithCallbacks.
- Fix E0004 (non-exhaustive patterns): Add Writable variant handling in:
* av_audio_player.rs: setCurrentTime and duration calculations
* ext_audio_file.rs: WrapAudioFileID clone, FileLengthFrames,
format extraction, read logic, and build_asbd helper
- Fix CI workflow (.github/workflows/touchHLE_release.yml):
Replace broken manual git clone of non-existent 'j92580498-max/touchHLE'
with standard actions/checkout@v4 + submodules:true for all 3 build jobs
(macOS, Android, Windows). The old workflow was cloning a repo that
doesn't exist, causing every CI run to fail immediately.
* fix: Point CI workflow to correct repo j92580498-max/HyperHLE-Dev-test
All 3 build jobs (macOS, Android, Windows) now clone from
https://github.com/j92580498-max/HyperHLE-Dev-test instead of the
non-existent j92580498-max/touchHLE.
* ci: trigger workflow run
* Fix app compatibility: NSRegularExpression captures, CFRunLoop modes, GKAchievement
- Add NSTextCheckingResult class with range/rangeAtIndex:/numberOfRanges
- Extend NSRegularExpression with firstMatchInString:options:range:,
matchesInString:options:range:, stringByReplacingMatchesInString:,
pattern, and numberOfCaptureGroups methods
- Fix CFRunLoopRunInMode to accept all non-nil run loop modes instead of
only kCFRunLoopDefaultMode/kCFRunLoopCommonModes (fixes Astro Shark
and other Unity games flooding log with 'unknown mode, skipping')
- Add GKAchievement stub class with resetAchievementsWithCompletionHandler:,
loadAchievementsWithCompletionHandler:, reportAchievements:withCompletionHandler:,
and instance methods (fixes Astro Shark 'unimplemented' error)
Apps affected: Doodle Egg, 3D Brick 2, Astro Shark HD
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* Fix gk_achievement: move class methods before instance methods
The objc_classes! macro requires all class methods (+) to precede
instance methods (-). Moving loadAchievementsWithCompletionHandler:,
resetAchievementsWithCompletionHandler:, and
reportAchievements:withCompletionHandler: to the top fixes the
'no rules expected +' compilation error.
* Fix borrow checker errors in NSRegularExpression
Clone regex before calling env-mutating functions (from_ranges,
from_rust_string, retain, etc.) to avoid holding an immutable borrow
on env.objc while needing &mut env. This fixes E0502 errors.
* Fix remaining compile errors: NSRange move and Copy issues
- Save range.location before passing range by value to
utf16_range_to_utf8_byte_range (fixes E0382: use after move)
- Replace pattern-matching &r with field access on NSRange references
in NSTextCheckingResult (fixes E0507: cannot move out of shared ref)
* Fix multiple app compatibility bugs
1. dlopen: Add libc.dylib/libc.so/libc.bundle aliases to libSystem DYLIB
- Unity/Mono games probe for libc under various names via dlopen()
- Without aliases, dlopen returned NULL causing PInvoke failures
- Fixes: CM SWAT (csportable), Coyote Boom, other Unity games
2. GLSL shaders: Fix compilation on native ES 2.0 drivers
- Hoist #extension directives before non-preprocessor tokens (Mali requirement)
- When GL_EXT_shader_texture_lod unsupported, strip extension directive
and replace texture2DLodEXT/textureCubeLodEXT with texture2D/textureCube
- Desktop GLSL translator: replace EXT calls with built-in equivalents
- Fixes: CM SWAT shader compile errors on Mali-G57
3. objc: Export _objc_msgForward and _objc_msgForward_stret
- Provides stub implementations that return nil/no-op
- Resolves unhandled external relocation warnings
- Fixes: Cut the Rope HD linker warning at 0x325308
4. GameKit: Ensure GK callbacks execute in main-thread context
- authenticateWithCompletionHandler: and setAuthenticateHandler: now
temporarily set current_thread=0 during block invocation
- Matches Apple docs: 'completion handler is called on the main thread'
- Fixes: Dalton assertion failure in GameCenterManager
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* Fix three emulator bugs: UIImageWriteToSavedPhotosAlbum, NSKeyedArchiver, UITextView
- Implement UIImageWriteToSavedPhotosAlbum: saves image as PNG to the
app's Documents directory and invokes the completion callback with nil
error. Previously this was a dyld return-0 stub causing apps like
Dismount to silently fail photo saves.
- Fix NSKeyedArchiver encode-after-finishEncoding false positive: the
previous check used 'encoded_data != nil' to detect finished state,
but initForWritingWithMutableData: also sets encoded_data before
encoding begins. Added a dedicated 'finished' bool field that is only
set to true after finishEncoding completes. This fixes spurious
warnings in DoodleJump and other apps using the mutable-data path.
- Add setSecureTextEntry:/isSecureTextEntry to UITextView: implements
the UITextInputTraits protocol property that Dragooo (Unity) calls on
UITextView. Stores the value for round-trip fidelity per Apple docs.
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* Fix critical bugs from crash logs of multiple iOS apps
- NSLock: Replace .unwrap() with graceful error handling in unlock/dealloc
to prevent panic on error 16 (EBUSY) during app shutdown (EnbornX)
- NSCalendar: Implement components:fromDate:toDate:options: selector with
full Gregorian date differencing logic. Expand components:fromDate: to
support year/month/hour/minute/second unit flags (EnbornX)
- Accelerate: Implement cblas_saxpy, cblas_snrm2, cblas_sscal, cblas_sdot,
cblas_scopy, cblas_sgemv, vDSP_dotpr, vDSP_vsdiv, vDSP_vsub, vDSP_vmax,
vDSP_vmin, vDSP_sve, vDSP_normalize, vDSP_vabs, vDSP_vneg, vDSP_vsadd,
vDSP_vma with real math implementations per Apple docs (EnbornX)
- CFString: Implement CFStringGetFileSystemRepresentation (UTF-8 encoding)
per Apple docs (Enigmo 2)
- libc/string: Implement __strncat_chk fortified variant (Flappy Bird)
- libc/stdlib: Add inflateReset2 host export for apps built against newer
zlib SDK than bundled libz.1.2.3 (Flappy Bird)
- libc/dispatch: Add dispatch_debug no-op export (Frontline Commando 2)
- dyld: Handle _objc_msgSendSuper/_objc_msgSendSuper_stret external
relocations by linking to existing Super2 implementations. Handle C++
typeinfo symbols (__ZTId, __ZTIf, __ZTIPKc, etc.) with proper type_info
struct allocation (FlyCraft, GameStop)
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* Fix E0107: use type inference instead of explicit generic for mem.read
The project's Mem::read method takes 2 generic arguments (T, MUT).
Using read::<f32>() only supplied 1, causing compilation failure.
Fixed by using 'let val: f32 = env.mem.read(...)' pattern consistent
with the rest of the codebase.
* Implement missing iOS APIs: CGDataProviderCreateSequential, CFString BOM handling, NSString propertyListFromStringsFileFormat, CLLocation init
- CGDataProviderCreateSequential: Read all data via getBytes callback into
guest memory buffer instead of returning null. Fixes image loading in
apps that use sequential data providers (e.g. The Simpsons Arcade).
- CFStringCreateWithBytes is_external=true: Properly detect and strip BOM
(Byte Order Mark) for UTF-16, UTF-32, and UTF-8 encodings, selecting the
correct byte order. Eliminates hundreds of warning log messages per app.
- NSString propertyListFromStringsFileFormat: Full implementation that parses
Apple .strings file format (quoted key=value pairs with C-style comments,
escape sequences including \Uxxxx unicode). Returns NSDictionary. Fixes
iATC and other apps that load localization files.
- CLLocation initWithCoordinate:altitude:horizontalAccuracy:verticalAccuracy:
timestamp: Add CLLocationCoordinate2D struct with GuestArg impl and the
full Apple initializer. Fixes iATC and other apps using CoreLocation.
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* fix: improve iOS app compatibility (NSURLRequest, fcntl, nil isa, null-page)
- NSURLRequest: Remove incorrect network_access check from initWithURL:
NSURLRequest is a pure value object per Apple docs and must always succeed.
The network failure should only occur at the NSURLConnection level.
This fixes cascading nil objects that caused massive nil-isa warnings.
- NSURLConnection: Schedule delegate failure callbacks via
performSelector:withObject:afterDelay: instead of silently dropping.
This properly notifies the app of network failure on the next run-loop
iteration, matching real iOS behavior.
- fcntl F_SETFD: Downgrade FD_CLOEXEC log from log!() to log_dbg!().
CLOEXEC is a no-op in a single-process emulator (no exec() calls)
but the flag is properly stored and retrievable via F_GETFD.
- fcntl F_DUPFD/F_DUPFD_CLOEXEC: Implement proper file descriptor
duplication using GuestFile::try_clone(). Adds Clone support to
IpaFile and a try_clone() method to GuestFile.
- NULL-page reads: Improve log messages to identify small-offset reads
as likely nil ObjC object field accesses (defined behavior in ObjC).
- nil isa warnings: Add rate-limiting (max 8 logged) to prevent log
flooding from guest use-after-free bugs. Improve message to explain
the root cause.
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* fix: multi-app compatibility improvements
- Implement CTParagraphStyleCreate/CreateCopy/GetValueForSpecifier in
CoreText framework (fixes Monkey Math - Jetpack Adventure crash)
- Add NSAttributeDescription, NSPropertyDescription, and
NSRelationshipDescription classes for Core Data support (fixes MX
Meltdown/Unity apps using Core Data)
- Export glDrawTexsOES/glDrawTexsvOES in OpenGL ES guest layer (fixes
OMH! unresolved symbol '_glDrawTexsOES'/'_glDrawTexsvOES')
- Implement setEdgesForExtendedLayout/edgesForExtendedLayout on
UIViewController (fixes Mayday 'does not respond to selector' warning)
- CFStreamCreatePairWithSocketToHost/ToCFHost now return valid stub
stream objects instead of nil (fixes OMH! 'SUPER HACK! Faking
borrow_mut for CFReadStreamHostObject' warnings)
- UIView addGestureRecognizer uses ObjC msg_send for setView: instead
of direct host-object cast (fixes Monkey Math gesture recognizer
borrow_mut warnings with subclass host objects)
- Path deduplication in resolve_path() for apps that concatenate the
Documents directory path twice (fixes OMH!/Triniti engine
NonexistentParentDir errors)
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* fix: multiple game compatibility improvements
- NSURLConnection: fake successful 200 OK responses instead of
NSURLErrorNotConnectedToInternet, allowing games like Sonic Runners
and The Simpsons to pass network checks
- NSHTTPURLResponse: full implementation with statusCode, headers,
initWithURL:statusCode:HTTPVersion:headerFields:
- environment.rs: replace hard assert!() in run_inner with graceful
early return to fix Pocket Army crash on re-entrant run loop
- MPMoviePlayerViewController: add moviePlayer property accessor,
fixing Rafter HD's movie playback initialization
- UIRuntimeOutletCollectionConnection: implement IBOutletCollection
NIB loading, fixing RacePenguin's UI initialization
- NSDictionary: add addEntriesFromDictionary: and setObject:forKey:
to immutable base class for compatibility with apps like Rigonauts
that incorrectly mutate immutable dictionaries
- AudioQueue: support 32-bit float PCM (kAudioFormatFlagIsFloat),
adding float-to-int16 conversion for Sonic Runners/Unity games
using 32kHz 2-channel float audio
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* fix: NSURLConnection returns network error instead of fake 200 OK
Sonic Runners crashes with NULL-PAGE READ when receiving a fake empty
JSON response '{}' because it tries to parse specific server-protocol
fields that don't exist in our stub response.
All tested games handle NSURLErrorNotConnectedToInternet (-1009) gracefully:
- Sonic Runners: shows error dialog, allows retry, render loop continues
- The Simpsons: shows 'Connection error' warning, gameplay continues
- Safe Cracker / Sky Dancer: proceed past network init
Returning an error is always the safe path. Faking server responses
would require implementing each game's full server protocol.
* feat(audio): add G.711 µ-law and A-law decoding to CAF decoder
Implement ITU-T G.711 µ-law (ulaw) and A-law (alaw) codec support in
the CAF audio file decoder. This fixes audio playback for games that
ship their sound effects as CAF files with µ-law compression (format_id
'ulaw'), which is common in iOS games like SSG2, Space Roadkill, and
many others.
Previously these files would fail with:
'format_id is not LPCM or IMA4 — leaving for Symphonia'
and Symphonia would also reject them with:
'DecodeError("pcm: unexpected bits per sample")'
The new implementation:
- Adds FormatType::Ulaw match arm with full G.711 µ-law → 16-bit PCM
decoding per ITU-T Rec. G.711 (11/88)
- Adds FormatType::Alaw match arm with full G.711 A-law → 16-bit PCM
decoding per ITU-T Rec. G.711 (11/88)
- Both produce 16-bit little-endian interleaved PCM matching the
SymphoniaDecodedToPcm output format used by the rest of the pipeline
References:
- Apple Core Audio Format Specification 1.0 (format IDs 'ulaw'/'alaw')
- ITU-T Recommendation G.711 (11/88)
- Sun Microsystems public domain G.711 reference implementation
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
* Delete .github/workflows/touchHLE_release.yml
* Add GitHub Actions workflow for touchHLE builds
This workflow builds the touchHLE project for macOS, Android, and Windows, handling dependencies and caching for efficient builds.
* Fix duplicate exports after HyperHLE merge
Remove duplicate dyld exports introduced when merging HyperHLE trunk
constants and methods that already existed in Hypertle submodule files.
Keeps canonical definitions in the more specific modules (ns_url,
ui_application, cf_error, ca_animation, etc.).
---------
Co-authored-by: j92580498-max <j92580498@gmail.com>
Co-authored-by: busik007 <busik0877@gmail.com>
Co-authored-by: busik007 <busik0877@users.noreply.github.com>
Co-authored-by: Kiro Agent <244629292+kiro-agent@users.noreply.github.com>
Co-authored-by: j92580498-max <252151737+j92580498-max@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Port upstream touchHLE/touchHLE trunk changes from the last 50 commits, merging into Hypertle's extended codebase where paths diverged: - Bump symphonia from 0.6.0-alpha.1 to 0.6.0 (bea3eaed) - Implement CGContextSetTextMatrix with text-transform glyph rendering and integration tests 6-8 (fe4d19bf) - Mirror's Edge audio hack for kAudioFilePropertyFileFormat (4213cb3e) - class_getProperty(UIScreen, scale) returns NULL for EA games (3cc4b133) Conflict resolution keeps Hypertle-specific behavior: - Extended CGContextHostObject (shadows, paths, state stack) unchanged - Font Option wrapper and raw_data for CGFont metrics preserved - MessageUI dylib stub kept; MFMailComposeViewController stays in MediaPlayer - Hypertle symphonia_formats CAF decoding and logging retained Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Port changes from touchHLE/touchHLE trunk commits: - 4a950ccf: Add AIFF audio type hint handling in AudioFileOpenURL - ea1d0347: Account for nil first object in NSArray arrayWithObjects: Skipped 98de7d8a (NSTimeZone -abbreviation stub) because Hypertle already implements abbreviation lookup via ZONE_TABLE. Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…ng (#24) * Recover the app delegate when UIApplicationMain gets no usable delegate class Some apps (e.g. "The Steak" / Charlie the Steak) reach UIApplicationMain without a usable delegate class name: the argument is nil, or it was built from a class reference that resolved to nil (NSStringFromClass returns nil, which decodes to the empty string). With no main-nib connection setting the delegate either, the application was left with a nil delegate, so application:didFinishLaunchingWithOptions: was never delivered and the app stayed frozen on its launch image. Add a fallback: when the normal delegate resolution yields nothing, discover the app's delegate class by scanning the loaded classes for one that declares a UIApplicationDelegate launch method, and instantiate that. This only runs when the app would otherwise have no delegate at all, so it cannot affect apps that launch correctly today. - objc: add ObjC::class_declaring_instance_method, which finds a registered class declaring a given instance method, skipping substituted/placeholder classes and metaclasses. Selection is deterministic and prefers app-delegate-like names so an unrelated class cannot shadow the real one. - UIApplicationMain: resolve the delegate from the explicit class name when usable (now via try_get_known_class, so an unknown name falls through to discovery instead of installing a broken placeholder), otherwise fall back to the discovered delegate class; log clearly when none can be determined. Also drop the leftover DIAG_CALLER debug prints. https://claude.ai/code/session_01FQFBWFcV8FV2YgLJnE73gJ * Fix headless-mode panic when an app queries preferred languages/region `get_preferred_language_codes` / `get_preferred_country_codes` route through `Environment::on_parent_stack_in_coroutine`, which unwraps `self.window`. That window is absent in headless mode, so an app that calls `[NSLocale preferredLanguages]` (a very common thing to do during launch) panicked with an `Option::unwrap()` on `None`, even though the closures here do not actually use the window. Short-circuit both helpers when there is no window and report no preference, which the caller already handles by falling back to English. The windowed path is unchanged. * NSCalendar: implement +autoupdatingCurrentCalendar Apps commonly call `[NSCalendar autoupdatingCurrentCalendar]` during launch (e.g. for date math). It was unimplemented, so the runtime returned nil and the app then did calendar/date work against a nil object. Apple's autoupdating calendar only differs from `currentCalendar` in that it tracks later changes to the user's settings, which touchHLE has none of, so forward to `currentCalendar`. * Don't panic in the main run loop when running headless Once an app fully finishes launching it enters the main NSRunLoop, which unconditionally calls `uikit::handle_events` and `core_animation::recomposite_if_necessary`. Both reach for the window, which is absent in headless mode, so they panicked with "Tried to do something that needs a window..." (the stale comment in `handle_events` even claimed it was never called headless). Guard both: with no window there are no input events to drain and nothing to composite, so return immediately. This makes headless mode able to run an app past launch (useful for automated testing); windowed behaviour is unchanged. * UINavigationBar: make it a real UIView subclass `UINavigationBar` is declared `: UIView`, but `UINavigationBarHostObject` was a plain `HostObject` with no embedded `UIViewHostObject`. As a result every `UIView` message sent to a nav bar (frame, subviews, layout, hidden, ...) failed to borrow the view host object and silently fell back to a zeroed phantom, so the nav bar had no real view state. Observed with "The Steak", whose launch path touches a nav bar during third-party SDK setup. Embed the superclass host object via `impl_HostObject_with_superclass!`, initialize it in `+allocWithZone:`, and chain `-init`/`-initWithFrame:`/ `-initWithCoder:` to `super` so the backing layer and view state are set up like any other UIView subclass. Also make the wrong-type `borrow` fallback report the object's actual host type, which is what made this mismatch diagnosable in the first place. --------- Co-authored-by: Claude <noreply@anthropic.com>
touchHLE renders UIAlertView as a *blocking* SDL2 system dialog, whereas real iOS -[UIAlertView show] is asynchronous and returns immediately. Outfit7 titles such as Talking Angela create a UIAlertView with an empty (or nil) title *and* message as a transient placeholder and dismiss it programmatically once background work finishes. Presenting a blocking modal for such an alert froze the app behind an empty dialog box that the user could never meaningfully act on. When both title and message are empty, skip the native dialog and dismiss the alert asynchronously (delivering any delegate callbacks) so the guest run loop keeps going. Content-bearing alerts still show the SDL2 dialog as before. Verified by running the Talking Angela IPA: previously the app dead-ended at the empty UIAlertView; it now skips both empty alerts and proceeds to load the ChatScript engine and run the game loop. https://claude.ai/code/session_01TpoV3dfiQLfQwPwbxnvDX2 Co-authored-by: Claude <noreply@anthropic.com>
Text containing Arabic characters previously rendered as tofu boxes because none of the bundled Latin or Noto Sans CJK fonts contain Arabic glyphs. This adds Noto Sans Arabic (regular + bold, SIL OFL) as a fallback and extends UIFont's script detection to route Arabic text to it, mirroring the existing CJK fallback. - Bundle NotoSansArabic-Regular.ttf and NotoSansArabic-Bold.ttf - Add Font::sans_regular_ar() / sans_bold_ar() loaders - Refactor get_font() with is_cjk_char()/is_arabic_char() helpers covering Arabic, Arabic Supplement, Arabic Extended-A and Arabic Presentation Forms-A/B blocks - Document the new fonts in the fonts README and license notice Co-authored-by: Claude <noreply@anthropic.com>
Text containing Arabic was laid out by rusttype in logical order, left-to-right, with no contextual shaping. That made Arabic words appear reversed and made each letter render in its isolated, disconnected form. Add a self-contained shaping/reordering pass that runs on each line just before it is handed to rusttype: - Contextual joining: map Arabic letters to their Unicode presentation forms (isolated/initial/medial/final), including mandatory lam-alef ligatures. The bundled Noto Sans Arabic font maps these forms in its cmap, so no GSUB support is required. - Bidirectional reordering: a simplified UAX #9 pass reverses RTL runs into visual order while keeping Latin/number runs and combining marks correctly placed. The transform is applied at the two rusttype layout call sites in font.rs (width measurement and drawing) so measured and drawn widths stay consistent. Non-Arabic lines are returned untouched and borrowed, so existing behaviour is unchanged. No new dependencies are added. Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
…ules (#29) ns_log and ns_objc_runtime only export C functions (NSLog/NSLogv and the NSStringFrom*/NSClassFromString family) and define no Objective-C classes, so they have no CLASSES const. The CLASSES aggregation list erroneously referenced ns_log::CLASSES and ns_objc_runtime::CLASSES, causing two E0425 'cannot find value CLASSES' errors. Their FUNCTIONS are already correctly registered in the FUNCTIONS list. Co-authored-by: Claude <noreply@anthropic.com>
…c I/O (#158) * Implement POSIX aio family to fix apps that stream resources via async I/O aio_read/aio_error/aio_return (plus aio_write/suspend/cancel/fsync) were previously missing, so dyld installed return-0 stubs. Apps that load their resource files through POSIX async I/O (e.g. Plants vs. Zombies HD) therefore saw every request report success with zero bytes transferred, leaving the destination buffers empty. That produced a black screen followed by an early crash (an empty buffer led to a bogus malloc((size_t)-1)). These are now implemented synchronously, reusing the regular positional pread/pwrite paths and stashing each result keyed by the guest struct aiocb pointer so aio_error/aio_return report the real completion status. The aiocb prefix is modelled as #[repr(C, packed)] to match the iOS armv7 ABI, where off_t is only 4-byte aligned (fildes 0, offset 4, buf 12, nbytes 16). Verified by running the PvZ HD IPA under HyperHLE: the app no longer crashes, aio now reads real data (incl. the ~1.4 MB resource pack), all 204 'Failed to load particle' errors are gone, and the render loop stays alive past frame 60. * aio: warn when an app requests unsupported completion notification The synchronous aio implementation handles SIGEV_NONE (poll via aio_error/aio_return) perfectly, but does not yet deliver SIGEV_SIGNAL or SIGEV_THREAD completion callbacks. Read the aiocb's sigev_notify and log a warning in that case so a future app relying on async notification produces a diagnosable message instead of silently blocking. (PvZ HD uses SIGEV_NONE, so this is purely defensive.) --------- Co-authored-by: Claude <noreply@anthropic.com>
* Add workflow to download and run an IPA via touchHLE * Run downloaded IPA on Linux, Windows and macOS --------- Co-authored-by: Claude <noreply@anthropic.com>
* Add CI workflow for testing iOS apps under touchHLE (#30) * Add workflow to download and run an IPA via touchHLE * Run downloaded IPA on Linux, Windows and macOS --------- Co-authored-by: Claude <noreply@anthropic.com> * CI: provide software OpenGL on Windows so apps can launch (#31) The 'Download and run IPA' workflow aborted on the Windows runner with 'Couldn't create OpenGL ES 1.1 context!'. Windows GitHub Actions runners only expose Microsoft's GDI generic OpenGL 1.1, which cannot satisfy the OpenGL 2.1 context that touchHLE's GLES1-on-GL2 fallback requires, so both the native GLES path and the GL2 fallback fail and the emulator panics before the app ever runs. Drop Mesa3D's llvmpipe software renderer (a per-app opengl32.dll plus its dependencies) next to touchHLE.exe and force GALLIUM_DRIVER=llvmpipe so a complete OpenGL implementation is available without a GPU. Linux already gets llvmpipe via libgl1-mesa-dri and macOS ships a usable system OpenGL, so this is only needed on Windows. Also restore diagnostics in libc exit()/abort(): they previously exited silently, so run logs ended abruptly with no explanation. They now log the exit/abort (with a guest stack trace on abort) before quitting. Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Updated decoding logic to align with Symphonia 0.6 changes, including adjustments to probe, track access, codec parameters, and decoder creation.
Updated alGetBufferi function parameter from *const ALint to *mut ALint to match OpenAL specification.
Updated GetBufferi function to accept a mutable pointer for the value parameter, aligning with OpenAL API requirements.
…etBufferi pointer (#161) * Add CI workflow for testing iOS apps under touchHLE (#30) * Add workflow to download and run an IPA via touchHLE * Run downloaded IPA on Linux, Windows and macOS --------- Co-authored-by: Claude <noreply@anthropic.com> * CI: provide software OpenGL on Windows so apps can launch (#31) The 'Download and run IPA' workflow aborted on the Windows runner with 'Couldn't create OpenGL ES 1.1 context!'. Windows GitHub Actions runners only expose Microsoft's GDI generic OpenGL 1.1, which cannot satisfy the OpenGL 2.1 context that touchHLE's GLES1-on-GL2 fallback requires, so both the native GLES path and the GL2 fallback fail and the emulator panics before the app ever runs. Drop Mesa3D's llvmpipe software renderer (a per-app opengl32.dll plus its dependencies) next to touchHLE.exe and force GALLIUM_DRIVER=llvmpipe so a complete OpenGL implementation is available without a GPU. Linux already gets llvmpipe via libgl1-mesa-dri and macOS ships a usable system OpenGL, so this is only needed on Windows. Also restore diagnostics in libc exit()/abort(): they previously exited silently, so run logs ended abruptly with no explanation. They now log the exit/abort (with a guest stack trace on abort) before quitting. Co-authored-by: Claude <noreply@anthropic.com> * Fix build: port symphonia_formats to Symphonia 0.6 API and alGetBufferi pointer (#32) The touchHLE lib failed to compile against symphonia 0.6.0, which reorganized its API relative to the 0.5-era code the module was written for: - probe() now returns the boxed FormatReader directly (no ProbeResult .format field) - Hint moved to symphonia::core::formats::probe - Track::codec_params is Option<CodecParameters> (an enum with an Audio variant carrying AudioCodecParameters) - decoders are created via CodecRegistry::make_audio_decoder with AudioDecoderOptions - next_packet() returns Result<Option<Packet>> (Ok(None) = end of stream) - decoded audio is a GenericAudioBufferRef exposing copy_bytes_to_vec_interleaved_as::<i16>() - SignalSpec/SampleBuffer are gone; AudioSpec (rate()/channels()) is used Also fix alGetBufferi to obtain a mutable pointer via ptr_at_mut, as GetBufferi writes the queried value back (matching alGetSourcei). Co-authored-by: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…(#162) * Add CI workflow for testing iOS apps under touchHLE (#30) * Add workflow to download and run an IPA via touchHLE * Run downloaded IPA on Linux, Windows and macOS --------- Co-authored-by: Claude <noreply@anthropic.com> * CI: provide software OpenGL on Windows so apps can launch (#31) The 'Download and run IPA' workflow aborted on the Windows runner with 'Couldn't create OpenGL ES 1.1 context!'. Windows GitHub Actions runners only expose Microsoft's GDI generic OpenGL 1.1, which cannot satisfy the OpenGL 2.1 context that touchHLE's GLES1-on-GL2 fallback requires, so both the native GLES path and the GL2 fallback fail and the emulator panics before the app ever runs. Drop Mesa3D's llvmpipe software renderer (a per-app opengl32.dll plus its dependencies) next to touchHLE.exe and force GALLIUM_DRIVER=llvmpipe so a complete OpenGL implementation is available without a GPU. Linux already gets llvmpipe via libgl1-mesa-dri and macOS ships a usable system OpenGL, so this is only needed on Windows. Also restore diagnostics in libc exit()/abort(): they previously exited silently, so run logs ended abruptly with no explanation. They now log the exit/abort (with a guest stack trace on abort) before quitting. Co-authored-by: Claude <noreply@anthropic.com> * Fix build: port symphonia_formats to Symphonia 0.6 API and alGetBufferi pointer (#32) The touchHLE lib failed to compile against symphonia 0.6.0, which reorganized its API relative to the 0.5-era code the module was written for: - probe() now returns the boxed FormatReader directly (no ProbeResult .format field) - Hint moved to symphonia::core::formats::probe - Track::codec_params is Option<CodecParameters> (an enum with an Audio variant carrying AudioCodecParameters) - decoders are created via CodecRegistry::make_audio_decoder with AudioDecoderOptions - next_packet() returns Result<Option<Packet>> (Ok(None) = end of stream) - decoded audio is a GenericAudioBufferRef exposing copy_bytes_to_vec_interleaved_as::<i16>() - SignalSpec/SampleBuffer are gone; AudioSpec (rate()/channels()) is used Also fix alGetBufferi to obtain a mutable pointer via ptr_at_mut, as GetBufferi writes the queried value back (matching alGetSourcei). Co-authored-by: Claude <noreply@anthropic.com> * Fix NSKeyedArchiver infinite recursion crash + collection round-trip Fixes the Talking Angela crash (App called exit with a garbage pointer argument after the objc_msgSend depth guard tripped and corrupted string objects). Root cause and related issues: - ns_keyed_archiver: NSString's encodeWithCoder: allocated a fresh NSString for its contents and re-encoded that via encodeObject:forKey:. Since the new object is itself an NSString, encode_object kept calling encodeWithCoder: on each freshly-created string, recursing infinitely. This blew the objc_msgSend recursion guard (or the native stack), corrupted string objects, and eventually crashed the guest. NSString is now stored inline as a plist string in $objects, matching what the decoder already expects. - ns_array / ns_dictionary: the archiver wrote collections in a bespoke layout (NS.objects.0, NS.objects.1, NS.count for arrays; a single object reference for dictionaries) that the decoder — which follows Apple's inline UID-array format — could not read, so touchHLE-produced archives round-tripped to empty collections. Both now emit NS.objects / NS.keys as inline arrays of UID references via the new encode_objects_as_uid_array helper. - ns_array: add -[NSArray isEqual:], which delegates to isEqualToArray: for NSArray operands. Without it the NSObject pointer-identity default made two distinct-but-equal arrays (e.g. an array and its unarchived copy) compare unequal, breaking dictionary/array equality after a round-trip. - foundation: remove duplicate constant exports (e.g. _AVPlayerItemTimeJumpedNotification, _PHImageErrorKey, several SK*/kSec*), which made the no_duplicate_constants unit test fail and would emit duplicate C declarations in generated link stubs. - dyld: dump_host_symbols now emits a sanitized C identifier with an asm() label for symbols whose names aren't valid C identifiers (e.g. OBJC_IVAR_$_NSObject.isa), so the integration-test link stubs compile. https://claude.ai/code/session_016jmFdZ859mfXeJZ1eubdEH --------- Co-authored-by: Claude <noreply@anthropic.com>
…mount) (#163) * Add CI workflow for testing iOS apps under touchHLE (#30) * Add workflow to download and run an IPA via touchHLE * Run downloaded IPA on Linux, Windows and macOS --------- Co-authored-by: Claude <noreply@anthropic.com> * CI: provide software OpenGL on Windows so apps can launch (#31) The 'Download and run IPA' workflow aborted on the Windows runner with 'Couldn't create OpenGL ES 1.1 context!'. Windows GitHub Actions runners only expose Microsoft's GDI generic OpenGL 1.1, which cannot satisfy the OpenGL 2.1 context that touchHLE's GLES1-on-GL2 fallback requires, so both the native GLES path and the GL2 fallback fail and the emulator panics before the app ever runs. Drop Mesa3D's llvmpipe software renderer (a per-app opengl32.dll plus its dependencies) next to touchHLE.exe and force GALLIUM_DRIVER=llvmpipe so a complete OpenGL implementation is available without a GPU. Linux already gets llvmpipe via libgl1-mesa-dri and macOS ships a usable system OpenGL, so this is only needed on Windows. Also restore diagnostics in libc exit()/abort(): they previously exited silently, so run logs ended abruptly with no explanation. They now log the exit/abort (with a guest stack trace on abort) before quitting. Co-authored-by: Claude <noreply@anthropic.com> * Fix build: port symphonia_formats to Symphonia 0.6 API and alGetBufferi pointer (#32) The touchHLE lib failed to compile against symphonia 0.6.0, which reorganized its API relative to the 0.5-era code the module was written for: - probe() now returns the boxed FormatReader directly (no ProbeResult .format field) - Hint moved to symphonia::core::formats::probe - Track::codec_params is Option<CodecParameters> (an enum with an Audio variant carrying AudioCodecParameters) - decoders are created via CodecRegistry::make_audio_decoder with AudioDecoderOptions - next_packet() returns Result<Option<Packet>> (Ok(None) = end of stream) - decoded audio is a GenericAudioBufferRef exposing copy_bytes_to_vec_interleaved_as::<i16>() - SignalSpec/SampleBuffer are gone; AudioSpec (rate()/channels()) is used Also fix alGetBufferi to obtain a mutable pointer via ptr_at_mut, as GetBufferi writes the queried value back (matching alGetSourcei). Co-authored-by: Claude <noreply@anthropic.com> * Fix infinite loop constructing std::string from NULL char* (Turbo Dismount) Some apps (e.g. Turbo Dismount) hang at startup, spinning forever while mem::memmove logs "memmove with likely-negative size (0xffffffff = -1); src=0x0" over and over. Root cause: the app builds std::strings in a loop from a table that contains a NULL `const char*` entry under touchHLE. libstdc++ constructs `std::string(const char*)` via `_S_construct(NULL, NULL + npos)`, detects the NULL pointer, and calls `std::__throw_logic_error`. touchHLE already neuters the `__throw_*` helpers to a bare `BX LR` so guest C++ "soft" failures don't abort the host. But for this path the neutered throw simply falls through into the normal copy code with `beg == NULL` and `end - beg == npos`, producing `memcpy(dest, NULL, npos)` and a string whose length is npos. The oversized copy is skipped by Mem::memmove, but the resulting corrupt string leaves the app's construction loop unable to make progress — an effectively infinite hang. The documented intent of the throw-neutering is for std::string(NULL) to behave like an empty string. Make that actually happen: retarget the NULL-pointer branch inside libstdc++'s char `_S_construct` so it jumps to the function's existing empty-string path (which returns `_S_empty_rep()._M_refdata()`) instead of the throw / oversized-copy path. The patch locates the branch by instruction pattern and verifies the expected encodings, skipping with a warning if the bundled libstdc++ ever changes, so it can never silently mis-patch. Verified with com.secretexit.trdismount 1.2.7: the "likely-negative size" spam (previously 400k+ occurrences in seconds, pegging a CPU core) drops to zero and the app proceeds past startup. https://claude.ai/code/session_0112hTEYgwBzuThq3tqwhno1 --------- Co-authored-by: Claude <noreply@anthropic.com>
…ead inheritsched This commit fixes several issues identified from touchHLE logs running PopCap games (PvZ iPad/iPhone): 1. CFPreferences: Added reverse-DNS prefix matching for shortened bundle IDs - Games use 'com.popcap.pvz' and 'com.popcap.pvzipad' instead of full bundle IDs - Per Apple docs, applicationID should be in Java package name form 2. memmove: Zero-fill destination when src is NULL instead of skipping - Real iOS behavior for corrupted std::string internals - Fixes warnings in PvZ logs 3. pthread: Implemented pthread_attr_setinheritsched and pthread_attr_getinheritsched - Added inheritsched field to pthread_attr_t struct - Per Apple pthread(3) manpage with proper EINVAL validation 4. CFURL: Implemented CFURLCreateStringByReplacingPercentEscapes - Using NSString stringByRemovingPercentEncoding instead of stub References: - Apple CFPreferencesCopyAppValue docs - Apple pthread(3) manpage - Apple CFURL docs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a test pull request to verify the repository workflow.