AnyFSE

repository·main·Indexed 43 days ago

https://github.com/ashpynov/anyfse

A Windows Home Application designed to provide a Gaming Full Screen Experience (FSE) by launching gaming launchers like Playnite, Steam, or LaunchBox in full-screen mode. It is optimized for handheld devices such as the ASUS ROG Ally, featuring custom button remapping via the ACSE Filter Injector and support for shuffled video splash screens.

Tokens
8.3K
Snippets
23
Records
30
Agent score
56%

What's inside AnyFSE

  1. ASUS ROG Ally button remapping and ACSE Filter

    main

    On ASUS ROG Ally devices, AnyFSE can redefine the Armoury Crate, Command Center, and Library buttons, including combinations with the Mode button.

    Handling Conflicts with ASUS Software

    If both AnyFSE and ASUS software (like Armoury Crate SE) handle the same button inputs, the native ASUS action may still trigger. To prevent this, you can either uninstall Armoury Crate SE or use the AnyFSE ACSE Filter Injector.

    The ACSE Filter Injector

    The AnyFSE ACSE Filter Injector is a Windows service that monitors the AsusOptimization.exe process. When remapping is enabled, it injects AnyFSE.ACSEFilterHook.dll into that process to intercept and suppress specific ASUS-specific button reports (Armoury Crate, Command Center, and Library) while allowing all other inputs to pass through normally.

    Note on Antivirus Alerts: The injection technique (using VirtualAllocEx, WriteProcessMemory, etc.) and the service's behavior of monitoring processes may trigger antivirus software (like Windows Defender) as these are common patterns used by malware. However, the filter is designed to be non-intrusive, contains no networking or malicious payloads, and only targets specific HID reports for ASUS devices (Vendor ID 0x0B05).

  2. Extract and trust the public CER file

    main

    The installer requires a public .cer file to be present in the build directory. You must export the public certificate from your personal store and place it in the repository root.

    1. Export the certificate using the script below (ensure $publisherCn matches your certificate subject):
    $publisherCn = "Your Publisher Name"
    $certFile = ".\Your.Publisher.cer"
    
    $cert = Get-ChildItem Cert:\CurrentUser\My |
        Where-Object { $_.Subject -eq "CN=$publisherCn" -and $_.HasPrivateKey } |
        Sort-Object NotAfter -Descending |
        Select-Object -First 1
    
    if (-not $cert) {
        throw "Code-signing certificate not found for CN=$publisherCn"
    }
    
    Export-Certificate -Cert $cert -FilePath $certFile
    1. Trust the certificate locally: To allow your machine to trust packages signed by this certificate, run PowerShell as Administrator and import it into the Local Machine Trusted Root:
    Import-Certificate `
        -FilePath ".\Your.Publisher.cer" `
        -CertStoreLocation "Cert:\LocalMachine\Root"
    1. Update Constants: If you use a filename other than the default Artem.Shpynov.cer, you must update the PublisherCertFile entry in src\App\Constants.hpp.
    # Exporting the certificate
    $publisherCn = "Your Publisher Name"
    $certFile = ".\Your.Publisher.cer"
    
    $cert = Get-ChildItem Cert:\CurrentUser\My |
        Where-Object { $_.Subject -eq "CN=$publisherCn" -and $_.HasPrivateKey } |
        Sort-Object NotAfter -Descending |
        Select-Object -First 1
    
    Export-Certificate -Cert $cert -FilePath $certFile
    
    # Trusting the certificate (Run as Admin)
    Import-Certificate -FilePath ".\Your.Publisher.cer" -CertStoreLocation "Cert:\LocalMachine\Root"
  3. Scan the offline installer with VirusTotal

    main

    You can automate the scanning of your offline installer using the VirusTotal API.

    1. Set the API Key: Set your VirusTotal API v3 key in your environment before launching VS Code:
    $env:VIRUSTOTAL_API_KEY = '<your API key>'
    code .
    1. Run the Scan:
    • Use the VS Code task Check AnyFSE.Installer Offline with VirusTotal.
    • Or run the script manually for a specific file:
    .\scripts\Test-VirusTotal.ps1 -FilePath .\build\Release\AnyFSE.Installer.Offline.0.90.18-56.exe

    Warning: The public API is rate-limited and files uploaded via the public API may be shared with VirusTotal partners. Do not use this for confidential builds.

    # Manual scan command
    .\scripts\Test-VirusTotal.ps1 -FilePath .\build\Release\AnyFSE.Installer.Offline.0.90.18-56.exe
  4. Install AnyFSE

    main

    To install AnyFSE, run the installer executable and then configure the application via the Start menu.

    Note: AnyFSE does not enable Windows Full Screen Experience (FSE) mode itself. You must use a supported handheld device (like ASUS ROG Ally) or use a third-party tool like XboxFullscreenExperienceTool to enable FSE mode on other devices.

    Prerequisites:

    • You must have your preferred launcher (e.g., Playnite, Steam, LaunchBox) already installed on your system.
    • AnyFSE only functions as intended when selected as the Home application in Windows via Settings -> Gaming -> Full screen experience.
    # Run the installer
    AnyFSE.Installer.exe
    
    # Configure via Start Menu after installation
  5. Prerequisites for building AnyFSE

    main

    To build the AnyFSE repository, ensure your environment meets the following requirements:

    • Visual Studio 2022 Community (v17.4 or later) with the Desktop development with C++ workload installed.
    • MSVC C++ platform toolset v143.
    • Windows SDK / Platform SDK 10.0.26100.0.
    • PowerShell with the PKI module (specifically New-SelfSignedCertificate).
    • Visual Studio Code is recommended for editing and building. Note that .vcxproj files are hand-written and may not be preserved correctly if edited using the Visual Studio project designer.

    To verify your local tool versions, run the following in PowerShell:

    $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
    & $vswhere -version '[17.0,18.0)' -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationVersion
    
    Get-ChildItem 'C:\Program Files (x86)\Windows Kits\10\bin' -Directory |
        Select-Object -ExpandProperty Name
  6. Build the offline package

    main

    To build the Release x64 offline installer, you must first enter the Visual Studio developer environment via PowerShell and then execute MSBuild.

    1. Enter the Dev Shell:
    Set-Location C:\Users\ashpynov\source\repos\ashpynov\AnyFSE\AnyFSE
    $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
    $vsInstall = & $vswhere -version '[17.0,18.0)' -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
    & "$vsInstall\Common7\Tools\Launch-VsDevShell.ps1" -Arch amd64 -HostArch amd64
    1. Run MSBuild:
    & $msbuild .\AnyFSE.sln `
        /m `
        /p:Configuration=Release `
        /p:Platform=x64 `
        /p:Offline=Offline `
        /p:WindowsTargetPlatformVersion=10.0.26100.0

    Outputs: The resulting files (including .appx, .zip, .pdb.zip, and the .exe installer) will be located in build\Release\.

    Note: AnyFSE.Package.vcxproj increments <VersionRevision> in AnyFSE.Version.props during packaging. Review this file after every packaging build.

    # Build command
    & $msbuild .\AnyFSE.sln /m /p:Configuration=Release /p:Platform=x64 /p:Offline=Offline /p:WindowsTargetPlatformVersion=10.0.26100.0
  7. Disable update checks for offline/private builds

    main

    If you are creating a private or offline build, you should disable update checks in the source code to prevent the application from attempting to contact upstream servers.

    1. Modify Configuration Defaults

    In src\Configuration\Config.cpp, set the following values:

    int  Config::UpdateCheckInterval = -2;     // Manual
    bool Config::UpdateNotifications = false;  // No update notifications

    Ensure the /Update/CheckInterval load fallback is -2 and /Update/Notifications is false in the same file.

    2. Disable UI Triggers

    • src\AppSettings\SettingsDialog.Update.cpp: Comment out the network trigger inside SettingsDialog::OnCheckUpdate().
    • src\AppSettings\SettingsPages\UpdatePage.cpp: Comment out the trigger inside UpdatePage::UpdateSettingsChangedCheck().

    3. Disable Scheduled Triggers

    In src\Updater\Updater.cpp, modify ScheduledCheckAsync to return the checkInterval immediately, effectively making it a no-op:

    int ScheduledCheckAsync(const std::wstring& lastCheck, int checkInterval, bool includePreRelease, HWND hWnd, UINT uMsg)
    {
        return checkInterval;
        // ... existing logic ...
    }

    4. Optional Cleanup

    Clear or update the release URLs in src\App\Constants.hpp and src\Updater\Updater.cpp to prevent accidental future contact with the upstream project.

    // src\Configuration\Config.cpp
    int  Config::UpdateCheckInterval = -2;     // Manual
    bool Config::UpdateNotifications = false;  // No update notifications
  8. Configure publisher and certificate references

    main

    When changing the publisher or certificate, you must update the following files simultaneously to maintain consistency:

    1. AnyFSE.Version.props: Update <AssemblyCompany>, <AssemblyCopyright>, and <PublisherCN>. Set PublisherCN to match the certificate's Common Name (CN).
    2. AppxManifest.xml: Update <Identity Name="..."> (if renaming) and <Identity Publisher="CN=..."> to exactly match the certificate subject (e.g., Publisher="CN=Your Publisher Name").
    3. AnyFSE.Package.vcxproj: Update <CertificateName> for build output clarity.
    4. src\App\Constants.hpp:
      • Update PublisherCertFile with the name of your exported .cer file.
      • If the package identity changed, update PackageFamilyName, AppUserModelId, and PackageAtomName.
      • For private builds, update GitHubReleaseRoot, CodebergReleaseRoot, and updater user-agent strings.

    Tip: To find the correct PackageFamilyName after installing a test package, use:

    Get-AppxPackage -Name "Your.Package.Identity.Name" | Select-Object Name, Publisher, PackageFamilyName, PackageFullName

    Note that AppUserModelId should be formatted as <PackageFamilyName>!App.

  9. Create a self-signed code-signing certificate

    main

    The build system uses a self-signed certificate from Cert:\CurrentUser\My to sign binaries and packages. To ensure compatibility with the MSBuild targets, the certificate's subject must contain PublisherCN (for AnyFSE.Package.vcxproj) and AssemblyCompany (for the installer and uninstaller). The simplest approach is to set the certificate subject to CN=<PublisherCN> and align AssemblyCompany with PublisherCN.

    Run the following PowerShell script to generate a 4096-bit RSA certificate and export it as a .pfx file:

    Set-Location C:\Users\ashpynov\source\repos\ashpynov\AnyFSE\AnyFSE
    
    $publisherName = "Your Publisher Name"
    $publisherCn = $publisherName
    $certBaseName = "Your.Publisher.AnyFSE"
    $pfxPassword = Read-Host "PFX password" -AsSecureString
    
    New-Item -ItemType Directory -Path .\certs -Force | Out-Null
    
    $cert = New-SelfSignedCertificate `
        -Type CodeSigningCert `
        -Subject "CN=$publisherCn" `
        -FriendlyName "$publisherName AnyFSE Code Signing" `
        -CertStoreLocation "Cert:\CurrentUser\My" `
        -KeyAlgorithm RSA `
        -KeyLength 4096 `
        -HashAlgorithm SHA256 `
        -KeyExportPolicy Exportable `
        -KeyUsage DigitalSignature `
        -NotAfter (Get-Date).AddYears(10)
    
    Export-PfxCertificate `
        -Cert $cert `
        -FilePath ".\certs\$certBaseName.pfx" `
        -Password $pfxPassword
  10. Configure custom splash videos

    main

    AnyFSE can display shuffled video splash screens while your launcher is loading.

    Setup Steps:

    1. Navigate to the AnyFSE data folder: C:\ProgramData\AnyFSE.
    2. Create a folder named splash inside that directory.
    3. Place your .mp4 or .webm video files into the splash folder. AnyFSE will shuffle these files each time a splash screen is shown.

    Best Practice: To avoid seeing two splash screens, suppress your launcher's native splash screen. For example, in Playnite, add the --hidesplashscreen startup argument in AnyFSE settings.

    Filename-based Loop Control: You can control the loop behavior by including specific tokens in the filename before the extension (e.g., filename.m4000.mp4 or filename.5000.webm).

    • m or M: Mutes the video during the loop.
    • [number]: The position in milliseconds from the start of the video to which the player will rewind during the loop (e.g., 4000 rewinds to 4 seconds).
    # Example filenames for loop control
    splash.m4000.mp4
    other_splash.5000.webm
  11. Configure and Launch AnyFSE

    main

    After installation, you can access the configuration interface through the Windows Start menu:

    1. Locate the AnyFSE application in your Start menu.
    2. Right-click the application.
    3. Select the 'Configure' task.
  12. Understand the AppInstaller lifecycle pages

    main

    The AppInstaller manages a multi-page wizard interface. The flow is controlled internally via the Pages enumeration. While end-users interact with the UI, developers looking at the installation logic can track the state through these stages:

    • Welcome: The initial landing page.
    • Path: Selection of the installation directory.
    • Progress: Visual feedback during file extraction or installation.
    • Complete: Final success screen.
    • Error: Error handling screen.
    • None: Initial state.