Many specializations of stringify store a reference to the wrapped
value. Therefore, passing arguments to make_string() by value can be
disastrous if the compiler does not perform copy elision and stringify
stores a reference to a variable that goes out of scope when
make_string() returns.
Cherry-picked from ares commit 3d826f5b266027529f0c12211c744a23bbe25a56.
* improved appended firmware detection [devinacker]
* added dynamic rate control support to ALSA and PulseAudio drivers [RedDwarf]
* added option to use native file dialogs
SFC: Disable color blending for first hires pixel with accuracy PPU
(fixes a green scanline on the left-edge of Jurassic Park)
libco: Don't include <sys/mman.h> when not using mprotect
nall: Detect Windows without invoking uname [Alcaro]
byuu says:
- bsnes: added video filters from bsnes v082
- bsnes: added ZSNES snow effect option when games paused or unloaded
(no, I'm not joking)
- bsnes: added 7-zip support (LZMA 19.00 SDK)
[Recent higan WIPs have also mentioned bsnes changes, although the higan code
no longer includes the bsnes code. These changes include:
- higan, bsnes: added EXLOROM, EXLOROM-RAM, EXHIROM mappings
- higan, bsnes: focus the viewport after leaving fullscreen exclusive
mode
- bsnes: re-added mightymo's cheat code database
- bsnes: improved make install rules for the game and cheat code
databases
- bsnes: delayed construction of hiro::Window objects to properly show
bsnes window icons
- Ed.]
byuu says:
Don't let the point release fool you, there are many significant changes in this
release. I will be keeping bsnes releases using a point system until the new
higan release is ready.
Changelog:
- GUI: added high DPI support
- GUI: fixed the state manager image preview
- Windows: added a new waveOut driver with support for dynamic rate control
- Windows: corrected the XAudio 2.1 dynamic rate control support [BearOso]
- Windows: corrected the Direct3D 9.0 fullscreen exclusive window centering
- Windows: fixed XInput controller support on Windows 10
- SFC: added high-level emulation for the DSP1, DSP2, DSP4, ST010, and Cx4
coprocessors
- SFC: fixed a slight rendering glitch in the intro to Megalomania
If the coprocessor firmware is missing, bsnes will fallback on HLE where it is
supported, which is everything other than SD Gundam GX and the two Hayazashi
Nidan Morita Shougi games.
The Windows dynamic rate control works best with Direct3D in fullscreen
exclusive mode. I recommend the waveOut driver over the XAudio 2.1 driver, as it
is not possible to target a single XAudio2 version on all Windows OS releases.
The waveOut driver should work everywhere out of the box.
Note that with DRC, the synchronization source is your monitor, so you will
want to be running at 60hz (NTSC) or 50hz (PAL). If you have an adaptive sync
monitor, you should instead use the WASAPI (exclusive) or ASIO audio driver.
byuu says:
Changelog:
- reverted nall/inline-if.hpp usage for now, since the
nall/primitives.hpp math operators still cast to (u)int64_t
- improved nall/primitives.hpp more; integer8 x = -128; print(-x) will
now print 128 (unary operator+ and - cast to (u)int64_t)
- renamed processor/lr35902 to processor/sm83; after the Sharp SM83
CPU core [gekkio discovered the name]
- a few bugfixes to the TLCS900H CPU core
- completed the disassembler for the TLCS900H core
As a result of reverting most of the inline if stuff, I guess the
testing priority has been reduced. Which is probably a good thing,
considering I seem to have a smaller pool of testers these days.
Indeed, the TLCS900H core has ended up at 131KiB compared to the M68000
core at 128KiB. So it's now the largest CPU core in all of higan. It's
even more ridiculous because the M68000 core would ordinarily be quite a
bit smaller, had I not gone overboard with the extreme templating to
reduce instruction decoding overhead (you kind of have to do this for
RISC CPUs, and the inverted design of the TLCS900H kind of makes it
infeasible to do the same there.)
This CPU core is bound to have dozens of extremely difficult CPU bugs,
and there's no easy way for me to test them. I would greatly appreciate
any help in looking over the core for bugs. A fresh pair of eyes to spot
a mistake could save me up to several days of tedious debugging work.
The core still isn't ready to actually be tested: I have to hook up
cartridge loading, a memory bus, interrupts, timers, and the micro DMA
controller before it's likely that anything happens at all.
byuu says:
First 32 instructions implemented in the TLCS900H disassembler. Only 992
to go!
I removed the use of anonymous namespaces in nall. It was something I
rarely used, because it rarely did what I wanted.
I updated all nested namespaces to use C++17-style namespace Foo::Bar {}
syntax instead of classic C++-style namespace Foo { namespace Bar {}}.
I updated ruby::Video::acquire() to return a struct, so we can use C++17
structured bindings. Long term, I want to get away from all functions
that take references for output only. Even though C++ botched structured
bindings by not allowing you to bind to existing variables, it's even
worse to have function calls that take arguments by reference and then
write to them. From the caller side, you can't tell the value is being
written, nor that the value passed in doesn't matter, which is terrible.
byuu says:
Any usage of natural and integer cast to 64-bit math operations now.
Hopefully this will be the last of the major changes for a bit on
nall/primitives, at least until serious work begins on removing implicit
conversion to primitive types.
I also completed the initial TLCS900H core, sans SWI (kind of a ways off
from support interrupts.) I really shouldn't say completed, though. The
micro DMA unit is missing, interrupt priority handling is missing,
there's no debugger, and, of course, there's surely dozens of absolutely
critical CPU bugs that are going to be an absolute hellscape nightmare
to track down.
It was a damn shame, right up until the very last eight instructions,
[CP|LD][I|D](R), the instruction encoding was consistent. Of course,
there could be other inconsistencies that I missed. In fact, that's
somewhat likely ... sigh.
byuu says:
So this turned out to be a rather unproductive ten-hour rabbit hole, but
...
I reworked nall/primitives.hpp a lot. And because the changes are
massive, testing of this WIP for regressions is critically important. I
really can't stress that enough, we're almost certainly going to have
some hidden regressions here ...
We now have a nall/primitives/ subfolder that splits up the classes into
manageable components. The bit-field support is now shared between both
Natural and Integer. All of the assignment operator overloads are now
templated and take references instead of values. Things like the
GSU::Register class are non-copyable on account of the function<>
object inside of it, and previously only operator= would work with
classes like that.
The big change is nall/primitives/operators.hpp, which is a really
elaborate system to compute the minimum number of bits needed for any
operation, and to return a Natural<T> or Integer<T> when one or both of
the arguments are such a type.
Unfortunately, it doesn't really work yet ... Kirby's Dream Land 3
breaks if we include operators.hpp. Zelda 3 runs fine with this, but I
had to make a huge amount of core changes, including introducing a new
ternary(bool, lhs, rhs) function to nall/algorithm to get past
Natural<X> and Natural<Y> not being equivalent (is_integral types get a
special exemption to ternary ?: type equivalence, yet it's impossible to
simulate with our own classes, which is bullshit.) The horrifying part
is that ternary() will evaluate both lhs and rhs, unlike ?:
I converted some of the functions to test ? uint(x) : uint(y), and
others to ternary(test, x, y) ... I don't have a strong preference
either way yet.
But the part where things may have gotten broken is in the changes to
where ternary() was placed. Some cases like in the GBA PPU renderer, it
was rather unclear the order of evaluations, so I may have made a
mistake somewhere.
So again, please please test this if you can. Or even better, look over
the diff.
Longer-term, I'd really like the enable nall/primitives/operators.hpp,
but right now I'm not sure why Kirby's Dream Land 3 is breaking. Help
would be appreciated, but ... it's gonna be really complex and difficult
to debug, so I'm probably gonna be on my own here ... sigh.
byuu says:
The biggest change was improving WonderSwan emulation. With help from
trap15, I tracked down a bug where I was checking the wrong bit for
reverse DMA transfers. Then I also emulated VTOTAL to support variable
refresh rate. Then I improved HyperVoice emulation which should be
unsigned samples in three of four modes. That got Fire Lancer running
great. I also rewrote the disassembler. The old one disassembled many
instructions completely wrong, and deviated too much from any known x86
syntax. I also emulated some of the quirks of the V30 (two-byte POP into
registers fails, SALC is just XLAT mirrored, etc) which probably don't
matter unless someone tries to run code to verify it's a NEC CPU and not
an Intel CPU, but hey, why not?
I also put more work into the MSX skeleton, but it's still just a
skeleton with no real emulation yet.
byuu says:
This synchronizes bsnes/higan with many recent internal nall changes.
This will be the last WIP until I am situated in Japan. Apologies for the
bugfixes that didn't get applied yet, I ran out of time.
byuu says:
Changelog:
- fixed bug in Emulator::Game::Memory::operator bool()
- nall: renamed view<string> back to `string_view`
- nall:: implemented `array_view`
- Game Boy: split cartridge-specific input mappings (rumble,
accelerometer) to their own separate ports
- Game Boy: fixed MBC7 accelerometer x-axis
- icarus: Game Boy, Super Famicom, Mega Drive cores output internal
header game titles to heuristics manifests
- higan, icarus, hiro/gtk: improve viewport geometry configuration;
fixed higan crashing bug with XShm driver
- higan: connect Video::poll(),update() functionality
- hiro, ruby: several compilation / bugfixes, should get the macOS
port compiling again, hopefully [Sintendo]
- ruby/video/xshm: fix crashing bug on window resize
- a bit hacky; it's throwing BadAccess Xlib warnings, but they're
not fatal, so I am catching and ignoring them
- bsnes: removed Application::Windows::onModalChange hook that's no
longer needed [Screwtape]
byuu says:
The main thing I worked on today was emulating the MBC7 EEPROM.
And... I have many things to say about that, but not here, and not now...
The missing EEPROM support is why the accelerometer was broken. Although
it's not evidently clear that I'm emulating the actual values
incorrectly. I'll think about it and get it fixed, though.
bsnes went from ~308fps to ~328fps, and I don't even know why. Probably
something somewhere in the 140KB of changes to other things made in this
WIP.
byuu says:
Changes to hiro will break all but the GTK target. Not that it matters
much given that the only ruby drivers that function are all on BSD
anyway.
But if you are fortunate enough to be able to run this ... you'll find
lots of polishing improvements to the bsnes GUI. I posted some
screenshots on Twitter, if anyone were interested.
byuu says:
I stand corrected, I managed to create and even larger diff than ever.
This one weighs in at 309KiB `>__>`
I'll have to create a changelog later, I'm too tired right now to go
through all of that.
byuu says:
Changelog:
- emulator/video,audio: various cleanups
- emulator/audio: removed reverb effect (it breaks very badly on
high-frequency systems)
- emulator/audio: the Nyquist anti-aliasing lowpass filter is now
generated automatically instead of set per-core
- at 44.1KHz output, it's set to 22KHz; at 48KHz, it's set to
22KHz; at 96KHz, it's set to 25KHz
- this filter now takes the bsnes emulation speed setting into
account
- all system/video.cpp files removed; inlined in System::power() and
Interface::set() instead
- sfc/cpu: pre-compute `HTIME` as `HTIME+1<<2` for faster comparisons of
HIRQs
- sfc/cpu: re-add check to block IRQs on the last dot of each frame
(minor speed hit)
- hiro/gtk3: fixed headers for Linux compilation finally
- hiro/gtk,qt: fixed settings.cpp logic so initial values are used
when no settings.bml file exists
- hiro/gtk: started a minor experiment to specify theming information
in settings.bml files
- nall/dsp: allow the precision type (double) to be overridden (to
float)
- nall: add some helpers for generating pre-compiled headers
- it was a failure to try using them for higan, however ...
- nall: add some helpers for reading fallback values from empty
`Markup::Node[search]` statements
Todo:
- CRITICAL: a lot of my IRQ/NMI/HDMA timing tests are failing with the
fast PPU ... need to figure out why
- space between Emulator::video functions and Emulator::audio
functions in gb/system/system.cpp
- remove Audio/Reverb/Enable from settings.bml in target-bsnes
byuu says:
This is probably the largest code-change diff I've done in years.
I spent four days working 10-16 hours a day reworking layouts in hiro
completely.
The result is we now have TableLayout, which will allow for better
horizontal+vertical combined alignment.
Windows, GTK2, and now GTK3 are fully supported.
Windows is getting the initial window geometry wrong by a bit.
GTK2 and GTK3 work perfectly. I basically abandoned trying to detect
resize signals, and instead keep a list of all hiro windows that are
allocated, and every time the main loop runs, it will query all of them
to see if they've been resized. I'm disgusted that I have to do this,
but after fighting with GTK for years, I'm about sick of it. GTK was
doing this crazy thing where it would trigger another size-allocate
inside of a previous size-allocate, and so my layouts would be halfway
through resizing all the widgets, and then the size-allocate would kick
off another one. That would end up leaving the rest of the first layout
loop with bad widget sizes. And if I detected a second re-entry and
blocked it, then the entire window would end up with the older geometry.
I started trying to build a message queue system to allow the second
layout resize to occur after the first one completed, but this was just
too much madness, so I went with the simpler solution.
Qt4 has some geometry problems, and doesn't show tab frame layouts
properly yet.
Qt5 causes an ICE error and tanks my entire Xorg display server, so ...
something is seriously wrong there, and it's not hiro's fault. Creating
a dummy Qt5 application without even using hiro, just int main() {
TestObject object; } with object performing a dynamic\_cast to a derived
type segfaults. Memory is getting corrupted where GCC allocates the
vtables for classes, just by linking in Qt. Could be somehow related to
the -fPIC requirement that only Qt5 has ... could just be that FreeBSD
10.1 has a buggy implementation of Qt5. I don't know. It's beyond my
ability to debug, so this one's going to stay broken.
The Cocoa port is busted. I'll fix it up to compile again, but that's
about all I'm going to do.
Many optimizations mean bsnes and higan open faster. GTK2 and GTK3 both
resize windows very quickly now.
higan crashes when you load a game, so that's not good. bsnes works
though.
bsnes also has the start of a localization engine now. Still a long way
to go.
The makefiles received a rather substantial restructuring. Including the
ruby and hiro makefiles will add the necessary compilation rules for
you, which also means that moc will run for the qt4 and qt5 targets, and
windres will run for the Windows targets.
byuu says:
Changelog:
- bsnes, higan: simplified make output; reordered rules
- hiro: added Window::set(Minimum,Maximum)Size() [only implemented in
GTK+ so far]
- bsnes: only allow the window to be shrunk to the 1x multiplier size
- bsnes: refactored Integral Scaling checkbox to {Center, Scale,
Stretch} radio selection
- nall: call fflush() after nall::print() to stdout or stderr [needed
for msys2/bash]
- bsnes, higan: program/interface.cpp renamed to program/platform.cpp
- bsnes: trim ".shader/" from names in Settings→Shader menu
- bsnes: Settings→Shader menu updated on video driver changes
- bsnes: remove missing games from recent files list each time it is
updated
- bsnes: video multiplier menu generated dynamically based on largest
monitor size at program startup
- bsnes: added shrink window and center window function to video
multiplier menu
- bsnes: de-minimize presentation window when exiting fullscreen mode
or changing video multiplier
- bsnes: center the load game dialog against the presentation window
(important for multi-monitor setups)
- bsnes: screenshots are not immediate instead of delayed one frame
- bsnes: added frame advance menu option and hotkey
- bsnes: added enable cheats checkbox and hotkey; can be used to
quickly enable/disable all active cheats
Errata:
- hiro/Windows: `SW_MINIMIZED`, `SW_MAXIMIZED `=> `SW_MINIMIZE`,
`SW_MAXIMIZE`
- hiro/Windows: add pMonitor::workspace()
- hiro/Windows: add setMaximized(), setMinimized() in
pWindow::construct()
- bsnes: call setCentered() after setMaximized(false)
byuu says:
Changelog:
- nall: renamed array to adaptive_array; marked it as deprecated
- nall: created new array class; which is properly static (ala
std::array) with optional bounds-checking
- sfc/ppu-fast: converted unmanaged arrays to use nall/array (no speed
penalty)
- bsnes: rewrote the cheat code editor to a new design
- nall: string class can stringify pointer types directly now, so
pointer() was removed
- nall: added array_view and pointer types (still unsure if/how I'll
use pointer)
byuu says:
Changelog:
- nall/GNUmakefile: fixed findstring parameter arguments [Screwtape]
- nall/Windows: always include -mthreads -lpthread for all
applications
- nall/memory: code restructuring
I really wanted to work on the new PPU today, but I thought I'd spend a
few minutes making some minor improvements to nall::memory, that was
five and a half hours ago. Now I have a 67KiB diff of changes. Sigh.
byuu says:
Changelog:
- Super Game Boy: fixed loading of boot ROM
- hiro: added ComboEdit::setEditable(bool = true);
- tomoko: added new systems settings panel
Note!!: this release will not compile on Windows or macOS due to the
missing ComboEdit control! I'll try to merge in hex's implementation
for the Windows release here soon. macOS users will probably be out of
luck for a while, sorry.
The new systems panel is an idea I've been meaning to implement for
quite a while, but finally got around to starting on it. It's still
fairly unpolished, but the basic idea is there for Linux/BSD users to
try out now.
So imagine the Super Game Boy, BS-X Satellaview, Sufami Turbo, and the
associated BS Memory Pack-slotted SNES cartridges. To play any of those,
you needed to choose Nintendo→Super Famicom, and then select the
relevant cartridge, and then select any slotted cartridges to play with
it.
This was acceptable-ish, if not ideal. But now imagine in the future if
we wanted to support the Famicom Disk System, which is technically a
cartridge that plugs into the Famicom deck. Or the PC Engine CD, which
has one of three special HuCards that must be inserted (ignoring the
Turbo Duo where it's built-in—I'm going to be emulating the Super CD
as if you're using a stock PCE CD.) Or the Mega CD, where there are
probably a half dozen or more BIOS + hardware revisions that are
region-specific, which connect to an expansion port that is identical to
the cartridge port save for the Mega Drive seeing an I/O register bit
toggled here.
In all of these cases, it's going to be a real pain to have to choose
the 'BIOS' every time you want to play a game for them.
I can't distribute these BIOSes with higan due to copyright
restrictions, and trying to ship dummy folders for every possible
combination would become quite odious, and difficult for people to use
(compare to setting up the Game Boy Advance system BIOS.)
And so I've created the new systems settings panel. Here, you can manage
a list of systems that show up under the higan library menu (now renamed
to “System”), where each entry contains name, boot, and hidden
parameters.
The name parameter is what shows up in the system menu. You can call any
system higan emulates whatever you like here. Don't like “Super
Famicom”? Change it to “SNES”, then.
The boot parameter is a combo edit with a dropdown for all of the
systems higan emulates. If you choose one of these, then the higan
system menu option will work exactly like in previous releases, and
prompt you for a cartridge. But if you choose the browse button next to
the combo edit control, you'll get to pick any gamepak from the higan
library of your choosing.
So you could choose the SGB2 BIOS, and name the menu option “Super Game
Boy 2”, and when you choose the menu option, it will load the SFC core,
load the SGB2 BIOS, and only prompt you for the Game Boy game you wish
to play on it. The same deal goes for the FDS, PCE-CD, Mega CD, Mega
Drive Sonic & Knuckles lock-on cartridge, BS-X Satellaview, SD Gundam
G-Next, etc. Whatever you want to be in the menu, you can put in there
by pointing higan at the appropriate 'BIOS' gamepak to load.
Astute readers have probably already noticed, but you can technically
use this on non-slotted games as well, thus creating instant boot
options for your absolute favorite games, if you so wanted. Point it at
Zelda 3, and you can boot it instantly from the main menu, without any
need for file selection.
The hidden option is a way to hide the system entries from the system
menu. Primarily this would be a fast way for users to disable emulation
cores they never use in higan, without having to remove the options.
The major concession with this change is the collapsing of the
per-manufacturer submenus. What this means is you will now have all
twelve higan emulated systems in the main menu by default. This makes
the list rather long, but ... oh well. I may try to offer some form of
grouping in the future, but the grouping defeats the “list order =
display order” design, and I'm not willing to auto-sort the list. I want
people to be able to control the ordering of the system menu, and have
added (as yet non-functional) sorting arrows for that purpose. I also
don't have a combined tree+table view widget in higan to try to and
group things. But ... we'll see how things go in the future.
Another idea is to add a specialty load option that opens up the user's
Emulation library path, and lets you pick a gamepak for any system,
which would boot the same way as when you drop a gamepak onto the higan
executable or main window. So say you almost never play Wonderswan
games, this would be a way to play them without them cluttering your
system menu list.
The “import ROM files” option has been removed. All it does is launch
icarus directly. I would rather users become familiar with using icarus.
The “load ROM file” option remains.
Anyway, this is all still a work in progress, so please give it time and
don't overload me with too many suggested changes right now, thanks :3
byuu says:
Changelog:
- game/memory/type/battery → game/memory/volatile
- (manufacturer.)content.type → (architecture.)content.type
- nall: Markup::find() strips spaces from values in comparisons
- higan: updated game manifest loading/saving code for all cores
- GBA: flash memory ID is internally selected based on the
manufacturer and memory size
- SFC: ST018 (ARM6) frequency can be modified via game manifest now
- WS: EEPROM::name removed (not useful)
- icarus, genius: battery→volatile updates
I did my best to look over the diff between r13 and r14, but it's 84KiB
excluding the game database changes. It's just too much for me. I'd
greatly appreciate if someone could look over it and check for any
errors in this update. But more than likely, I suppose we'll iron out
any issues by determining which games fail to load.
Right now, I know the Super Game Boy support doesn't seem to work. But
all non-SFC cores should work fully, and all normal + NEC DSP SFC games
should work as well. Unsure about the rest.
Also, I'm planning to change the Game Boy “MBC1M” mapper to “MBC1#A” to
indicate it's an alternate wiring configuration of the stock MBC1, and
not a new mapper type.
byuu says:
Changelog:
- nall: `Markup::Node::operator[]` now uses `find()` instead of `lookup()`
behind the scenes
- Super Famicom: RAM memory ordering is now independent of ROM memory
ordering
- Super Famicom: added 19 new generic board definitions
- icarus: improved Super Famicom heuristics generation
Not putting it in the changelog, but the SPC7110 RAM now has write
protection disabled again.
99% of games should now be playable with heuristics. The exceptions
should be:
- 4MB LoROM games with SRAM (Ys 3, FE: Thracia 776)
- 2MB DSP LoROM games
- BS-X Town
- BS-X slotted games
- SA1 BSX slotted games
- SPC7110 games without the RTC (Momotarou Dentetsu Happy, Super Power
League 4)
- SPC7110 7MB fan translation (wasn't supported earlier either)
- ExLoROM games (wasn't supported earlier either)
- Sufami Turbo
- Campus Challenge '92 and Powerfest '94
- ST010 is going to run at 15MHz instead of 11MHz
- MSU1 (needs to be supported in higan, not icarus)
I'll add support for most of these before the release of v107.
byuu says:
Changelog:
- Super Famicom: added support for loading manifests without embedded
mapping information¹
- genius: initial commit
- various Makefile cleanups
¹: so the idea here is to try and aim for a stable manifest format,
and to allow direct transposition of icarus/genius database entries into
manifest files. The exact mechanics of how this is going to work is
currently in flux, but we'll get there.
For right now, `Super Famicom.sys` gains `boards.bml`, which is the raw
database from my board-editor tool, and higan itself tries to load
`boards.bml`, match an entry to game/board from the game's `manifest.bml`
file, and then transform it into the format currently used by higan. It
does this only when the game's `manifest.bml` file lacks a board node.
When such a board node exists, it works as previous versions of higan
did.
The only incompatible change right now is information/title is now
located at game/label. I may transition window title display to just use
the filenames instead.
Longer term, some thought is going to need to go into the format of the
`boards.bml` database itself, and at which point in the process I should
be transforming things.
Give it time, we'll refine this into something nicer.
byuu says:
Changelog:
- gb: added accelerometer X-axis, Y-Axis inputs¹
- gb: added rumble input¹
- gb/mbc5: added rumble support²
- gb/mbc6: added skeleton driver, but it doesn't boot Net de Get
- gb/mbc7: added mostly complete driver (only missing EEPROM), but it
doesn't boot Kirby Tilt 'n' Tumble
- gb/tama: added leap year assignment
- tomoko: fixed macOS compilation [MerryMage]
- hiro/cocoa: fix table cell redrawing on updates and automatic column
resizing [ncbncb]
- hiro/cocoa: fix some weird issue with clicking table view checkboxes
on Retina displays [ncbncb]
- icarus: enhance Game Boy heuristics³
- nall: fix three missing return statements [Jonas Quinn]
- ruby: hopefully fixed all compilation errors reported by Screwtape
et al⁴
¹: because there's no concept of a controller for cartridge inputs,
I'm attaching to the base platform for now. An idea I had was to make
separate ports for each cartridge type ... but this would duplicate the
rumble input between MBC5 and MBC7. And would also be less discoverable.
But it would be more clean in that users wouldn't think the Game Boy
hardware had this functionality. I'll think about it.
²: it probably won't work yet. Rumble isn't documented anywhere, but
I dug through an emulator named GEST and discovered that it seems to use
bit 3 of the RAM bank select to be rumble. I don't know if it sets the
bit for rumbling, then clears when finished, or if it sets it and then
after a few milliseconds it stops rumbling. I couldn't test on my
FreeBSD box because SDL 1.2 doesn't support rumble, udev doesn't exist
on FreeBSD, and nobody has ever posted any working code for how to use
evdev (or whatever it's called) on FreeBSD.
³: I'm still thinking about specifying the MBC7 RAM as EEPROM, since
it's not really static RAM.
⁴: if possible, please test all drivers if you can. I want to ensure
they're all working. Especially let me know if the following work:
macOS: input.carbon Linux: audio.pulseaudiosimple, audio.ao (libao)
If I can confirm these are working, I'm going to then remove them from
being included with stock higan builds.
I'm also considering dropping SDL video on Linux/BSD. XShm is much
faster and supports blurring. I may also drop SDL input on Linux, since
udev works better. That will free a dependency on SDL 1.2 for building
higan. FreeBSD is still going to need it for joypad support, however.
byuu says:
Changelog:
- gb/interface: fix Game Boy Color extension to be "gbc" and not "gb"
[hex\_usr]
- ms/interface: move Master System hardware controls below controller
ports
- sfc/ppu: improve latching behavior of BGnHOFS registers (not
hardware verified) [AWJ]
- tomoko/input: rework port/device mapping to support non-sequential
ports and devices¹
- todo: should add move() to inputDevice.mappings.append and
inputPort.devices.append
- note: there's a weird GCC 4.9 bug with brace initialization of
InputEmulator; have to assign each field separately
- tomoko: all windows sans the main presentation window can be
dismissed with the escape key
- icarus: the single file selection dialog ("Load ROM Image...") can
be dismissed with the escape key
- tomoko: do not pause emulation when FocusLoss/Pause is set during
exclusive fullscreen mode
- hiro/(windows,gtk,qt): implemented Window::setDismissable() function
(missing from cocoa port, sorry)
- nall/string: fixed printing of largest possible negative numbers (eg
`INT_MIN`) [Sintendo]
- only took eight months! :D
¹: When I tried to move the Master System hardware port below the
controller ports, I ran into a world of pain.
The input settings list expects every item in the
`InputEmulator<InputPort<InputDevice<InputMapping>>>>` arrays to be
populated with valid results. But these would be sparsely populated
based on the port and device IDs from inside higan. And that is done so
that the Interface::inputPoll can have O(1) lookup of ports and devices.
This worked because all the port and device IDs were sequential (they
left no gaps in the maps upon creating the lists.)
Unfortunately by changing the expectation of port ID to how it appears
in the list, inputs would not poll correctly. By leaving them alone and
just moving Hardware to the third position, the Game Gear would be
missing port IDs of 0 and 1 (the controller ports of the Master System).
Even by trying to make separate MasterSystemHardware and
GameGearHardware ports, things still fractured when the devices were no
longer contigious.
I got pretty sick of this and just decided to give up on O(1)
port/device lookup, and moved to O(n) lookup. It only knocked the
framerate down by maybe one frame per second, enough to be in the margin
of error. Inputs aren't polled *that* often for loops that usually
terminate after 1-2 cycles to be too detrimental to performance.
So the new input system now allows non-sequential port and device IDs.
Remember that I killed input IDs a while back. There's never any reason
for those to need IDs ... it was easier to just order the inputs in the
order you want to see them in the user interface. So the input lookup is
still O(1). Only now, everything's safer and I return a
maybe<InputMapping&>, and won't crash out the program trying to use a
mapping that isn't found for some reason.
Errata: the escape key isn't working on the browser/message dialogs on
Windows, because of course nothing can ever just be easy and work for
me. If anyone else wouldn't mind looking into that, I'd greatly
appreciate it.
Having the `WM_KEYDOWN` test inside the main `Application_sharedProc`, it
seems to not respond to the escape key on modal dialogs. If I put the
`WM_KEYDOWN` test in the main window proc, then it doesn't seem to get
called for `VK_ESCAPE` at all, and doesn't get called period for modal
windows. So I'm at a loss and it's past 4AM here >_>
byuu says:
Changelog:
- MD/PSG: fixed 68K bus Z80 status read address location
- MS, GG, MD/PSG: channels post-decrement their counters, not
pre-decrement [Cydrak]¹
- MD/VDP: cache screen width registers once per scanline; screen
height registers once per frame
- MD/VDP: support 256-width display mode (used in Shining Force, etc)
- MD/YM2612: implemented timers²
- MD/YM2612: implemented 8-bit PCM DAC²
- 68000: TRAP instruction should index the vector location by 32 (eg
by 128 bytes), fixes Shining Force
- nall: updated hex(), octal(), binary() functions to take uintmax
instead of template<typename T> parameter³
¹: this one makes an incredible difference. Sie noticed that lots of
games set a period of 0, which would end up being a really long period
with pre-decrement. By fixing this, noise shows up in many more games,
and sounds way better in games even where it did before. You can hear
extra sound on Lunar - Sanposuru Gakuen's title screen, the noise in
Sonic The Hedgehog (Mega Drive) sounds better, etc.
²: this also really helps sound. The timers allow PSG music to play
back at the correct speed instead of playing back way too quickly. And
the PCM DAC lets you hear a lot of drum effects, as well as the
"Sega!!" sound at the start of Sonic the Hedgehog, and the infamous,
"Rise from your grave!" line from Altered Beast.
Still, most music on the Mega Drive comes from the FM channels, so
there's still not a whole lot to listen to.
I didn't implement Cydrak's $02c test register just yet. Sie wasn't 100%
certain on how the extended DAC bit worked, so I'd like to play it a
little conservative and get sound working, then I'll go back and add a
toggle or something to enable undocumented registers, that way we can
use that to detect any potential problems they might be causing.
³: unfortunately we lose support for using hex() on nall/arithmetic
types. If I have a const Pair& version of the function, then the
compiler gets confused on whether Natural<32> should use uintmax or
const Pair&, because compilers are stupid, and you can't have explicit
arguments in overloaded functions. So even though either function would
work, it just decides to error out instead >_>
This is actually really annoying, because I want hex() to be useful for
printing out nall/crypto keys and hashes directly.
But ... this change had to be made. Negative signed integers would crash
programs, and that was taking out my 68000 disassembler.
byuu says:
Changelog:
- added \~130 new PAL games to icarus (courtesy of Smarthuman
and aquaman)
- added all three Korean-localized games to icarus
- sfc: removed SuperDisc emulation (it was going nowhere)
- sfc: fixed MSU1 regression where the play/repeat flags were not
being cleared on track select
- nall: cryptography support added; will be used to sign future
databases (validation will always be optional)
- minor shims to fix compilation issues due to nall changes
The real magic is that we now have 25-30% of the PAL SNES library in
icarus!
Signing will be tricky. Obviously if I put the public key inside the
higan archive, then all anyone has to do is change that public key for
their own releases. And if you download from my site (which is now over
HTTPS), then you don't need the signing to verify integrity. I may just
put the public key on my site on my site and leave it at that, we'll
see.
byuu says:
Changelog:
- added 30 new PAL games to icarus (courtesy of Mikerochip)
- new version of libco no longer requires mprotect nor W|X permissions
- nall: default C compiler to -std=c11 instead of -std=c99
- nall: use `-fno-strict-aliasing` during compilation
- updated nall/certificates (hopefully for the last time)
- updated nall/http to newer coding conventions
- nall: improve handling of range() function
I didn't really work on higan at all, this is mostly just a release
because lots of other things have changed.
The most interesting is `-fno-strict-aliasing` ... basically, it joins
`-fwrapv` as being "stop the GCC developers from doing *really* evil
shit that could lead to security vulnerabilities or instabilities."
For the most part, it's a ~2% speed penalty for higan. Except for the
Sega Genesis, where it's a ~10% speedup. I have no idea how that's
possible, but clearly something's going very wrong with strict aliasing
on the Genesis core.
So ... it is what it is. If you need the performance for the non-Genesis
cores, you can turn it off in your builds. But I'm getting quite sick of
C++'s "surprises" and clever compiler developers, so I'm keeping it on
in all of my software going forward.
byuu says:
Changelog:
- Emulator: use `(uintmax)-1 >> 1` for the units of time
- MD: implemented 13 new 68K instructions (basically all of the
remaining easy ones); 21 remain
- nall: replaced `(u)intmax_t` (64-bit) with *actual* `(u)intmax` type
(128-bit where available)
- this extends to everything: atoi, string, etc. You can even
print 128-bit variables if you like
22,552 opcodes still don't exist in the 68K map. Looking like quite a
few entries will be blank once I finish.
byuu says:
(Windows users may need to include <sys/time.h> at the top of
nall/chrono.hpp, not sure.)
Unchangelog:
- forgot to add the Scheduler clock=0 fix because I have the memory of
a goldfish
Changelog:
- new icarus database with nine additional games
- hiro(GTK,Qt) won't constantly write its settings.bml file to disk
anymore
- added latency simulator for fun (settings.bml => Input/Latency in
milliseconds)
So the last one ... I wanted to test out nall::chrono, and I was also
thinking that by polling every emulated frame, it's pretty wasteful when
you are using Fast Forward and hitting 200+fps. As I've said before,
calls to ruby::input::poll are not cheap.
So to get around this, I added a limiter so that if you called the
hardware poll function within N milliseconds, it'll return without
doing any actual work. And indeed, that increases my framerate of Zelda
3 uncapped from 133fps to 142fps. Yay. But it's not a "real" speedup,
as it only helps you when you exceed 100% speed (theoretically, you'd
need to crack 300% speed since the game itself will poll at 16ms at 100%
speed, but yet it sped up Zelda 3, so who am I to complain?)
I threw the latency value into the settings file. It should be 16,
but I set it to 5 since that was the lowest before it started negatively
impacting uncapped speeds. You're wasting your time and CPU cycles setting
it lower than 5, but if people like placebo effects it might work. Maybe
I should let it be a signed integer so people can set it to -16 and think
it's actually faster :P (I'm only joking. I took out the 96000hz audio
placebo effect as well. Not really into psychological tricks anymore.)
But yeah seriously, I didn't do this to start this discussion again for
the billionth time. Please don't go there. And please don't tell me this
WIP has higher/lower latency than before. I don't want to hear it.
The only reason I bring it up is for the fun part that is worth
discussing: put up or shut up time on how sensitive you are to
latency! You can set the value above 5 to see how games feel.
I personally can't really tell a difference until about 50. And I can't
be 100% confident it's worse until about 75. But ... when I set it to
150, games become "extra difficult" ... the higher it goes, the worse
it gets :D
For this WIP, I've left no upper limit cap. I'll probably set a cap of
something like 500ms or 1000ms for the official release. Need to balance
user error/trolling with enjoyability. I'll think about it.
[...]
Now, what I worry about is stupid people seeing it and thinking it's an
"added latency" setting, as if anyone would intentionally make things
worse by default. This is a limiter. So if 5ms have passed since the
game last polled, and that will be the case 99.9% of the time in games,
the next poll will happen just in time, immediately when the game polls
the inputs. Thus, a value below 1/<framerate>ms is not only pointless,
if you go too low it will ruin your fast forward max speeds.
I did say I didn't want to resort to placebo tricks, but I also don't
want to spark up public discussion on this again either. So it might
be best to default Input/Latency to 0ms, and internally have a max(5,
latency) wrapper around the value.
byuu says:
(Windows: compile with -fpermissive to silence an annoying error. I'll
fix it in the next WIP.)
I completely replaced the time management system in higan and overhauled
the scheduler.
Before, processor threads would have "int64 clock"; and there would
be a 1:1 relationship between two threads. When thread A ran for X
cycles, it'd subtract X * B.Frequency from clock; and when thread B ran
for Y cycles, it'd add Y * A.Frequency from clock. This worked well
and allowed perfect precision; but it doesn't work when you have more
complicated relationships: eg the 68K can sync to the Z80 and PSG; the
Z80 to the 68K and PSG; so the PSG needs two counters.
The new system instead uses a "uint64 clock" variable that represents
time in attoseconds. Every time the scheduler exits, it subtracts
the smallest clock count from all threads, to prevent an overflow
scenario. The only real downside is that rounding errors mean that
roughly every 20 minutes, we have a rounding error of one clock cycle
(one 20,000,000th of a second.) However, this only applies to systems
with multiple oscillators, like the SNES. And when you're in that
situation ... there's no such thing as a perfect oscillator anyway. A
real SNES will be thousands of times less out of spec than 1hz per 20
minutes.
The advantages are pretty immense. First, we obviously can now support
more complex relationships between threads. Second, we can build a
much more abstracted scheduler. All of libco is now abstracted away
completely, which may permit a state-machine / coroutine version of
Thread in the future. We've basically gone from this:
auto SMP::step(uint clocks) -> void {
clock += clocks * (uint64)cpu.frequency;
dsp.clock -= clocks;
if(dsp.clock < 0 && !scheduler.synchronizing()) co_switch(dsp.thread);
if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread);
}
To this:
auto SMP::step(uint clocks) -> void {
Thread::step(clocks);
synchronize(dsp);
synchronize(cpu);
}
As you can see, we don't have to do multiple clock adjustments anymore.
This is a huge win for the SNES CPU that had to update the SMP, DSP, all
peripherals and all coprocessors. Likewise, we don't have to synchronize
all coprocessors when one runs, now we can just synchronize the active
one to the CPU.
Third, when changing the frequencies of threads (think SGB speed setting
modes, GBC double-speed mode, etc), it no longer causes the "int64
clock" value to be erroneous.
Fourth, this results in a fairly decent speedup, mostly across the
board. Aside from the GBA being mostly a wash (for unknown reasons),
it's about an 8% - 12% speedup in every other emulation core.
Now, all of this said ... this was an unbelievably massive change, so
... you know what that means >_> If anyone can help test all types of
SNES coprocessors, and some other system games, it'd be appreciated.
----
Lastly, we have a bitchin' new about screen. It unfortunately adds
~200KiB onto the binary size, because the PNG->C++ header file
transformation doesn't compress very well, and I want to keep the
original resource files in with the higan archive. I might try some
things to work around this file size increase in the future, but for now
... yeah, slightly larger archive sizes, sorry.
The logo's a bit busted on Windows (the Label control's background
transparency and alignment settings aren't working), but works well on
GTK. I'll have to fix Windows before the next official release. For now,
look on my Twitter feed if you want to see what it's supposed to look
like.
----
EDIT: forgot about ICD2::Enter. It's doing some weird inverse
run-to-save thing that I need to implement support for somehow. So, save
states on the SGB core probably won't work with this WIP.
byuu says:
Changelog:
- hiro: BrowserDialog can navigate up to drive selection on Windows
- nall: (file,path,dir,base,prefix,suffix)name =>
Location::(file,path,dir,base,prefix,suffix)
- higan/tomoko: rename audio filter label from "Sinc" to "IIR - Biquad"
- higan/tomoko: allow loading files via icarus on the command-line
once again
- higan/tomoko: (begrudging) quick hack to fix presentation window focus
on startup
- higan/audio: don't divide output audio volume by number of streams
- processor/r65816: fix a regression in (read,write)DB; fixes Taz-Mania
- fixed compilation regressions on Windows and Linux
I'm happy with where we are at with code cleanups and stability, so I'd
like to release v100. But even though I'm not assigning any special
significance to this version, we should probably test it more thoroughly
first.
byuu says:
Changelog:
- nall::lstring -> nall::string_vector
- added IntegerBitField<type, lo, hi> -- hopefully it works correctly...
- Multitap 1-4 -> Super Multitap 2-5
- fixed SFC PPU CGRAM read regression
- huge amounts of SFC PPU IO register cleanups -- .bits really is lovely
- re-added the read/write(VRAM,OAM,CGRAM) helpers for the SFC PPU
- but they're now optimized to the realities of the PPU (16-bit data
sizes / no address parameter / where appropriate)
- basically used to get the active-display overrides in a unified place;
but also reduces duplicate code in (read,write)IO
byuu says:
Changelog:
- (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel
like they were contributing enough to be worth it]
- cleaned up nall::integer,natural,real functionality
- toInteger, toNatural, toReal for parsing strings to numbers
- fromInteger, fromNatural, fromReal for creating strings from numbers
- (string,Markup::Node,SQL-based-classes)::(integer,natural,real)
left unchanged
- template<typename T> numeral(T value, long padding, char padchar)
-> string for print() formatting
- deduces integer,natural,real based on T ... cast the value if you
want to override
- there still exists binary,octal,hex,pointer for explicit print()
formatting
- lstring -> string_vector [but using lstring = string_vector; is
declared]
- would be nice to remove the using lstring eventually ... but that'd
probably require 10,000 lines of changes >_>
- format -> string_format [no using here; format was too ambiguous]
- using integer = Integer<sizeof(int)*8>; and using natural =
Natural<sizeof(uint)*8>; declared
- for consistency with boolean. These three are meant for creating
zero-initialized values implicitly (various uses)
- R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees
up struct IO {} io; naming]
- SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {}
(status,registers); now
- still some CPU::Status status values ... they didn't really fit into
IO functionality ... will have to think about this more
- SFC CPU, PPU, SMP now use step() exclusively instead of addClocks()
calling into step()
- SFC CPU joypad1_bits, joypad2_bits were unused; killed them
- SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it
- SFC PPU OAM moved into PPU::Object; since nothing else uses it
- the raw uint8[544] array is gone. OAM::read() constructs values from
the OAM::Object[512] table now
- this avoids having to determine how we want to sub-divide the two
OAM memory sections
- this also eliminates the OAM::synchronize() functionality
- probably more I'm forgetting
The FPS fluctuations are driving me insane. This WIP went from 128fps to
137fps. Settled on 133.5fps for the final build. But nothing I changed
should have affected performance at all. This level of fluctuation makes
it damn near impossible to know whether I'm speeding things up or slowing
things down with changes.
byuu says:
Changelog:
- nall/vector rewritten from scratch
- higan/audio uses nall/vector instead of raw pointers
- higan/sfc/coprocessor/sdd1 updated with new research information
- ruby/video/glx and ruby/video/glx2: fuck salt glXSwapIntervalEXT!
The big change here is definitely nall/vector. The Windows, OS X and Qt
ports won't compile until you change some first/last strings to
left/right, but GTK will compile.
I'd be really grateful if anyone could stress-test nall/vector. Pretty
much everything I do relies on this class. If we introduce a bug, the
worst case scenario is my entire SFC game dump database gets corrupted,
or the byuu.org server gets compromised. So it's really critical that we
test the hell out of this right now.
The S-DD1 changes mean you need to update your installation of icarus
again. Also, even though the Lunar FMV never really worked on the
accuracy core anyway (it didn't initialize the PPU properly), it really
won't work now that we emulate the hard-limit of 16MiB for S-DD1 games.
byuu says:
Changelog:
- fixed SNES sprite priority regression from r17
- added nall/windows/guard.hpp to guard against global namespace
pollution (similar to nall/xorg/guard.hpp)
- almost fixed Windows compilation (still accuracy profile only, sorry)
- finished porting all of gba/ppu's registers over to the new .bit,.bits
format ... all GBA registers.cpp files gone now
- the "processors :=" line in the target-$(ui)/GNUmakefile is no longer
required
- processors += added to each emulator core
- duplicates are removed using the new nall/GNUmakefile's $(unique)
function
- SFC core can be compiled without the GB core now
- "-DSFC_SUPERGAMEBOY" is required to build in SGB support now (it's
set in target-tomoko/GNUmakefile)
- started once again on loki (higan/target-loki/) [as before, loki is
Linux/BSD only on account of needing hiro::Console]
loki shouldn't be too horrendous ... I hope. I just have the base
skeleton ready for now. But the code from v094r08 should be mostly
copyable over to it. It's just that it's about 50KiB of incredibly
tricky code that has to be just perfect, so it's not going to be quick.
But at least with the skeleton, it'll be a lot easier to pick away at it
as I want.
Windows compilation fix: move hiro/windows/header.hpp line 18 (header
guard) to line 16 instead.
byuu says:
Changelog:
- ruby: if DirectSoundCreate fails (no sound device present), return
false from init instead of crashing
- nall: improved edge case return values for
(basename,pathname,dirname,...)
- nall: renamed file_system_object class to inode
- nall: varuint_t replaced with VariadicNatural; which contains
.bit,.bits,.byte ala Natural/Integer
- nall: fixed boolean compilation error on Windows
- WS: popa should not restore SP
- GBA: rewrote the CPU/APU cores to use the .bit,.bits functions;
removed registers.cpp from each
Note that the GBA changes are extremely major. This is about five hours
worth of extremely delicate work. Any slight errors could break
emulation in extremely bad ways. Let's hold off on extensive testing
until the next WIP, after I do the same to the PPU.
So far ... endrift's SOUNDCNT_X I/O test is failing, although that code
didn't change, so clearly I messed up SOUNDCNT_H somehow ...
To compile on Windows:
1. change nall/string/platform.hpp line 47 to
return slice(result, 0, 3);
2. change ruby/video.wgl.cpp line 72 to
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
3. add this line to the very top of hiro/windows/header.cpp:
#define boolean FuckYouMicrosoft
byuu says:
This is a few days old, but oh well.
This WIP changes nall,hiro,ruby,icarus back to (u)int(8,16,32,64)_t.
I'm slowly pushing for (u)int(8,16,32,64) to use my custom
Integer<Size>/Natural<Size> classes instead. But it's going to be one
hell of a struggle to get that into higan.
byuu says:
A minor WIP to get us started.
Changelog:
- System::Video merged to PPU::Video
- System::Audio merged to DSP::Audio
- System::Configuration merged to Interface::Settings
- created emulator/emulator.cpp and accompanying object file for shared
code between all cores
Currently, emulator.cpp just holds a videoColor() function that takes
R16G16B16, performs gamma/saturation/luma adjust, and outputs
(currently) A8R8G8B8. It's basically an internal function call for cores
to use when generating palette entries. This code used to exist inside
ui-tomoko/program/interface.cpp, but we have to move it internal for
software display emulation. But in the future, we could add other useful
cross-core functionality here.
byuu says:
Changelog:
- fixed icarus to save settings properly
- fixed higan's full screen toggle on OS X
- increased "Add Codes" button width to avoid text clipping
- implemented cocoa/canvas.cpp
- added 1s delay after mapping inputs before re-enabling the window
(wasn't actually necessary, but already added it)
- fixed setEnabled(false) on Cocoa's ListView and TextEdit widgets
- updated nall::programpath() to use GetModuleFileName on Windows
- GB: system uses open collector logic, so unmapped reads return 0xFF,
not 0x00 (passes blargg's cpu_instrs again) [gekkio]
byuu says:
New update. Most of the work today went into eliminating hiro::Image
from all objects in all ports, replacing with nall::image. That took an
eternity.
Changelog:
- fixed crashing bug when loading games [thanks endrift!!]
- toggling "show status bar" option adjusts window geometry (not
supposed to recenter the window, though)
- button sizes improved; icon-only button icons no longer being cut off
byuu says:
Changelog:
- restructured the project and removed a whole bunch of old/dead
directives from higan/GNUmakefile
- huge amounts of work on hiro/cocoa (compiles but ~70% of the
functionality is commented out)
- fixed a masking error in my ARM CPU disassembler [Lioncash]
- SFC: decided to change board cic=(411,413) back to board
region=(ntsc,pal) ... the former was too obtuse
If you rename Boolean (it's a problem with an include from ruby, not
from hiro) and disable all the ruby drivers, you can compile an
OS X binary, but obviously it's not going to do anything.
It's a boring WIP, I just wanted to push out the project structure
change now at the start of this WIP cycle.
byuu says:
Changelog:
- int_t<bits> replaced with Integer<bits>
- uint_t<bits> replaced with Natural<bits>
- fixed "Synchronize Audio" menu option that broke recently
- all of sfc/performance ported to "auto function() -> return;" syntax
With this WIP, all of higan is finally ported over to the new function
declaration syntax. Thank the gods.
There's still going to be periodic disruption for diffs from porting
over signed->int, unsigned->uint, and whatever we come up with for the
new Natural<> and Integer<> classes. But the worst of it's behind us
now.