byuu says:
This release adds low-level emulation of the Hitachi HG51B169 DSP, which
was used in Mega Man X2 and Mega Man X3 as the Cx4 chip. It also fixes
a regression in both the sound core and cheat engine.
You will now need the HG51B169 data ROM to play MMX2/MMX3.
Once again, Cx4 LLE could not have been possible without the help of Dr.
Decapitator, Jonas Quinn, Overload and Segher. Be sure to thank them,
please!
Changelog:
* added Cx4 low-level emulation; removed Cx4 high-level emulation code
* fixed S-SMP synchronization to S-CPU on CPUIO writes
* controllers now have their own threads and classes
* serial controller is now emulated as an actual controller, rather than
as a coprocessor
* added link coprocessor module for special chip research and homebrew
* fixed cheat codes that target mask ROM addresses [Cydrak]
* fixed compilation error with the latest GCC 4.6.0 beta releases
* added flexibility to XML memory mapping file format
* updated to mightymo's latest cheat pack (2011-06-20)
byuu says:
It does add some more code to the CPU::step() function, so performance
probably went down actually, by about 1%. Removing the input.tick() call
didn't compensate as much as I'd hoped.
Hooked up Super Scope and Justifier support. The good news is that the
Justifier alignment doesn't get fucked up anymore when you go
off-screen. Never could fix that in the old version.
The bad news is that it takes a major speed hit for the time being.
I need to figure out how to run the CPU and input threads out of order.
Every time I try, the input gets thrown off by most of a scanline.
Right now, I'm forced to sync constantly to get the latching position
really accurate. But worst case, I can cut the syncs down by skipping
large chunks around the cursor position, +/-40 clock cycles. So it's
only temporarily slow.
Lastly, killed the old Input class, merged Controllers class into it.
I actually like Controllers as a name better, but it doesn't jive with
video/audio/input, so oh well.
byuu says:
- Fixed GCC-4.6 casting errors in ui/input/input.cpp.
- Fixed some of the opcode mnemonics specified in the HG51B169 core (was
unable to speed up the code)
- Started on a new core input system: snes/controller. More on that
here:
http://board.byuu.org/viewtopic.php?f=16&t=1761
- Have not yet attempted to add threading support to the controllers, so
serial is still there as a coprocessor.
- I'm going to move the Controllers {} class back to Input {} once all
individual controllers have been ported over.
Note: Super Scope and Justifier do not have counter latching support
yet, so you can't really use them. The gamepad, multitap and mouse all
work great; and the SS/Justifier cursors work at least. I also colored
the SS cursor red, so that all three (SS, Justifier, chained secondary
Justifier) all have unique R/G/B colors now. Should prevent confusion
between the SS and one Justifier.
byuu says:
Back from vacation. We were successful in emulating the Cx4 using LLE
during my vacation. We finished on June 15th. And now that I'm back,
I've rewritten the code and merged it into bsnes official. With that,
the very last HLE emulation code in bsnes has now been purged.
[...]
The emulation is as minimal as possible. If I don't see an opcode or
feature actually used, I don't implement it. The one exception being
that I do support the vector override functionality. And there are also
dummy handlers for ld ?,$2e + loop, so that the chip won't stall out.
But things like "byte 4" on rdram/wrram, the two-bit destination
selections for all but ld, etc are treated as invalid opcodes, since we
aren't 100% sure if they are there and work as we hypothesize. I also
only map in known registers into the 256-entry register list. This
leaves 90% of the map empty.
The chip runs at 20MHz, and it will disable the ROM while running. DMA
does transfer one byte at a time against the clock and also locks out
the ROM. rdbus won't fetch from IRAM, only from ROM. DMA transfer only
reads from ROM, and only writes to RAM. Unless someone verifies that
they can do more, I'll leave it that way. I don't yet actually buffer
the program ROM into the internal program RAM just yet, but that is on
the to-do list. We aren't entirely sure how that works either, but my
plan is to just lock the Cx4 CPU and load in 512-bytes.
There's still a few unknown registers in $7f40-5f that I don't do
anything with yet. The secondary chip disable is going to be the
weirdest one, since MMX3 only has one chip. I'd really rather not have
to specify the ROM mapping as two separate chips on MMX2 and as one on
MMX3 just to support this, so I don't know yet.
Save state support is of course there already.
Speed hit is 118fps HLE -> 109fps LLE in most scenes. Not bad, honestly.
byuu says:
This fixes the S-SMP synchronization on CPUIO writes that was broken by
improvements in v078.01. Terranigma will work now. Also adds the 'link'
coprocessor module that was added in v079.01, and improved in v079.02.
byuu says:
Added "unsigned link_run();" which acts as its own thread synchronized
against the S-CPU. Specify the frequency in the configuration file.
I intend to prototype the Cx4 LLE openly using the link module, and that
required timing support, so there we go.
It's very basic, and it synchronizes the CPU to the coprocessors and
vice versa after every call to link_run(). Meaning performance won't be
super exceptional at full 21MHz or higher, but then this is for
prototyping only. I didn't want to expose cothreading, yielding, calls
back into bsnes' core, calls to sync up the S-CPU, etc.
This version adds a "link" SNES coprocessor module, which just loads
a shared library. It was posted outside the v079 WIP thread, in this
thread:
http://board.byuu.org/viewtopic.php?f=16&t=1700
byuu says:
This release includes Nintendo Super System DIP switch emulation and
improved PPU rendering accuracy, among other things.
Changelog:
- added Nintendo Super System DIP switch emulation [requires XML setting
maps]
- emulated Super Game Boy $6001 VRAM offset selection port [ikari_01]
- fixed randomness initialization of S-SMP port registers [fixes
DBZ:Hyper Dimension and Ninja Warriors]
- mosaic V-countdown caches BGOFS registers (fixes Super Turrican
2 effect) [reported by zal16]
- non-mosaic BGOFS registers are always cached at H=60 (fixes NHL '94
and Super Mario World flickering)
- fixed 2xSaI family of renderers on 64-bit systems
- cleaned up SMP source code
- phoenix: fixed a bug when closing bsnes while minimized
Please note that the mosaic BGOFS fix is only for the accuracy profile.
Unfortunately the older scanline-based compatibility renderer's code is
nearly unmaintainable at this point, so I haven't yet been able to
backport the fixes.
Also, I have written a new cycle-accurate SMP core that does not use
libco. The aim is to implement it into Snes9X v1.54. But it would of
course be prudent to test the new core first.
[...then in the next post...]
Decided to keep that Super Mario World part a surprise, so ... surprise!
Realized while working on the Super Turrican 2 mosaic fix, and from
looking at NHL '94 and Dai Kaijuu Monogatari 2's behavior, that BGOFS
registers must be cached between H=0 and H=88 for the entire scanline
... they can't work otherwise, and it'd be stupid for the PPU to re-add
the offset to the position on every pixel anyway. I chose H=60 for now.
Once I am set up with the RGB monitor and the North American cartridge
dumping is completed, I'll set it on getting exact timings for all these
things. It'll probably require a smallish speed hit to allow exact-cycle
timing events for everything in the PPU.
byuu says:
Would appreciate testing on any games with mosaic, especially Mode7
mosaic.I have tested Super Turrican 2, Sim Earth, Contra III and SNES
Test Program.
This only applies to BG modes 0-6, and technically should not affect
Mode7 at all. I am not sure if Mode7 needs the same change made or not,
but given the way it fetches that could prove quite challenging. I also
simplified the background renderer a good bit. See eg the pixel copy
stuff in Background::run().
I've only fixed this in the accuracy renderer. I'm sorry, but the
compatibility renderer is a fucking mess. I haven't really touched it in
four or five years now.
Will probably just revert to the accuracy/SMP in the performance profile
for the next release since it's not being used otherwise. People can
toggle it on if they want to try it out.
byuu says:
This adds ikari_01's emulation of the ICD2 (Super Game Boy) $6001 register.
It basically removes a really ugly hack where I was intercepting the DMA
transfer destination address to determine while Game Boy tile row to
transfer. This should make implementing SGB emulation in other
emulators easier, as said hooks were very emulator-specific.
byuu says:
This WIP adds Nintendo Super System emulation, at least of its DIP
switches. This is done via XML mapping, like so:
<?xml version="1.0" encoding="UTF-8"?>
<cartridge region="NTSC">
<name>ActRaiser</name>
<rom>
<map mode="linear" address="00-7f:8000-ffff"/>
<map mode="linear" address="80-ff:8000-ffff"/>
</rom>
<nss>
<setting name="Difficulty">
<option value="0000" name="Easy"/>
<option value="0001" name="Normal"/>
<option value="0002" name="Hard"/>
<option value="0003" name="Expert"/>
</setting>
<setting name="Lives">
<option value="0000" name="5 lives"/>
<option value="0004" name="4 lives"/>
<option value="0008" name="3 lives"/>
<option value="000c" name="2 lives"/>
</setting>
</nss>
</cartridge>
The value field is a 16-bit value. All selected options are ORed
together to produce the final DIP switch values. The number of options
per setting is unlimited, but there are only sixteen settings allowed
(you can't have more settings than you have switches, that's just
stupid.)
In the example above, d0-d1 controls difficulty, and d2-d3 controls # of
lives. d4-d15 appear to be unused, as far as I can tell.
byuu says:
Changelog:
- file and slot load dialogs should now have perfectly square buttons
that are based on the platform's default button height.
- cleaned up bsnes/Accuracy SMP source code (removed old !! stuff, stage
3 timer is now uint4, memory access switch/case cleaned up,
sSMPTimer->Timer, etc.)
- cleaned up bsnes/Accuracy memory access functions (read/writestack ->
read/writesp, read/writeaddr -> read/write)
- minor optimization to bsnes/Performance SMP core in cycle-mode
byuu says:
I apparently wasted two days writing that SMP core for nothing. I had
a perfectly well-written and well-tested core in bsnes v045. The old
opcode.b files that were a cycle-based markup language.
So I took that core, and wrote new parsers to generate both opcode-based
(one switch) and cycle-based (two switch) cores. Throw in a
little #define magic around CYCLE_ACCURATE, and it is compile-time
toggleable.
EWJ2's bug was due to not resetting the timer variables, and Bahamut
Lagoon's was due to dividing timer frequencies by 3, but failing to
remove the 0->1 transition phase (should have done the latter and
divided by two.)
Anyway, all fixed up.
byuu says:
New S-SMP core is feature-complete, but still buggy. It's good enough
for perfect audio in Zelda 3 and Super Mario World, but there are plenty
of issues. No audio in Bahamut Lagoon, deadlock in Earthworm Jim 2,
etc.
With this core, bsnes/Performance runs about 3-5% faster than with the
old one. That won't seem like much, because the S-SMP is the least
demanding portion of the SNES. blargg's SMP core netted me a 5-8%
speedup the last time I tried it, so I'm sure there's still room to
speed things up.
The core is opcode-based, but has dummy op_io() calls (they compile to
nothing), so it is trivial to make it cycle-based if desired. I'm not
convinced that is necessary, but we shall see once we get the opcode
bugs ironed out.
byuu says:
Started on a new SMP core for bsnes/Performance. I wanted to start
clean, and only copied over the debugger+disassembler portions from the
existing version. I figured that if I took the existing one and tried
trimming it down, that it'd end up with too much old baggage. But so
far, the opcodes are looking mostly the same anyway, only I'm
using #defines and a switch table in place of the template function
trickery.
I have enough written now that I can run Zelda 3 at least (although it
gets stuck in a loop immediately after.) No real point in comparing
speed yet, because it'll definitely go down as it becomes more complete.
byuu says:
Finally, a new release. I have been very busy finishing up SNES box,
cartridge and PCB scanning plus cataloguing the data, however this
release still has some significant improvements.
Most notably would be randomization on startup. This will help match the
behavior of real hardware and uninitialized memory + registers. It
should help catch homebrew software that forgets to initialize things
properly. Of course, I was not able to test the complete library, so it
is possible that if I've randomized anything that should be constant,
that this could cause a regression. You can disable this randomization
for netplay or to work around any incompatibilities by editing bsnes.cfg
and setting snes.random to false.
The GUI also received some updates. Widget sizes are now computed based
on font sizes, giving it a perfectly native look (because it is native.)
I've also added a hotkey remapping screen to the input settings. Not
only can you remap inputs to controllers now, but those who did not know
the hotkey bindings can now quickly see which ones exist and what they
are mapped to.
Changelog (since v077):
- memory and most registers are now randomly initialized on power-up
- fixed auto joypad polling issue in Super Star Wars
- fixed .nec and .rtc file extensions (they were missing the dot) [krom]
- PPU/accuracy now clears overscan region on any frame when it is
disabled
- PPU/compatibility no longer auto-blends hires pixels (use NTSC filter
for this)
- added hotkey remapping dialog to input settings window
- added a few new hotkeys, including quick-reset
- phoenix API now auto-sizes widgets based on font sizes
- file dialog once again remembers previously selected file when
possible
byuu says:
Changelog:
- fixed .nec and both .rtc file extensions (thanks krom)
- randomized most S-PPU registers, should trip up some broken homebrew
that does not initialize all registers
- randomization is now seeded with time(0) rather than 'byuu'
- SNES::interface.video_refresh() now always receives
{256,512}x{240,480}
- PPU/accuracy scanline 0 does not render the screen back color anymore,
fixes strange coloring look on first scanline in PAL TV mode in
non-overscan games
- disabled hires blending in PPU/compatibility; all three cores act the
same now
byuu says:
Changelog:
- setGeometry is called after append(layout) now. This fixes the window
sizing on Qt.
- removed enum Style {} code, as it's no longer necessary.
- removed Filter, Shader path selection code from the file load dialog,
since that is menu-driven now.
- improved the file load dialog to remember last selected file when mode
doesn't change (had to split a switch statement into two switches.)
- added Hotkeys port onto input settings window, allowing one to
dynamically see and remap GUI shortcuts
- added power cycle / reset shortcuts
Still very minimal with the hotkeys, so I packed them all into one group
for now. A few more I'd like to add, but I don't want to get ridiculous
like with the Qt GUI.
byuu says:
Fixed up the geometry calculation code. There is now minimumGeometry()
[returns minimum size needed to display a layout, treats MaximumSize as
MinimumSize], and minimumLayoutGeometry() [like minimumGeometry(), but
it will return MaximumSize if a single container item has that
attribute. Used mostly internally for layout sizing.]
It looks great on Windows, but it looks visually off on Qt. Not exactly
sure what's up there. When I make a test application, everything looks
great. Going to have to clone a bsnes window that's having a problem (eg
bsnes main debugger checkbox window), and see what's up.
byuu says:
Wouldn't recommend using this, but it has bsnes ported to the new auto-size calculating phoenix API.
Known issues:
- minimumWidth/Height on layouts isn't working right, windows that use
it are usually too small
- Windows gives 0,0 size for empty text string sizes, which messes up
a lot of default sizes for LineEdit controls
byuu says:
Changelog:
- fixed auto joypad polling bug (fixes Super Star Wars start button
input)
- added pseudo-random class; so far it is RAM only [WRAM, APURAM, VRAM,
OAM, CGRAM]
- added new system configuration options to bsnes.cfg
The pseudo-random class is optional. For right now, I am defaulting it
to enabled. bsnes.cfg::snes.random = true.
You can of course turn it off if you want. This will break Death Brade
and Unnamed Euro Racer, no questions about it.
So I don't know if I want to leave this on or off by default. Leaving it
on will thwart emulator detection code and help to keep code that relies
on uninitialized memory from working, but leaving it off will increase
compatibility.
byuu says:
Changelog (since v076):
- video filters and shaders now populate inside main menu; no longer
have to select them as files
- fixed 2xSaI, Super 2xSaI and Super Eagle on 32-bit platforms; still
buggy on 64-bit Windows
- fixed linear mirroring issues (fixes Mega Man X dash bug)
- fixed RAM memory mapping bug in Sufami Turbo games
- home folder is now %APPDATA%/bsnes or ~/.config/bsnes
- added paths.cfg file, which will allow you to specify custom paths for
any file types
- save states and cheat files for multi-slot games are based on slot
names instead of BIOS names
- fixed compilation warning on OS X with nall::decimal
- fixed calculation bug in nall::fp
- Makefile now has options variable, example: make options=debugger
- configuration files and cheat database can now reside in the same
folder as the binary itself
- updated to 2011-03-11 release of mightymo's cheat database
byuu says:
Rather than make the libsnes API incompatible with previous versions,
I just implemented path as return { basename, hint };
So you will still use the set basename function already there as before.
So either DSP/MSU1/Serial all go in the ROM folder, or they all go
somewhere else. You can be fancy and detect the gametype and override
the basename as you like, if you really want.
Bumped the API to 1.3, and added const char* snes_library_id(void); it
will return "bsnes v076.07" at the moment. The internal string is
static, but don't try caching it or modifying it anyway. You'll have to
split the name and version yourself if you want them separately. API is
backward-compatible to 1.0 still.
Also improved string::assign and string::append to take a variadic
number of arguments. To make this happen, I had to make to_string return
const char* so that infinite recursion did not happen.
byuu says:
Changelog:
- path code finished for ui/, just need to expose for ui-libsnes/ now
- filters and shaders use radio items now, so you know which is active
- smooth video was placed inside video mode (list is getting too long)
- .bsnes -> .config/bsnes in make install
- pixelshaders -> snesshader, added Makefile with make install target
- snesfilter, added Makefile with make install and make clean targets
- maybe other stuff
byuu says:
Changelog:
- QMenu::setVisible() does nothing, have to use
QMenu::menuAction::setVisible()
- improved path system, especially for ST games (states will be
/path/to/slotA+notdir(slotB).ext, saves are per-game and per-path)
- paths are now valid when you load just the BS-X/ST/SGB BIOSes with no
carts inserted; maybe useful for BS-X I guess
- removed video filter and pixel shader code from video settings dialog
- added Settings->Video Filter and Settings->Video Shader menu lists
- fixed the SaI family of filters in lores-mode only; although I don't
really know how or why the change fixed them, the code is too vague
The menu list for the video filters and shaders are populated from
either base/filters and base/shaders, or user/.config/bsnes/filters and
user/.config/bsnes/shaders. It tries the first, and if it does not find
anything it tries the second, just like the configuration files.
That meant doing away with multiple folders for the shaders, so now the
shaders have a suffix to indicate what driver uses them, eg
"Curvature.OpenGL.shader" and "Sepia.Direct3D.shader" -- probably nicer
to use GLSL/HLSL, but using the driver name lets me sub in the currently
loaded video driver with no special casing. So the filter if you have eg
OpenGL loaded is "*.OpenGL.shader"; and for SDL you get "*.SDL.shader",
which will obviously not be there as the non-GL-based SDL driver doesn't
support shaders.
If there are no filters or no shaders available, the menu options do not
show up. The lists are not radio items with active item ticked states
just yet, but they will be.
byuu says:
Changelog:
- fixed Sufami Turbo ROM and RAM mapping bugs
- more paths work, definitely need to clean up parameter names and enum
typenames now
I had to cheat just a bit on the ST SRAM. For now, I am specifying the
RAM size in the XML file.
The base XML isn't supposed to know about the slots though. What I need
to do is write an ST header parser to get actual RAM sizes, and then
from there generate an ST-specific XML file (like I do for the Game Boy)
to specify this info. Would also be nice for some BS-X info.
Added NECDSP, MSU1 and Serial paths. This eliminates
SNES::Cartridge::basename.
byuu says:
Changelog:
- paths.cfg work completed
- save states/archives and cheat files for multi-slot games are more
intelligent now
For paths.cfg, there are three types of entries. Each have different
special prefixes.
Folder paths: sfc, bs, st, gb, filter, shader
By default, bsnes will remember the last path you loaded a file of said
type from. It will be prefixed with "recent/" in the file. Specify an
explicit hard-coded path to override this.
BIOS paths: satellaviewBios, sufamiTurboBios, superGameBoyBios
Remembers an explicit hard-coded path to the BIOS you selected last.
I was thinking that a nice feature would be for the "Load Special"
windows to pop open the slot A load dialog if a BIOS was selected.
Select a game from this popup and it loads directly, cancel it to get
the regular window to override the BIOS.
Save paths: srm, rtc, bsa, bst, cht, log
Paths to write various files that the emulator generates. Note: srm
groups bsp, bss and sav for now. Was being lazy.
There are four special prefixes for these:
"base/" -- gets replaced with the executable path
"user/" -- gets replaced with the same folder where bsnes.cfg goes
(%APPDATA%/bsnes or ~/.config/bsnes) -- good for hiding
files
"./" -- gets replaced with the current ROM path
"../" -- gets replaced with the folder above the current ROM path
If you want to go up two folders or more, then use a hard-coded path. If
that's not good enough, kill yourself because God hates you.
byuu says:
Changelog:
- fixed a crashing bug when you toggle a cheat code and then load a save state
- added paths.cfg
- bsnes now remembers the most recent path per file-type, like bsnes/Qt
used to do
- re-added -s to Linux linker flags
- fixed crash with libsnes/SGB XML parsing
byuu says:
Changelog:
- fixed linear mirroring issue in memory map (fixes dash in Mega Man X)
- home path for Windows is now %APPDATA%/bsnes (not %APPDATA%/.bsnes)
- home path for OS X and Linux is now ~/.config/bsnes (not ~/.bsnes)
- bsnes-geometry.cfg is now geometry.cfg; and it stores width,height
- I do not yet restore width, height; because the GTK+ and Qt APIs treat window
resize as implying setMinimumSize
- added bsnes/ui/path; which I have some significant plans for
- fixed a bug in realpath (specified path is not always a folder, so we should
not always append / as with userpath)
- bsnes.cfg, geometry.cfg and cheats.xml may now optionally exist in the same
folder as the binary itself
- ruby only imports the nall namespace after including system headers (should
fix OS X 'decimal' issue)
- nall::fp now uses atof (fixes nall::fp("0.05"))
- I split the CheatDatabase to a separate cheat-database.cpp file; it was
pretty ugly packed into cheat-editor.cpp
- Makefile now has "options := " line; where you can add "debugger" if you
like, and in the future maybe more options
- also works via command-line: make options=debugger
byuu says:
Most notable in this release is that sound support has been added to my
own Super Game Boy emulation. The GUI toolkit, phoenix, has also
received a complete rewrite; with the most visible change there being
that windows are now resizable.
Changelog (since v075):
* added sound emulation to Game Boy core
* fixed Super Game Boy save state
* support added HexEdit widget to Windows and Qt targets; debugger can
now be compiled on all platforms
* entering fullscreen now auto-hides mouse; and mouse capture is toggled
otherwise by F12 key
* fullscreen command and geometry caching works much better on GTK+ and
Qt targets
* phoenix rewritten from scratch; now supports resizable layout
containers
* phoenix/Windows no longer relies on buggy SetParent API to reparent
widgets
byuu says:
This has my latest API enhancements, but there are some known issues:
- resize on Windows seems to not repaint the buttons properly in rare
cases. I may just need to revert to flickering resize.
- GTK+ reports the wrong menu height, off by two pixels, prior to the
window being realized (made visible)
- this results in the main window moving up two pixels after each run
of bsnes
The menu height bug was actually there previously, it was just that Qt
and GTK+ were computing the frame margins incorrectly (ignoring the menu
bar) before.
On the bright side, ui/settings/input.cpp has been improved by way of
the new multi-layout support. The window is no longer forced to an
awkward 640 pixels wide, as the mouse axes/buttons can overlap now. The
code is also simpler since I am using the Layout::setVisible command to
toggle groups on and off instead of doing it for each and every control.
byuu says (in the thread about rewriting Phoenix):
- added phoenix/reference; a dummy implementation that contains the 22KB
of static boilerplate code needed to start a new target
- OS::setDefaultFont removed; problem is that objects in the global
scope are constructed before you can call that function
- added Window::setWidgetFont, which is applied if your widgets have no
custom font set already upon attaching them to the window with
Window::setLayout, more understandable behavior
- renamed ListBox to ListView
byuu says (in the v075 WIP thread):
Found the source of lag on cartridge load. ListView::modify() was not
locking Qt messages, so it was causing a CheatEditor::refresh (copies
16MB of memory each call) for all 128 cheat items.
Final issue now is that nested submenus (menus inside of menus) are not
applying Window::setMenuFont yet.
byuu says:
phoenix has been completely rewritten from scratch, and bsnes/ui + bsnes/ui-gameboy have been updated to use the new API. Debugger works too. Currently, only phoenix/Qt is completed, and there are two known issues:
1: font sizes of menu items are wrong, I can fix this easily enough
2: there's some sort of multi-second lag when loading games, not sure
what's happening there yet
The new phoenix isn't exactly complete yet, still making some key
changes, and then I'll start on phoenix/Windows and phoenix/GTK+.
The most noticeable difference is that you don't have to give all of the
header paths and PHOENIX_PLATFORM defines when compiling individual GUI
object files. It's only needed for phoenix.cpp itself. The overall
structure of the phoenix source folder is much saner as well for
sync.sh.
I'm really surprised things are working as well as they are for
a two-day power rewrite of an entire phoenix target. The other targets
won't be as bad insofar as the core stuff is completed this time. And
thank god for that, I was about ready to kill myself after writing
dozens of lines like this:
HorizontalSlider::HorizontalSlider() : state(*new State),
base_from_member<pHorizontalSlider&>(*new pHorizontalSlider(*this)),
Widget(base_from_member<pHorizontalSlider&>::value),
p(base_from_member<pHorizontalSlider&>::value) {}
But each platform does have some new, unique problems. phoenix/GTK+ was
acting screwy prior to the rewrite, and will most likely still have
issues. Even more important, one of the major points of this rewrite was
having the new phoenix/core cache widget settings/data, so that I can
destroy and recreate widgets rather than relying on SetParent. This
means that simple copying of the old phoenix/Windows won't work, and
this new method is significantly more involved.
byuu says:
Rewrote the way menus are attached, they act like layouts/widgets now.
All three phoenix targets once again work with both radio menu items and
radio widgets. Both GTK+ and Qt have built-in group controls right
inside the widgets, so I don't have to keep my own groups around
anymore. They do act screwy at widget creation though, have to jump
through some hoops to get it to work right. All I can say is, definitely
set all child widgets to the parent before trying to check any of them.
My long-term goal for the main window is to honor the fullscreen video
setting as a generic setting, and let the window scale auto-fit the best
possible size that matches your scale preference into the output window,
centered just like fullscreen. For now, I've just set it to a fixed
window size until I finish working on phoenix. The scale X settings will
just be to snap the window to an exact size in case you don't want any
black borders, they won't be radio items and the bsnes-geometry.cfg file
will save width/height information as well.
Simplified the sizing requirements for creating layouts and updated all
bsnes windows to support the new system. Layouts also expose their
minimum width/height values, which I use to create perfectly sized
windows on all three platforms. This will fix cut-off heights on the
last Windows WIP. Qt is being annoying though and forcing a minimum
window size of 300,100 despite me telling it to use a smaller window
size. Always have to fight with Qt, I swear to god.
byuu says:
phoenix/Windows and phoenix/Qt are mostly fully operational now. All
platforms support dynamic layout resizing. I tried WM_GETMINMAXINFO
(thanks, OV2), but it was acting kind of choppy on resize, and it would
get confused and go crazy if you snapped one direction to the minimum
height but not another, so for now I'm leaving it off.
phoenix/GTK+ will be missing some functionality in regards to window
geometry. The other two have a more coherent strategy now: geometry() is
the client area, and setGeometry moves the client area to where you ask
for. This makes truly centering your client area trivial.
frameGeometry() includes the borders, menu and status. There is no
setFrameGeometry(), not sure if I really even want that, but it could be
useful so who knows. All targets also support non-resizable windows.
X11 is of course horrendously poor with frame sizes, Qt and GTK+ don't
even pretend to simulate them, so they say the frame is 0x0 pixels in
size until your widget is fully realized and visible to the end user. So
for now, to get window positioning right, I have to wait until the
window appears and then reposition the window again, causing a slight
jump. My plan is to build some persistent caching support directly into
phoenix. From here, I can just have the window snap the very first time
you run your very first phoenix app. I'll then determine the frame size
information, and use that to create future windows. Once they spawn,
I'll recheck and update the frame size info in case it has changed (eg
user changed themes.) Saving settings into .config/phoenix will allow me
to avoid having to snap the window every time on first startup. If the
config file is missing or unwritable, too bad, happens every time then.
I'm thinking about renaming onResize to onSize, and getting rid of
Window::create(). Rather make it spawn like every other control in its
constructor.
byuu says:
Ported phoenix/Windows and phoenix/GTK+ over to the new system. There
are some problems that need to be addressed:
- Windows ComboBox height setting needs widget creation height to
properly scale itself (make Widget::setGeometry virtual and override
ComboBox::setGeometry)
- Windows Canvas is completely broken
- GTK+ Canvas is slow as shit compared to Qt Canvas, probably nothing
I can do about it, have to do a very costly conversion because GTK+ is
stupid and uses BGR like Nintendo
- GTK+ listboxes are fucking insanely complicated to set up. Currently
I just split the second-half of creation to the setHeaderText call,
but when you don't call that, things explode
- I'm probably going to have to completely destroy and recreate
listboxes when changing the header text / column count
- Qt resize code is still impossible to get right, it's not letting me
size a window > 2/3rds of the screen size (it's in their docs)
- I swear, Qt is the most painful API in the world to move/size
windows with
- now that Window is separate, it really needs geometry() and
frameGeometry() as the two are quite different
- I need a way to toggle window resizability for fixed layouts, Qt is
once again going to be a nightmare as it lacks a way to do this other
than fixed layouts
- GTK+ currently explodes on bsnes, millions of console messages,
wonderful
- plenty more I'm forgetting
One bit of really cool/good news though: I made
Fixed/Horizontal/Vertical layouts external to phoenix itself. The code
is included for all targets so that it's always there and compiled into
one object, but the great news is that you can easily write your own
layout widgets and they'll work on all toolkits instantly.
That resize issue with bsnes was so simple it's annoying: my FixedLayout
container was repositioning on geometry updates. Made it only do it once
at creation like it should.
bsnes now has a fancy resize, grow the window and get black borders,
shrink it and the video shrinks with it. I plan to make it fancier with
constraint settings (center, scale, stretch). Basically I want to turn
the fullscreen setting into a general setting that also applies to
windowed scaling. I will probably turn the video scale X sizes into
regular items instead of radio boxes, so you can easily reset to a fixed
size whenever you want. Update bsnes to remember width,height geometry
as well and it should be quite nice.
byuu says:
Eleven hours of work. Window is now a base type (inherits from Object,
not Widget), same for Layout. FixedLayout still inherits from Layout.
Added HorizontalLayout and VerticalLayout types, that can append each
other to themselves to create box layouts. Layout margins are supported,
spacing is specified inline (I find this a much better way to fine-grain
spacing than Qt's single setSpacing function), and alignment is handled
strictly via padding widgets (insert a zero-sized label and it will
automatically grow to consume all extra space.)
Overall, my box packing model is slightly less powerful than Qt's, but
it is a good deal simpler and and easier to use in 90% of cases. The one
limitation I hit was with my input settings window, I'm not currently
able to embed two different layouts and toggle one on and the other off
to show only either { mouse x-axis, y-axis } or { mouse left, middle,
right }, so they instead just space out differently and I had to grow
the input window width a bit to compensate.
Resizing works great, pretty cool seeing that this is the first time
I've ever written my own resizer. I had to fight with Qt for several
hours to the point of potentially developing an aneurysm, but I finally
got it to properly handle geometry and sizing stuff. Some weird issue
with the bsnes viewport widget, I tell it to resize and for some reason
it doesn't. Cheap hack, I just make it constantly resize every video
refresh and it eventually takes. Wish I knew what was up with that.
All of bsnes now uses dynamic layouts sans the main window, so you can
resize them however you like.
This is still all Qt-only, I'm afraid. The other two ports are
in-progress.
byuu says:
This has the phoenix changes applied. Instead of widgets attaching
directly to windows, you now attach them to layouts, which can then be
attached to windows. Layouts are widgets themselves, so adding layouts
to layouts is trivial. It also allows for multi-widget show/hide, etc.
Right now there is only FixedLayout, but of course the plan is to
support a BoxLayout, that lets you add HorizontalLayout and
VerticalLayout containers to it, thus enabling auto-resize and simpler
form layout.
So far only phoenix/Qt is 100% moved over. phoenix/GTK+ has about 1/3rd
ported, and phoenix/Windows only has one control ported over as
a proof-of-concept.
On the user side, bsnes, bgameboy, snespurify and curse have been moved
to this new layout system. All of bsnes works great with it, as far as
I can tell. Fullscreen, debugger, etc are good.
byuu says:
Removed the floating-point volume adjustments from the wave channel and
the left/right speaker mixers. Also, against my better judgment I'm
backing out of left/right computation when they are both turned off.
This basically makes non-stereo games run faster, but will make stereo
games appear to run slower. I don't like it when end-users experience
mystery slowdowns.
Anyway, it appears that the audio calculation is really fucking
demanding. Knocks FPS from 800 down to 300. I thought it might be libco,
so I took it out and it only went up to 305fps o.O
There is also some sort of problem with bsnes/Super Game Boy audio. The
latency is really great when you first start, but it seems to drift
apart over time until it is well over 500ms, and then it either pops or
fades back to very low, sub-50ms latency again. The way I handle mixing
is that the coprocessor audio samples go into a resampler to the native
SNES rate, and fed to an output buffer. SNES audio samples go there
untouched. When there is a sample in each, I add them together and
average the result (I still don't understand why we divide by two since
these are signed integers), and output it immediately. It's just-in-time
sampling, so as long as DSP v Coprocessor do not drift very far, it
should have very low latency. And I make the CPU sync DSP and
Coprocessor once per scanline, which is something like 15 samples or so.
byuu says:
Added Game Boy sound emulation, all four channels.
It's really, really, really bad. Plenty of bugs, I don't even know what
the fuck a high-pass filter is so that isn't there. Hermite resampling
from 4MHz down to 44KHz. But it's tolerable.
I don't understand what sweep is for at all, and I'm sure I have that
insane recursive reload behavior wrong.
This is pretty much my own design. I referenced blargg's gb snd emu,
blargg's older gb apu ref, Cydrak's APU core, that lousy gbdev wiki
article, the completely and utterly worthless pandocs, and received
nothing but bad and wrong information that just wasted my time from
But I managed to pull it off. It's also painfully slow, like 250fps on
my machine slow. Countless optimizations are possible.
byuu says:
Changelog:
- hooked up everything necessary for Game Boy sound emulation ...
- bgameboy and bsnes/SGB input 4MHz frequency, and output 44.1KHz
frequency (produces soft static for now, to verify it is working)
- rewrote all of gameboy/apu, it now has a 4MHz worker thread, and
separate classes/folders for each channel+master, and serializes
So it's basically all I can do without actual emulation code or
human-readable documentation/example code.
byuu says:
Changelog:
- added full HexEditor widget to phoenix/Qt (has dynamic scrollbar like
phoenix/GTK, but does not yet support page up/down scrolling)
- optimized debugger to look great with either phoenix/GTK or phoenix/Qt
- fixed phoenix/Qt fullscreen mode (had to allow resizing of the layout,
and resize the container)
- fixed phoenix/Qt Window::setBackgroundColor() bug that was making
statusbar invisible
- entering fullscreen now captures mouse, leaving fullscreen releases it
- so by default, no cursor in fullscreen mode now
- F12 key was assigned the task of toggling mouse capture,
Tools->Capture Mouse was removed
- above change allows toggling mouse capture in fullscreen if you like
It wasn't my idea, but toggling the mouse capture in fullscreen also hiding the mouse cursor is what I call genius design. Two birds with one stone, and very intuitive.
Also, the default GUI on Linux for bsnes and bgameboy is now Qt, instead
of GTK+. I did this because Qt's fullscreen is far more stable, and
I fixed up the remaining bugs anyway.
byuu says:
Changelog:
- added ui-libsnes directory back into source archive; make archive-all
includes it now
- added basic HexEditor widget to phoenix/Windows
byuu says:
Changelog:
- fixed Super Game Boy save state support
- both SNES and GameBoy only initialize serialize size on cartridge load
once now, just like I've already done with memory mapping
- added nall/public_cast.hpp for fun ... don't worry, I'm never actually
going to use it in production code :D
byuu says:
This release brings improved Super Game Boy emulation, the final SHA256
hashes for the DSP-(1,1B,2,3,4) and ST-(0010,0011) coprocessors, user
interface improvements, and major internal code restructuring.
Changelog (since v074):
- completely rewrote memory sub-system to support 1-byte granularity in
XML mapping
- removed Memory inheritance and MMIO class completely, any address can
be mapped to any function now
- SuperFX: removed SuperFXBus : Bus, now implemented manually
- SA-1: removed SA1Bus : Bus, now implemented manually
- entire bus mapping is now static, happens once on cartridge load
- as a result, read/write handlers now handle MMC mapping; slower
average case, far faster worst case
- namespace memory is no more, RAM arrays are stored inside the chips
they are owned by now
- GameBoy: improved CPU HALT emulation, fixes Zelda: Link's Awakening
scrolling
- GameBoy: added serial emulation (cannot connect to another GB yet),
fixes Shin Megami Tensei - Devichil
- GameBoy: improved LCD STAT emulation, fixes Sagaia
- ui: added fullscreen support (F11 key), video settings allows for
three scale settings
- ui: fixed brightness, contrast, gamma, audio volume, input frequency
values on program startup
- ui: since Qt is dead, config file becomes bsnes.cfg once again
- Super Game Boy: you can now load the BIOS without a game inserted to
see a pretty white box
- ui-gameboy: can be built without SNES components now
- libsnes: now a UI target, compile with 'make ui=ui-libsnes'
- libsnes: added WRAM, APURAM, VRAM, OAM, CGRAM access (cheat search,
etc)
- source: removed launcher/, as the Qt port is now gone
- source: Makefile restructuring to better support new ui targets
- source: lots of other internal code cleanup work
byuu says:
Changelog:
- debugger compiles on all three profiles
- libsnes compiles on all three platforms (no API changes to libsnes)
- memory.cpp : namespace memory removed (wram -> cpu, apuram -> smp,
vram, oam, cgram -> ppu)
- sa1.cpp : namespace memory removed (SA-1 specific functions merged
inline to SA1::bus_read,write)
- GameBoy: added serial link support with interrupts and proper 8192hz
timing, but obviously it acts as if no other GB is connected to it
- GameBoy: added STAT OAM interrupt, and better STAT d1,d0 mode values
- UI: since Qt is dead, I've renamed the config files back to bsnes.cfg
and bsnes-geometry.cfg
- SA1: IRAM was not syncing to CPU on SA-1 side
- PPU/Accuracy and PPU/Performance needed Sprite oam renamed to Sprite
sprite; so that I could add uint8 oam[544]
- makes more sense anyway, OAM = object attribute memory, obj or
sprite are better names for Sprite rendering class
- more cleanup
byuu says:
Major WIP, countless changes. I really went to town on cleaning up the
source today with all kinds of new ideas. I'll post the ones I remember,
use diff -ru to get the rest.
What I like the most is my new within template:
template<unsigned lo, unsigned hi>
alwaysinline bool within(unsigned addr) {
static const unsigned mask = ~(hi ^ lo);
return (addr & mask) == lo;
}
Before, you would see code like this:
if((addr & 0xe0e000) == 0x206000) { //$20-3f:6000-7fff
The comment is basically necessary, and you have to trust that the mask
is right, or do the math yourself.
Now, it looks like this:
if(within<0x20, 0x3f, 0x6000, 0x7fff>(addr)) {
That's the same as within<0x206000, 0x3f7fff>, I just made an
SNES-variant to more closely simulate my XML mapping style:
20-3f:6000-7fff.
Now obviously this has limitations, it only works in base-2 and it can't
manage some tricky edge cases like (addr & 0x408000) == 0x008000 for
00-3f|80-bf:8000-ffff. But for the most part, I'll be using this where
I can. The Game Boy is fully ported over to it (via the MBCs), but the
SNES only has the BS-X town cartridge moved over so far. SuperFX and
SA-1 at the very least could benefit.
Next up, since the memory map is now static, there's really no reason to
remap the entire thing at power-on and reset. So it is now set up at
cartridge load and that's it. I moved the CPU/PPU/WRAM mapping out of
memory.cpp and into their respective processors. A bit of duplication
only because there are multiple processor cores for the different
profiles, but I'm not worried about that. This is also going to be
necessary to fix the debugger.
Next, Coprocessor::enable() actually does what I initially intended it
to now: it is called once to turn a chip on after cartridge load. It's
not called on power cycle anymore. This should help fix power-cycle on
my serial simulation code, and was needed to map the bus exactly one
time. Although most stuff is mapped through XML, some chips still need
some manual hooks for monitoring and such (eg S-DD1.)
Next, I've started killing off memory::, it was initially an
over-reaction to the question of where to put APURAM (in the SMP or
DSP?). The idea was to have this namespace that contained all memory for
everything. But it was very annoying and tedious, and various chips
ignored the convention anyway like ST-0011 RAM, which couldn't work
anyway since it is natively uint16 and not uint8. Cx4 will need 24-bit
RAM eventually, too. There's 8->24-bit functions in there now, because
the HLE code is hideous.
So far, all the cartridge.cpp memory:: types have been destroyed.
memory::cartrom, memory::cartram become cartridge.rom and cartridge.ram.
memory::cartrtc was moved into the SRTC and SPC7110 classes directly.
memory::bsxflash was moved into BSXFlash. memory::bsxram and
memory::bsxpram were moved into BSXCartridge (the town cartridge).
memory::st[AB](rom|ram) were moved into a new area,
snes/chip/sufamiturbo. The snes/chip moniker really doesn't work so
well, since it also has base units, and the serial communications stuff
which is through the controller port, but oh well, now it also has the
base structure for the Sufami Turbo cartridge too. So now we have
sufamiturbo.slotA.rom, sufamiturbo.slotB.ram, etc.
Next, the ST-0010/ST-0011 actually save the data RAM to disk. This
wasn't at all compatible with my old system, and I didn't want to keep
adding memory types to check inside the main UI cartridge RAM loading
and saving routines.
So I built a NonVolatileRAM vector inside SNES::Cartridge, and any chip
that has memory it wants to save and load from disk can append onto it
: data, size, id ("srm", "rtc", "nec", etc) and slot (0 = cartridge,
1 = slot A, 2 = slot B)
To load and save memory, we just do a simple: foreach(memory,
SNES::cartridge.nvram) load/saveMemory(memory).
As a result, you can now keep your save games in F1 Race of Champions II
and Hayazashi Nidan Morita Shougi. Technically I think Metal Combat
should work this way as well, having the RAM being part of the chip
itself, but for now that chip just writes directly into cartridge.ram,
so it also technically saves to disk for now.
To avoid a potential conflict with a manipulated memory map, BS-X SRAM
and PSRAM are now .bss and .bsp, and not .srm and .psr. Honestly I don't
like .srm as an extension either, but it doesn't bother me enough to
break save RAM compatibility with other emulators, so don't worry about
that changing.
I finally killed off MappedRAM initializing size to ~0 (-1U). A size of
zero means there is no memory there just the same. This was an old
holdover for handling MMIO mapping, if I recall correctly. Something
about a size of zero on MMIO-Memory objects causing it to wrap the
address, so ~0 would let it map direct addresses ... or something.
Whatever, that's not needed at all anymore.
BSXBase becomes BSXSatellaview, and I've defaulted the device to being
attached since it won't affect non-BSX games anyway. Eventually the GUI
needs to make that an option. BSXCart becomes BSXCartridge. BSXFlash
remains unchanged.
I probably need to make Coprocessor::disable() functions now to free up
memory on unload, but it shouldn't hurt anything the way it is.
libsnes is most definitely broken to all hell and back now, and the
debugger is still shot. I suppose we'll need some tricky code to work
with the old ID system, and we'll need to add some more IDs for the new
memory types.
byuu says:
This WIP fixes up the last bit from the old memory mapping system, the
BS-X Satellaview town cartridge now has a static memory mapper that is
dynamically decoded based on register settings. Tested with BS Town + BS
Zelda, and I can get in-game just fine. The mapping code is actually
a lot more readable this way, too.
byuu says:
The nall::function binding for the memory map apparently breaks when the
debugger is enabled, as PPU:: becomes PPUdebugger::, etc; and C++ isn't
smart enough to upconvert for us.
Not sure how I am going to work around that yet ...
Changelog:
- improved GameBoy::CPU::Halt emulation, fixes Legend of Zelda intro
water+world-map scrolling at the same time
- added GameBoy::APU skeleton, and hooked up MMIO read/write for all
registers
- modified nall integer->string functions
byuu says:
Fullscreen works on all ports, but Qt is in general pretty wonky at the
moment. Don't really care right now.
F11 toggles fullscreen, there is no menu or status in fullscreen, and it
auto-scales to the highest even multiple that it can.
It copies all other settings (filter, shader, aspect correction, video
region, vsync, async) from your windowed mode settings.
You cannot enable the menu or status bars, because those are a major
pain in the ass to support with both GTK+ and Qt returning nonsense
geometries.
Combine with each platform treating whether or not to handle menus
and/or statuses as part of the geometry or not, and it's a recipe for
pain.
It is pseudo-fullscreen for now, but if we have some spiffy code in the
future to set a true fullscreen that works on Linux (and hopefully OS
X), I'll add a true-FS option to ruby later.
byuu says:
This WIP uses the 16MB+64MB memory tables for 1:1 mapping of the S-CPU
bus.
Minimum RAM requirement goes up to 128MB, dare I be bold here and
recommend you have 256MB.
I also hooked up the basic bindings for making pseudo-fullscreen windows
in phoenix/Windows and phoenix/GTK+, but both have some serious issues.
- GTK+ won't resize my form container, even though it's the same code
I used successfully in bsnes v039 and prior with hiro
- Windows scale selection breaks the faux-fullscreen effects
- I am intending to write off the menu/status bars and just auto-size
the video to fill the screen, nice and simple
byuu says:
Oh good, that turned out to be a lot easier than I expected.
Almost all of the work was already done yesterday in porting the SA-1
over to a static map.
byuu says:
SuperFXBus was inheriting from Bus, in other words using a copy of the
same memory mapping subsystem.
I've removed that and made it a simple mask, since only ROM+RAM are
mapped there.
byuu says:
You guys are going to hate the hell out of this one. It's twenty hours
of non-stop work, no exaggeration at all. Started at 4AM, just wrapped
up now at 8PM.
I rewrote the entire memory subsystem.
Old system:
65536 pages that map 256 bytes each
Mapping a new page overwrites old page
Granularity capped at 256 bytes minimum, requiring ST-001x to map
60:0000-00ff instead of 60:0000,0001
Classes inherit from MMIO and Memory, forcing only one mappable function
per class, and fixed names
MMIO sub-mapper inside memory: 00-3f:2000-5fff for one-byte granularity
Can dynamically change the map at run-time, MMC register settings
perform dynamic remapping
New system:
XML mapping is still based around banklo-bankhi:addrlo-addrhi, as that
shapes almost everything on the SNES very well
Internally, 2048 pages that map 8192 bytes each
Pages are vectors, scans O(n) from last to first (O(log n) would not
help, n is never > 3)
Can multi-cast writes, but not reads [for the obvious reason of: which
read do you return?]
Can map reads and writes separately
Granularity of one for entire 24-bit address range, no need for MMIO
- whatever is in XML is exactly what you get
Read/Write tables bind function callbacks, so I can have any number of
functions with any names from any classes with no inheritance (no
more uPD7725DR, uPD7725SR helpers, etc)
Less memory usage overall due to less tables [ I tried 16 million tables
and it used 2GB of RAM >_o ]
Cannot dynamically change the map at run-time, MMC read/write functions
perform address translation [worse average case speed, better worst
case speed]
Now the hate me part, functors can't beat virtual functions for speed.
There are speed penalties involved:
-4.5% on average games
-11% on SuperFX games (SFX has its own bus)
-15% on SA-1 games (SA-1 has two buses)
Of course the two that need the speed the most get the biggest hits.
I'm afraid there's really not a lot of wiggle room to boost speed back
up.
I suppose one bright spot is that we can much more easily try out
entirely new mapping systems now, since the dynamic portions have been
eliminated.
byuu says:
Changelog:
- updated/fixed st0011.bin SHA256 sum
- removed launcher/
- building ui-gameboy only builds the Game Boy core, not the SNES core
- binary name output is bgameboy for ui-gameboy
- make install/make uninstall work as expected with the extra data files
[Editor's note - those last three changes seem to have been made in
v074r01]
byuu says:
Changelog:
- fixed libsnes to compile again, the GB RTC constant is there but
doesn't do anything just yet (no serialize support in GameBoy core)
- libsnes: added SNES_MEMORY_(WRAM,APURAM,VRAM,OAM,CGRAM) -- really only
for the first one, it allows libsnes users to implement their own
cheat search
- you can now load the SGB BIOS without a game!! please be sure to enjoy
the blinking cartridge icon emulation :D
- necdsp (uPD7725,96050) - simplified code a bit: removed persistent
regs.idb, simplified jumps, merged exec() with main loop, etc.
- nall::function - fixed an initialization bug when copy-constructing
objects
- nall::vector - use calloc instead of malloc to help safeguard against
uninitialized class data (potentially hides errors, but better than
crashing in production)
byuu says (since v073):
This release adds full low-level emulation of the NEC uPD96050
coprocessor, used by the ST-0010 (F1 Race of Champions II) and the
ST-0011 (Hayazashi Nidan Morita Shougi). The former was already playable
with HLE, but lacked timing emulation. The latter has never been
playable through emulation before now. But as with SD Gundam GX before,
you really weren't missing much.
[...]
Also new in this release is my own Game Boy emulator. It is being used
to provide native Super Game Boy support, built directly into bsnes.
This core is released under the GPLv2, but I am willing to grant a more
permissive license for other SNES emulators, if anyone is interested.
Of course I cannot compete with the quality of gambatte, and certainly
not from only a weeks' worth of work. Currently, there is no Game
Boy-side sound output and there are quite a few bugs remaining in its
emulation core. I would appreciate any help on this, the Game Boy is not
my forte. So yes, we are taking a step back today, so that we may take
two steps forward in the future.
[...]
Lastly, the debugger is still Linux-only, but it is now stable enough to
be considered usable. Check it out if you like, compile with -DDEBUGGER
to enable it.
byuu says:
I give up for now. This WIP doesn't really improve uPD any, but it does
have major fixes to the debugger.
Debugger is still Linux-only for want of a HexEditor widget, but the
Linux one is now usable.
Before it'd trace and search for breakpoint at sub-1fps. Fixed it to not
break out of core for simple things and it'll run at near-fullspeed for
BPs, half-speed for tracing to file (lots of I/O.)
byuu says:
Above WIP will automatically map in the ST-001x chips, no need for an
XML file.
F1 Race of Champions II (J) is fully playable, at least. It's forced to
15MHz like the ST-0011 for now.
The core (snes/chip/necdsp/core) is somewhat unstable at the moment,
some debugging hooks commented out and some hacks / ideas floating
around in there. Disassembler can't handle long jumps yet.
Added uPD96050 emulation, but it's not working right now. I'm totally
stumped. The ST-0010 player cars aren't moving right, and it crashes
sometimes on exit like it's going out of bounds.
I had decided to try and avoid duplicating the 20KB uPD7725 core, so
I made a new folder:
snes/chip/necdsp
snes/chip/necdsp/upd7725
snes/chip/necdsp/upd96050
The latter two derive from the former, and they specify the PC, RP and
DP sizes, which allocates appropriate memory.
I use simple runtime-masked registers (to avoid template hell on every
uPDcore function), and then I derive from that to complete each actual
DSP. The uPD7725 seems to work great, but the uPD96050 is fucked and
I don't know why :(
Help would be appreciated, it must be something simple because I am
certain the cars were working before.
Kinda wish I didn't scrap the old code now :(
I've merged the bgameboy GUI into the bsnes project, as it's only ~3KB
and it means I don't have to keep manually editing and copying two
projects around. You can set ui := ui-gameboy to build bgameboy as
a standalone, and ui := ui to build the bsnes you are used to. I will be
polishing it to allow changing the binary output name, not building the
SNES portions when not needed, etc in time.
So that'll end bgameboy standalone releases, at least for now. If it
ever gets important enough to split back out again I can, but I prefer
it this way. bgameboy was never meant to be mainstream anyway, just
a component for bsnes.
byuu says:
Changelog:
- much tighter SGB integration, but this is still a work-in-progress
- memory::gb(rom,ram,rtc) is gone, uses GameBoy:: memory structures
directly (a big gain, no need to copy memory to save and load)
- UI-based cartridge loading works with GameBoy:: directly as well
- libsnes will need to be updated internally to reflect this
- games can save and load (even before bgameboy can, hah)
- save states hooked up, but they crash the DMG. I don't know why, as
if it was hard enough saving states with libco, try doing it for an
emulator inside an emulator >_<
- last remnants of old SGB stuff removed, <sueprgameboy> XML converted
to <icd2>
- looks like the XML list idea is looking pretty useless for
SNES::Cartridge now that bgameboy handles its own XML mapping
byuu says:
Changelog:
- removed bsnes/supergameboy (libgameboy -> libgambatte binding)
- added direct ICD2-R coprocessor emulation
- linked in bgameboy to the ICD2-R module
- Makefile removes -Isnes, all files adjusted from <name.hpp> to
<snes/name.hpp> [relic from asnes split]
You can now play Super Game Boy games with the core bsnes library.
byuu says:
Changelog:
- adds XML memory mapping to cartridge loading;
nall/gameboy/cartridge.hpp will bullshit one for now
- still need to add proper MMM01 detection (menu code goes at end of ROM
apparently)
- added save state support, which works here (but not inside bsnes, go
figure), to aid in debugging. Expect constant changes for now a long
while, it's way too early to add states
byuu says:
Changelog:
- fixed LYC interrupt at LY=0 (fixes Makai Toushi SaGa)
- fixed MBC3 ROM bank mapping (fixes Harvest Moon GBC)
- added Super Game Boy MLT_REQ support to JOYP, needed for ICD2-R emulation
- temporarily changed System::run() to execute only four cycles before
exiting for bsnes, will make two versions later
- uses actual boot ROMs, has DMG+SGB1 for now. Need SGB2, don't care
about CGB. Defaults to SGB1, no way to select just yet. DMG 4-second
wait is annoying. Does not force games to act like SGB on bgameboy
itself, because that has no ICD2 and fails the required MLT_REQ check
byuu says:
Changelog:
- added skeleton HuC1 (gets to a menu)
- added skeleton HuC3 (gets to a menu, this one is supposedly a lot more
complex (IR, RTC, etc.))
- added MMM01 emulation
byuu says:
Changelog:
- rewrote sprite rendering, grabs first ten sprites, draws them in
revere order of a: X-index, b: OAM appearance order
- simplified tile decoding to use less variables
- added MBC3 emulation (for now, RTC is always enabled)
- STOP can be broken via joypad IF, this may not be correct though (it
may trigger even without P10-13 being modified)
- cleaned up all MBC emulation to use masks instead of ranges
- MBC2 uses 512-byte table now, ignores high 4-bits. Easier this way I guess
- tools menu temporarily has a console tracer enable option
- some other stuff
No real visible improvements :(
byuu says:
Changelog:
- fixed sprite Vflip check
- fixed up window rendering (well, mostly, works great in Megaman II but
not so great in Makaitoushi SaGa)
- added MBC2, MBC5 (already had MBC0, MBC1)
- removed reset, hooked up power cycle and Vsync toggle
- some other stuff
Makaitoushi SaGa locks on the main menu after some graphical glitches on
the title screen, damn.
Shin Megami Tensei - Devichil Black Book locks up immediately, hitting
HALT opcodes all the time, damn again.
Megaman II should be fully playable now.
Contra 3 is really close, but goes crazy on the turtle boss fight.
byuu says:
Added MBC1 emulation, although battery RAM doesn't save or load to disk
yet.
Made up a fake MBC0 which is really just saying 'no MBC', for consistent
handling of all MBCs.
Added bumpers to stop ROM/RAM out of bounds accesses.
Added STAT interrupts for LY coincidence, Vblank and Hblank (not for OAM
access yet, I don't know the timings.)
Fixed timer interrupt [Jonas Quinn]
Made all interrupts call a CPU function instead of just setting a flag
for better control (to allow below addition.)
Added HALT and STOP emulation, the latter permanently locks the Game Boy
for now. The former breaks on interrupts.
Rewrote all the rendering code to suck 50% less, though it's still
absolutely miserable and scanline-based.
Added pixel-level horizontal scrolling to BGs.
Fixed OBJ rendering error that was making them render upside down (I was
flipping to compensate before.)
Added OBJ 8x16 mode.
Added OBJ priority support.
Added window (but it's broken to all hell on Mega Man II.)
byuu says:
Fixed all of the previously mentioned problems by myself and Jonas
Quinn.
Fixed up JOYP and hooked up JOYP interrupts, they work on JOYP writes as
well if your selection makes the low four bits change to != 0xF.
Added basic sprite emulation, very very very lousy but it works for
Tetris.
Fixed DAA, fuck that opcode. Fixes blargg's CPU tests 1 and 11 (for some
odd reason.) Only test 2 is failing, on the "EI" test. Maybe it relies
on STAT interrupts?
Did some other stuff.
Tetris is now 100% fully playable. But that renderer is an abomination.
Soooooo simplistic and missing so many edge cases.
But holy shit, a fully playable commercial game in three days. I would
have killed to have made that progress when I started on bsnes.
byuu says:
All 512 instructions implemented. To make debugging flags easier and to
reduce the code size, I made parent routines for all the bit-logic that
sets flags. This bumped up the speed to 3,045fps. So about 51x faster
than a real Game Boy.
I suspect the frame rate to plummet rapidly as I emulate more stuff and
try and get timings more accurate. Wild ballpark, I'd guess 300fps or
so. Not based on anything, just a made up number. I have no idea what it
will end up being.
So I still need:
* decode MMIO reads/writes
* add CPU interrupt support
* add LCD emulation (probably the hardest part)
* add PCM emulation (well, this would likely be the hardest; but it's
not essential right now)
* debug the holy living shit out of the CPU core. Anyone want to help
now by looking it over? :D
byuu says:
314 of 512 opcodes implemented, can execute the first 67,450
instructions of Tetris.
I also added an MMIO bus, ala bsnes, so that I can map and access
individual registers with a single indirection.
byuu says:
Hooked up a scheduler to enter/exit the CPU core wherever I want. Added
basic 4*1024*1024hz clock, and about eleven or so opcodes. Creating the
disassembler as I encounter each new opcode, not skipping ahead to do
all 'like other' opcodes, eg if I add 'dec b', I don't then add 'dec c'
until I encounter it.
The source tarball also included empty obj/ and out/ directories which
git does not support.
byuu says:
Project started, so basically everything is new.
It's basically a rough skeleton that mimics bsnes project structure.
Eventually the src/gameboy folder will be copied into bsnes-official and
used by the chip/supergameboy core.
The middleware layer (supergameboy/interface) will be merged into a new
chip/icd2 folder that will represent direct Super Game Boy emulation in
the future.
At least, if all goes according to plan.
There is a simple GUI that can load ROMs, but do nothing after it. It's
not hooked up to ruby yet.
There is a basic system class and interface to expose the
video/audio/input functions.
There is a basic memory bus that doesn't support any MBCs yet.
There is a CPU skeleton that only handles easy read/write access to the
CPU registers (AF is a really fucked up register.)
The core is not hooked up to libco yet, but I intend for it to be, so
that I can run the CPU + LCD how I like.
If it turns out the LCD+audio is easily enslavable, then I'll probably
drop libco and just run it like a regular emulator, using a thread
wrapper around it in bsnes only. We'll see.
The CPU doesn't actually support any opcodes, and loading a ROM won't
actually execute anything.
byuu says:
While perhaps not perfect, pretty good is better than nothing ... I've
added emulation of auto-joypad poll timing.
Going off ikari_01's confirmation of what we suspected, that the strobe
happens every 256 clocks, I've set up emulation as follows:
Upon reset, our clock counter is reset to zero.
At the start of each frame, our poll counter is reset to zero.
Every 256 clocks, we call the step_auto_joypad_poll() function.
If we are at V=225/240+ (based on overscan setting), we check the poll
counter.
At zero, we poll the actual controller and set the joypad polling flag
in $4212.d0 to 1.
From zero through fifteen, we read in one bit for each controller and
shift it into the register.
At sixteen, we turn off the joypad polling flag.
The 256-clock divider allows the start point of polling for each frame
to fluctuate wildly like real hardware.
I count regardless of auto joypad enable, as per $4212.d0's behavior;
but only poll when it's actually enabled.
I do not consume any actual time from this polling. I honestly don't
know if I even should, or if it manages to do it in the background.
If it should consume time, then this most likely happens between opcode
edges and we'll have to adjust the code a good bit.
All commercial games should continue to work fine, but this will likely
break some hacks/translations not tested on hardware.
Without the timing emulation, reading $4218-421f before V=~228 would
basically give you the valid input controller values of the previous
frame.
Now, like hardware, it should give you a state that is part previous
frame, part current frame shifted into it. Button positions won't be
reliable and will shift every 256 clocks.
I've also removed the Qt GUI, and renamed ui-phoenix to just ui. This
removes 400kb of source code (phoenix is a lean 130kb), and drops the
archive size from 564KB to 475KB. Combined with the DSP HLE, and we've
knocked off ~570KB of source cruft from the entire project. I am looking
forward to not having to specify which GUI is included anymore.
byuu says:
This release marks a major step forward, offering full low-level
emulation of all four DSP coprocessors based on the NEC uPD77C25
processor core. Many people were responsible for this milestone: Dr.
Decapitator for the actual decapping and extraction; Lord Nightmare for
the cartridges and some special analysis tools; myself, Jonas Quinn and
Cydrak for the uPD77C25 emulation; and all of the donors who raised the
necessary $1,000 for the necessary hardware and equipment needed to pull
this all off. To say thanks to the donors, I am releasing the uPD77C25
emulation core to the public domain, so that everyone can benefit from
it.
All four DSP emulations will be improved by this by way of having
realistic timing; the DSP-4 will benefit further as the high-level
emulation was incomplete and somewhat buggy; and the DSP-3 will benefit
the most as the high-levle emulation there was not complete enough to be
playable. As a result, most notably, this means bsnes v073 is the first
emulator to fully be able to play SD Gundam GX (J)!
As bsnes' primary goal is accuracy, the LLE DSP support renders the old
HLE DSP support obsolete. Ergo, I have removed the 166KB of HLE source
code, and replaced it with the uPD77C25 core, which comprises a mere
20KB of source code. As this LLE module supports save states, this also
means that for the first time, DSP-3 and DSP-4 games have save state
support.
On the other hand, this also means that to run any DSP game, you will
need the appropriate program ROM. As these are copyrighted, I cannot
distribute them nor tell you where to get them. All I can do is provide
you with the necessary filenames and hashes.
Changelog (since v072 release):
* added NEC uPD77C25 emulation core
* added low-level emulation of the DSP-1, DSP-1B, DSP-2, DSP-3, DSP-4
coprocessors
* removed high-level emulation of the DSP-n coprocessors
* added blargg's libco::ppc.c module, which is far more portable, even
running on the PS3
* added software filter support via binary plugins
* added debugger (currently Linux-only); but it is as yet unstable
* added pause shortcut
* updated mightymo's cheat code database
byuu says:
Changelog:
* added SNES::interface.message(const string&) so that the core can send
messages for the GUI to display
* failing to load a DSP-n ROM, or failing the DSP-n SHA256 hash (if
there is one) will result in a warning message
* all DSP-1 games by default once again use the DSP-1B program, now that
it has been redumped and reverified
* fixed bugs in uPD77C25 SHL2 and SHL4 opcodes; fixes DSP-2 and DSP-4
emulation
* removed all DSP HLE (DSP-1, DSP-2, DSP-3, DSP-4)
* as a result of LLE, DSP-3 and DSP-4 games can now load and save states
byuu says:
The DSP-1 and DSP-3 emulation appears to be great.
However, there are bugs in the other two.
DSP-2, Dungeon Master: the graphics in-game appear corrupt. It looks
like the first two pixels have the right color, the next six have the
wrong color, resulting in vertical stripes.
DSP-4, Top Gear 3000: the car sprites appear to be showing 8x8 tiles
instead of 16x16 files, resulting in 3/4ths of the cars being invisible,
but only up close.
Dr. Decapitator and Lord Nightmare are supremely confident that our
dumps are 100% accurate, there was no bus wavering at all this time.
We believe they are bugs in the uPD77C25 emulation.
I desperately need help! I have spent the past several hours trying to
ascertain what the problem is, to no avail.
I've tried messing with just about every flag, every register, checking
for use of OV1, S1, custom opcodes, etc ... I am having no luck.
I'm going to keep trying with even more sophisticated cross-analysis.
But Cydrak, if you would please rework that magic of yours, I'd be
eternally grateful :D
byuu says:
This release defaults DSP-3 loading to use the uPD77C25 core. It also
pre-emptively does the same for the DSP-2 and DSP-4. v072r11 did this
for the DSP-1.
I've also renamed my string<>integer conversion function names:
strhex -> hex
strsigned -> integer
strunsigned -> decimal
strbin -> binary
strdouble -> fp (this one will no doubt be trouble since 'file fp' is
a common idiom. floatingpoint is too long, float and double are
already reserved.)
A number of changes in this release were contributed by Cydrak in the
WIP thread, who described his changes from r09/r10 thusly:
- Call cpu.synchronize_coprocessor() on external R/W to avoid missing data
- Sign-extend K, L before multiplying
- Load IDB before ALU. Supports the MOV A, d; XOR A, A idiom which is
all over the place
- Use 16-bit types in flag checks (notably Z)
- Flags mostly unified; hopefully at least OV0 and SGN work
- Carry-in comes from the *other* accumulator's flags, this is used for
long arithmetic
- CMP is ~q (see the many CMP A; INC A where values get negated)
- SHR1 is arithmetic shift and retains the sign bit (Mario Kart sprites
and physics are broken without it)
- SHL1 has carry-in per the datasheet, it doesn't seem to be used though
- XCHG probably byteswaps, but it's not used either
- Reversed DR external R/W order again, big-endian seems to break it
byuu described the remaining changes:
You do not need the XML files anymore, bsnes will automatically choose
the new uPD module, and look for dsp1b.bin.
If you make your own XML file, you can force the old HLE mode, or use
a differently-named PROM.
If and when we get the DSP-2,3,4 modules, bsnes v072.11 and above should
already be able to run them, assuming no more emulation core bugs.
Unfortunately, I missed the v072r08 release; it was taken down before
I saw the announcement.
byuu says (about v072r08):
This WIP adds NEC uPD77C25 emulation. Unfortunately it's not at all functional yet, there are way too many things I don't understand about the chip.
I'm absolutely going to need help to complete this.
[...]
For now, you need the included PCB XML to manually map the program/data ROM in, which are included with the archive. You'll have to rewrite the map yourself to run other DSP-1 games, unless they have the same layout as Mario Kart. I am using the US [!] version, name it mariokart.sfc and put all the archive files and the ROM together.
From here, bsnes will load up the ROMs, and start executing instructions. Since the emulation is so incomplete, it just deadlocks on the "Nintendo" logo as if there were no DSP on the cart at all, but if you enable tracing, you'll see it actually starts doing a lot of stuff before getting stuck in a really long and confusing loop.
[Note: the DSP-1B program and data ROMs are not included in this commit.
The PCB XML file mentioned above looks like this:
<?xml version='1.0' encoding='UTF-8'?>
<cartridge region='NTSC'>
<rom>
<map mode='shadow' address='00-3f:8000-ffff'/>
<map mode='linear' address='40-7f:0000-ffff'/>
<map mode='shadow' address='80-bf:8000-ffff'/>
<map mode='linear' address='c0-ff:0000-ffff'/>
</rom>
<ram size='800'>
<map mode='linear' address='20-3f:6000-7fff'/>
<map mode='linear' address='a0-bf:6000-7fff'/>
<map mode='linear' address='70-7f:0000-ffff'/>
</ram>
<upd77c25 program="dsp1b-program.bin" data="dsp1b-data.bin">
<dr>
<map address='00-1f:6000-6fff'/>
<map address='80-9f:6000-6fff'/>
</dr>
<sr>
<map address='00-1f:7000-7fff'/>
<map address='80-9f:7000-7fff'/>
</sr>
</upd77c25>
</cartridge>
Save it as 'mariokart.xml']
byuu says (about v072r09):
Fixes OP/LD RQM=1 on DR modify, Mario Kart can get in-game, but the
track is completely corrupted.
Reorders order of operations for OP, in an attempt to mimic parallelism.
Added support for OP KLM DST.
Added S1 flag setting, probably not correct.
byuu says:
I'm happy enough with the debugger now. Not 100% up to par with the old
one, but it also does some new things the old one didn't.
- step into / step over are disabled unless they can be done safely
- this means step over is usually grayed unless you hit step into first,
due to bsnes not being opcode-based (you can't skip an opcode that is
half-executed)
- you can now trace console output to disk
- stepping the CPU will print stepped SMP opcodes if the checkbox for it
is on and vice versa
- button added to clear the console log
(there was no r05 release posted to the WIP thread)
byuu says:
Updated libsnes to use new file and function names.
Also added EditBox::setCursorPosition for GTK+ and Qt, only used by the
debugger so far so that when text is added, it auto-scrolls to the
bottom.
(there was no r03 release posted to the WIP thread)
byuu says:
nall/snes/smp.hpp created, ~68 addressing modes compared to the CPU's
~27, ugh. All hooked up, you can step into / step over / trace the S-SMP
now as well.
byuu says:
Just debugger work here. About three or four hours to write
nall/snes/cpu.hpp, which is basically opcode encoding information for
disassembly.
byuu says:
- added pause shortcut ('P' key, as pause/break is too finicky)
- pause and auto-pause show on status bar
- added a debugger skeleton, very very primitive and completely unusable
- don't try it yet
- added software filter support
Also included is the new snesfilter library. It has all of the filters
the old one had, as well as scanline filters since that's not in my GUI
anymore
If you want scanlines and other software filters, then you can either
make your own hybrid two-in-one software filter, or make a pixel shader
(I don't have one of those yet.)
byuu says (since v070):
- fixed a regression in the accuracy/compatibility CPU core with IRQ
masking; fixes World Heroes 2
- fixed OAM address reset on $2100 writes for performance PPU core;
fixes Mahjongg 2 and others
- DSP-1 always returns high 8-bits of status register; fixes Ace wo
Nerae! freeze [Jonas Quinn]
- performance core can now take advantage of serial support
- pixel shaders now use a unified XML format; in the future they will
support multi-pass shaders and textures
- major code restructuring
- first public release of phoenix GUI port
- mightymo's cheat code pack is now an external file for the phoenix
port
- phoenix port stores cheat codes in XML format as well, unifying all
file formats to the same markup language
(there was no r15 release posted to the WIP thread)
byuu says:
This mostly contains improvements for nall, like path unification.
This should fix FitzRoy's issue with .. on Windows.
(there was no r13 release posted to the WIP thread)
byuu says:
- nall/string: trim and split functions now take the limit as a template
parameter for clarity, trim_once variants are removed
- quotable.trim<1>("\""); //remove quotes from string
- cheatcode.split<3>(","); //split up to three times, third one is
a description that may have commas
- foobar.trim(" "); //remove any and all spaces
- nall/string: added wildcard() and iwildcard() functions for pattern
matching
- nall/directory: accepts an optional pattern parameter to perform
wildcard matching
- lstring cartridges = directory::contents(path, "*.sfc");
- some people may prefer directory::contents("/path/to/files/*.sfc"),
but I like not having to build a string when you have the path
separated already
- nall/qt: removed entirely, now resides in bsnes/ui-qt/template; I do
intend to replace the check/radio actions with native Qt versions
later
- bsnes/data: new folder, share the parts that both UIs use; bsnes.ico,
bsnes.png, bsnes.Desktop, cheats.xml; simplify Makefile install target
- Makefile: install target now creates .bsnes folder and copies
cheats.xml there for you
- Makefile: gconftool hack removed, not needed for phoenix, will work
around with Qt later
- will probably make bsnes/Qt read the cheats.xml file externally as
well, as that file makes each profile 1MB bigger when embedded
- as such, will probably make bsnes also look in the binary directory
for that file, so Windows users don't have to copy it to their
userdata folder
byuu says:
- removed support for images with copier headers
- phoenix/Windows: Label properly refreshes on text changes, fixes video
settings sliders
- alt/ppu-performance: fixed mosaic Voffset bug, fixes Super Bowling et al
- alt/cpu: fixed CPU::joylatch() reporting, allows serial applications
to work with performance profile
- hooked up SNES::cartridge.basename, allows MSU1 and serial support
with the phoenix UI
- updated UPS patching code for bsnes/Qt, allowing it to compile again,
hidden config option file.bypassPatchCrc32 was removed
byuu says:
- phoenix/All: converted all instances of const char* to const
nall::string&
- above used to require: label.setText(string("FPS: ", fps)); but can
now use: label.setText({"FPS", fps});
- also avoids the need for the internal implementations to have to
check for null string pointers
- phoenix/GTK+: no longer disabling double buffering on the viewport.
Does not cause flickering, and fixes redraw issue on window resize
- phoenix/Qt: like phoenix/GTK+, it will use the default font on the
menubar as well, so child menu items are consistently sized now
- Linux: file browser can list contents of / and won't let you go
higher; Windows needs a similar guard for n:/ or \\
- UPS soft-patching support added
- external XML memory map loading support added
- cartridge folder support added: if folder ends in .sfc and there is
ONE .sfc ROM inside it, it will load the folder as if it were a ROM
- input assignment refreshes text instead of reloading the list, this
saves your position
- auto-advance wasn't working very well, will try again later
- input clear all button removed since it's pretty fast now to do
clear+down:repeat
byuu says:
- added workaround to phoenix/Windows to prevent horizontal scrollbar
always being visible on single-column ListBoxes
- phoenix gains Window::geometry()
- added code to save and restore window positions, as in bsnes/Qt.
Positions are saved to bsnes-phoenix-geometry.cfg this time
- resizing the main window will keep its position onscreen now
There's one issue with GTK+, if you close a window and then call
gtk_window_get_position(), it returns the previously set position rather
than where you actually placed the window. My easy fix of calling
gtk_window_get_position right before actually closing the window didn't
work, so for now you'll have to live with it.
byuu says:
- removed native OS dialog option, I don't plan to add all the code
required to make it optional everywhere
- cheat database supported, although it's external now. Either in the
.bsnes folder or with the binary, named cheats.xml
- cheats.xml is external so that binaries can be much smaller, important
for multiple profiles
- added "find codes" button to cheat editor (need to gray it out
permanently if cheats.xml isn't found)
- added cheat database add window, works the same as bsnes/Qt, but it
will also alert you if you run out of empty cheat slots upon import
- note: I should rename that ok button to "Import"
- hooked up callbacks for multitap/mouse/SS/justifier input
- added mapping for mouse axes and buttons
- used a simplified approach that only lets you map left/middle/right
buttons, but doesn't need a separate popup window or fake controls
- moved capture mouse command to tools menu
- different from Qt where you'd click inside the main window, meant to
be safer from accidental capture, escape still releases capture
- made a skeleton for GUI hotkey support, but the only hotkey is escape
byuu says:
- all three ports of phoenix gain the ability to use
ListBox::setCheckable(), checked(row), setChecked(row, checked
= true);
- cheat editor updated to take advantage of this
Some fun differences between the implementations. Windows was the least
flexible, it only lets you have a check at the start of each item.
Luckily that's all I need for my purposes so it'll work. It's also a lot
easier, as now I don't need a ton of extra code to try and set
per-column checkboxes. Now both Windows and Qt can put text into the
first item with the checkbox, but GTK+ cannot. Further, Qt needs this
because even if you hide the checkbox column, it still tries to search
for typed text from the checkbox column. GTK+ does this too, but unlike
GTK+, Qt lacks an API call to set the search column. Since my code
basically has to change this in real-time since you have to call the
setProperty functions after create(), this means I always set up the
checkbox columns regardless of whether or not they are used. For Qt,
I had to work around this and it'll be an annoying edge case if you try
and use setCheckable(true) and then setCheckable(false), because Qt has
no way to clear the checkboxes from an item once you've enabled them for
the first time. But without doing it this way, there's no way for eg the
ROM file loader to allow type-searching, so that's the way I do it.
Windows works the same, and GTK+ has a separate column (hidden from the
phoenix API standpoint) for the checkboxes, with no column header label
text.
All in all, a major hassle, but it was the only really major GUI hit
from leaving Qt, aside from the horror that's going to be the debugger,
which needs all kinds of highly specialized controls.
byuu says:
- added menu options to select controller port devices, they do actually
work too
- however, input mapping can't map analog axes yet, and the mouse can't
be captured yet, so it's of little use
- added clear and clear all buttons to the input mapper window, mainly
because there was no reason not to (escape clears active input too)
- going to be adding a "special" button in the future that lets you map
mouse axes and buttons
- fixed phoenix/Qt port, both the video rendering and Window::focused()
commands work now
The way I've implemented mouse mapping has always been screwy. So the
special button is going to pop open another window. For digital mapping,
it'll let you choose a mouse button, and for analog mapping, it'll let
you choose an axis. May add in some manual joypad assignment stuff in
there for analog joypad buttons, those things are impossible to
auto-detect.
(there was no r05 release posted to the WIP thread)
byuu says:
- bsnes/phoenix uses XML for per-game cheat codes, markup is identical
to the main database
- added clear and clear all buttons to the cheat code editor
- phoenix/GTK+ sets all child menu elements to match the parent menu font
- phoenix/Windows will draw a black canvas for the Viewport widget
(phoenix/GTK+ still needs this)
byuu says:
- fixed new config file input driver name (you'll have to delete your old config, or change to a different driver and back and restart)
- fixed slot loader windows' OK button placement
- fixed nall/directory.hpp when list size was zero
- rewrote nall/function.hpp, no longer requires <functional> or union tricks
- added state manager
The state manager is a little bit different this time. It's functionally
identical to bsnes/Qt, 100% of the way. But when you save slots, it
stores them in RAM. It only writes the BSA archive upon ROM unload
/ program exit. Yes, this means that technically if the emulator
crashes, you'll lose your states. But a) that very rarely happens, and
b) the old way was thrashing the disk like crazy, every letter you typed
dumped up to 8MB to disk. With this new method, I can simply store
a boolean valid flag before each slot, and pack the file better. Before,
a save on only slot 3 would be 3*state size (~1.2mb), it will now be
3bytes+state size (~400kb.) I have also added a proper signature because
of this, so it will detect when you load an archive for a previous
serializer version and ignore it. When you go to save (unload the game),
if there are no valid slots, the BSA archive gets unlinked (deleted.)
I am also planning a feature around the now-hidden "slot 0". My idea is
for it to be a fallback slot. How many times have you loaded a state
when you meant to save and said, "shit, now I lost some of my progress"?
The idea is that whenever you load a state, right before loading, it
will save to slot 0. When you unload the game, or exit the emulator, it
will also save to slot 0. You will be able to load from slot 0 from the
menu, but not save to it. It will appear at the bottom of the load list.
And lastly, I'll add an advanced option to auto-load slot 0 if it
exists, which will enable "close the emulator and restart where you left
off." functionality.
byuu has traditionally kept these shaders separately, but I don't see
why they shouldn't be stored alongside the code that uses them.
Unlike previous versions of pixel shaders, these are updated to use the
new file-format introduced in v070r03.
byuu says:
- fixed a bug in xml_element::parse() with <![CDATA[...]]> tags
- merged FragmentShader and and VertexShader into Shader, which is an
XML file that contains all relevant data
- updated Qt port to reflect the above
- added support for pixel shaders to the phoenix port
- updated all pixel shaders to use the new format
- ruby won't crash if you give an HLSL driver a GLSL shader or vice
versa, but it will still crash on bad programs
- phoenix::Viewport has its own window class, that paints a black brush
background
[The XML shader] format is subject to change, more specifically I may
change the <source> tag from HLSL shaders.
In the long-long term, it'd be nice to extend the format to allow
multiple shaders to be chained together and to encode base64 texture
files.
But for now, this is good enough.
byuu says:
- phoenix supports onActivate, or return key pressed, on text boxes
- phoenix supports setGeometry() on all widgets
- input settings can now map analog axes and analog buttons
- analog button support is simplified over bsnes/Qt, and it supports the
trigger inversion you see between Xbox 360 and Thrustmaster
controllers
- load cartridge window lets you press enter in the path box to select
the folder, but currently allows invalid folders (makes list empty)
- load cartridge won't reset your view if the folder doesn't change
- this means the last ROM you loaded is highlighted the next time you
go to load cartridge; you're welcome, FitzRoy :P
- removed quit system menu option
- added dummy controller port system menu options, there's no code
behind them yet
- added power/reset menu options, dropped the power checkbox in favor of
a standard power cycle option, removes unnecessary complexity
- added video mode scaling, 1x to 5x; and aspect ratio correction
- added video mode smooth toggle
- added audio settings panel with volume and input frequency adjustment
- config file is where you can control output frequency and latency,
they are too niche for a GUI
- fixed a realpath() crash on Linux when the bsnes binary was in /usr/bin
byuu says:
This release represents the coup de grâce of bsnes/Qt.
Changelog:
- configuration file is now called bsnes-qt.cfg; the first run of this
release will start with a clean state
- MSU1 now supports audio looping via new PCM file format
- disabled state load/save menu due to a serious bug in Qt 4.6.0 for
Windows
- RawInput: all keyboards merged to KB0, it should no longer be required
to reconfigure the keyboard out-of-the-box
- RawInput: fixed a bug where Xbox 360 controller states were being
overwritten by DirectInput controllers
- RawInput: fixed a device sorting bug caused by moving ruby to Unicode
- Direct3D: fixed a pixel shader bug caused by moving ruby to Unicode
- Linux port: fixed sudo make install target
- Linux port: default to gcc/g++ instead of gcc-4.5/g++-4.5 for one last
release
- updated to mightymo's 2010-09-20 cheat pack
byuu says (since v068):
- added new effect toggle tool window, which allows toggling of BG/OAM
graphics layers and DSP audio channels
- added an option to use the native OS file and folder open dialogs
instead of my custom browser
- added a new state selection window
- added frame skipping support, which is only used during fast
forwarding; as a result, fast forward is now ~80% faster
- removed unnecessary icons, added workaround for checkbox/radiobox menu
icons on Linux/GNOME
- added RTS/CTS support to serial simulation
- all cores: OAM high table even address writes should update OAM latch
data register [blargg]
- accuracy core: major improvements to mosaic emulation
- accuracy core: added additional hardware-based caching, resulting in
a ~15% speed boost
- accuracy core: emulated CGRAM address invalidation for writes during
active display
- performance core: added new S-PPU renderer, resulting in a ~10% speed
bost
byuu says:
This is basically the v069 release candidate, heavy testing would really
be appreciated. I'd like for v070 to be the first official phoenix
release, but if a major bug slips past us that will ruin it.
The big change is that save state support was added to the
PPU-performance core.
(there was no r23 release posted to the WIP thread)
byuu says:
Fixes OAM latchdata for all 3 cores and CGRAM address invalidation for
the accuracy core (the only one that really does it because it needs
cycle PPU timing.) Also removes the OAM/CGRAM read/write functions to
put them inside the actual MMIO functions. Easier to handle all the
special cases that way. VRAM is a bit more annoying since there's two
read and two write functions.
This should fix battletech/mechwarrior 3050 palette at least.
byuu says:
Wanted to torture myself, so I implemented the hardest window of all,
the cheat code editor. I had to sacrifice checkboxes inside lists,
unfortunately, but it's a necessary evil. Maybe some day if we can port
checkboxes inside list items to Windows and GTK+, we can add it back. It
should be the only really apparent GUI sacrifice, though. You toggle
cheats by double-clicking them in the list. Easy to do, but not
apparent.
I also added in the focus policy.
byuu says:
Changelog:
- adds synchronize video
- adds synchronize audio
- adds mute audio
- adds advanced settings window with driver selection only
- adds the pretty section header thing I started going toward with Qt
- adds a configuration file, saves to bsnes-phoenix.cfg (I don't make
the .bsnes folder yet)
- the status bar shows [A] for accuracy, [C] for compatibility and [P]
for carburetor
byuu says:
Changelog:
- fixed window casting crash in phoenix
- added perfect forwarding to nall::string variadic templates to fix
file load dialog crash in phoenix
- disabled copy constructors in utf8_t to prevent this problem from
occurring again in the future
- separated canvas window proc by creating a separate class for it
(ironically it was a desktop window causing the first crash)
- use processorArchitecture="*" to make compilation easier
- fixed status bar font assignment in phoenix/Windows
- added InitCommonControls + CoInitialize for XAudio2 on XP
- had to use DirectSound for audio; XAudio2 is crashing on exit which
breaks the profiling (only a problem because you can't change the
drivers without recompiling, there's really no reason to profile
XAudio2 anyway)
byuu says:
This adds proper manifest files to get the nice XP/Vista controls. Need
to find a way to auto-detect MinGW 32 vs 64 since I can't use $shell or
`` on gcc -v on Windows. For now you have to edit the
ui-phoenix/Makefile by hand.
I've implemented the video settings window. I am going to be using
separate windows this time. As nice as having everything in one place
was, I didn't like being forced to stretch things to fill out the
one-size-fits-all tab window I was using before. That and I don't feel
like implementing tab support with phoenix anyway.
The menu gets a load cartridge command, and bsnes writes save RAM files
now. Loading by file dialog crashes on 64-bit. Something's fucked up
there, but I don't know what. Again, help would be great here :)
byuu says:
This WIP fixes the Mode7 repeat issue in the accuracy core.
More importantly, it's the first build to include phoenix. There is
a stub GUI that does basically nothing right now. It will give you
a window, a command to close the emulator, and an FPS meter so you can
tell how fast it is. To load a ROM, you have to drag the ROM on top of
the binary. I don't know if it will work if the filename+path has spaces
in it or not, so avoid that to be safe.
[...]
For some reason, the 64-bit binary sometimes crashes on start, maybe 1:6
times. So just keep trying. I don't know what's up with that, I'd
appreciate if someone here wanted to debug that for me though :D
One really good bit of news, there was that old hiro bug where keyboard
input would cause the main window to beep. I spied on the main event
loop and, as suspected, the status bar was getting focus and rejecting
key presses. What. The. Fuck. Why would a status bar ever need focus? So
I set WM_DISABLED on it, which luckily leaves the font color alone.
I also had to use WM_DISABLED on the Viewport widget that I use for
video output. These two combined let me have my main window with no
keyboard beeping AND allow tab+shift-tab to work as you'd expect on
other windows, so hooray.
Now, at the moment there's no Manifest included, because Microsoft for
some reason includes the processorArcitecture in the file. So I can't
use the same manifest for 32-bit and 64-bit mode, or the binary will
crash on one or the other. Fuck. So the status bar may look old-school
or something, whatever, it's only temporary.
Next up, my goal is to avoid the hiro icon corruption bullshit by making
phoenix itself try and use an internal resource icon. So just compile
your app with that resource icon and voila, perfect icon. Not in there
yet so you get the white box.
Input is hard-coded, up/down/left/right/z/x/a/s/d/c/apostrophe/return.
Lastly, compilation is ... in a serious state of flux. The code is set
to compile bsnes/phoenix-gtk right now. Try it at your own risk. Give me
a few WIPs to get everything nice and refined. Ubuntu users will need
gcc-4.5, which you can get by adding the Maverick Meerkat repository,
updating apt, installing the gcc-4.5 + g++-4.5 packages, and then
removing and re-updating your apt/sources.list file so you don't end up
fucking your whole system when you run apt again in the future.
For anyone who can work with all of that, great! Please post a framerate
comparison between 32-bit and 64-bit builds. Any game, any screen, so
long as the FPS is not fluctuating when you measure it (eg don't do it
during an attract sequence.)
If anyone complains about the 64-bit binary not working and it turns out
they are on 32-bit Windows, they are going to be removed from this WIP
forum :P
byuu says:
This hopefully fixes vertical and horizontal mosaic with the accurate
S-PPU core.
It also adds frame-skipping support to the compatibility and performance
S-PPU cores. This is not visible to the user interface, because I feel
that virtually nobody is going to play with frame-skipping on when they
could use a faster emulation with it off. However, I did use it to
enhance the 'Fast Forward' key. When you press it, it will now turn off
video and audio sync, and set a frameskip of 9. This allows you to speed
things up an additional ~60% over your max theoretical speed without
frameskipping. ~35% with the compatible core, because the PPU is less of
a bottleneck for it. Slowdown was improved, it will turn on audio sync
if it is off until you release the key to ensure you actually get 30fps.
Eventually it'd probably be wise to set a cap on the fast forward speed,
but I hardly think it's an issue on today's computers.
byuu says:
Testing this one and all the new features would be appreciated.
New features?
http://img203.imageshack.us/img203/505/bsnes20100907.jpg
[For future reference, the above URL points to a screenshot of bsnes' Qt
GUI running with the following windows (apart from the main window) visible:
- A new 'state selection' dialog wih buttons labelled 'Slot 1' through
'Slot 10'.
- The 'Tools' dialog open to a new 'Effect Toggle' tab, which has
checkboxes for the various PPU backgrounds and sprites, and SPU
channels.
- The 'Configuration Settings' dialog open to the 'Advanced' tab, with
a "Use Native OS File Dialogs" checkbox.
- A 'Load Cartridge' dialog, which is the standard Windows file-open
dialog.
It seems these are the new features referred to. -- Ed]
byuu says:
This adds a new "Effect Toggle" window to the tools tab list. There's no
menu entry for it yet, oversight, but you can go to another tool and tab
to it.
The effect toggle window lets you toggle background/OAM layers on
a per-priority basis and DSP sound channels. This only works with the
compatibility and performance cores, because I'm not going to allow
accuracy-violating hacks like that into the core.
Non-essential icons have been removed, there's six of them left at the
moment. I am too much of a consistency guy to only have some scattered
around. I know other apps do that, but I'm not going to do that, and
I grow tired of trying to hammer in icons that don't really represent
the actions. Anyway, it still looks pretty good I think.
byuu says:
Holy hell, that was a total brain twister. After hours of crazy bit
twiddling and debug printf's, I finally figured out how to allow both
lores and hires scrolling in the accurate PPU renderer. In the process,
I modified the main loop to run from -7 to 255, regardless of the hires
setting, and perform X adjustment inside the tile fetching. This fixed
a strange main/subscreen misalignment issue, so I was able to restore
the proper sub-then-main rendering for the final screen output stage.
Code looks a good bit cleaner this way overall.
I also added load state and save state menus to the tools menu, so you
can use the menubar to load and save to ten slots. I am thinking that
I should nuke the icons. As pretty as they are, it's getting tiresome
trying to find icons for everything, I have no pictures to represent
loading or saving a slot, nor to represent individual slots. I'll just
stick to radios and checkboxes.
byuu says:
Bug-fix night for the new PPUs.
Accuracy:
Fixed BG palette clamping, which fixes Taz-Mania.
Added blocking for CGRAM writes during active display, to match the
compatibility core. It really should override to the last fetched
palette color, I'll probably try that out soon enough.
Performance:
Mosaic should match the other renderers. Unfortunately, as suspected, it
murders speed. 290->275fps. It's now only 11fps faster, hardly worth it
at all. But the old rendering code is really awful, so maybe it's for
the best it gets refreshed.
It's really tough to understand why this is such a performance hit, it's
just a decrement+compare check four times per pixel. But yeah, it hits
it really, really hard.
Fixed a missing check in Mode4 offset-per-tile, fixes vertical alignment
of a test image in the SNES Test Program.
(there was no r11 release posted to the WIP thread)
byuu says:
This took ten hours of mind boggling insanity to pull off.
It upgrades the S-PPU dot-based renderer to fetch one tile, and then
output all of its pixels before fetching again. It sounds easy enough,
but it's insanely difficult. I ended up taking one small shortcut, in
that rather than fetch at -7, I fetch at the first instance where a tile
is needed to plot to x=0. So if you have {-3 to +4 } as a tile, it
fetches at -3. That won't work so well on hardware, if two BGs fetch at
the same X offset, they won't have time.
I have had no luck staggering the reads at BG1=-7, BG3=-5, etc. While
I can shift and fetch just fine, what happens is that when a new tile is
fetched in, that gives a new palette, priority, etc; and this ends up
happening between two tiles which results in the right-most edges of the
screen ending up with the wrong colors and such.
Offset-per-tile is cheap as always. Although looking at it, I'm not sure
how BG3 could pre-fetch, especially with the way one or two OPT modes
can fetch two tiles.
There's no magic in Hoffset caching yet, so the SMW1 pixel issue is
still there.
Mode 7 got a bugfix, it was off-by-one horizontally from the mosaic
code. After re-designing the BG mosaic, I ended up needing a separate
mosaic for Mode7, and in the process I fixed that bug. The obvious
change is that the Chrono Trigger Mode7->Mode2 transition doesn't cause
the pendulum to jump anymore.
Windows were simplified just a tad. The range testing is shared for all
modes now. Ironically, it's a bit slower, but I'll take less code over
more speed for the accuracy core.
Speaking of speed, because there's so much less calculations per pixel
for BGs, performance for the entire emulator has gone up by 30% in the
accuracy core. Pretty neat overall, I can maintain 60fps in all but,
yeah you can guess can't you?
(there was no r09 release posted to the WIP thread)
byuu says:
It is feature-complete, but horizontal mosaic is less accurate. I have
an idea for a mosaic color ring buffer to get it equally accurate, but
I haven't implemented it yet. For now it's just a simple x & ~(mosaic >>
1) trick that is passable.
Hires blending was left out, as it's more processor intensive and
blargg's NTSC does a better job with that anyway.
There's some OPT vertical positioning issues in the SNES Test Program's
character test; Goodbye, Anthrox has some sort of fast CPU DMA issue;
etc.
Total speedup is a mere 13.5%. Not quite the 50% I wanted in the best
case, but I'll take what I can get.
254->289fps in Zelda 3 on my E8400 now. There's another 15% hiding with
blargg's SMP and 5-10% with blargg's fast DSP, but they lose too much
accuracy. It'd put me at or below Snes9X accuracy, while still being 50%
slower.
SSE2 was performing worse this time, both on x86 and amd64, so I left
that optimization off.
So, barring a miracle, this is about the best it's going to get.
byuu says:
This gets the basic new PPU skeleton up and running, still missing
a lot:
- Mode7
- direct color mode
- OAM color exemption (this one will impact performance negatively)
- vertical mosaic
- horizontal mosaic (this one may impact performance negatively)
- offset per tile
- interlace
- hires
- pseudo-hires
But it's correct enough to play most games okay.
So far, the new PPU is about 11% faster on my Atom, and 17% faster on my
E8400. I was hoping for more, but the window masking and sprite
calculation is just kicking my ass.
The 11/17 figure is total emulator overhead, so that means raw PPU vs
PPU, the new one is at least 22-34% faster than the old one.
I don't really have any ideas for additional optimizations. I'm even
using little-endian word reads where applicable. But at any rate, I need
to get all the above implemented correctly before trying to push
optimizations even further.
(there was no r06 release posted to the WIP thread)
byuu says:
New PPU renderer is coming along. Lots of new ideas, especially with
regards to the way the background renders in tiles rather than in
pixels. That skips the need for tile caching and compares, and it even
gets scrolling right.
The sprite item+tile lists are computing, but they are not rendering
yet.
It's a good deal faster for now, obviously, because 90% of the PPU
features are missing.
byuu says:
Started over again on the new S-PPU, heh. Three hours wasted last night
I guess.
I wanted to make the new one more like the accurate core in its
structure: multiple class instances for each background. It makes the
code easier to read, results in less structure insanity
(regs.main_enabled[bg] -> main_enabled), and will probably make it a tad
easier to parallelize if we want to go that route eg for the ARM.
Still very incomplete.
(there was no r03 release posted to the WIP thread)
byuu says:
This should provide hardware-accurate mosaic support in the accurate
renderer, with the exception that I'm still not sure what mid-frame
vertical mosaic or mid-scanline horizontal mosaic writes do. Either the
code I have is correct, or it bypasses the mosaic adjust and gives the
exact H/V positions.
I've also renamed the fast folder to alternative (thinking about naming
it simply alt instead), and started on a brand new PPU renderer. So far
it's just a barebones setup with some MMIO support and VRAM/OAM/CGRAM
writing. I'm not even confident that I can get this to be faster than
the current scanline renderer, but it's the only avenue that we have
left for any kind of significant bsnes speedup, so I have to try. I'm
going to finish up the MMIO stuff first, that way we have a clean slate
with no actual rendering. And then from here we can try various
different approaches.
byuu says:
This adds mosaic improvements to the S-PPU dot renderer. Specifically,
it eliminates the mosaic_table entirely, and performs mosaic adjustment
per pixel instead. It also moves from a mosaic countdown for mosaic Y to
a mosaic counter (incrementing).
In the process, I realized Sim Earth's map was broken, so I fixed that.
In doing so, I also fixed my old Mode7 demo that was always off-by-one,
causing different results on real hardware versus emulation. But then
I broke both Final Fantasy 5 and Air Strike Patrol effects that use
Mode7 but no mosaic.
I'm not really sure what's going on, but I think I am close. This is the
first time I can reproduce the Mode7 test ROM results without screwing
with M7Y which was obviously wrong. I think that somehow a mosaic >=
1 is glitching the Ycounter for the BG layers to tick one extra time.
There's a workaround that's not very nice to get everything going right
now. It could very well be that the workaround is hardware accurate, but
I can't help but feel there's a more eloquent way of doing this.
byuu says:
This adds RTS/CTS support to the serial communications emulation. Okay,
well the PC acts as if it is always ready, because it always is even on
the real thing, but the PC-waiting-for-SNES side works.
Source only, hardware communication only works on OS X and Linux
(Windows serial communication is totally different, I don't feel like
writing a Windows version), more documentation will come later.
byuu describes the changes since v067:
This release officially introduces the accuracy and performance cores,
alongside the previously-existing compatibility core. The accuracy core
allows the most accurate SNES emulation ever seen, with every last
processor running at the lowest possible clock synchronization level.
The performance core allows slower computers the chance to finally use
bsnes. It is capable of attaining 60fps in standard games even on an
entry-level Intel Atom processor, commonly found in netbooks.
The accuracy core is absolutely not meant for casual gaming at all. It
is meant solely for getting as close to 100% perfection as possible, no
matter the cost to speed. It should only be used for testing,
development or debugging.
The compatibility core is identical to bsnes v067 and earlier, but is
now roughly 10% faster. This is the default and recommended core for
casual gaming.
The performance core contains an entirely new S-CPU core, with
range-tested IRQs; and uses blargg's heavily-optimized S-DSP core
directly. Although there are very minor accuracy tradeoffs to increase
speed, I am confident that the performance core is still more accurate
and compatible than any other SNES emulator. The S-CPU, S-SMP, S-DSP,
SuperFX and SA-1 processors are all clock-based, just as in the accuracy
and compatibility cores; and as always, there are zero game-specific
hacks. Its compatibility is still well above 99%, running even the most
challenging games flawlessly.
If you have held off from using bsnes in the past due to its system
requirements, please give the performance core a try. I think you will
be impressed. I'm also not finished: I believe performance can be
increased even further.
I would also strongly suggest Windows Vista and Windows 7 users to take
advantage of the new XAudio2 driver by OV2. Not only does it give you
a performance boost, it also lowers latency and provides better sound by
way of skipping an API emulation layer.
Changelog:
- Split core into three profiles: accuracy, compatibility and
performance
- Accuracy core now takes advantage of variable-bitlength integers (eg
uint24_t)
- Performance core uses a new S-CPU core, written from scratch for speed
- Performance core uses blargg's snes_dsp library for S-DSP emulation
- Binaries are now compiled using GCC 4.5
- Added a workaround in the SA-1 core for a bug in GCC 4.5+
- The clock-based S-PPU renderer has greatly improved OAM emulation;
fixing Winter Gold and Megalomania rendering issues
- Corrected pseudo-hires color math in the clock-based S-PPU renderer;
fixing Super Buster Bros backgrounds
- Fixed a clamping bug in the Cx4 16-bit triangle operation [Jonas
Quinn]; fixing Mega Man X2 "gained weapon" star background effect
- Updated video renderer to properly handle mixed-resolution screens
with interlace enabled; fixing Air Strike Patrol level briefing screen
- Added mightymo's 2010-08-19 cheat code pack
- Windows port: added XAudio2 output support [OV2]
- Source: major code restructuring; virtual base classes for processor
- cores removed, build system heavily modified, etc.
byuu says:
Re-added blargg's DSP, but this time I merged only spc_dsp and also
fixed the initial regs for Dual Orb II. Which restores the 5-10% speedup
on the compatibility and performance cores. Fixed the initial register
values for the fast CPU core, which fixes Armored Police and the other
Atlus game's title screen in the performance core. Added a missing
debugvirtual prefix to op_step, which fixes CPU stepping in the
performance core. I was using the description field for profile
identification in savestates, but that was of course the description for
the state manager. Whoops. Added a new field for profile name to the
save states, and fixed the state manager to work with that change.
Adjusted the about screen colors, which is how you can tell which core
you're using without it being annoying. Probably did some other stuff
too, meh.
byuu says:
Removed snes_spc, and the fast/smp + fast/dsp wrappers around it.
Cloned dsp to fast/dsp, and re-added the state machine, affects
Compatibility and Performance cores.
Added debugger support to fast/cpu, with full properties list and Qt
debugger functionality.
Rewrote all debugger property functions to return data directly:
- this avoids some annoying conflicts where ChipDebugger::foo()
overshadows Chip::foo()
- this removes the need for an extra 20-200 functions per debugger
core
- this makes the overall code size a good bit smaller
- this currently makes PPU::oam_basesize() inaccessible, so the OAM
viewer will show wrong sprite sizes
Used an evil trick to simplify MMIO read/write address decoding:
- MMIO *mmio[0x8000], where only 0x2000-5fff are used, allows direct
indexing without -0x2000 adjust
So end result: both save states and debugger support work on all three
cores now. Dual Orb II sound is fixed. The speed hit was worse than
I thought, -7% for compatibility, and -10% for performance. At this
point, the compatibility core is the exact same code and speed as v067
official, and the performance core is now only ~36-40% faster than the
compatibility core. Sigh, so much for my dream of using this on my
netbook. At 53fps average now, compared to 39fps before. Profiling will
only get that to ~58fps, and that's way too low for the more intensive
scenes (Zelda 3 rain, CT black omen, etc.)
It would probably be a good idea to find out why my DSP is so much
slower than blargg's, given that it's based upon the same code. The
simple ring buffer stuff can't possibly slow things down that much.
More precisely, it would probably be best to leave blargg's DSP in the
performance core since it's a pretty minor issue, but then I'd have to
have three DSPs: accuracy=threaded, compatibility=state-machine,
performance=blargg. Too much hassle.
Only code in the core emulator now that wasn't at the very least
rewritten for bsnes would be the DSP-3 and DSP-4 modules, which are
really, really lazily done #define hacks around the original C code.
byuu says:
Fixed bsnes launcher on Windows XP
Fixed Windows bsnes launcher internationalization support (emulator can
be in a folder with spaces and Japanese characters, and you can drag
a Japanese file name onto the launcher, and it will load it properly)
Moved fast CPU to use a switch table for MMIO, unfortunately for no
speed gain
Bus::read/write take uint24 parameters for address, luckily no speed
penalty
MMIOAccess gained a handle() function, and hid the mmio[] table. Makes
hooking it cleaner
Added malloc.h header to nall/function.hpp to fix a ridiculous GCC 4.5.0
error
Fixed a fairly large bug in the fast CPU IRQ handler, which fixes
Robocop et al
Forgot to bump revision to .24 in the compiled binaries, too lazy to
recompile or hex edit to change them
Unfortunately, in order to add nice battery usage, I have to add the
sleep calls to the video and audio wait loops. But they don't know
anything about the GUI and its settings, nor do I really want to make
them know about this setting. I do not want to force allow it. Even with
the media timer trick, Sleep(0) makes Vsync+Async fail a lot more
frequently than never sleeping at all. I would rather laptop users
suffer 100% utilization of a single core than for all users to not be
able to get good audio+video sync. Not sure what to do about that, so
I'll probably just remove the battery usage comment from performance
mode for now.
byuu says:
Added missing $4200 IRQ lock, which fixes Chou Aniki on the fast CPU
core, so slower PCs can get their brotherly love on.
Added range-based controller IOBit latching to the fast CPU core, which
enables Super Scope and Justifier support. Uses the priority queue as
well, so there is zero speed-hit. Given the way range-testing works, the
trigger point may vary by 1-2 pixels when firing at the same spot. Not
really a big deal when it avoids a massive speed penalty.
Fixed PAL and interlace-mode HVIRQs at V=0,H<2 on the fast CPU core.
Added the dot-renderer's sprite list update-on-OAM-write functionality
to the scanline-based PPU renderer. Unfortunately it looks like all the
speed gain was already taken from the global dirty flag I was using
before, but this certainly won't hurt speed any, so whatever.
Added #ifdef to stop CoInitialize(0) on non-Windows ports.
Added #ifdefs to stop gradient fade on Windows port. Not going to fuck
over the Linux port aesthetic because of Qt bug #47,326,927. If there's
a way to tell what Qt theme is being used, I can leave it enabled for
XP/Vista themes.
Moved HDMA trigger from 1104 to 1112, and reduced channel overhead from
24 to 16, to better simulate one-cycle DMA->CPU sync.
Code clarity: I've re-added my varint.hpp classes, and am actively using
them in the accuracy cores. So far, I haven't done anything that would
detriment speed, but it is certainly cool. The APU ports exposed by the
CPU and SMP now take uint2 address arguments, the CPU WRAM address
register is a uint17, and the IRQ H/VTIME values are uint10. This
basically allows the source to clearly convey the data sizes, and
eliminates the need to manually mask values when writing to registers or
reading from memory. I'm going to be doing this everywhere, and it will
have a speed impact eventually, because the automation means we can't
skip masks when we know the data is already masked off.
Source: archive contains the launcher code, so that I can look into why
it's crashing on XP tomorrow.
It doesn't look like Circuit USA's flags are going to work too well with
this new CPU core. Still not sure what the hell Robocop vs The
Terminator is doing, I'll read through the mega SNES thread for clues
tomorrow. Speedy Gonzales is definitely broken, as modifying the MDR was
breaking things with my current core. Probably because the new CPU core
doesn't wait for a cycle edge to trigger.
I was thinking that perhaps we could keep some form of cheat codes list
to work as game-specific hacks for the performance core. Keeps the hacks
out of the emulator, but could allow the remaining bugs to be worked
around for people who have no choice but to use the performance core.
byuu says:
Added OV2's XAudio2 driver (it's better and faster than the DirectSound
one)
Fixed DirectInput keypad number codes
Added launcher to make the profiles work
Profiles now called: Accuracy, Compatibility, Performance (not debating
names anymore)
The launcher isn't going to work on OS X because of the .app folder
bullshit (yes, yes, .sfc folders.)
It also crashes on Windows XP for god only knows what reason. Works fine
on Windows 7 and Linux. So XP users, rename the .dll files to .exe to
test this release. I'll fix it on Monday.
The color highlighting fucks up the radio boxes on the Windows classic
theme, because Nokia can't afford a god damn QA team.
Lastly, I forgot to add launcher to the make archive-all command, so the
source for it will be in the next WIP.
byuu says:
This moves toward a profile-selection mode. Right now, it is incomplete.
There are three binaries, one for each profile. The GUI selection
doesn't actually do anything yet. There will be a launcher in a future
release that loads each profile's respective binary.
I reverted away from blargg's SMP library for the time being, in favor
of my own. This will fix most of the csnes/bsnes-performance bugs. This
causes a 10% speed hit on 64-bit platforms, and a 15% speed hit on
32-bit platforms. I hope to be able to regain that speed in the future,
I may also experiment with creating my own fast-SMP core which drops bus
hold delays and TEST register support (never used by anything, ever.)
Save states now work in all three cores, but they are not
cross-compatible. The profile name is stored in the description field of
the save states, and it won't load a state if the profile name doesn't
match.
The debugger only works on the research target for now. Give it time and
it will return for the other targets.
Other than that, let's please resume testing on all three once again.
See how far we get this time :)
I can confirm the following games have issues on the performance
profile:
- Armored Police Metal Jacket (minor logo flickering, not a big deal)
- Chou Aniki (won't start, so obviously unplayable)
- Robocop vs The Terminator (major in-game flickering, unplayable)
Anyone still have that gigantic bsnes thread archive from the ZSNES
forum? Maybe I posted about how to fix those two broken games in there,
heh.
I really want to release this as v1.0, but my better judgment says we
need to give it another week. Damn.
byuu says:
Since we're now talking about three splits, that's getting a bit out of
hand.
This WIP combines everything back into one project again. Added the
src/fast folder that has all the speed-oriented cores.
A slight slowdown to csnes from what it was before, I'm using blargg's
accurate DSP. I just don't like the idea of releasing a less accurate
DSP core than Snes9X v1.52 has. Plus the fast DSP core doesn't serialize
yet.
I moved back to snes_spc 0.9.0 because I care more about Tales and Star
Ocean than I do about Earthworm Jim 2. So if you try EWJ2 on csnes,
expect it to sound like it does on Snes9X. In other words, don't wear
headphones if you value your hearing.
The middle-of-the-road bsnes core uses blargg's accurate DSP, because
it's about 3% faster than mine which removes all of blargg's
optimizations. There is absolutely no accuracy loss here. bsnes v067.20
that is included should be equal to v067 official.
Performance:
Code:
asnes = 58fps
bsnes = 172fps +2.97x
csnes = 274fps +1.59x +4.72x
The binaries are not profiled, so that's an additional 15% slower from
the previous builds.
Save states only work on asnes, as I don't know how to serialize
blargg's cores yet. The copy_func thing is very confusing to me for some
reason. The debugger won't work anywhere.
Outside of that, please go ahead and bug test. Once I get the debugger
and save states working, I'll build some profiled v1.0 releases for all
three, and we can test that for a bit and then release.
byuu says:
12-15% faster than v067.10, and my Atom never goes below 58fps for
normal lo-res games at this point. Just a little more and I can leave
Async on. That's pretty much it though for the low hanging fruit.
Everything else will be a lot of work for a little gain. Speedups are
from range testing across scanline boundaries and from using blargg's
fast DSP core.
Snes9X is now only 1.93x faster than bsnes, and bsnes is now faster than
Super Sleuth.
I also fixed the Circuit USA menus (HDMA timing adjustment), Wild Guns
flickering (IRQ lock) and Jumpin' Derby (external IRQ triggering.)
There's definitely a lot of troublesome games, mostly the same ones we
had in the past (Koushien 2, Robocop vs The Terminator, etc.) I'm
definitely going to debug Starfox, but I may not bother with some of the
more obscure ones.
byuu says:
I wrote a new CPU core from scratch. It has range-based IRQs, and is
good enough even to run F-1 Grand Prix and Sink or Swim. It also uses
a binary min-heap array for the timing priority queue. This resulted in
a ~40% speedup.
I also added in blargg's snes_spc library, which is an S-SMP + S-DSP
emulator. I am still using his accurate DSP core, and not the fast one.
This gives an additional ~10% speedup.
THIS IS NOT PERFECT, THERE WILL BE BUGS!
I already know that Tales of Phantasia and Star Ocean are hitting some
edge cases. Now that it's fast enough, hopefully blargg can take a look
at it. Something he couldn't test before because you can't rip SPCs of
these games, so it's probably something simple.
My CPU core also doesn't nail every last possible edge case. So things
like Wild Guns and the two or three games that rely on NMI/IRQ hold
aren't going to work ... yet. Be patient.
The SuperFX and SA-1 cores are still cycle-accurate. It wouldn't hurt
compatibility to reduce their precision a bit.
End result is that you can now get well over 60fps in normal games even
n a first-generation Intel Atom.
byuu says:
This adds some sync.sh improvements to make it handle errors more
gracefully.
It also updates asnes a good bit. All of the four base processors now
have all publicly accessible functions right at the top of the main
headers, and everything else is private. This is to allow these headers
to essentially take the place of the previous base classes in the old
bsnes-merged format. So if there's something public there, you need to
implement that exact function to make your own module.
I removed the frame counter from the PPU, as it has nothing to do with
emulation. That now resides inside the Qt -> SNES interface code. Quite
amazing, I was actually saving the frame counter into the save state
files before, yuck.
Removed some baggage in the System class: it was friending a bunch of
long-dead functions and classes.
Forgot to re-add the CHEAT_SYSTEM define to info.hpp, so that's been put
back.
byuu says:
This fixes libsnes and debugger builds, and collapses bsnes/ppu/bppu to
bsnes/ppu and bsnes/dsp/sdsp to bsnes/dsp. It also introduces
bsnes/sync.sh, which will synchronize all of asnes/ with bsnes/,
excepting the custom speed-focused modules. So far, that's bsnes/ppu
(scanline renderer) and bsnes/dsp (state machine.)
Should make keeping the two ports in sync much, much easier. It's
basically the same thing as before, only you run sync.sh and have a few
duplicated folders now. May make it clearer by creating a stub/ or src/
folder inside bsnes to do all of the copying, so that you only see the
custom folders in bsnes/' root directory.
Loaded 100 of 1631 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.