n64js/README.md
2023-10-15 13:54:16 +01:00

111 lines
No EOL
3.5 KiB
Markdown

# n64js
n64js is an n64 emulator written in (mostly) pure ES6 JavaScript. It runs many roms at full framerate.
## Why?
Mostly for the challenge. I've spent ~25 years (on and off) working on N64 emulators and writing one in JavaScript gives me the opportunity to expand my comfort zone and learn something new. It's a good showcase for how powerful modern browsers have become.
## How To Run
A hosted version is available on GitHub pages at https://hulkholden.github.io/n64js/.
## Development
Install `bun`': https://bun.sh/.
Compile sources (pass --watch to automatically recompile on any change):
```
bun run build --watch
```
Run a local webserver in the root directory:
```
python3 -m http.server
```
Navigate to http://localhost:8000/.
If you want to run without installing bun, you can change the importmap in index.html to point at src/n64.js instead of build/n64.min.js.
## Compatibility
Compatibility has improved a lot over the past few months.
As of 2023-09-23 95% of [n64-systemtest](https://github.com/lemmy-64/n64-systemtest) tests now pass.
The areas where tests are failing are:
* 64-bit memory access (rarely/never used by roms)
* RDP (shouldn't be a problem, as n64js uses HLE)
* Floating point accuracy
The floating point issues are largely edge cases with rounding values close to the numerical limits for 32 bit floats.
Beyond the things n64-systemtest covers, the main compatibility issues I'm aware of are:
* imprecise cycle counting
* graphics
Imprecise cycle counting affects some roms more than others. GoldenEye in particular seems to hang when LLE audio emulation is enabled on the RSP.
I suspect this is due to the CPU running faster than it should be and causing the game to overflow audio buffers.
Graphics are rendered using high-level emulation and there are still a lot of TODOs. Many roms are playable but most have graphical issues of some kind.
## Browser Compatibility
* Chrome 116.0.5845.140 - I've been doing most of my development in Chrome so this is the preferred option
* Firefox 117.0 - runs, but is slower than Chrome.
* Safari 16.6 - runs, but is slower than Chrome.
* Edge - untested. Please let me know how you get on.
## Performance
I've been testing on an Apple M2 Max and most roms run at full framerate *most* of the time.
LLE audio emulation seems to be the biggest performance hit. To date I've mostly been focussed compatibility so there are likely a lot of improvements to be made here.
## Implementation Status
* [ ] CPU
* [x] cop0 instructions
* [x] cop1 instructions
* [x] TLB
* [ ] Cycle accuracy
* [x] RSP
* [ ] Controller
* [x] Static key bindings
* [ ] Configurable bindings
* [ ] Gamepad API
* [ ] Graphics
* [ ] HLE
* [ ] GBI0 - mostly implemented
* [ ] GBI1 - partially implemented
* [ ] GIB2 - partically immplemented
* [ ] LLE - not implemented
* [ ] Audio
* [ ] HLE - not implemented
* [x] LLE - implemented
* [ ] Save
* [x] Persistance (via localStorage)
* [ ] Import/Export
* [x] Mempack
* [x] Eeprom 4k
* [x] Eeprom 16k
* [x] SRAM
* [x] FlashRAM
## TODOs
Here's some things I'd like to get around to:
* Fix graphics issues
* Save game import/export
* Savestates
* [Gamepad](https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API) support.
## History
n6js is derived from [Daedalus](https://github.com/hulkholden/daedalus), an emulator I started working on around 1999 and continued working on periodically for many years.
Around 2012 I made a bet with [@mmalex](https://github.com/mmalex) that I could write a port in JavaScript, and n64js was born!