Browser player
Run a libtini game in a web page. tools/web.py compiles the development machine of the repository to WebAssembly, and puts it in a package with the disk of the game. The page runs the same 65C02 program as the hardware. Thus a game needs no changes.
STARFALL runs in this player at appletini.org/demo/starfall. The player is an emulator, and its timing comes from the emulator models.
Build and play on your computer
Install Emscripten 6.0.13 with emsdk. The tool does not accept other versions. Build the disk of the game with tools/build.py. Then run:
python tools/web.py --emsdk D:/Repos/emsdk --game starfall --boot-roms build-inputs/native-roms --serve 8642
Open http://localhost:8642/, select a speed and push Play. The output is build/web/GAME/, a folder of static files.
Browsers permit audio worklets and module workers only through http://localhost or HTTPS. Thus open the page through a server, not as a file. --serve serves the page only to this computer, with the MIME types that browsers need.
| Option | Effect |
|---|---|
--emsdk DIR | The installed emsdk. You can also set EMSDK. |
--game NAME | The game in examples/. The default is STARFALL. |
--boot-roms DIR | Boot all of the disk through the installed enhanced //e ROM and slot-7 SmartPort firmware. The package then contains the Apple ROM and the ProDOS of the disk. |
--download-disk | Also offer the disk, with its ProDOS, as GAME.po next to the page. |
--serve PORT | After the build, serve the page on http://localhost:PORT/. |
--rebuild | Build the WebAssembly player again. |
Without --boot-roms, the player loads the files of the disk, except PRODOS, through the ProDOS MLI stand-in of the machine. The package then contains only the game. The stand-in does not have ALLOC_INTERRUPT, so ti_audio_init fails. A game that needs the slot-4 clock then reports that the card is missing. STARFALL shows "SLOT 4 AUDIO REQUIRED". Use --boot-roms for such games.
What the page does
- It runs full NTSC frames of 262 lines of 63.695 µs. It uses the
vtw33model (33.33 MHz) or theturbo-f122TURBO cost model. - It runs frames so that 100 ms of audio is always in the queue. Without sound, it follows the real time. It runs a maximum of four frames for each display refresh.
- A second instance of the module mixes SSI-263 speech in a Web Worker, as the native runner does. The page doubles the speech level before the mix, because the speech of the hardware is louder than the speech of the reference model.
- After each frame, it decodes SHR from AUX $2000-$9FFF and draws it at 640x400. This is the square-pixel shape of the Appletini. Other video modes show black. The page does not model the production capture stream.
- Keys go to the //e as a held key with any-key-down. A gamepad controls paddles 0 and 1 and buttons 0-2.
- Touch devices get a virtual stick, A and B buttons, Return and Esc keys, and a Keyboard button that opens the keyboard of the device. Typed characters arrive in capitals.
- The touch controls appear for a coarse pointer or after the first touch.
?touch=1or?touch=0overrides this. - On iOS, the page starts audio in the Play tap and asks for the playback audio session. Thus sound plays when the silent switch is on. The status line shows "tap for sound" while sound is off.
Publish a game page
Copy build/web/GAME/ to a static host that serves HTTPS. The page sets its base URL from its own location, so it works at all paths. Each package contains COPYING.txt and source.zip. source.zip is the Corresponding Source of the player, with its build record.
The player links the GPL-3.0 emulator and speech code of the repository. Thus the player and its files in tools/web/ are GPL-3.0-only. The library is MIT. A published copy must offer its source, and the package does this. A --boot-roms or --download-disk package also contains the Apple ROM and ProDOS. Publish it only if you have the right to distribute them.
The comparison check
python tests/web_validate.py --emsdk D:/Repos/emsdk --cc C:/msys64/ucrt64/bin/gcc.exe --boot-roms build-inputs/native-roms
This check runs a STARFALL script of 1,100 frames two times: in the player under Node, and in the native machine with its separate speech worker. The script boots, starts with the Mockingboard, moves, drops a bomb and uses the joystick.
At each checkpoint, the tick count, the program counter, AUX $2000-$9FFF and the decoded frame must be the same. The digest of the mixed audio must also be the same. The two profiles match at all nine checkpoints.
Under Node, the player runs at approximately 2.1 times real time at vtw33 and 1.3 times real time at turbo-f122. A slower computer can be too slow for turbo-f122.