byuu says:
Changelog:
- emulator/interface: removed unused Region struct
- gba/cpu: optimized CPU::step() as much as I could for a slight
speedup¹
- gba/cpu: synchronize the APU better during FIFO updates
- higan/md, icarus: add automatic region detection; make it the
default option [hex\_usr]
- picks NTSC-J if there's more than one match ... eventually, this
will be a setting
- higan/md, icarus: support all three combinations of SRAM (8-bit low,
8-bit high, 16-bit)
- processor/arm7tdmi: fix bug when changing to THUMB mode via MSR
[MerryMage]
- tomoko: redesigned crash detector to only occur once for all three
ruby drivers
- this will reduce disk thrashing since the configuration file
only needs to be written out one extra time
- technically, it's twice ... but we should've always been writing
one out on first run in case it crashes then
- tomoko: defaulted back to the safest ruby drivers, given the optimal
drivers have some stability concerns
¹: minor errata: spotted a typo saying `synchronize(cpu)` when the CPU
is stopped, instead of `synchronize(ppu)`. This will be fixed in the v104
official 7zip archives.
I'm kind of rushing here but, it's really good timing for me to push out
a new official release. The blocking issues are resolved or close to it,
and we need lots of testing of the new major changes.
I'm going to consider this a semi-stable testing release and leave links
to v103 just in case.
byuu says:
Changelog:
- Master System: merged Bus into CPU
- Mega Drive: merged BusCPU into CPU; BusAPU into AU
- Mega Drive: added TMSS emulation; disabled by default [hex\_usr]
- VDP lockout not yet emulated
- processor/arm7tdmi: renamed interrupt() to exception()
- processor/arm7tdmi: CPSR.F (FIQ disable) flag is set on reset
- processor/arm7tdmi: pipeline decode stage caches CPSR.T (THUMB mode)
[MerryMage]
- fixes `msr_tests.gba` test F
- processor/arm7tdmi/disassembler: add PC address to left of currently
executing instruction
- processor/arm7tdmi: stop forcing CPSR.M (mode flags) bit 4 high (I
don't know what really happens here)
- processor/arm7tdmi: undefined instructions now generate Undefined
0x4 exception
- processor/arm7tdmi: thumbInstructionAddRegister masks PC by &~3
instead of &~2
- hopefully this is correct; &~2 felt very wrong
- processor/arm7tdmi: thumbInstructionStackMultiple can use sequential
timing for PC/LR PUSH/POP [Cydrak]
- systems/Mega Drive.sys: added tmss.rom; enable with cpu version=1
- tomoko: detect when a ruby video/audio/input driver crashes higan;
disable it on next program startup
v104 blockers:
- Mega Drive: support 8-bit SRAM (even if we don't support 16-bit;
don't force 8-bit to 16-bit)
- Mega Drive: add region detection support to icarus
- ruby: add default audio device information so certain drivers won't
default to silence out of the box
byuu says:
Changelog:
- gba/cpu: slight speedup to CPU::step()
- processor/arm7tdmi: fixed about ten bugs, ST018 and GBA games are
now playable once again
- processor/arm: removed core from codebase
- processor/v30mz: code cleanup (renamed functions; updated
instruction() for consistency with other cores)
It turns out on my much faster system, the new ARM7TDMI core is very
slightly slower than the old one (by about 2% or so FPS.) But the
CPU::step() improvement basically made it a wash.
So yeah, I'm in really serious trouble with how slow my GBA core is now.
Sigh.
As for higan/processor ... this concludes the first phase of major
cleanups and rewrites.
There will always be work to do, and I have two more phases in mind.
One is that a lot of the instruction disassemblers are very old. One
even uses sprintf still. I'd like to modernize them all. Also, the
ARM7TDMI core (and the ARM core before it) can't really disassemble
because the PC address used for instruction execution is not known prior
to calling instruction(), due to pipeline reload fetches that may occur
inside of said function. I had a nasty hack for debugging the new core,
but I'd like to come up with a clean way to allow tracing the new
ARM7TDMI core.
Another is that I'd still like to rename a lot of instruction function
names in various cores to be more descriptive. I really liked how the
LR35902 core came out there, and would like to get that level of detail
in with the other cores as well.
byuu says:
Changelog:
- processor/arm7tdmi: completed implemented
- gba/cpu, sfc/coprocessor/armdsp: use arm7tdmi instead of arm
- sfc/cpu: experimental fix for newly discovered HDMA emulation issue
Notes:
The ARM7TDMI core crashes pretty quickly when trying to run GBA games,
and I'm certain the same will be the case with the ST018. It was never
all that likely I could rewrite 70KiB of code in 20 hours and have it
work perfectly on the first try. So, now it's time for lots and lots of
debugging. Any help would *really* be appreciated, if anyone were up for
comparing the two implementations for regressions =^-^= I often have a
really hard time spotting simple typos that I make.
Also, the SNES HDMA fix is temporary. I would like it if testers could
run through a bunch of games that are known for being tricky with HDMA
(or if these aren't known to said tester, any games are fine then.) If
we can confirm regressions, then we'll know the fix is either incorrect
or incomplete. But if we don't find any, then it's a good sign that
we're on the right path.
byuu says:
Changelog:
- processor/arm7tdmi: implementation all nine remaining ARM
instructions
- processor/arm7tdmi: implemented five more THUMB instructions
(sixteen remain)
byuu says:
Changelog:
- processor/arm7tdmi: implemented 10 of 19 ARM instructions
- processor/arm7tdmi: implemented 1 of 22 THUMB instructions
Today's WIP was 6 hours of work, and yesterday's was 5 hours.
Half of today was just trying to come up with the design to use a
lambda-based dispatcher to map both instructions and disassembly,
similar to the 68K core. The problem is that the ARM core has 28 unique
bits, which is just far too many bits to have a full lookup table like
the 16-bit 68K core.
The thing I wanted more than anything else was to perform the opcode
bitfield decoding once, and have it decoded for both instructions and
the disassembler. It took three hours to come up with a design that
worked for the ARM half ... relying on #defines being able to pull in
other #defines that were declared and changed later after the first
one. But, I'm happy with it. The decoding is in the table building, as
it is with the 68K core. The decoding does happen at run-time on each
instruction invocation, but it has to be done.
As to the THUMB core, I can create a 64K-entry lambda table to cover all
possible encodings, and ... even though it's a cache killer, I've
decided to go for it, given the outstanding performance it obtained in
the M68K core, as well as considering that THUMB mode is far more common
in GBA games.
As to both cores ... I'm a little torn between two extremes:
On the one hand, I can condense the number of ARM/THUMB instructions
further to eliminate more redundant code. On the other, I can split them
apart to reduce the number of conditional tests needed to execute each
instruction. It's really the disassembler that makes me not want to
split them up further ... as I have to split the disassembler functions
up equally to the instruction functions. But it may be worth it if it's
a speed improvement.
byuu says:
Changelog:
- hiro/windows: set dpiAware=false, fixes icarus window sizes relative
to higan window sizes
- higan, icarus, hiro, ruby: add support for high resolution displays
on macOS [ncbncb]
- processor/lr35902-legacy: removed
- processor/arm7tdmi: new processor core started; intended to one day
be a replacement for processor/arm
It will probably take several WIPs to get the new ARM core up and
running. It's the last processor rewrite. After this, all processor
cores will be up to date with all my current programming conventions.
byuu says:
Changelog:
- processor/lr35902: completed rewrite
I'd appreciate regression testing of the Game Boy and Game Boy Color
emulation between v103r24 and v103r26 (skip r25) if anyone wouldn't
mind.
I fixed up processor/lr35902-legacy to compile and run, so that trace
logs can be created between the two cores to find errors. I'm going to
kill processor/lr35902-legacy with the next WIP release, as well as make
changes to the trace format (add flags externally from AF; much easier
to read them that way), which will make it more difficult to do these
comparisons in the future, hence r26 may prove important later on if we
miss regressions this time.
As for the speed of the new CPU core, not too much to report ... at
least it's not slower :)
Mega Man II: 212.5 to 214.5fps
Shiro no Sho: 191.5 to 191.5fps
Oracle of Ages: 182.5 to 190.5fps
byuu says:
Changelog:
- gb/cpu: force STAT mode to 0 when LCD is disabled (fixes Pokemon
Pinball, etc)
- gb/ppu: when LCD is disabled, require at least one-frame wait to
re-enable, display white during this time
- todo: should step by a scanline at a time: worst-case is an
extra 99% of a frame to enable again
- gba/ppu: cache tilemap lookups and attribute parsing
- it's more accurate because the GBA wouldn't read this for every
pixel
- but unfortunately, this didn't provide any speedup at all ...
sigh
- ruby/audio/alsa: fixed const issue with free()
- ruby/video/cgl: removed `glDisable(GL_ALPHA_TEST)` [deprecated]
- ruby/video/cgl: removed `glEnable(GL_TEXTURE_2D)` [unnecessary as
we use shaders]
- processor/lr35902: started rewrite¹
¹: so, the Game Boy and Game Boy Color cores will be completely
broken for at least the next two or three WIPs.
The old LR35902 was complete garbage, written in early 2011. So I'm
rewriting it to provide a massive cleanup and consistency with other
processor cores, especially the Z80 core.
I've got about 85% of the main instructions implemented, and then I have
to do the CB instructions. The CB instructions are easier because
they're mostly just a small number of opcodes in many small variations,
but it'll still be tedious.
byuu says:
Changelog:
- gb/mbc6: mapper is now functional, but Net de Get has some text
corruption¹
- gb/mbc7: mapper is now functional²
- gb/cpu: HDMA syncs other components after each byte transfer now
- gb/ppu: LY,LX forced to zero when LCDC.d7 is lowered (eg disabled),
not when it's raised (eg enabled)
- gb/ppu: the LCD does not run at all when LCDC.d7 is clear³
- fixes graphical corruption between scene transitions in Legend
of Zelda - Oracle of Ages
- thanks to Cydrak, Shonumi, gekkio for their input on the cause
of this issue
- md/controller: renamed "Gamepad" to "Control Pad" per official
terminology
- md/controller: added "Fighting Pad" (6-button controller) emulation
[hex\_usr]
- processor/m68k: fixed TAS to set data.d7 when
EA.mode==DataRegisterDirect; fixes Asterix
- hiro/windows: removed carriage returns from mouse.cpp and
desktop.cpp
- ruby/audio/alsa: added device driver selection [SuperMikeMan]
- ruby/audio/ao: set format.matrix=nullptr to prevent a crash on some
systems [SuperMikeMan]
- ruby/video/cgl: rename term() to terminate() to fix a crash on macOS
[Sintendo]
¹: The observation that this mapper split $4000-7fff into two banks
came from MAME's implementation. But their implementation was quite
broken and incomplete, so I didn't actually use any of it. The
observation that this mapper split $a000-bfff into two banks came from
Tauwasser, and I did directly use that information, plus the knowledge
that $0400/$0800 are the RAM bank select registers.
The text corruption is due to a race condition with timing. The game is
transferring font letters via HDMA, but the game code ends up setting
the bank# with the font a bit too late after the HDMA has already
occurred. I'm not sure how to fix this ... as a whole, I assumed my Game
Boy timing was pretty good, but apparently it's not that good.
²: The entire design of this mapper comes from endrift's notes.
endrift gets full credit for higan being able to emulate this mapper.
Note that the accelerometer implementation is still not tested, and
probably won't work right until I tweak the sensitivity a lot.
³: So the fun part of this is ... it breaks the strict 60fps rate of
the Game Boy. This was always inevitable: certain timing conditions can
stretch frames, too. But this is pretty much an absolute deal breaker
for something like Vsync timing. This pretty much requires adaptive sync
to run well without audio stuttering during the transition.
There's currently one very important detail missing: when the LCD is
turned off, presumably the image on the screen fades to white. I do not
know how long this process takes, or how to really go about emulating
it. Right now as an incomplete patch, I'm simply leaving the last
displayed image on the screen until the LCD is turned on again. But I
will have to output white, as well as add code to break out of the
emulation loop periodically when the LCD is left off eg indefinitely, or
bad things would happen. I'll work something out and then implement.
Another detail is I'm not sure how long it takes for the LCD to start
rendering again once enabled. Right now, it's immediate. I've heard it's
as long as 1/60th of a second, but that really seems incredibly
excessive? I'd like to know at least a reasonably well-supported
estimate before I implement that.
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:
- ruby: ported all remaining drivers to new API¹
- ruby/wasapi: fix for dropping one sample per period [SuperMikeMan]
- gb: emulated most of the TAMA RTC; but RTC state is still volatile²
¹: the new ports are:
- audio/{directsound, alsa, pulseaudio, pulseaudiosimple, ao}
- input/{udev, quartz, carbon}
It's pretty much guaranteed many of them will have compilation errors.
Please paste the error logs and I'll try to fix them up. It may take a
WIP or two to get there.
It's also possible things broke from the updates. If so, I could use
help comparing the old file to the new file, looking for mistakes, since
I can't test on these platforms apart from audio/directsound.
Please report working drivers in this list, so we can mark them off the
list. I'll need both macOS and Linux testers.
audio/directsound.cpp:112:
if(DirectSoundCreate(0, &_interface, 0) != DS_OK) return terminate(), false;
²: once I get this working, I'll add load/save support for the RTC
values. For now, the RTC data will be lost when you close the emulator.
Right now, you can set the date/time in real-time mode, and when you
start the game, the time will be correct, and the time will tick
forward. Note that it runs off emulated time instead of actual real
time, so if you fast-forward to 300%, one minute will be 20 seconds.
The really big limitation right now is that when you exit the game, and
restart it, and resume a new game, the hour spot gets corrupted, and
this seems to instantly kill your pet. Fun. This is crazy because the
commands the game sends to the TAMA interface are identical between
starting a new game and getting in-game versus loading a game.
It's likely going to require disassembling the game's code and seeing
what in the hell it's doing, but I am extremely bad at LR35092 assembly.
Hopefully endrift can help here :|
byuu says:
Changelog:
- gb: added TAMA emulation [thanks to endrift for the initial notes]
- gb: save RTC memory to disk (MBC3 doesn't write to said memory yet;
TAMA doesn't emulate it yet)
- gb: expect MMM01 boot loader to be at end of ROM instead of start
- gb: store MBC2 save RAM as 256-bytes (512x4-bit) instead of
512-bytes (with padding)
- gb: major cleanups to every cartridge mapper; moved to Mapper class
instead of MMIO class
- gb: don't serialize all mapper states with every save state; only
serialize the active mapper
- gb: serialize RAM even if a battery isn't present¹
- gb/cartridge: removed unnecessary code; refactored other code to
eliminate duplication of functions
- icarus: improve GB(C) heuristics generation to not include filenames
for cartridges without battery backup
- icarus: remove incorrect rearrangement of MMM01 ROM data
- md/vdp: fix CRAM reads -- fixes Sonic Spinball colors [hex\_usr]
- tomoko: hide the main higan window when entering fullscreen
exclusive mode; helps with multi-monitor setups
- tomoko: destroy ruby drivers before calling Application::quit()
[Screwtape]
- libco: add settings.h and defines to fiber, ucontext [Screwtape]
¹: this is one of those crystal clear indications that nobody's
actually playing the higan DMG/CGB cores, or at least not with save
states. This was a major mistake.
Note: I can't find any official documentation that `GL_ALPHA_TEST` was
removed from OpenGL 3.2. Since it's not hurting anything except showing
some warnings in debug mode, I'm just going to leave it there for now.
byuu says:
Changelog:
- ruby/audio/xaudio2: ported to new ruby API
- ruby/video/cgl: ported to new ruby API (untested, won't compile)
- ruby/video/directdraw: ported to new ruby API
- ruby/video/gdi: ported to new ruby API
- ruby/video/glx: ported to new ruby API
- ruby/video/wgl: ported to new ruby API
- ruby/video/opengl: code cleanups
The macOS CGL driver is sure to have compilation errors. If someone will
post the compilation error log, I can hopefully fix it in one or two
iterations of WIPs.
I am unable to test the Xorg GLX driver, because my FreeBSD desktop
video card drivers do not support OpenGL 3.2. If the driver doesn't
work, I'm going to need help tracking down what broke from the older
releases.
The real fun is still yet to come ... all the Linux-only drivers, where
I don't have a single Linux machine to test with.
Todo:
- libco/fiber
- libco/ucontext (I should really just delete this)
- tomoko: hide main UI window when in exclusive fullscreen mode
byuu says:
Changelog:
- tomoko: Application::onMain assigned at end of Program::Program()
[Screwtape]¹
- libco: add `#define _XOPEN_SOURCE 500` to fix compilation of sjlj.c
[Screwtape]
- ruby/audio/openal: fixed device driver string list enumeration
- ruby/audio/wasapi: changing device re-initializes the driver now
- ruby/audio/wasapi: probably a pointless change, but don't fill the
buffer beyond the queue size with silence
- ruby/video/xvideo: renamed from ruby/video/xv
- ruby/video/xvideo: check to see if `XV_AUTOPAINT_COLORKEY` exists
before setting it [SuperMikeMan]
- ruby/video/xvideo: align buffer sizes to be evenly divisible by four
[SuperMikeMan]
- ruby/video/xvideo: fail nicely without crashing (hopefully)
- ruby/video/xvideo: add support for YV12 and I420 12-bit planar YUV
formats²
¹: prevents crashes when drivers fail to initialize from running the
main loop that polls input drivers before the input driver is
initialized (or fails to initialize itself.) Some drivers still don't
block their main functions when initialization fails, so they will still
crash, but I'll work to fix them.
²: this was a **major** pain in the ass, heh. You only get one chroma
sample for every four luma samples, so the color reproduction is even
worse than UYVY and YUYV (which is two to four chroma to luma.) Further,
the planar format took forever to figure out. Apparently it doesn't care
what portion of the image you specify in XvShmPutImage, it expects you
to use the buffer dimensions to locate the U and V portions of the data.
This is probably the most thorough X-Video driver in existence now.
Notes:
- forgot to rename the configuration settings dialog window title to
just "Settings"
byuu says:
Changelog:
- tomoko: improved handling of changing audio devices on the audio
settings panel
- ruby/audio/wasapi: added device enumeration and selection support¹
- ruby/audio/wasapi: release property store handle from audio device
- ruby/audio/wasapi: fix exclusive mode buffer filling
- ruby/video/glx2: ported to new API -- tested and confirmed working
great²
- ruby/video/sdl: fixed initialization -- tested and confirmed working
on FreeBSD now³
- ruby/video/xv: ported to new API -- tested and mostly working great,
sans fullscreen mode⁴
Errata:
- accidentally changed "Driver Settings" label to "Driver" on the
audio settings tab because I deleted the line and forgot the
"Settings" part
- need to use "return initialize();" from setDevice() in the WASAPI
driver, instead of "return true;", so device selection is currently
not functioning in this WIP for said driver
¹: for now, this will likely end up selecting the first available
endpoint device, which is probably wrong. I need to come up with a
system to expose good 'default values' when selecting new audio drivers,
or changing audio device settings.
²: glx2 is a fallback driver for system with only OpenGL 2.0 and no
OpenGL 3.2 drivers, such as FreeBSD 10.1 with AMD graphics cards.
³: although I really should track down why InputManager::poll() is
crashing the emulator when Video::ready() returns false ...
⁴: really bizarrely, when entering fullscreen mode, it looks like the
image was a triangle strip, and the bottom right triange is missing, and
the top left triangle skews the entire image into it. I'm suspecting
this is a Radeon driver bug when trying to create a 2560x1600 X-Video
surface. The glitch persists when exiting fullscreen, too.
If anyone can test the X-Video driver on their Linux/BSD system, it'd be
appreciated. If it's just my video card, I'll ignore it. If not,
hopefully someone can find the cause of the issue :|
byuu says:
Changelog:
- tomoko: re-hid the video sync option¹
- tomoko: removed " Settings" duplication on all the individual
settings tab options
- ruby/audio/wasapi: finished port to new syntax; adapted to an
event-driven model; support 32-bit integral audio²
- ruby/video/sdl: ported to new syntax; disabled driver on FreeBSD³
¹: still contemplating a synchronize submenu of {none, video, audio},
but ... the fact that video can't work on PAL, WonderSwan games is a
real limitation for it
²: this driver actually received a ton of work. There's also a new
ring-buffer queue, and I added special handling for when exclusive mode
fails because the latency requested is lower than the hardware can
support. It'll pick the closest latency to the minimum that is possible
in this case.
On my Audigy Rx, the results for non-exclusive mode are the same. For
exclusive mode, the framerate drops from 60fps to ~50fps for smaller
buffers, and ~55fps for larger buffers (no matter how big, it never hits
60fps.) This is a lot better than before where it was hitting ~15fps,
but unfortunately it's the best I can do.
The event system used by WASAPI is really stupid. It just uses SetEvent
at some arbitrary time, and you have to query to see how many samples
it's waiting on. This makes it unknowable how many samples we should
buffer before calling `WaitForSingleObject(INFINITE)`, and it's also
unclear how we should handle cases where there's more samples available
than our queue has: either we can fill it with zeroes, or we can write
less samples. The former should prevent audio looping effects when
running too slowly, whereas the latter could potentially be too
ambitious when the audio could've recovered from a minor stall.
It's shocking to me how there's as many ways to send audio to a sound
card as there are sound card APIs, when all that's needed is a simple
double buffer and a callback event from another thread to do it right.
It's also terrifying how unbelievably shitty nearly all sound card
drivers apparently are.
Also, I don't know if cards can output an actual 24-bit mode with three
byte audio samples, or if they always just take 32-bit samples and
ignore the lower 8-bits. Whatever, it's all nonsense for the final
output to be >16-bits anyway (hi, `double[]` input from ruby.)
³: unfortunately, this driver always crashes on FreeBSD (even before
the rewrite), so I'll need someone on Linux to test it and make sure it
actually works. I'll also need testing for a lot of the other drivers as
well, once they're ported over (I don't have X-video, PulseAudio, ALSA,
or udev.)
Note that I forgot to set `_ready=true` at the end of `initialize()`,
and `_ready=false` in `terminate()`, but it shouldn't actually matter
beyond showing you a false warning message on startup about it failing
to initialize.
byuu says:
Changelog:
- emulator/audio: added the ability to change the output frequency at
run-time without emulator reset
- tomoko: display video synchronize option again¹
- tomoko: Settings→Configuration expanded to Settings→{Video,
Audio, Input, Hotkey, Advanced} Settings²
- tomoko: fix default population of audio settings tab
- ruby: Audio::frequency is a double now (to match both
Emulator::Audio and ASIO)³
- tomoko: changing the audio device will repopulate the frequency and
latency lists
- tomoko: changing the audio frequency can now be done in real-time
- ruby/audio/asio: added missing device() information, so devices can
be changed now
- ruby/audio/openal: ported to new API; added device selection support
- ruby/audio/wasapi: ported to new API, but did not test yet (it's
assuredly still broken)⁴
¹: I'm uneasy about this ... but, I guess if people want to disable
audio and just have smooth scrolling video ... so be it. With
Screwtape's documentation, hopefully that'll help people understand that
video synchronization always breaks audio synchronization. I may change
this to a child menu that lets you pick between {no synchronization,
video synchronization, audio synchronization} as a radio selection.
²: given how much more useful the video and audio tabs are now, I
felt that four extra menu items were worth saving a click and going
right to the tab you want. This also matches the behavior of the Tools
menu displaying all tool options and taking you directly to each tab.
This is kind of a hard change to get used to ... but I think it's for
the better.
³: kind of stupid because I've never seen a hardware sound card where
floor(frequency) != frequency, but whatever. Yay consistency.
⁴: I'm going to move it to be event-driven, and try to support 24-bit
sample formats if possible. Who knows which cards that'll fix and which
cards that'll break. I may end up making multiple WASAPI drivers so
people can find one that actually works for them. We'll see.
byuu says:
Changelog:
- ruby: rewrote the API interfaces for Video, Audio, Input
- ruby/audio: can now select the number of output channels (not useful
to higan, sorry)
- ruby/asio: various improvements
- tomoko: audio settings panel can now select separate audio devices
(for ASIO, OSS so far)
- tomoko: audio settings panel frequency and latency lists are
dynamically populated now
Note: due to the ruby API rewrite, most drivers will not compile. Right
now, the following work:
- video: Direct3D, XShm
- audio: ASIO, OSS
- input: Windows, SDL, Xlib
It takes a really long time to rewrite these (six hours to do the
above), so it's going to be a while before we're back at 100%
functionality again.
Errata:
- ASIO needs device(), setDevice()
- need to call setDevice() at program startup to populate
frequency/latency settings properly
- changing the device and/or frequency needs to update the emulator
resampler rates
The really hard part is going to be the last one: the only way to change
the emulator frequency is to flush all the audio streams and then
recompute all the coefficients for the resamplers. If this is called
during emulation, all audio streams will be erased and thus no sound
will be output. I'll most likely be forced to simply ignore
device/frequency changes until the user loads another game. It is at
least possible to toggle the latency dynamically.
byuu says:
Changelog:
- tomoko: by popular choice, default to adaptive mode on new installs
- hiro/windows: fix bug that was preventing the escape key from
closing some dialog windows
- nall/registry: use "\\\\" as separator instead of "/" ... because
some registry keys contain "/" in them >_>
- ruby: add ASIO driver stub (so far it can only initialize and grab
the driver name/version information)
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:
- ruby/video: cleaned up Direct3D9 driver and fixed catastrophic
memory leak
- ruby/video: added fullscreen exclusive mode support to the Direct3D9
driver¹
- ruby/video: minor cosmetic code cleanups to various drivers
- tomoko: added support to always allow input when in fullscreen
exclusive mode
- tomoko: fixed window to not remove resizability flag when exiting
fullscreen mode
¹: I am assuming that exclusive mode will try to capture the primary
monitor. I don't know what will happen in multi-monitor setups, however,
as I don't use such a setup here.
Also, I am using `D3DPRESENT_DISCARD` instead of `D3DPRESENT_FLIP`. I'm
not sure if this will prove better or worse, but I've heard it will
waste less memory, and having a BackBufferCount of 1 should still result
in page flipping anyway. The difference is supposedly just that you
can't rely on the back buffer being a valid copy of the previous frame
like you can with FLIP.
Lastly, if you want Vsync, you can edit the configuration file to enable
that, and then turn off audio sync.
Errata: "pause emulation when focus is lost" is not working with
exclusive mode. I need to add a check to never auto-pause when in
exclusive mode. Thanks to bun for catching that one.
byuu says:
Changelog:
- tomoko: removed "Settings→Video Emulation→Overscan Mask" setting¹
- tomoko: remove a few unnecessary calls to resizeViewport on startup
- tomoko: only resize main window from video settings when in adaptive
or toggling adaptive mode²
- hiro/windows: add `SWP_NOACTIVATE` flag to prevent focus stealing on
resizing invisible windows³
- hiro/windows: suppress spurious API-generated `onSize()` callback
when calling `setVisible()`
¹: it just seemed like bad design to default to overscan masking
being disabled with overscan masks of 8 horizontal, 8 vertical out of
the box. Users would adjust the sliders and not see anything happening.
Instead, I've set the default masks to zero. If you want to turn off
overscan masking, simply slide those to zero again.
²: I figure the only way we're going to be able to fairly evaluate
Screwtape's suggestion is to try it both ways. And I will admit, I kind
of like the way this works as well ... a lot more so than I thought I
would, so I think it was a great suggestion. Still, now's the time if
people have strong opinions on this. Be sure to try both r10 and r11 to
compare. Barring no other feedback, I'm going to keep it this way.
³: this fixes the blinking of the main window on startup.
Screwtape, thanks again for the improvement suggestions. At this point
though, I am not using a tiling window manager. If you are able to patch
hiro/gtk and/or hiro/qt (I mostly use GTK) to work with tiling window
managers better, I wouldn't mind applying said patches, so long as they
don't break things on my own Xfce desktop with xfwm4.
Also, I noticed one issue with Xfce ... if the window is maximized and I
try to call `Window::setSize()`, it's not actually removing the maximize
flag. We'll need to look into how to add that to GTK, but I don't think
it's a huge issue. A similar glitch happens on windows where the icon
still reflects being maximized, but it does actually shrink, it just
sticks to the top left corner of the screen. So this isn't really a
critical bug, but would be extra polish.