Try my Java SNES emulator? :)

Announce new emulators, discuss which games run best under each emulator, and much much more.

Moderator: General Mods

creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

You can send news to RHDN and AEP, and post threads on RHDN and nesdev.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
spiller
JSNES Developer
JSNES Developer
Posts: 43
Joined: Sun Mar 15, 2009 11:09 pm
Location: Ireland

Post by spiller »

Thank you! Another question, does anyone know any games or demos which use either:
1) Offset-per-tile mode.
2) Mode7's ExtBG
?
I haven't implemented those yet because I haven't found anything that uses them. Apart from that, it's only hires, interlace, and mosaic left to implement, and then that will finally be the damn PPU finished.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

CT's intro sounds funny :)
Also, the giant frog summoned by Frog is broken.
spiller wrote:Thank you! Another question, does anyone know any games or demos which use either:
1) Offset-per-tile mode.
2) Mode7's ExtBG
?
I haven't implemented those yet because I haven't found anything that uses them. Apart from that, it's only hires, interlace, and mosaic left to implement, and then that will finally be the damn PPU finished.
Here's a list of features:

Actraiser 2 (Direct Color)
Contra 3 (Mode7 ExtBG)
Chrono Trigger (windowing)
Chrono Trigger (hi-res)
Chrono Trigger (hi-res)
Chrono Trigger (horz. Offset-Per-Tile)
Donkey Kong Country (Color Subtraction)
Jurassic Park (hi-res used for blending? don't remember)
RPM Racing (hi-res)
Secret of Mana (Direct Color)
Tetris Attack (Offset-Per-Tile)
Tiny Toons (Mode7 ExtBG)

EDIT:
Here's Offset-Per-Tile mode usage in Yoshi's Island: 1 2 3
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
spiller
JSNES Developer
JSNES Developer
Posts: 43
Joined: Sun Mar 15, 2009 11:09 pm
Location: Ireland

Post by spiller »

Brilliant! Thank you! Color math and windowing is all already done (yep, Torchlight Trouble works!), but the rest I needed. Direct color mode -- I had forgotten that -- I did program it, just didn't test it. Right, I'll go code all that. Be back in ten years. :roll:
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

DirectColor at least is relatively easy - just a different way to get from pixel/tile info to final color value. Even if there's a bug it's easy to fix.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
byuu

Post by byuu »

The color bits in the tilemap part is the weirdest thing I have seen. I just can't imagine any use for specifying one extra bit of color, but only for a full 8x8 tile at a time :/

But it's really great if you want to put a bunch of high color sprites on top of a full color backdrop.

Well, I guess EXTBG mode is crazy, too. Sure, games technically enable it, but the only possible way to show any difference between it and regular Mode7 is to rely on the mosaic glitch to cause the two layers to be different.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

byuu wrote:Well, I guess EXTBG mode is crazy, too. Sure, games technically enable it, but the only possible way to show any difference between it and regular Mode7 is to rely on the mosaic glitch to cause the two layers to be different.
Well, you can put it in front of sprites. ;)
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

Do you have a public svn? (or mercurial)
whicker
Trooper
Posts: 479
Joined: Sat Nov 27, 2004 4:33 am

Post by whicker »

creaothceann wrote:
byuu wrote:Well, I guess EXTBG mode is crazy, too. Sure, games technically enable it, but the only possible way to show any difference between it and regular Mode7 is to rely on the mosaic glitch to cause the two layers to be different.
Well, you can put it in front of sprites. ;)
is this how the wooden posts "holding up" the Ghost Valley tracks in Super Mario Kart work?
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

normal mode7 priority 0 sprite.


EXTBG's a whole different beast. Read up anomie's stuff for more info on what it actually can do.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
spiller
JSNES Developer
JSNES Developer
Posts: 43
Joined: Sun Mar 15, 2009 11:09 pm
Location: Ireland

Post by spiller »

i30817 wrote:Do you have a public svn? (or mercurial)
No, though if you're asking because there's some aspect of JSNES you're particularly interested in, I'll put the relevant code on Pastebin.

Btw I've been ill for a bit; Next JSNES version (if I ever get it done), will have NES support. Several NES games are already playable (albeit with no sound) in the newest unreleased version.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

whicker wrote:
creaothceann wrote:
byuu wrote:Well, I guess EXTBG mode is crazy, too. Sure, games technically enable it, but the only possible way to show any difference between it and regular Mode7 is to rely on the mosaic glitch to cause the two layers to be different.
Well, you can put it in front of sprites. ;)
is this how the wooden posts "holding up" the Ghost Valley tracks in Super Mario Kart work?
Like grinvader said - press 5 in ZSNES and they disappear.

(What's also interesting is that ZSNES emulates EXTBG, but doesn't bind it to key 2.)
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

the whole mode 7 rendering is done with another set of functions/macros/files that isn't bound to these controls
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

spiller wrote:
i30817 wrote:Do you have a public svn? (or mercurial)
No, though if you're asking because there's some aspect of JSNES you're particularly interested in, I'll put the relevant code on Pastebin.

Btw I've been ill for a bit; Next JSNES version (if I ever get it done), will have NES support. Several NES games are already playable (albeit with no sound) in the newest unreleased version.
Just looking how a hardware emulator would work on java, that is my main language (seriously can't stand compiling to various architectures).

Also i just changed to a amd64.

*shakes fist at zsnes*
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

i30817 wrote:Also i just changed to a amd64.

*shakes fist at zsnes*
yeah that totally matters




except not
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

I'm just shaking, because you still use assembler.

And anyway if it doesn't matter why am i not seeing it in the ubuntu repositories now?
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

Probably because the public source is way too old to support and they don't exactly want to reproduce all the stuff we did to turn it into the current (private) source that's not especially hard to compile for amd64 (given a sane multilib setup, but that's also mostly trivial nowadays - except for libao).
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
spiller
JSNES Developer
JSNES Developer
Posts: 43
Joined: Sun Mar 15, 2009 11:09 pm
Location: Ireland

Post by spiller »

i30817 wrote:Just looking how a hardware emulator would work on java
How? With difficulty. Java has all these silly notions designed to irritate the programmer, e.g., no automatic numeric to boolean conversions, so bitmask tests are forced to look all ugly like:
if ((x & 0x80) != 0) blah();

Anyway, um, "how" you say? What you're asking isn't very specific so I'll just give a loose overview of some stuff.

The emulation runs in its own thread and works on a per-frame basis. The first step in the frame is waiting (if the console is paused in the emulator interface), then loading a cart, issuing a hardware reset, or savestate load, if necessary. Once/if all that passes, it runs each component or chip (CPU, APU, PPU) for the frame separately (though individual components will sync lazily whenever necessary). Then it blits the frame to the screen, counts how much time is free, then pauses (or at least yields) the thread, and after that loops to the next frame.

CPUs -- are in their own classes. (Or multiple classes, since, e.g., SNESCPU.java extends from CPU65816.java and just sets things differently). Registers and flags are just variables. Opcodes are in individual functions, compiled from a separate macro file with a PHP script. (Java doesn't have a preprocessor but you really need one to make a fast CPU, because there's a lot of code reuse possible when writing the CPU ops, but it's too slow to deal with that at run time.) Before running an opcode it checks the debug flag, which if necessary will signal the step debugger, and wait the emulation thread, and pressing the Step button in the debugger later wakes it up again.

The SNES memory mapping is about as annoying as any system's memory space can get. The 24-bit address space is littered with registers and different views of the same stuff, and it all runs at different speeds. To minimize the calculation overhead of that, each of the 256 16-bit banks is a separate object. It loads the program bank & data bank objects whenever the real SNES would load the program bank & data bank registers (relatively infrequently). Banks look like this: http://pastebin.com/0w9nQVzg. There are subclasses for different parts of the SNES address space: http://pastebin.com/ByQi4JAG. The opcode address mode support functions call the appropriate bank functions depending on what stupidly complicated wrapping behavior they want.

PPUs -- work on a per-scanline basis, mostly. Backgrounds and sprites are in classes. Um, lots of optimizations depending on precisely what is visible and present on a particular scanline. E.g., color math ops are in function pointers, and are chosen once the subscreen scanline has rendered just before doing the mainscreen or backdrop, so if nothing was rendered to the subscreen for a particular scanline (i.e., backgrounds and sprites have no pixels there, or are clipped or disabled or whatever), an Add+Halve Subscreen else Add Fixed Color color math op can be replaced with an Add Fixed Color op, and if the fixed color is black that can be replaced with null, which throws out color math entirely, and so on and so on. There's a lot of that sort of stuff. It's very, very untidy at the moment.

APUs -- are difficult and annoying, though Java makes its side of the sound output stuff nice and easy.
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

That looks pretty damn clean code (what you showed).
And sound output only looks easy for you because you are on a recent jdk that has pulseaudio integration. Otherwise you would find that when they replaced their software mixer implementation for the hardware by default they fucked it up beyond belief, by the fact that if ALSA reports that some line is available for some audio format, it doesn't mean it will work (since the line can be in use, erg: the flash problem).
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

BTW let me give you a little hint on making the default filechoosers bearable (well within limits - i am using for linux the one on google code).

If you do this somewhere at before using swing:
UIManager.put("FileChooser.readOnly", Boolean.TRUE);

Your filechooser should disallow file rename and so avoid that ridiculous fast file rename interval on linux.
That happens apparently because it is a old gnome default, however gnome doesn't use it anymore and slowed it down - duh - but they left it alone, like the numbskulls they can be. And the swing team like the numbskulls they are left it alone, since it is still "supported".
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

BTW i have a stupid project to *search* inside compressed files in pure java, zip and rar files. You might find it useful (or might want to use the pure java rar library directly - it's name is junrar, but be sure to profile it's memory, you might have to do a optimization i had to too - recycle the memory array, since there is a lot of memory unrar needs, and two arrays in the transition can overflow the heap in default jvm configs).

Feel free to butcher the parts that interest you.
http://code.google.com/p/bookjar-utils/ ... ector.java
i30817
Rookie
Posts: 11
Joined: Mon Mar 29, 2010 6:42 am

Post by i30817 »

That file preview is cool...
byuu

Post by byuu »

No one can defeat the quad poster.

Image
That looks pretty damn clean code (what you showed).
All of the speed optimizations, like trying to read two bytes at once, make the code significantly larger and potentially error prone. A better speedup would be unrolling the bank_00_3f_8000_ffff etc functions so that memory access doesn't require the transformation nor custom handling. Java doesn't have pointer arithmetic, but it should be possible to store an offset in each block, and then do data[offset + (addr & 0xffff)]; with offset being negative as needed.

I'm very interested in the use of PHP to generate the CPU opcodes, that sounds pretty neat. Luckily C++ had templates which I could hack up to work, but I too went with a preprocessor for a long while. The C one is nearly unusable, it's so bad. It boggles the mind why "modern" languages lack powerful macro tools for code generation.
spiller
JSNES Developer
JSNES Developer
Posts: 43
Joined: Sun Mar 15, 2009 11:09 pm
Location: Ireland

Post by spiller »

i30817 wrote:That looks pretty damn clean code (what you showed).
Most of the rest of the code is *not* that good (though it improves gradually).
Your filechooser should disallow file rename and so avoid that ridiculous fast file rename interval on linux.
I never got around to trying it on Linux but I'll look into it.
BTW i have a stupid project to *search* inside compressed files in pure java, zip and rar files.
Opening ROMs in archives is something I've put aside for the moment. I think JSNES can still actually do that (for zips), but I removed it from the file chooser because I couldn't decide on a neat way to handle saving of files associated with archived ROMs (i.e., saved games).
That file preview is cool...
Thanks. It doesn't play too nicely with the Java Motif theme though because its file dialog doesn't seem to let the accessory component choose its own size. (?)
byuu wrote:All of the speed optimizations, like trying to read two bytes at once, make the code significantly larger and potentially error prone.
I know. The two-byte access functions in the bank subclasses are a very recent addition to that code, and a bit of a disappointing one. The speed improvement is marginal at best, but I can trivially comment them out at any time and let the superclass handle it, if I decide they're not worth the code duplication inelegance.
A better speedup would be unrolling the bank_00_3f_8000_ffff etc functions so that memory access doesn't require the transformation nor custom handling. Java doesn't have pointer arithmetic, but it should be possible to store an offset in each block, and then do data[offset + (addr & 0xffff)]; with offset being negative as needed.
Explain this. I don't follow but I really want to! By the way something I tried very early on was to split the complex banks into smaller objects so instead of using if/elses to dissect the address ranges it would use some of the upper bits of the 16-bit bank offset as an index into an array of more function pointer things. It turned out slower, though.
I'm very interested in the use of PHP to generate the CPU opcodes.
I originally spent about two weeks learning about and manually typing out the various opcode variations. Once I switched to macros I had the CPU rebuilt in an afternoon. All three CPU cores (65816, SPC700, 6502) currently look something like this: http://pastebin.com/QRv6AjgT
That code makes heavy reference to a lot of (mainly trivial) support memory and logic functions in the main CPU class file, but Java is good at inlining so that doesn't affect performance.

Those op files are compiled with a rather big and uglyish PHP parser, but there are two big advantages:
(1) reduced code duplication
(2) I can directly compare, for each CPU, running the opcodes with a switch block versus arrays of function pointers, and also ways of handling the states of the M/X/E CPU flag bits, because it takes seconds to switch between different ways of generating the code.
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

Why PHP, though?
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
Post Reply