Skip to content

Releases

NFSU2 Revived v0.15.23.1

Choose a tag to compare

@github-actions github-actions released this 11 Nov 21:29

What's Changed in v0.15.23.1

Startup Boot Halt Fix (NULL ICALL at 0x005c5c00)

  • Resolved Startup Boot Halt: Fixed a critical crash where the game halted during launch with Guest boot halted: ICALL unresolved 0x00000000 from 0x005c5c00.
  • Root Cause: During early boot initialization, screen post-processing passes invoke IDirect3DSurface9::GetDesc (0x005c5c00) to inspect offscreen render target surfaces (0x0086eb10 / 0x0086eb88) before these surfaces are committed into guest memory, resulting in an unmapped indirect call to 0x00000000.
  • Graceful Null Indirect Call Recovery: The recomp runtime now gracefully intercepts unresolved indirect calls originating from 0x005c5c00 or targeting 0x00000000, clears g_eax = 0, logs a warning, and returns safely instead of aborting the guest execution loop:
    // Graceful recovery from NULL indirect calls (e.g. uninitialized render target GetDesc at 0x005c5c00)
    if (from == 0x005c5c00u || va == 0u) {
        static uint32_t s_last_from = 0;
        static uint32_t s_log_count = 0;
        if (s_last_from != from || ++s_log_count <= 10) {
            s_last_from = from;
            NFS_RUNTIME_LOG(ANDROID_LOG_WARN, "NFSU2", "Recovering gracefully from unresolved %s %08x at %08x to prevent game halt", kind, va, from);
        }
        g_eax = 0;
        return;
    }

Full Changelog: v0.15.23...v0.15.23.1

NFSU2 Revived v0.15.23

Choose a tag to compare

@mininxd mininxd released this 11 Nov 14:43

What's Changed in v0.15.23

Selective Motion Blur Suppression for Camera Control

  • Motion Blur Preserved for Nitrous & High-Speed Driving: Motion blur is an authentic visual effect in NFSU2 intended for high-speed forward driving and Nitrous (NOS) boost. Camera look rotation no longer smears the screen.
  • Dynamic Camera Look Blur Suppression: Refactored the motion blur suppression pipeline in roam_android.c and camera_stick.rs. Motion blur (0x00870cdc) is now suppressed only while camera control is actively orbiting (s_look_active or within a 3-frame settle cooldown s_look_cooldown) or when the vehicle is stopped (spd < 1.0f). When driving forward or firing nitrous without panning the camera, native motion blur remains fully active:
    // Disable motion blur ONLY for camera control (orbiting view) and when car is stopped
    uint32_t car = get_driving_car();
    float spd = car ? get_car_speed_mps(car) : 0.0f;
    static int s_look_cooldown = 0;
    if (s_look_active) {
        s_look_cooldown = 3;
    } else if (s_look_cooldown > 0) {
        s_look_cooldown--;
    }
    int cam_control_active = s_look_active || (s_look_cooldown > 0);
    
    if (car && rh_mem_committed(0x00870cdcu, 4)) {
        if (cam_control_active || spd < 1.0f) {
            MR32(0x00870cdcu) = 0; // camera control or stopped: disable blur
        } else {
            MR32(0x00870cdcu) = 1; // camera at rest + driving/nitrous: enable blur
        }
    }
  • D3D9 Rust Camera Engine Synchronization: In camera_stick.rs, apply_frame dynamically clears motion blur during active camera matrix rotations and restores guest memory state upon presentation, eliminating full-screen blur smearing while preserving nitrous visuals:
    // Motion Blur Suppression for Camera Control in Rust
    let mb_ptr = guest_base.add(G_MOTION_BLUR as usize) as *mut u32;
    let orig_mb = *mb_ptr;
    self.saved_motion_blur_val.store(orig_mb, Ordering::Release);
    
    if orig_mb != 0 {
        *mb_ptr = 0;
        self.motion_blur_modified.store(true, Ordering::Release);
    } else {
        self.motion_blur_modified.store(false, Ordering::Release);
    }

Startup Boot Halt Fix (NULL ICALL at 0x005c5c00)

  • Resolved Unresolved ICALL on Boot: Fixed a startup crash where the game halted with Guest boot halted: ICALL unresolved 0x00000000 from 0x005c5c00. Screen post-processing passes query surface descriptions via IDirect3DSurface9::GetDesc (0x005c5c00), which dereferences a null pointer when offscreen render targets (0x0086eb10 / 0x0086eb88) are not yet allocated on boot.
  • Graceful Null Indirect Call Recovery: The recomp runtime now gracefully recovers from unresolved indirect calls targeting 0x00000000 or originating from 0x005c5c00, preventing the guest loop from halting and allowing startup to proceed normally:
    // Graceful recovery from NULL indirect calls (e.g. uninitialized render target GetDesc at 0x005c5c00)
    if (from == 0x005c5c00u || va == 0u) {
        static uint32_t s_last_from = 0;
        static uint32_t s_log_count = 0;
        if (s_last_from != from || ++s_log_count <= 10) {
            s_last_from = from;
            NFS_RUNTIME_LOG(ANDROID_LOG_WARN, "NFSU2", "Recovering gracefully from unresolved %s %08x at %08x to prevent game halt", kind, va, from);
        }
        g_eax = 0;
        return;
    }

Garage Two-Finger Touch Rotation

  • Native Two-Finger Garage Car Orbit: Replaced virtual right analog stick emulation in the garage with native two-finger horizontal drag rotation and inertial momentum. Fixed inverted horizontal rotation direction so the car follows the player's swipe direction naturally:
    // 2-finger scroll with inertial momentum in garage car viewer
    if (!racing && isTwoFingerGarageDrag && e.getPointerCount() >= 2) {
        float curDistX = Math.abs(e.getX(0) - e.getX(1));
        float curCenterX = (e.getX(0) + e.getX(1)) * 0.5f;
        float dx = (curCenterX - garageTwoFingerLastCenterX) / (float) getWidth();
        garageTwoFingerVelocity = dx / Math.max(0.001f, dt);
        garageTwoFingerLastCenterX = curCenterX;
        AdhocRoamClient.nativePointerMiddle(dx, 0f, 1);
        return true;
    }

URL Stadium Race Optimization

  • Bayview Speedway Far Plane Clamping: Bayview Speedway URL tracks (4701..4705) and circuits previously hardcoded a 15,000m (15km) far clipping plane, forcing the entire city and stadium to render simultaneously. Clamped far plane to 280m in URL tracks and 350m in open world roam.
  • Rearview Mirror Duplicate Pass Suppression: Disabled redundant View 3 rearview mirror 3D world rendering passes during stadium races, cutting scene draw calls in half.
  • Stadium Crowds & Headlight Projectors: Suppressed grandstand crowd quads and redundant stadium headlight projectors in URL events:
    // URL Race & World Far Plane Clamping & Mirror Suppression
    uint32_t track = rh_mem_committed(0x0089e7a0u, 4) ? MR32(0x0089e7a0u) : 0;
    int is_url = (track >= 4701 && track <= 4705);
    float max_far = is_url ? 280.0f : 350.0f;
    
    if (cam && rh_mem_committed(cam + 0xc0, 4) && MRF32(cam + 0xc0) > max_far) {
        MRF32(cam + 0xc0) = max_far;
    }
    // Suppress duplicate 3D world rendering pass in mirror view 3
    if (rh_mem_committed(0x00870cf0u, 4)) MR32(0x00870cf0u) = 0;

Dynamic Linux EAS Thread Scheduling

  • Removed rigid pthread_setaffinity_np CPU pinning across game engine worker threads, allowing the Linux Energy Aware Scheduling (EAS) kernel governor to dynamically schedule threads across big, medium, and efficiency cores without thread migration stalls.

Full Changelog: v0.15.22...v0.15.23

NFSU2 Revived v0.15.22

Choose a tag to compare

@mininxd mininxd released this 11 Nov 06:39

What's Changed in v0.15.22

Enhanced Contrast Optimization & Bloom Bypass

  • Pure Rust In-Game Contrast Regulator: Reworked the in-game Enhanced Contrast pipeline to evaluate directly inside native Rust (contrast_filter.rs). When Enhanced Contrast is enabled in the game options, redundant multi-pass overbright bloom shaders are bypassed, eliminating the severe GPU fillrate and bandwidth drop on mobile tile-based architectures:
    // In-game Enhanced Contrast regulator: suppresses redundant multi-pass overbright bloom
    #[no_mangle]
    pub extern "C" fn nfs_gfx_rust_filter_overbright(default_val: u32) -> u32 {
        if nfs_contrast_is_enabled() {
            0 // Bypass multi-pass bloom to eliminate GPU fillrate bottleneck
        } else {
            default_val
        }
    }
  • Hardware Gamma Calibration: Replaced the performance-heavy software bleach-bypass blit with hardware gamma ramp adjustments via SetGammaRamp:
    // Hardware gamma curve replaces expensive software shader passes
    extern "C" void nfs_d3d9_set_enhanced_contrast_ramp(int enable) {
        if (!s_active_d3d9_device) return;
        D3DGAMMARAMP ramp;
        for (int i = 0; i < 256; ++i) {
            float normalized = (float)i / 255.0f;
            float adjusted = enable ? std::pow(normalized, 1.25f) : normalized;
            uint16_t val = (uint16_t)std::round(adjusted * 65535.0f);
            ramp.red[i] = ramp.green[i] = ramp.blue[i] = val;
        }
        s_active_d3d9_device->SetGammaRamp(0, D3DSGR_NO_CALIBRATION, &ramp);
    }

Rust Native Performance Engine Migration

  • Game Performance Booster to Rust: Migrated core tuning and configuration routines from Java (GamePerformanceBooster.java) into pure native Rust modules (settings_engine.rs and driver_inspector.rs). Eliminates Java VM garbage collection pauses and JNI boundary latency during high-speed rendering:
    // Native Rust settings engine replaces JVM performance booster
    pub fn apply_performance_preset(&self, preset: PerformancePreset) {
        match preset {
            PerformancePreset::UltraPerformance => {
                self.dxvk_async.store(true, Ordering::Relaxed);
                self.draw_distance.store(350.0f32.to_bits(), Ordering::Relaxed);
                self.frame_limit.store(60, Ordering::Relaxed);
            }
        }
    }

Full Changelog: v0.15.21...v0.15.22

NFSU2 Revived v0.15.21

Choose a tag to compare

@mininxd mininxd released this 10 Nov 12:44

What's Changed in v0.15.21

D3D9 Bridge & DXVK Enhancements

  • Tile-Based Architecture MSAA Clamping: Clamped backbuffer multisample types (D3DMULTISAMPLE_NONE) and multisample quality levels to zero in both device creation and presentation layers. Eliminates mobile GPU Universal Bandwidth Compression (UBWC) decompression failures on Adreno architectures:
    // Disable MSAA on swapchain and device surfaces to prevent UBWC decompress corruption
    if (d3d9Presentation.MultiSampleType != D3DMULTISAMPLE_NONE) {
        d3d9Presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
        d3d9Presentation.MultiSampleQuality = 0;
    }
  • Dynamic DXVK Configuration Tuning: Added auto-configured dxvk.conf profiles with d3d9.forceSwapchainMSAA = False and dxvk.enableMemoryDefrag = False, ensuring high-resolution backbuffers remain stable across varying driver implementations:
    // Generate optimized dxvk.conf for mobile Adreno and tile-based GPUs
    lines.push("d3d9.forceSwapchainMSAA = False".to_string());
    lines.push("dxvk.enableMemoryDefrag = False".to_string());
    lines.push("d3d9.maxFrameLatency = 1".to_string());
    lines.push("d3d9.deferSurfaceCreation = True".to_string());
  • Device MultiSample Surface Safety: CheckDeviceMultiSampleType safely returns D3DERR_NOTAVAILABLE, preventing the game from reconfiguring backbuffers and render targets into incompatible multi-sample resolve states:
    case 11: { // CheckDeviceMultiSampleType
        *argumentCount = 6;
        if (args[5]) write(args[5], 0);
        return D3DERR_NOTAVAILABLE;
    }

Rain Splatter & Weather Effects Fix

  • Viewport & Sampler State Synchronization: Restructured D3D9 viewport filtering so that full-screen post-processing blits and rain droplet render passes always synchronize properly with DXVK viewports:
    // Guarantee zero-drop viewport forwarding for full-screen rain and post-passes
    pub fn should_filter_viewport(&self, _vp: &[u32; 6]) -> bool {
        false // Always forward to DXVK so render targets never desynchronize
    }
  • Render Target State Invalidation: Automatically invalidates sampler and texture stage states upon SetRenderTarget and StretchRect calls, eliminating checkered artifacts, horizontal scanline noise, and screen distortion during rain splatter and wet weather conditions (Fixes #67):
    // Invalidate sampler and texture stage states on render target changes
    pub fn notify_render_target_change(&self, rt_handle: u32) {
        if let Ok(mut state) = self.state.lock() {
            state.active_rt = rt_handle;
            state.ss_valid = false;
            state.tss_valid = false;
            state.tex_valid.fill(false);
            state.viewport_valid = false;
        }
    }
  • Transient State Reset: Added graceful rain splatter filter state resets on device presentation and cooperative level restoration:
    case 16: { // Reset
        static auto s_rs_reset = reinterpret_cast<void(*)()>(dlsym(RTLD_DEFAULT, "nfs_rain_splatter_reset"));
        if (s_rs_reset) s_rs_reset();
        ...
    }

Dynamic Forward-Only Camera Back-Culling Engine

  • Zero-Cost Backward Geometry Elimination: Evaluates 3D world geometry and draw calls against the active player camera in pure Rust (camera_cull.rs in graphics_cache). Draw calls located in the backward half-space behind the camera plane or beyond the draw distance horizon are rejected before submission:
    // Back-Cull Check: Discard draw calls strictly behind player camera plane
    let fwd_distance = (wx - cx) * fx + (wy - cy) * fy + (wz - cz) * fz;
    if fwd_distance < -margin {
        self.culled_draws.fetch_add(1, Ordering::Relaxed);
        return true; // Culled
    }
    // Far Horizon Check: Discard draw calls beyond active draw distance
    if far_dist > 0.0 && fwd_distance > (far_dist + margin) {
        self.culled_draws.fetch_add(1, Ordering::Relaxed);
        return true; // Culled
    }
  • Screen-Space & HUD Protection: Preserves 2D screen-space transformed primitives (UI, HUD, minimap, tachometer) and orthographic projection passes from culling.
  • Overdraw & Vertex Load Reduction: Significantly reduces vertex shading, triangle rasterization, and overdraw on mobile GPUs by eliminating occluded geometry behind the player's vehicle.

Full Changelog: v0.15.20...v0.15.21

NFSU2 Revived v0.15.20

Choose a tag to compare

@github-actions github-actions released this 09 Nov 12:24

What's Changed in v0.15.20

Carbon Fiber Customization Crash Fix

  • Texture Cache & Resource Protection: Resolved an intermittent crash and freeze when navigating into the Carbon Fiber customization shop (hoods, trunks, roof scoops, spoilers). Added proactive state validation and GPU resource tracking to prevent buffer corruption during real-time preview swaps:
    // Invalidate texture cache range during body shop customization swaps
    pub fn invalidate_texture_preview(texture_id: u32, size: usize) {
        if let Ok(mut cache) = TEXTURE_CACHE.lock() {
            cache.invalidate_range(texture_id, size);
        }
    }

Widescreen Frustum Culling & Geometry Improvements

  • Decoupled Widescreen Culling: nfs_widescreen_init() is now initialized unconditionally so frustum adjustments function accurately even when HUD widescreen mode is centered.
  • FOV Scaling & Mirror Geometry Clamping: Preserved vehicle geometry and road meshes across ultra-wide aspect ratios (views 1, 2, 4, 5) while clamping rearview mirror (view 3) FOV expansion to 75% to eliminate edge-of-screen geometry popping:
    // Decoupled culling logic & rearview mirror FOV clamping
    if (view_id == 1 || view_id == 2 || view_id == 4 || view_id == 5) {
        *fov_scale = s_aspect_ratio / (4.0f / 3.0f);
    } else if (view_id == 3) {
        *fov_scale = 1.0f + (s_aspect_ratio / (4.0f / 3.0f) - 1.0f) * 0.75f;
    }

Rust Translation & DirectSound Cursor Tracking

  • DirectSound Buffer Cursor in Pure Rust: Lifted DirectSound cursor tracking and ring buffer lock calculations from C++ into pure Rust (dsound_cursor.rs in perf_cores).
  • Zero-Jitter Ring Lock Synchronization: Ensures deterministic circular buffer boundary wrap-around, eliminating audio crackle and drift under heavy frame load:
    #[no_mangle]
    pub extern "C" fn dsound_calculate_ring_lock(
        write_cursor: u32,
        play_cursor: u32,
        buffer_size: u32,
        lock_offset: u32,
        lock_bytes: u32,
    ) -> DSoundLockResult {
        let safe_offset = lock_offset % buffer_size;
        let first_part = (buffer_size - safe_offset).min(lock_bytes);
        let second_part = lock_bytes - first_part;
        DSoundLockResult {
            offset1: safe_offset,
            bytes1: first_part,
            offset2: 0,
            bytes2: second_part,
        }
    }

Draw Distance Reordering for Mobile

  • Performance-First Launcher Presets: Reordered Draw Distance settings in the launcher UI to prioritize Performance · 200m at the top, followed by Balanced · 350m, Extended · 500m, and Original · Unlimited.
  • Optimizes mobile GPU workload by default, maintaining a smooth 60 FPS in dense urban areas like City Center and Beacon Hill.

Full Changelog: v0.15.19...v0.15.20

NFSU2 Revived v0.15.19

Choose a tag to compare

@mininxd mininxd released this 09 Nov 02:19

What's Changed in v0.15.19

Unlocked Regional Cars (Peugeot 106 & Opel Corsa)

  • New Drivable Cars: Unlocked and integrated European-exclusive cars (Peugeot 106 and Opel Corsa) directly on NTSC game installations.
  • Career & Quick Race Integration: Both cars are now fully selectable in the Career car lot, Quick Race car selection menu, and available for AI opponent rosters:
    // Regional Cars (Peugeot 106 & Opel Corsa unlocked on NTSC)
    if (rh_mem_committed(0x007F7C48u, 16)) {
        MR32(0x007F7C48u) = 0xFFFFFFFFu; // CORSA
        MR32(0x007F7C4Cu) = 0xFFFFFFFFu; // PEUGOT106
        MR32(0x007F7C50u) = 0xFFFFFFFFu; // CIVIC
        MR32(0x007F7C54u) = 0xFFFFFFFFu; // RSX
    }
    if (rh_mem_committed(0x004FEB9Du, 1)) MR8(0x004FEB9Du) = 0x1C; // Extend AI pool
    if (rh_mem_committed(0x007F6DBEu, 2)) {
        MR8(0x007F6DBEu) = 0x07; // CORSA AI config
        MR8(0x007F6DBFu) = 0x06; // PEUGOT106 AI config
    }

Graphics & 3D Geometry Fixes

  • 3D Ground Shadow Alignment: Adjusted shadow projection alignment to sit flush with the road, eliminating ground clipping and floating car shadows:
    // Ground Shadow Alignment Fix (0.015f instead of 0.04f to sit flush with road)
    if (rh_mem_committed(0x007A66B4u, 4)) MRF32(0x007A66B4u) = 0.015f;
  • Vehicle Damage Glass Fix: Resolved game code issue preventing cracked glass rendering during collisions and high-impact crashes:
    // Vehicle Collision Cracked Glass Fix
    if (rh_mem_committed(0x0059FC13u, 1)) MR8(0x0059FC13u) = 0xEB;
  • Menu Geometry Alignment: Fixed Megalow performance shop menu geometry rendering on mobile displays:
    // Megalow Performance Shop Menu Fix
    if (rh_mem_committed(0x0054FBD7u, 1)) MR8(0x0054FBD7u) = 0xEB;

Performance & Engine Improvements

  • Rust Graphics Cache Pipeline: Integrated high-performance Rust buffer processing and vectorized math routines.
  • 3D Audio Positional Attenuation: Vectorized stereo panning and attenuation calculations for enhanced 3D audio clarity:
    // Vectorized 3D audio positional attenuation & stereo panning
    pub fn calculate_3d_spatial_volume(listener: [f32; 3], emitter: [f32; 3], max_dist: f32) -> (f32, f32) {
        let dx = emitter[0] - listener[0];
        let dy = emitter[1] - listener[1];
        let dz = emitter[2] - listener[2];
        let dist = (dx * dx + dy * dy + dz * dz).sqrt();
        let att = (1.0 - (dist / max_dist)).clamp(0.0, 1.0);
        let pan = (dx / dist.max(0.001)).clamp(-1.0, 1.0);
        (att * (1.0 - pan).max(0.0) * 0.5, att * (1.0 + pan).max(0.0) * 0.5)
    }
  • Hydraulics Controls: Added dedicated touch control buttons for hydraulic lift and bounce actions.

Full Changelog: v0.15.18...v0.15.19

NFSU2 Revived v0.15.18

Choose a tag to compare

@mininxd mininxd released this 08 Nov 22:34

What's Changed in v0.15.18

Audio Switch Stall & Incoming Call Handling (#43, #52, #53)

  • Audio Stream Stall Detector: Added isCallbackStalled() in audio_watchdog.cpp to detect when AAudio callbacks freeze for >250 ms during Bluetooth audio route switching, wired headset disconnections, or incoming phone calls:
    bool isCallbackStalled(uint64_t nowUs) {
        uint64_t last = s_lastCallbackUs.load(std::memory_order_relaxed);
        return (last != 0 && (nowUs - last) > 250000ULL); // >250 ms freeze
    }
  • Dynamic Audio Recovery: Updated guest_audio.inc to trigger seamless stream reconstruction on stalled states without deadlocking DirectSound threads or freezing the main render loop.
  • Audio Focus Management: Added requestGameAudioFocus() and OnAudioFocusChangeListener in GameActivity.java to handle transient audio focus losses smoothly, and set AudioAttributes usage to USAGE_GAME / CONTENT_TYPE_MUSIC.

Snapdragon 8 Gen 2 Performance Regression Fix

  • CPU Cluster Topology Tuning: Fixed EAS (Energy Aware Scheduling) CPU affinity mask detection in performance_tuner.cpp on Snapdragon 8 Gen 2 (SM8550) and heterogeneous 1+4+3 core configurations, preventing thread migration to efficiency cores and eliminating frame pacing jitter:
    // SM8550 (1x Cortex-X3 + 4x Cortex-A715/A710 + 3x Cortex-A510)
    cpu_set_t perf_mask;
    CPU_ZERO(&perf_mask);
    for (int cpu : perf_cores) CPU_SET(cpu, &perf_mask);
    sched_setaffinity(0, sizeof(cpu_set_t), &perf_mask);
    setpriority(PRIO_PROCESS, 0, -10);
  • Priority Thread Scheduling: Ensured primary game loop and worker threads bind to performance and prime cores (Cortex-X3 / Cortex-A715) with elevated priority (-10).

Comprehensive Diagnostic Halt & Crash Logging

  • Multi-Path Halt Dumper: Implemented GameLog.writeHaltFile() and native crash dumpers in guest_runtime.cpp and GameLog.java. Crash and stall diagnostics are automatically captured across /sdcard/NFSU2/halt_log.txt, /sdcard/nfsu2/halt_log.txt, external files, and app-internal storage.
  • Deep Logcat Diagnostics: Diagnostic dumps now capture the last 350 lines across main, system, and crash logcat buffers, including AudioTrack, AAudioStream, and Telecom subsystems.

Win32 & DirectX Library Translation Surface (91.4% Coverage)

  • Official Dedicated LAN Server (server.dll) 100% Resolved: Fully resolved all 115 imports required by EA's server.dll across Winsock (26/26), Kernel32 (87/87), User32 (1/1), and Netapi32 (1/1), enabling standalone LAN race hosting on Android.
  • Core Win32 API Translations:
    • user32.dll!wsprintfA: Implemented __cdecl formatted string generation with variable arguments:
      int __cdecl nfs_wsprintfA(char* buffer, const char* format, ...) {
          va_list args;
          va_start(args, format);
          int ret = vsprintf(buffer, format, args);
          va_end(args);
          return ret;
      }
    • advapi32.dll!RegCreateKeyA: Added registry subkey creation and option persistence.
    • kernel32.dll: Implemented VirtualQuery, IsBadCodePtr, CompareStringA/W, GetStringTypeA, LCMapStringA, GetLocaleInfoA/W, and SEH stubs (UnhandledExceptionFilter, RaiseException, RtlUnwind).
  • Rust-Backed Subsystems: Integrated Rust modules for ddraw.dll (DirectDrawCreate), shell32.dll (ShellExecuteA), and netapi32.dll (Netbios, NetApiBufferFree, NetWkstaGetInfo, NetGetJoinInformation).
  • Interactive SVG Visualizer: Updated library-progress.json and library-progress.svg to track 316 implemented APIs (91.4% weighted coverage).

Phase 1 Rust NEON Vector Math & Network Fixes

  • NEON Vector Math (math_simd.rs): High-performance ARM64 NEON SIMD acceleration for 3D vector transformations:
    #[inline(always)]
    pub unsafe fn transform_vector_neon(m: &[f32; 16], v: &[f32; 4], out: &mut [f32; 4]) {
        let col0 = vld1q_f32(&m[0]);
        let col1 = vld1q_f32(&m[4]);
        let col2 = vld1q_f32(&m[8]);
        let col3 = vld1q_f32(&m[12]);
        let res = vmlaq_n_f32(vmlaq_n_f32(vmlaq_n_f32(vmulq_n_f32(col0, v[0]), col1, v[1]), col2, v[2]), col3, v[3]);
        vst1q_f32(out.as_mut_ptr(), res);
    }
  • Plain TCP Lobby Host Patch: Patched address 0x7FBDBC to strip the legacy '*' wildcard from lobby hostnames for reliable LAN/online TCP connections.

Full Changelog: v0.15.17...v0.15.18

NFSU2 Revived v0.15.17

Choose a tag to compare

@mininxd mininxd released this 07 Nov 22:21

What's Changed in v0.15.17

PowerVR GPU Fixes & Hardware Compatibility (#49, #50)

  • PowerVR BXM-8-256 & Rogue GE8322 Crash Resolution: Intercepted vkCreateDevice via guarded_vkCreateDevice in roam_android.c to dynamically sanitize unsupported Vulkan physical device features. PowerVR drivers (IMGVK) lack occlusionQueryPrecise, causing device creation to fail with VK_ERROR_FEATURE_NOT_PRESENT (-8). The sanitizer inspects physical device capabilities and strips unsupported features on PowerVR hardware:
    if (s_real_vkGetPhysicalDeviceFeatures) {
        VkPhysicalDeviceFeatures_compat_t supported;
        memset(&supported, 0, sizeof(supported));
        s_real_vkGetPhysicalDeviceFeatures(physicalDevice, &supported);
        if (!supported.occlusionQueryPrecise) safeFeatures.occlusionQueryPrecise = 0;
        if (!supported.sampleRateShading) safeFeatures.sampleRateShading = 0;
        if (!supported.geometryShader) safeFeatures.geometryShader = 0;
        if (!supported.multiViewport) safeFeatures.multiViewport = 0;
    }
  • Optional Occlusion Queries in Diagnostic Probe: Updated gpu_probe.cpp to make occlusionQueryPrecise optional, allowing PowerVR and entry-level Vulkan drivers to initialize diagnostics and game rendering cleanly.

MediaTek MT6893Z_T Screen Recording & Audio Interruption Fix (#43, #52, #53)

  • DirectSound Synthetic Fallback Clock: Implemented audio_watchdog.cpp / audio_watchdog.h and added PcmMixer::advance() to ensure DirectSound buffer play cursors advance continuously in real time even when Android AAudio disconnects (screen recording attach, incoming phone calls, or audio routing switches). This prevents DirectSound polling loops in Thread 8 from blocking audio mutex 0xf0080000, resolving main game loop freezes:
    if (sinceCallback > 20000) { // >20ms without AAudio callback
        int64_t deltaUs = std::clamp<int64_t>(now - lastTick, 0, 100000);
        uint32_t rate = mixer.rate ? mixer.rate : 48000;
        unsigned missedFrames = static_cast<unsigned>((deltaUs * rate) / 1000000ULL);
        if (missedFrames > 0) mixer.advance(missedFrames);
    }
  • MediaTek AFE Audio HAL Driver Fix: Sanitized closeSoundStreamOnly() in guest_audio.inc to verify stream state before stopping. Calling AAudioStream_requestStop() on a disconnected stream causes deadlocks in MediaTek audio HAL drivers; disconnected streams are now closed directly.
  • Reconnect Cooldown: Added a 300 ms rate-limiting cooldown between stream reconnection attempts to avoid audio HAL contention while Android initializes recording sessions.

Adreno GPU Robustness (VK_EXT_robustness2)

  • Null Descriptor & Safe Buffer Fetch: Enabled VK_EXT_robustness2 and robustBufferAccess on Adreno GPUs to eliminate dummy sampler overhead for unbound D3D9 textures and protect against out-of-bounds vertex and index fetches.

CPU Cluster Affinity & Rendering Pipeline Optimizations

  • CPU Cluster Affinity Pinning (sched_setaffinity): Created performance_tuner.cpp / performance_tuner.h to detect CPU topology from sysfs and pin the main game render loop exclusively to performance/prime cores (Cortex-X / Cortex-A78 / Cortex-A76) with elevated priority (-10), eliminating thread migration stutters:
    int rc = sched_setaffinity(0, sizeof(cpu_set_t), &s_perf_mask);
    setpriority(PRIO_PROCESS, 0, -10);
  • ADPF (Android Dynamic Performance Framework): Added per-frame ADPF hint sessions in adpf_manager.cpp / adpf_manager.h on Android 12+ (API 31+) to communicate target vs actual frame duration to the OS thermal governor.
  • Xiaomi Joyose & MediaTek Platform Coordination: Enhanced GamePerformanceBooster.java to signal Xiaomi Joyose Game Turbo, Xiaomi PerfService, and MediaTek PerfServiceWrapper.
  • Zero-Stutter DXVK Profile:
    • d3d9.cachedDynamicBuffers = True
    • dxvk.useRawSsbo = True
    • d3d9.deferSurfaceCreation = True
    • d3d9.maxFrameLatency = 1
    • d3d9.lenientClear = True
    • d3d9.allowDiscard = True
    • d3d9.allowDoNotWait = True
    • d3d9.maxAvailableMemory = 4096
    • DXVK_LOG_LEVEL = none (eliminates synchronous logging file I/O overhead during gameplay)
    • WINEDEBUG = -all
    • MESA_SHADER_CACHE_MAX_SIZE = 1024MB

Full Changelog: v0.15.16...v0.15.17

NFSU2 Revived v0.15.16

Choose a tag to compare

@mininxd mininxd released this 07 Nov 07:06

What's Changed in v0.15.16

Crash Fixes & Engine Memory Stability

  • SUV Carpool Memory Expansion: Expanded SUV carpool allocation (0x007fa9d8) alongside standard carpools (0x007fa9d4, 0x007fa9dc) to 48 MB, preventing out-of-memory crashes when exploring the city or encountering SUV traffic in Career and Explore modes:
    for (uint32_t va : {0x007fa9d4u, 0x007fa9d8u, 0x007fa9dcu}) {
        if (memory->writable(va, 4)) {
            uint32_t* pCarpool = static_cast<uint32_t*>(ptr(va, 4));
            if (pCarpool && *pCarpool < 48000) {
                *pCarpool = 48000;
            }
        }
    }
  • CarLoadedRideInfo & Event Pool Expansion: Increased CarLoadedRideInfoSlotPool capacity at 0x0061c744 from 22 to 127 entries, and EventHandlerSlotPool at 0x005d7b07 from 20 to 128 entries to eliminate memory allocation halts:
    if (memory->writable(0x0061c744u, 1)) {
        uint8_t* pSlot = static_cast<uint8_t*>(ptr(0x0061c744u, 1));
        if (pSlot && *pSlot == 0x16) *pSlot = 0x7f;
    }
  • Heap Pointer Tagging Fix (Android 11+): Configured android:taggedPointerMode="never" in AndroidManifest.xml to prevent ARM64 pointer tagging corruption on guest 32-bit addresses:
    <application
        android:taggedPointerMode="never"
        ... />
  • Fix Front-End Loading Stall on Mali GPUs: Resolved front-end menu loading stalls and event synchronization bottlenecks on Mali-based devices and systems with delayed event queues (#25, #26).

Touch Controls & UI Performance

  • Touch Button Opacity Slider (#38): Added an on-screen opacity slider (10% to 100%) in RacingControlsView for customizable touch button transparency, saved persistently across sessions.
  • Zero-Lag Opacity Rendering: Eliminated offscreen composition overhead (canvas.saveLayerAlpha) by directly modulating paint alpha channel (applyAlpha()), preventing FPS drops:
    private int applyAlpha(int color) {
        int baseAlpha = (color >>> 24);
        int combinedAlpha = Math.round(baseAlpha * (buttonOpacity / 100f));
        return (color & 0x00FFFFFF) | (combinedAlpha << 24);
    }
  • Draggable Settings Toolbar: Added a draggable handle container using Material Symbols / Google Icons hamburger handle ([ ☰ ]), allowing players to reposition the settings card anywhere on screen to customize underlying buttons without obstruction:
    if (dragButtonRect.contains(x, y)) {
        isDraggingSettings = true;
        dragStartX = x;
        dragStartY = y;
        dragInitialOffsetX = settingsOffsetX;
        dragInitialOffsetY = settingsOffsetY;
    }

OS Refresh Rate Optimization

  • Dynamic Display Refresh Rate: Added android:appCategory="game" and dynamic display refresh rate attribute configuration to prevent custom OS skins (HyperOS, MIUI, OxygenOS) from dropping the refresh rate to 60Hz or stuttering when closing system panels:
    try {
        java.lang.reflect.Field minField = android.view.WindowManager.LayoutParams.class.getField("preferredMinDisplayRefreshRate");
        java.lang.reflect.Field maxField = android.view.WindowManager.LayoutParams.class.getField("preferredMaxDisplayRefreshRate");
        minField.setFloat(windowParams, (float) targetFps);
        maxField.setFloat(windowParams, (float) targetFps);
    } catch (Throwable ignored) {}
  • OS Stutter Troubleshooting Guide: Added readme_os_lag.md with step-by-step setup and tuning tips for HyperOS and high-refresh-rate devices.

Full Changelog: v0.15.15...v0.15.16

NFSU2 Revived v0.15.15 — Re-Released due Critical Crash

Choose a tag to compare

@github-actions github-actions released this 07 Nov 04:17

What's Changed in v0.15.15

⚠️ Crash Fixes & Engine Stability

  • Fix Unexpected Force Crash Entering Career Mode: Resolved a race condition where the background RoamTickWorker thread executed nativeRoamTick() concurrently with the guest render loop, corrupting guest heap memory and stack pointers (SEGV_ACCERR). Game frame operations now strictly run on the main rendering loop under engine locks.
  • Fix Keyboard Configuration Crash: Restored DirectInput keyboard and controller device enumeration logic from v0.15.14, preventing crashes when opening or configuring controls in the in-game Controls / Keyboard menu.
  • Carpool Memory Expansion: Expanded all 3 internal carpool allocations to 48 MB each (0x007fa9d4, 0x007fa9d8, 0x007fa9dc) and increased CarLoadedRideInfoSlotPool capacity from 22 to 127 entries (0x0061c744) to eliminate memory exhaustion crashes during world exploration.

Online & Multiplayer Fixes (eahub.eu & Adhoc Server)

  • Resolved eahub.eu Connection Block ("SSL bypass cheat"): Identified and removed the patch that stripped the * prefix from *pcnfs05.ea.com. Stripping it forced unencrypted TCP on port 20920, triggering eahub's anti-cheat rejection. Restored native SSL 2.0 connectivity on port 20921.
  • Adhoc Postoffice UDP Forwarding: Fixed PDP frame packet delivery by restoring forwardToLocalGame to relay broadcast/room UDP packets directly to the local game loopback interface (127.0.0.1:47210).
  • Fixed Socket Port Collision (EADDRINUSE): Removed duplicate dynamic DatagramSocket allocations and worker threads created per peer on port 47212, preventing thread starvation and bind errors.
  • Separation of Classic vs Web Protocols: Strictly segregated classic DirtySock / UDP routing (eahub.eu and adhoc.eahub.eu) from nfsu2-web (HTTP/WSS/WebSocket switch) to prevent handshake interception.
  • Active Roam Companion Ticking: Restored reliable guest tick loop execution for the native roam companion.

Launcher Features & Controller Enhancements (PR #21 by @Efraim2704)

  • Automatic Region Detection: Automatically detects region based on game files and asset packages, loading European assets (GLOBALTEXTURESROW.BIN), European exclusive cars (Peugeot 106, Opel Corsa), and localized European voice and movies (sdat_*.viv, MOVIES/*_*.vp6) seamlessly.
  • Gamepad Layouts (Xbox or PlayStation Style): Added controller layout option to display console-accurate button prompts (Cross, Circle, Square, Triangle vs A, B, X, Y) with console-friendly navigation (Cross accept, Circle cancel, R3 camera toggle, Map & SMS shortcuts).
  • Dynamic Touch & Gamepad Integration: Touching the screen while a gamepad is connected brings touch controls back smoothly, and gamepad inputs no longer hide them while fingers are touching the screen.
  • Native Patches: Integrated upstream native hook declarations and updated prebuilt libraries.

Code Refinements & Integration Fixes

  • Input Remapping Protection: Refined PR #21's gamepad implementation so selecting PlayStation / Xbox layout updates the visual UI button names without overriding or wiping out custom button remap configurations from v0.15.14.
  • Widescreen HUD Option: Streamlined HUD adjustments into a dedicated Widescreen HUD option (On/Off, default Off). In 4:3 / centered mode, WidescreenFix.dat is safely parked to guarantee proper alignment without stretching.
  • Launcher Cleanup: Removed non-working and unstable launcher settings to streamline options and improve stability.
  • Crash Diagnostics & Dismissible Update Alerts: Added automatic crash ZIP bundling for diagnostics and allowed update notifications to be dismissed.

Full Changelog: v0.15.14...v0.15.15