PS2 Web Recomp
PS2 Web Recomp is een technisch project waarmee PlayStation 2-games in een webbrowser kunnen worden afgespeeld zonder gebruik van een traditionele emulator. In plaats daarvan wordt de machinecode van de Emotion Engine vooraf vertaald naar C++, gecompileerd naar WebAssembly en gekoppeld aan een reimplementatie van de PS2-hardware en het besturingssysteem.
Technische Werkwijze
- Recompilatie: Met het hulpmiddel
eerecomp wordt de gamecode omgezet naar C++, waarbij specifieke eigenschappen van de R5900 CPU (zoals 128-bit registers en floating-point gedrag) behouden blijven.
- Graphics: De Graphics Synthesizer (GS) wordt nagebootst via WebGPU compute shaders, wat zorgt voor hoge prestaties en de mogelijkheid om de native resolutie te verhogen.
- Vector Units: Microprogramma's worden vooraf gecompileerd naar SIMD C++ of ter plekke vertaald naar WebAssembly.
- Systeem: De I/O-processor wordt beheerd via een interpreter, terwijl de audio (SPU2) en video (IPU/MPEG-2) volledig zijn reimplementeerd.
Resultaten en Optimalisaties
Het project is succesvol getest met veeleisende titels zoals Gran Turismo 4 en God of War II. Door optimalisaties in texture caching, het verminderen van compute dispatches en het gebruik van MessageChannel voor browser-scheduling, kunnen games op moderne laptops op volle snelheid (50-60 fps) draaien.
Gebruik en Porting
Gebruikers kunnen zelf games porten via een Linux-omgeving met specifieke tools (CMake, Ninja, Emscripten). Het systeem vereist een browser met WebGPU-ondersteuning (zoals Chrome of Edge) en maakt gebruik van browser-opslag voor het beheren van virtuele geheugenkaarten.
PS2 Web Recomp
Toegepaste Voorbeelden
Dit project is een zustersysteem van psp-web-recomp en volgt dezelfde methode.
Gran Turismo 4
De eerste titel die op deze manier werd opgestart is Gran Turismo 4, gekozen omdat dit een van de meest veeleisende games op het systeem is. Het spel maakt intensief gebruik van beide vector units, vereist exact floating-point gedrag voor replays en licentietesten, en gebruikt grafische trucs waarbij gerenderde beelden als paletten worden teruggelezen.
Het spel draait volledig, van het opstarten en de openingsfilm tot de menu's en races, inclusief muziek en geluidseffecten. Voortgang wordt opgeslagen op een geheugenkaart die in de browser wordt bewaard. Op een laptop met een geïntegreerde GPU in Chrome draait een race op volle snelheid (50 frames per seconde voor deze PAL-release) op een tweevoudige resolutie ten opzichte van de PS2.
God of War II
God of War II werd via dezelfde scripts geïmplementeerd. Er was geen gamespecifieke code nodig, maar het proces bracht twee bugs aan het licht die Gran Turismo 4 niet had getriggerd: één in de recompiler en één in de timing van de vector unit, naast enkele ontbrekende onderdelen van de I/O-processor van de PS2.
Het spel speelt nu van de menu's via de tussenfilmpjes tot aan de gevechten. Bij de native PS2-resolutie in Chrome haalt het spel 60 frames per seconde, zelfs tijdens zware gevechten. Bij een tweevoudige resolutie varieert dit tussen de 48 en 60 fps, beperkt door de geïntegreerde GPU van de laptop.
Let op: Er worden geen gamegegevens meegeleverd. De gebruiker dient zelf een disc-image van een eigen spel te gebruiken, waarna de scripts in deze repository dit omzetten naar een webpagina op de eigen machine.
Hoe het werkt
Recompilatie
eerecomp leest het uitvoerbare bestand van het spel, volgt de control flow om functies te vinden en genereert C++ code in eenheden van 16 KiB guest code. De output behoudt de eigenschappen van de R5900:
- 128-bit registers en de bijbehorende multimedia-instructies.
- Branch delay slots.
- De floating-point unit van de PS2 (die geen infinities of denormals kent en anders afrondt dan IEEE).
- Vector unit 0 die als coprocessor fungeert.
Sprongen tussen eenheden worden tail calls. Een thread-switch ontwindt de host stack en hervat de uitvoering bij het guest-adres, waardoor de gegenereerde code geen aparte stack per guest-thread nodig heeft.
Een compacte PS2-kernel
De EE-zijde van het besturingssysteem wordt afgehandeld via high-level emulatie: threads, semaforen, interrupt handlers voor de DMA-controller en de vertical blank, alarms, en het SIF-kanaal dat de hoofd-CPU verbindt met de I/O-processor.
De I/O-processor draait de eigen IRX-modules van het spel (geluidsdriver, disc streaming code, controller- en geheugenkaartdrivers) via een interpreter van de R3000 CPU. De IOP-kernel en de libraries die deze modules aanroepen zijn echter reimplementaties in C++. De disc wordt gelezen via HTTP Range requests, zodat alleen het uitvoerbare bestand vooraf wordt gedownload.
Vector Units
Het grootste deel van het 3D-werk van een PS2-game gebeurt in microprogramma's die het spel uploadt naar vector unit 1. Deze draaien met bit-exacte PS2 float-berekeningen en gemodelleerde pipeline-vertragingen van de MAC, status en clip flags, omdat games hun code hierop inplannen.
Microprogramma's die tijdens een testrun worden waargenomen, worden vooraf gecompileerd naar SIMD C++. Programma's die de pagina voor het eerst tegenkomt, worden ter plekke vertaald naar een WebAssembly-module (dit duurt enkele milliseconden per programma).
Grafische weergave
De 4 MB videogeheugen van de Graphics Synthesizer (GS) bevindt zich op de GPU in native swizzled layouts. Het tekenen gebeurt via WebGPU compute shaders: driehoeken worden in tiles verdeeld en gerasteriseerd volgens de eigen regels van de GS voor texturing, paletten, alpha blending, depth en destination alpha tests.
Omdat alles in het GS-geheugen blijft, werken effecten die renderen naar een textuur of een framebuffer als palet herinterpreteren precies zoals op de console. De interne resolutie kan één, twee of drie keer de native resolutie zijn. Ter referentie is er een software-rasterizer beschikbaar om de GPU-output te controleren.
Threads
De emulatie draait in een worker. Vector unit 1 heeft een eigen worker (net zoals deze parallel draait op de console). De GS-commando's gaan via een ring buffer naar de paginathread, die de WebGPU-device beheert.
Geluid en video
De SPU2 is reimplementiert met 48 ADPCM-stemmen, ADSR-enveloppen en de streaming DMA voor muziek. De output gaat via shared memory naar een AudioWorklet. Video's worden gedecodeerd door een implementatie van de IPU, de MPEG-2-decoder van de PS2.
Optimalisaties en lessen
De eerste race draaide op 3 frames per seconde (fps) met een software-rasterizer en een interpreter voor vector unit 1. Door de GS over te zetten naar WebGPU compute shaders en de vector unit-programma's te compileren, steeg dit naar ongeveer 70 fps. De resterende optimalisaties richtten zich op de browser-overhead:
- Compute Dispatches: De eerste GPU-renderer verstuurde circa 650 compute dispatches per frame. Door texture-uploads en palette-loads te verschuiven naar voren (hoisting), werd dit teruggebracht naar ongeveer 80.
- Texture Caching: Gran Turismo 4 uploadt elke frame 3 MB aan textures. Door een cache van 16 MB op de GPU aan te leggen voor recent geüploade inhoud, werd de hoeveelheid data per frame met ongeveer 60% verminderd.
- Shader Divergentie: Bij een drievoudige resolutie zakte de framerate naar 23 fps. Profiling toonde aan dat de per-triangle setup divergent was en dat grote uploads de paginathread blokkeerden. Door de setup uniform te laden en data in één stuk te schrijven, steeg de snelheid naar 48-50 fps op dezelfde geïntegreerde GPU.
- Browser Scheduling: Omdat geneste
setTimeout-aanroepen beperkt zijn tot 4 ms, is de emulatie-loop nu aangepast om via een MessageChannel af te geven. Door de emulatie in een worker te plaatsen, werd de framerate gestabiliseerd op een constante 50 fps.
Technische uitdagingen bij God of War II
God of War II kon via port.sh met alleen generieke wijzigingen worden omgezet, maar legde diverse bugs bloot:
- Geluid: Het spel was aanvankelijk stil omdat de geluidsdriver afhankelijk is van een hardware-timer van de I/O-processor die nog niet was geïmplementeerd.
- Crashes en Rendering: In het begin verschenen er enorme platte polygonen. Het spel crashte wanneer de render-lijst het einde van het geheugen bereikte en de vertical blank-handlers overschreef.
- Recompiler Bug: Er werd een fout ontdekt waarbij een branch als laatste instructie van een 16 KiB-unit stond. Het pad dat de branch niet nam, vervolgde de uitvoering in de volgende unit bij de delay slot in plaats van daarna, waardoor instructies dubbel werden uitgevoerd of onterecht werden overgeslagen.
- Vector Unit Timing: De enorme polygonen werden veroorzaakt door driehoeken die geculd hadden moeten worden. De microcode van God of War II leest de clip-flags drie instructies na de CLIP-instructie; het model maakte deze pas na vier instructies zichtbaar. Gran Turismo 4 merkte dit niet omdat die microcode langer wacht.
Daarnaast waren een boot-pad (vergelijkbaar met de BIOS), modules die vanuit het geheugen in plaats van de disc worden geladen, en de destination chain mode van de scratchpad DMA nodig.
Zelf een game porten
Vereisten
- git, CMake, Ninja
- C++20 compiler (Clang heeft de voorkeur)
- Python 3
- 7-Zip (voor .7z disc-images)
- Besturingssysteem: Linux op x86-64
Bij de eerste run wordt de Emscripten SDK geïnstalleerd in tools/emsdk en wordt wgpu-native gedownload voor de headless test runner. Houd rekening met ongeveer 300 MB schijfruimte per game voor de gegenereerde code en builds; de disc-image zelf wordt gelinkt en niet gekopieerd.
Instructies
git clone https://github.com/snuri00/ps2-web-recomp.git
cd ps2-web-recomp
scripts/port.sh mygame "My Game.iso"
python3 scripts/serve.py build/web-mygame games/mygame/disc.iso # http://localhost:8620/
port.sh voert het volledige proces uit: het leest het boot-programma uit SYSTEM.CNF, vertaalt de machinecode naar C++ en draait het spel enkele keren in headless mode. Omdat statische analyse niet alle functies via pointers kan vinden, registreert elke run onbekende adressen, waarna het script deze toevoegt als entry points en opnieuw vertaalt. Ook de vector unit microprogramma's worden tijdens deze runs vastgelegd en vooraf gecompileerd. God of War II wordt in ongeveer 3,5 minuut omgezet op een 8-core laptop.
De exploring runs simuleren een speler door op 'Start' te drukken en elke vijf seconden op 'Kruis'. Dit kan worden aangepast met --press 900:cross voor eigen inputs en --frames voor de duur van de run. Frames van de laatste run worden opgeslagen in games/mygame/shots. Gebruik scripts/build_web.sh mygame om alleen de pagina opnieuw te bouwen.
Verwachtingen: Tot nu toe zijn twee games succesvol geport. Andere games zullen waarschijnlijk stoppen bij een niet-geïmplementeerde system call of IOP-library functie (gelogd als [sys] unhandled syscall of [iop] missing <library> #<n>), of een GS-functie gebruiken die de renderer nog niet ondersteunt.
Browserondersteuning en Bediening
WebGPU
De pagina heeft WebGPU nodig voor de GPU-renderer. Chrome en Edge ondersteunen dit op Windows en macOS. Op Linux moet dit handmatig worden ingeschakeld in Chrome/Chromium via:
chrome://flags/#enable-unsafe-webgpu
chrome://flags/#enable-vulkan
Zonder WebGPU neemt de software-renderer het over; dit is voldoende voor menu's, maar te traag voor 3D. Op laptops met twee GPU's probeert de pagina beide adapters te gebruiken en valt indien nodig terug op het kopiëren van frames via een 2D-canvas.
Besturing
- Toetsenbord:
- Face buttons: Z (kruis), X (cirkel), A (vierkant), S (driehoek)
- Shoulders: Q, W, 1, 2
- Start/Select: Enter / Backspace
- D-pad: Pijltjestoetsen
- Linker stick: I, J, K, L
- Overig: Gamepads werken via de browser Gamepad API, telefoons krijgen on-screen controls, en de
F-toets schakelt fullscreen. De resolutie-selector herlaadt de pagina bij een wijziging.
Opslag (Saves)
De pagina plaatst een geheugenkaart in slot 1 en bewaart deze in de browseropslag van het adres van waaruit wordt gespeeld. Games formatteren en gebruiken deze kaart zoals een echte kaart.
- Export card: Downloadt de kaart als een
.ps2 bestand (compatibel met PCSX2).
- Import card: Plaatst een
.ps2 bestand terug in het slot.
?nocard start het spel met een leeg slot.
Hosting
De pagina maakt gebruik van SharedArrayBuffer voor threads en moet daarom cross-origin isolated worden geserveerd met de volgende headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
scripts/serve.py verzendt beide headers en ondersteunt de Range requests die nodig zijn voor disc streaming.
Juridische Informatie
Deze repository bevat uitsluitend originele code en third-party code onder de eigen licenties. Er is geen gamecode of game-data inbegrepen. De gegenereerde C++ en WebAssembly zijn vertalingen van het uitvoerbare bestand van het spel en behoren daarmee toe aan de eigenaren van het spel; bewaar deze op je eigen machine en publiceer ze niet. Gebruik uitsluitend disc-images van spellen die je zelf bezit.
Gran Turismo, God of War en PlayStation zijn handelsmerken van Sony Interactive Entertainment. Dit project is niet gelieerd aan of onderschreven door Sony, Polyphony Digital, Santa Monica Studio of andere game-uitgevers.
Credits & Licentie
- MPEG-decoder: De VLC-tabellen zijn aangepast van Play! (BSD 2-clause).
- Referenties: PCSX2, Play! en de ps2sdk headers dienden als referentie voor de hardware- en systeememulatie.
- Technologie:
wgpu-native en Dawn zorgen voor WebGPU, en Emscripten bouwt de WebAssembly.
- Licentie: De code in deze repository is beschikbaar onder de MIT-licentie. De bestanden in
runtime/src/ipu/tables.hpp bevatten de BSD 2-clause notice van Play!.
PS2 Web Recomp
Toegepaste Voorbeelden
Dit project is een zustersysteem van psp-web-recomp en volgt dezelfde methode.
Gran Turismo 4
De eerste titel die op deze manier werd opgestart is Gran Turismo 4, gekozen omdat dit een van de meest veeleisende games op het systeem is. Het spel maakt intensief gebruik van beide vector units, vereist exact floating-point gedrag voor replays en licentietesten, en gebruikt grafische trucs waarbij gerenderde beelden als paletten worden teruggelezen.
Het spel draait volledig, van het opstarten en de openingsfilm tot de menu's en races, inclusief muziek en geluidseffecten. Voortgang wordt opgeslagen op een geheugenkaart die in de browser wordt bewaard. Op een laptop met een geïntegreerde GPU in Chrome draait een race op volle snelheid (50 frames per seconde voor deze PAL-release) op een tweevoudige resolutie ten opzichte van de PS2.
God of War II
God of War II werd via dezelfde scripts geïmplementeerd. Er was geen gamespecifieke code nodig, maar het proces bracht twee bugs aan het licht die Gran Turismo 4 niet had getriggerd: één in de recompiler en één in de timing van de vector unit, naast enkele ontbrekende onderdelen van de I/O-processor van de PS2.
Het spel speelt nu van de menu's via de tussenfilmpjes tot aan de gevechten. Bij de native PS2-resolutie in Chrome haalt het spel 60 frames per seconde, zelfs tijdens zware gevechten. Bij een tweevoudige resolutie varieert dit tussen de 48 en 60 fps, beperkt door de geïntegreerde GPU van de laptop.
Let op: Er worden geen gamegegevens meegeleverd. De gebruiker dient zelf een disc-image van een eigen spel te gebruiken, waarna de scripts in deze repository dit omzetten naar een webpagina op de eigen machine.
Hoe het werkt
Recompilatie
eerecomp leest het uitvoerbare bestand van het spel, volgt de control flow om functies te vinden en genereert C++ code in eenheden van 16 KiB guest code. De output behoudt de eigenschappen van de R5900:
- 128-bit registers en de bijbehorende multimedia-instructies.
- Branch delay slots.
- De floating-point unit van de PS2 (die geen infinities of denormals kent en anders afrondt dan IEEE).
- Vector unit 0 die als coprocessor fungeert.
Sprongen tussen eenheden worden tail calls. Een thread-switch ontwindt de host stack en hervat de uitvoering bij het guest-adres, waardoor de gegenereerde code geen aparte stack per guest-thread nodig heeft.
Een compacte PS2-kernel
De EE-zijde van het besturingssysteem wordt afgehandeld via high-level emulatie: threads, semaforen, interrupt handlers voor de DMA-controller en de vertical blank, alarms, en het SIF-kanaal dat de hoofd-CPU verbindt met de I/O-processor.
De I/O-processor draait de eigen IRX-modules van het spel (geluidsdriver, disc streaming code, controller- en geheugenkaartdrivers) via een interpreter van de R3000 CPU. De IOP-kernel en de libraries die deze modules aanroepen zijn echter reimplementaties in C++. De disc wordt gelezen via HTTP Range requests, zodat alleen het uitvoerbare bestand vooraf wordt gedownload.
Vector Units
Het grootste deel van het 3D-werk van een PS2-game gebeurt in microprogramma's die het spel uploadt naar vector unit 1. Deze draaien met bit-exacte PS2 float-berekeningen en gemodelleerde pipeline-vertragingen van de MAC, status en clip flags, omdat games hun code hierop inplannen.
Microprogramma's die tijdens een testrun worden waargenomen, worden vooraf gecompileerd naar SIMD C++. Programma's die de pagina voor het eerst tegenkomt, worden ter plekke vertaald naar een WebAssembly-module (dit duurt enkele milliseconden per programma).
Grafische weergave
De 4 MB videogeheugen van de Graphics Synthesizer (GS) bevindt zich op de GPU in native swizzled layouts. Het tekenen gebeurt via WebGPU compute shaders: driehoeken worden in tiles verdeeld en gerasteriseerd volgens de eigen regels van de GS voor texturing, paletten, alpha blending, depth en destination alpha tests.
Omdat alles in het GS-geheugen blijft, werken effecten die renderen naar een textuur of een framebuffer als palet herinterpreteren precies zoals op de console. De interne resolutie kan één, twee of drie keer de native resolutie zijn. Ter referentie is er een software-rasterizer beschikbaar om de GPU-output te controleren.
Threads
De emulatie draait in een worker. Vector unit 1 heeft een eigen worker (net zoals deze parallel draait op de console). De GS-commando's gaan via een ring buffer naar de paginathread, die de WebGPU-device beheert.
Geluid en video
De SPU2 is reimplementiert met 48 ADPCM-stemmen, ADSR-enveloppen en de streaming DMA voor muziek. De output gaat via shared memory naar een AudioWorklet. Video's worden gedecodeerd door een implementatie van de IPU, de MPEG-2-decoder van de PS2.
Optimalisaties en lessen
De eerste race draaide op 3 frames per seconde (fps) met een software-rasterizer en een interpreter voor vector unit 1. Door de GS over te zetten naar WebGPU compute shaders en de vector unit-programma's te compileren, steeg dit naar ongeveer 70 fps. De resterende optimalisaties richtten zich op de browser-overhead:
- Compute Dispatches: De eerste GPU-renderer verstuurde circa 650 compute dispatches per frame. Door texture-uploads en palette-loads te verschuiven naar voren (hoisting), werd dit teruggebracht naar ongeveer 80.
- Texture Caching: Gran Turismo 4 uploadt elke frame 3 MB aan textures. Door een cache van 16 MB op de GPU aan te leggen voor recent geüploade inhoud, werd de hoeveelheid data per frame met ongeveer 60% verminderd.
- Shader Divergentie: Bij een drievoudige resolutie zakte de framerate naar 23 fps. Profiling toonde aan dat de per-triangle setup divergent was en dat grote uploads de paginathread blokkeerden. Door de setup uniform te laden en data in één stuk te schrijven, steeg de snelheid naar 48-50 fps op dezelfde geïntegreerde GPU.
- Browser Scheduling: Omdat geneste
setTimeout-aanroepen beperkt zijn tot 4 ms, is de emulatie-loop nu aangepast om via een MessageChannel af te geven. Door de emulatie in een worker te plaatsen, werd de framerate gestabiliseerd op een constante 50 fps.
Technische uitdagingen bij God of War II
God of War II kon via port.sh met alleen generieke wijzigingen worden omgezet, maar legde diverse bugs bloot:
- Geluid: Het spel was aanvankelijk stil omdat de geluidsdriver afhankelijk is van een hardware-timer van de I/O-processor die nog niet was geïmplementeerd.
- Crashes en Rendering: In het begin verschenen er enorme platte polygonen. Het spel crashte wanneer de render-lijst het einde van het geheugen bereikte en de vertical blank-handlers overschreef.
- Recompiler Bug: Er werd een fout ontdekt waarbij een branch als laatste instructie van een 16 KiB-unit stond. Het pad dat de branch niet nam, vervolgde de uitvoering in de volgende unit bij de delay slot in plaats van daarna, waardoor instructies dubbel werden uitgevoerd of onterecht werden overgeslagen.
- Vector Unit Timing: De enorme polygonen werden veroorzaakt door driehoeken die geculd hadden moeten worden. De microcode van God of War II leest de clip-flags drie instructies na de CLIP-instructie; het model maakte deze pas na vier instructies zichtbaar. Gran Turismo 4 merkte dit niet omdat die microcode langer wacht.
Daarnaast waren een boot-pad (vergelijkbaar met de BIOS), modules die vanuit het geheugen in plaats van de disc worden geladen, en de destination chain mode van de scratchpad DMA nodig.
Zelf een game porten
Vereisten
- git, CMake, Ninja
- C++20 compiler (Clang heeft de voorkeur)
- Python 3
- 7-Zip (voor .7z disc-images)
- Besturingssysteem: Linux op x86-64
Bij de eerste run wordt de Emscripten SDK geïnstalleerd in tools/emsdk en wordt wgpu-native gedownload voor de headless test runner. Houd rekening met ongeveer 300 MB schijfruimte per game voor de gegenereerde code en builds; de disc-image zelf wordt gelinkt en niet gekopieerd.
Instructies
git clone https://github.com/snuri00/ps2-web-recomp.git
cd ps2-web-recomp
scripts/port.sh mygame "My Game.iso"
python3 scripts/serve.py build/web-mygame games/mygame/disc.iso # http://localhost:8620/
port.sh voert het volledige proces uit: het leest het boot-programma uit SYSTEM.CNF, vertaalt de machinecode naar C++ en draait het spel enkele keren in headless mode. Omdat statische analyse niet alle functies via pointers kan vinden, registreert elke run onbekende adressen, waarna het script deze toevoegt als entry points en opnieuw vertaalt. Ook de vector unit microprogramma's worden tijdens deze runs vastgelegd en vooraf gecompileerd. God of War II wordt in ongeveer 3,5 minuut omgezet op een 8-core laptop.
De exploring runs simuleren een speler door op 'Start' te drukken en elke vijf seconden op 'Kruis'. Dit kan worden aangepast met --press 900:cross voor eigen inputs en --frames voor de duur van de run. Frames van de laatste run worden opgeslagen in games/mygame/shots. Gebruik scripts/build_web.sh mygame om alleen de pagina opnieuw te bouwen.
Verwachtingen: Tot nu toe zijn twee games succesvol geport. Andere games zullen waarschijnlijk stoppen bij een niet-geïmplementeerde system call of IOP-library functie (gelogd als [sys] unhandled syscall of [iop] missing <library> #<n>), of een GS-functie gebruiken die de renderer nog niet ondersteunt.
Browserondersteuning en Bediening
WebGPU
De pagina heeft WebGPU nodig voor de GPU-renderer. Chrome en Edge ondersteunen dit op Windows en macOS. Op Linux moet dit handmatig worden ingeschakeld in Chrome/Chromium via:
chrome://flags/#enable-unsafe-webgpu
chrome://flags/#enable-vulkan
Zonder WebGPU neemt de software-renderer het over; dit is voldoende voor menu's, maar te traag voor 3D. Op laptops met twee GPU's probeert de pagina beide adapters te gebruiken en valt indien nodig terug op het kopiëren van frames via een 2D-canvas.
Besturing
- Toetsenbord:
- Face buttons: Z (kruis), X (cirkel), A (vierkant), S (driehoek)
- Shoulders: Q, W, 1, 2
- Start/Select: Enter / Backspace
- D-pad: Pijltjestoetsen
- Linker stick: I, J, K, L
- Overig: Gamepads werken via de browser Gamepad API, telefoons krijgen on-screen controls, en de
F-toets schakelt fullscreen. De resolutie-selector herlaadt de pagina bij een wijziging.
Opslag (Saves)
De pagina plaatst een geheugenkaart in slot 1 en bewaart deze in de browseropslag van het adres van waaruit wordt gespeeld. Games formatteren en gebruiken deze kaart zoals een echte kaart.
- Export card: Downloadt de kaart als een
.ps2 bestand (compatibel met PCSX2).
- Import card: Plaatst een
.ps2 bestand terug in het slot.
?nocard start het spel met een leeg slot.
Hosting
De pagina maakt gebruik van SharedArrayBuffer voor threads en moet daarom cross-origin isolated worden geserveerd met de volgende headers:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
scripts/serve.py verzendt beide headers en ondersteunt de Range requests die nodig zijn voor disc streaming.
Juridische Informatie
Deze repository bevat uitsluitend originele code en third-party code onder de eigen licenties. Er is geen gamecode of game-data inbegrepen. De gegenereerde C++ en WebAssembly zijn vertalingen van het uitvoerbare bestand van het spel en behoren daarmee toe aan de eigenaren van het spel; bewaar deze op je eigen machine en publiceer ze niet. Gebruik uitsluitend disc-images van spellen die je zelf bezit.
Gran Turismo, God of War en PlayStation zijn handelsmerken van Sony Interactive Entertainment. Dit project is niet gelieerd aan of onderschreven door Sony, Polyphony Digital, Santa Monica Studio of andere game-uitgevers.
Credits & Licentie
- MPEG-decoder: De VLC-tabellen zijn aangepast van Play! (BSD 2-clause).
- Referenties: PCSX2, Play! en de ps2sdk headers dienden als referentie voor de hardware- en systeememulatie.
- Technologie:
wgpu-native en Dawn zorgen voor WebGPU, en Emscripten bouwt de WebAssembly.
- Licentie: De code in deze repository is beschikbaar onder de MIT-licentie. De bestanden in
runtime/src/ipu/tables.hpp bevatten de BSD 2-clause notice van Play!.