Giter VIP home page Giter VIP logo

n64js's Introduction

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 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
    • cop0 instructions
    • cop1 instructions
    • TLB
    • Cycle accuracy
  • RSP
  • Controller
    • Static key bindings
    • Configurable bindings
    • Gamepad API
  • Graphics
    • HLE
      • GBI0 - mostly implemented
      • GBI1 - partially implemented
      • GIB2 - partially immplemented
    • LLE - not implemented
  • Audio
    • HLE - not implemented
    • LLE - implemented
  • Save
    • Persistance (via localStorage)
    • Import/Export
    • Mempack
    • Eeprom 4k
    • Eeprom 16k
    • SRAM
    • FlashRAM

TODOs

Here's some things I'd like to get around to:

  • Fix graphics issues
  • Save game import/export
  • Savestates
  • Gamepad support.

History

n6js is derived from 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 that I could write a port in JavaScript, and n64js was born!

n64js's People

Contributors

hulkholden avatar jancborchardt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

n64js's Issues

Controls

If I wanted to change the controls, how would I do so?

GoldenEye intro "spots" render inconsistently

One my laptop screen the spots during the intro sequence have white outline and the center is black. One one of my monitors they appear black (i.e. fully black screen). On my other monitor they render correctly.

Screenshots don't seem to show the problem:

goldeneye_spots

They are rendering just using the primcolor:

RGB0 = (0            - 0           ) * 0            + Primitive   
  A0 = (0            - 0           ) * 0            + Primitive   
RGB1 = (0            - 0           ) * 0            + Primitive   
  A1 = (0            - 0           ) * 0            + Primitive   

The primcolor is set to 230, 230, 230, 0, i.e. no alpha. I suspect the Canvas is being composited inconsistently because the alpha is not being set.

Not working with Chrome 22/Linux

I'm loading Super Mario 64.z64 and I'm getting this as soon as it starts executing it:

Error! Exception :Unknown op: 0xa4000430, 0x0020fffd

It used to work with Chrome 21.

Homebrews

Hi

Are you still working on this project?
I'd like to tell you that it's very inspiring, as well as the blog, and it made me begin a GBA emulator.

So I was wondering if you could provide some homebrews on the main page, that can be run in one click?

I made this myself: I gathered almost 700 ROMs with the permission of the authors and I plan to make them playable directly from the project's page, as soon as they work properly.

http://xem.github.io/GBA.js
(nothing much yet, but it's coming...)

Thanks!

Name select rendering issues in Zelda OOT and MM

Zelda OOT and MM both seem to run into a similar issue on the name select dialog.

OOT
MM

Both seem to be using a G_CYC_2CYCLE combine mode which uses the primitive color (white) for rgb and select Texel1 for the alpha:

01374 e3000a0100100000 gsDPSetCycleType(G_CYC_2CYCLE);
01375 e200001c0c184240 gsDPSetRenderMode(IM_RD|CVG_DST_FULL|ZMODE_OPA|FORCE_BL, GBL_c1(G_BL_CLR_IN,G_BL_0,G_BL_CLR_IN,G_BL_1) | GBL_c2(G_BL_CLR_IN,G_BL_A_IN,G_BL_CLR_MEM,G_BL_1MA) /*0x0c18*/);
01376 fcffadfffffd9238 gsDPSetCombine(0x00ffadff, 0xfffd9238);
RGB0 = (0            - 0           ) * 0            + Primitive   
  A0 = (Texel1       - Texel0      ) * 1            + Texel0      
RGB1 = (0            - 0           ) * 0            + Combined    
  A1 = (0            - 0           ) * 0            + Combined    

In both cases they don't seem to be setting Texture1 correctly. OOT loads both latin and romaji glyphs into Texture0 and Texture1 and so is rendering the romaji glyph.

texture state for OOT

MM doesn't seem to set Texture1 at all in this part of the display list and is showing a broken CI tile used earlier in the scene.

If this were G_CYC_1CYCLE then I think Texel1 would get mapped to the next texel of texture0 (see here). But they do seem to be selecting G_CYC_2CYCLE.

SRAM, how to implement?

Hi I am getting this issue in the web gui for a certain game:

Warning! Unhandled savegame type: SRAM.

Just curious, is there a timeline for implementation of certain features?

GoldenEye crashes with LLE audio enabled

GoldenEye runs well with LLE audio disabled (skipAudioTaskEmulation = true) but seems to crash after a minute or so with it enabled.

I've noticed that it seems very sensitive to timing issues. For instance, at some point the COUNT register was being incremented at 2x the expected rate (once per instruction rather than per 2 instructions) and the RSP seemed to get ahead of the CPU and overflow some internal buffers (wrapping around in dmem) and corrupt internal state. Since fixing that issue the RSP no longer seems to crash but the game appears to become deadlocked (nothing running on the RSP).

Incorrect texture wrapping in Super Mario 64

example of wrapping problem
exmaple of wrapping problem

The textures themselves are being decoded ok

star texture

The tiles are configured with G_TX_WRAP at 16 pixels:

tile # format size line tmem palette cmS maskS shiftS cmT maskT shiftT left top right bottom width height unmasked w unmasked h
G_TX_RENDERTILE G_IM_FMT_RGBA G_IM_SIZ_16b 4 0 0 G_TX_WRAP 4 0 G_TX_WRAP 4 0 0 0 15 15 16 16 16 16
G_TX_LOADTILE G_IM_FMT_RGBA G_IM_SIZ_16b 0 0 0 G_TX_WRAP 4 0 G_TX_WRAP 4 0 0 0 0 0 1 1 1 1

RDP is set up with bilinear filtering:

setting value
textureConvert G_TC_FILT
textureFilter G_TF_BILERP

In the case of the star it's being rendered with texrect:

02636 e4404078003c803c gsSPTextureRectangle(242,15,258,31,G_TX_RENDERTILE,0,0,1,1);
cmd2 = 0x00000000, cmd3 = 0x10000400
st0 = (0, 0) st1 = (16, 16)

Some possibilities:

  • texture lookup in the fragment shader using float UVs is too imprecise
  • texrect coords are slightly off (it's generating st1 of (16,16) but maybe this should be (15,15)?

Method of profiling n64js?

Is there a way to profile this emulator? In particular I'd like to know why the "star-wipe" animation at the start of Mario 64 is slow while the Nintendo logo isn't.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.