Please check out my browser-based javascript emulator

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

peteward44
Posts: 5
Joined: Mon Nov 10, 2014 7:54 am

Please check out my browser-based javascript emulator

Post by peteward44 »

Hi, i have spent the last 18 months porting my C++ NES emulator to JS to see if it can work within a browser rendering to a HTML5 canvas. It uses a ported version of Blargg's apu library for sound. You can see it here

http://peteward44.github.io/WebNES (you'll need chrome or firefox)

Source code is GPL, available here

https://github.com/peteward44/WebNES

I'd appreciate any comments you guys have. Cheers
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Please check out my browser-based javascript emulator

Post by tokumaru »

That worked surprisingly well! Nice work! I'll definitely take a better look at it when I get home.

For now, the only thing bothering me has absolutely nothing to do with NES or emulation: there are a few blank lines between the canvas and the drop shadow at the bottom, which can be removed if you add "display: block;" to the canvas' CSS rules. :)
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Please check out my browser-based javascript emulator

Post by Dwedit »

Performance goes way down when the window is made big. It's too bad browsers can't implement the Canvas tag worth shit. Even a simple test program that flashes colors uses 100% CPU usage, while a Windows GDI program that does the same uses under 1%.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
peteward44
Posts: 5
Joined: Mon Nov 10, 2014 7:54 am

Re: Please check out my browser-based javascript emulator

Post by peteward44 »

Good call, the drop shadow is now fixed :)

Not much i can do about resizing the canvas, as you say it's a browser problem. HTML5 is still in it's infancy however so hopefully browsers will catch up in due time.

Performance wise i believe i've pretty much done as much as i can, it's still a lot faster (in Chrome at least) than all the other javascript-based emulators i've benchmarked it against.

There's still quite a bit i'd like to do on this project, mobile device support and a proper MMC5 implementation for instance (currently only castlevania works on it and the extra audio stuff isn't implemented at all), but after spending the last 18 months on it i've ran out of steam and am ready for my next project. Hopefully by releasing the source code other people can benefit from it just as i have learnt a lot by studying other people's source code.
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Re: Please check out my browser-based javascript emulator

Post by Bregalad »

Cool idea ! However the controls are terrible for german-style keyboards, because x and z are on opposite sides of the keyboard. This is racism !

I am having sound issues, it sounds like buffer problems. I'm on Opera 25.0 by the way.
Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: Please check out my browser-based javascript emulator

Post by Sik »

Bregalad wrote:Cool idea ! However the controls are terrible for german-style keyboards, because x and z are on opposite sides of the keyboard. This is racism !
Stupid question, but is there any way to get scancodes from HTML5? I know each key has an ASCII and a scancode value in HTML+JS, but I don't know if those scancodes are truly layout independent (as usual) or not.

The best idea would be to allow remapping of controls anyway =P Not everybody wants to use the same mappings.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Please check out my browser-based javascript emulator

Post by tepples »

X and Z appear to be backwards, making Lode Runner harder than it's supposed to be. Remap should fix this.

Let me go through my homebrew folder:

When I tried beta version of Double Action 53, I got this:

Code: Select all

uncaught exception: mapper id 28 is not supported
Here's a definition of the mapper.

When I tried a graphics editor, I couldn't find a way to extract the battery RAM.

When I tried a music ROM, I noticed the sound was breaking up because it wasn't running anywhere near full speed, though I sort of didn't expect it to on an Atom N450. So I tried to run an NSF instead so that the PPU didn't need to be emulated, but it gave "unsupported file extension".

When I tried RHDE and my robotfindskitten clone, I couldn't figure out how to control player 2.

There appears to be no way to capture the mouse for my sound effects editor, Thwaite, Sliding Blaster, and other NES programs that use the Super NES Mouse, or for Zapper games like Zap Ruder, or for Arkanoid paddle demos like Vaus Test.

Which features covered by the above tests do you plan to implement soon?

EDIT: A second round of tests produced more results.

When trying BNTest, I discovered two problems:
  • If I drop a zipfile that contains more than one .nes file, it'll choose the "first" one without giving the user a chance to pick one.
  • Oversize BNROM (mapper 34, no CHR ROM) doesn't work. The ROM is truncated to 128 KiB.
Attempt to use .7z files gives ReferenceError: LZMA is not defined

DPCM Letterbox gives a blank dark green screen.

In Boing 2007, the ball does not squash.

Mapper 180 gives unknown. It's similar to UNROM but using a quad AND instead of a quad OR. I can't give you the ROM because of copyright issues, but Midwest Gaming Classic 2011 and Crazy Climber use this.

Pretendo gives one message "Nintendon't" when loading the ROM and then another ("No entiendo") after every soft reset. An NES gives different messages depending on analog effects.

Sprite Cans 2011 doesn't drop sprites when more than 8 are on a line.

But rgb121 and the (not fully released) 2011 version of Who's Cuter work well. You're off to a good start.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Please check out my browser-based javascript emulator

Post by koitsu »

@peteward44: are you still actively supporting/maintaining this project or not? The reason I ask for such a binary/direct answer is because of your previous words (which I think many people could easily skim over, but I keyed in on):
... but after spending the last 18 months on it i've ran out of steam and am ready for my next project. Hopefully by releasing the source code other people can benefit from it just as i have learnt a lot by studying other people's source code.
It sounds like you dropped by to let us know of your work and hope someone else picks it up (which is totally cool! Thumbs up!), but as you can see most of the responses here are either feature or compatibility requests, which falls into the realm of support.
Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: Please check out my browser-based javascript emulator

Post by Sik »

Oh wait, I feel like an idiot, it's Z and Y that swap on a German keyboard, not Z and X. Whoops. (and I should know better, since I'm using a German laptop right now) Although my original point still stands since that can bring issues (or maybe map to X and C instead of Z and X for now?)
peteward44
Posts: 5
Joined: Mon Nov 10, 2014 7:54 am

Re: Please check out my browser-based javascript emulator

Post by peteward44 »

Thanks for everyone spending their time looking at this :)

@koitsu I will go through all the issues raised in this thread and have a go at fixing them. Although I think my days of spending days at a time trying to fix esoteric behaviour on certain roms is over. I think most of the stuff tepples and others have brought up I can do, like key remapping, player 2 controls, mouse, zapper and mapper 28 + 180 support, and I can look at NSF support. There was no point in doing all this work if a lot of people can't use it.

These are the issues I know about and probably won't address:

- APU IRQ doesn't work - no matter how i tried i just couldn't get the blargg tests to work, so i've given up on this
- 8 sprite limitation / sprite overflow flag. I don't think it really benefits the play experience and just slows the emu down, i did have the sprite overflow flag code in but i found it was quite expensive to emulate the ppu bug correctly and that no game roms actually relied upon it so i removed it.
- Doesn't prefetch the 2 bg tiles correctly as an accurate emu would, it renders them straight to the front buffer. I did have this working correctly but removed it for optimisation purposes. This means scanline.nes will fail. But Mike tyson's punch out still works though. This is probably why boing 2007 doesn't squash the ball.
- Sound buffering issue that a couple of people have noticed. This is due to the fact the emu just isn't running fast enough, on a powerful enough PC it is fine. I have spent a lot of time trying to make it run as quickly as possible but sadly Javascript just isn't as fast as i'd like it to be. Like i said before, i don't think i can really optimise any further but hopefully browsers and hardware will catch up in due time.
- I did try to get .7z support working as it is my preferred compression method, but i couldn't find a decent enough JS library that can handle them. So maybe when someone gets round to publishing one i can implement that.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Please check out my browser-based javascript emulator

Post by tokumaru »

peteward44 wrote:- 8 sprite limitation / sprite overflow flag. I don't think it really benefits the play experience and just slows the emu down, i did have the sprite overflow flag code in but i found it was quite expensive to emulate the ppu bug correctly and that no game roms actually relied upon it so i removed it.
My unfinished project relies on it. =) I use the sprite limitation to mask the topmost scanlines and the overflow flag to detect when rendering has started, all in one go. Several games rely on the sprite limitation for effects only, like Gimmick! (when entering levels) and Felix the Cat (when entering/leaving bags), but since those are just effects the games still work fine without this aspect emulated, only without the sprite masking.

Is this really that slow to emulate? These things can be emulated at the scanline level... wouldn't 240 tests per frame solve this issue?
on a powerful enough PC it is fine.
I was surprised at how well it ran on my work PC and my home PC, as neither is particularly powerful (they're both more than 5 years old), but have somewhat decent video cards. It felt full speed most of the time.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Please check out my browser-based javascript emulator

Post by koitsu »

Speaking generally here (not a support request), re: sprite overflow:

Castlevania 2: Simon's Quest: when walking through a swamp, the lower half of Simon's body is visible (normally should be hidden by the swamp). I've attached screenshots from Nestopia (001.png = with sprite overflow implemented/enabled, 002.png = with sprite overflow disabled).

Majou Densetsu II: Daimashikyou Galious, which I demonstrated in a 2-part Youtube video (2nd part goes over more of the technical aspects).

Point I'm trying to make: there are games that "use" this (more clearly, rely on the behaviour); what's more common is that people don't have a good/concise list of games that do (and where/how in the game to verify). I think this is something "we" (community) should be adding to the nesdev wiki, similar to our game bugs, program compatibility, and tricky-to-emulate games sections. Thus I've created such a page.
Attachments
Castlevania II - Simon's Quest (U)_001.png
Castlevania II - Simon's Quest (U)_001.png (4.43 KiB) Viewed 12454 times
Castlevania II - Simon's Quest (U)_002.png
Castlevania II - Simon's Quest (U)_002.png (4.56 KiB) Viewed 12454 times
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

"use asm"

Post by tepples »

peteward44 wrote:I have spent a lot of time trying to make it run as quickly as possible but sadly Javascript just isn't as fast as i'd like it to be. Like i said before, i don't think i can really optimise any further but hopefully browsers and hardware will catch up in due time.
I wonder if it might help to write certain parts in C and use Emscripten to compile them to asm.js, a subset of JavaScript designed for maximum JIT performance. It still probably wouldn't run at full speed on an Atom, but oh well.
- I did try to get .7z support working as it is my preferred compression method, but i couldn't find a decent enough JS library that can handle them. So maybe when someone gets round to publishing one i can implement that.
Is there an LZMA library written in C that you can compile to JavaScript using Emscripten?
JRoatch
Formerly 43110
Posts: 422
Joined: Wed Feb 05, 2014 7:01 am
Contact:

Re: "use asm"

Post by JRoatch »

tepples wrote:I wonder if it might help to write certain parts in C and use Emscripten to compile them to asm.js, a subset of JavaScript designed for maximum JIT performance. It still probably wouldn't run at full speed on an Atom, but oh well.
You might get a similar performance gain by using ArrayBuffers for all of the NES state, including memory, CPU registers, and anything byte based, but this was originally ported from C++, so Emscripten is an option.
If pixel pushing is a bottleneck, using WebGL might be a good path to take. WebGL can at least offload the palette conversion to the GPU.
Dwedit wrote:Performance goes way down when the window is made big.
Maybe using css transforms, instead of repainting a scaled version in a larger canvas, might help?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: "use asm"

Post by tepples »

43110 wrote:If pixel pushing is a bottleneck, using WebGL might be a good path to take.
Which would make the ability to run the emulator at all, even if not at full speed, depend on the installed video drivers. Here's what a spinning cube looks like in Firefox 33 on Xubuntu 14.04 on an Atom N450:
Hmm. While your browser seems to support WebGL, it is disabled or unavailable. If possible, please ensure that you are running the latest drivers for your video card.

For more help, please click this link.
Then I try about:support and get this:
WebGL Renderer: Blocked for your graphics card because of unresolved driver issues.
Apparently WebGL requires OpenGL 2 or something, and some Atom IGPs can't handle more than OpenGL 1.4 without prohibitively slow software rendering.
Post Reply