mirror of https://github.com/bsnes-emu/bsnes.git
74 Commits
Author | SHA1 | Message | Date |
---|---|---|---|
Tim Allen | 0b4e7fb5a5 |
Update to v103r17 release.
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. |
|
Tim Allen | f87c6b7ecb |
Update to v103r16 release.
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. |
|
Tim Allen | 4129630d97 |
Update to v103r15 release.
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. |
|
Tim Allen | 17697317d4 |
Update to v103r14 release.
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) |
|
Tim Allen | ed5ec58595 |
Update to v103r13 release.
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 >_> |
|
Tim Allen | 434e303ffb |
Update to v103r12 release.
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. |
|
Tim Allen | ee982f098a |
Update to v103r11 release.
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. |
|
Tim Allen | cbbf5ec114 |
Update to v103r10 release.
byuu says: Changelog: - tomoko: video scaling options are now resolutions in the configuration file, eg "640x480", "960x720", "1280x960" - tomoko: main window is now always resizable instead of fixed width (also supports maximizing) - tomoko: added support for non-integral scaling in windowed mode - tomoko: made the quick/managed state messaging more consistent - tomoko: hide "Find Codes ..." button from the cheat editor window if the cheat database is not present - tomoko: per-game cheats.bml file now goes into the higan/ subfolder instead of the root folder So the way the new video system works is you have the following options on the video settings panel: Windowed mode: { Aspect correction, Integral scaling, Adaptive } Fullscreen mode: { Aspect correction, Integral scaling } (and one day, hopefully Exclusive will be added here) Whenever you adjust the overscan masking, or you change any of the windowed or fullscreen mode settings, or you choose a different video scale from the main menu, or you load a new game, or you unload a game, or you rotate the display of an emulated system, the resizeViewport logic will be invoked. This logic will remember the last option you chose for video scale, and base the new window size on that value as an upper limit of the new window size. If you are in windowed mode and have adaptive enabled, it will shrink the window to fit the contents of the emulated system's video output. Otherwise, if you are not in integral scaling mode, it will scale the video as large as possible to fit into the video scaled size you have selected. Otherwise, it will perform an integral scale and center the video inside of the viewport. If you are in fullscreen mode, it's much the same, only there is no adaptive mode. A major problem with Xorg is that it's basically impossible to change the resizability attribute of a window post-creation. You can do it, but all kinds of crazy issues start popping up. Like if you toggle fullscreen, then you'll find that the window won't grow past a certain fairly small size that it's already at, and cannot be shrunk. And the multipliers will stop expanding the window as large as they should. And sometimes the UI elements won't be placed in the correct position, or the video will draw over them. It's a big mess. So I have to keep the main window always resizable. Also, note that this is not a limitation of hiro. It's just totally broken in Xorg itself. No amount of fiddling has ever allowed this to work reliably for me on either GTK+ 2 or Qt 4. So what this means is ... the adaptive mode window is also resizable. What happens here is, whenever you drag the corners of the main window to resize it, or toggle the maximize window button, higan will bypass the video scale resizing code and instead act as though the adaptive scaling mode were disabled. So if integral scaling is checked, it'll begin scaling in integral mode. Otherwise, it'll begin scaling in non-integral mode. And because of this flexibility, it no longer made sense for the video scale menu to be a radio box. I know, it sucks to not see what the active selection is anymore, but ... say you set the scale to small, then you accidentally resized the window a little, but want it snapped back to the proper small resolution dimensions. If it were a radio item, you couldn't reselect the same option again, because it's already active and events don't propagate in said case. By turning them into regular menu options, the video scale menu can be used to restore window sizing. Errata: On Windows, the main window blinks a few times on first load. The fix for that is a safeguard in the video settings code, roughly like so ... but note you'd need to make a few other changes for this to work against v103r10: auto VideoSettings::updateViewport(bool firstRun) -> void { settings["Video/Overscan/Horizontal"].setValue(horizontalMaskSlider.position()); settings["Video/Overscan/Vertical"].setValue(verticalMaskSlider.position()); settings["Video/Windowed/AspectCorrection"].setValue(windowedModeAspectCorrection.checked()); settings["Video/Windowed/IntegralScaling"].setValue(windowedModeIntegralScaling.checked()); settings["Video/Windowed/AdaptiveSizing"].setValue(windowedModeAdaptiveSizing.checked()); settings["Video/Fullscreen/AspectCorrection"].setValue(fullscreenModeAspectCorrection.checked()); settings["Video/Fullscreen/IntegralScaling"].setValue(fullscreenModeIntegralScaling.checked()); horizontalMaskValue.setText({horizontalMaskSlider.position()}); verticalMaskValue.setText({verticalMaskSlider.position()}); if(!firstRun) presentation->resizeViewport(); } That'll get it down to one blink, as with v103 official. Not sure I can eliminate that one extra blink. I forgot to remove the setResizable toggle on fullscreen mode exit. On Windows, the main window will end up unresizable after toggling fullscreen. I missed that one because like I said, toggling resizability is totally broken on Xorg. You can fix that with the below change: auto Presentation::toggleFullScreen() -> void { if(!fullScreen()) { menuBar.setVisible(false); statusBar.setVisible(false); //setResizable(true); setFullScreen(true); if(!input->acquired()) input->acquire(); } else { if(input->acquired()) input->release(); setFullScreen(false); //setResizable(false); menuBar.setVisible(true); statusBar.setVisible(settings["UserInterface/ShowStatusBar"].boolean()); } resizeViewport(); } Windows is stealing focus on calls to resizeViewport(), so we need to deal with that somehow ... I'm not really concerned about the behavior of shrinking the viewport below the smallest multiplier for a given system. It might make sense to snap it to the window size and forego all other scaling, but honestly ... meh. I don't really care. Nobody sane is going to play like that. |
|
Tim Allen | 7af270aa59 |
Update to v103r09 release.
byuu says: Changelog: - gba/apu: fixed wave RAM nibble ordering (fixes audio in Castlevania, PocketNES) - emulator: restructured video information to just a single videoResolution() → VideoResolution function - returns "projected size" (between 160x144 and 320x240) - "internal buffer size" (up to 1280x480) - returns aspect correction multiplier that is to be applied to the width field - the value could be < 1.0 to handle systems with taller pixels; although higan doesn't emulate such a system - tomoko: all calculations for scaling and overscan masking are done by the GUI now - tomoko: aspect correction can be enabled in either windowed or fullscreen mode separately; moved to Video settings panel - tomoko: video scaling multipliers (against 320x240) can now me modified from the default (2,3,4) via the configuration file - use this as a really barebones way of supporting high DPI monitors; although the GUI elements won't scale nicely - if you set a value less than two, or greater than your resolution divided by 320x240, it's your own fault when things blow up. I'm not babysitting anyone with advanced config-file only options. - tomoko: added new adaptive windowed mode - when enabled, the window will shrink to eliminate any black borders when loading a game or changing video settings. The window will not reposition itself. - tomoko: added new adaptive fullscreen mode - when enabled, the integral scaling will be disabled for fullscreen mode, forcing the video to fill at least one direction of the video monitor completely. I expect we will be bikeshedding for the next month on how to describe the new video options, where they should appear in the GUI, changes people want, etc ... but suffice to say, I'm happy with the functionality, so I don't intend to make changes to -what- things do, but I will entertain better ways to name things. |
|
Tim Allen | 191a71b291 |
Update to v103r08 release.
byuu says: Changelog: - emulator: improved aspect correction accuracy by using floating-point calculations - emulator: added videoCrop() function, extended videoSize() to take cropping parameters¹ - tomoko: the overscan masking function will now actually resize the viewport² - gba/cpu: fixed two-cycle delay on triggering DMAs; not running DMAs when the CPU is stopped - md/vdp: center video when overscan is disabled - pce/vce: resize video output from 1140x240 to 1120x240 - tomoko: resize window scaling from 326x240 to 320x240 - tomoko: changed save slot naming and status bar messages to indicate quick states vs managed states - tomoko: added increment/decrement quick state hotkeys - tomoko: save/load quick state hotkeys now save to slots 1-5 instead of always to 0 - tomoko: increased overscan range from 0-16 to 0-24 (in case you want to mask the Master System to 240x192) ¹: the idea here was to decouple raw pixels from overscan masking. Overscan was actually horrifically broken before. The Famicom outputs at 256x240, the Super Famicom at 512x480, and the Mega Drive at 1280x480. Before, a horizontal overscan mask of 8 would not reduce the Super Famicom or Mega Drive by nearly as much as the Famicom. WIth the new videoCrop() function, the internals of pixel size distortions can be handled by each individual core. ²: furthermore, by taking optional cropping information in videoSize(), games can scale even larger into the viewport window. So for example, before the Super Famicom could only scale to 1536x1440. But by cropping the vertical resolution by 6 (228p effectively, still more than NTSC can even show), I can now scale to 1792x1596. And wiht aspect correction, that becomes a perfect 8:7 ratio of 2048x1596, giving me perfectly crisp pixels without linear interpolation being required. Errata: for some reason, when I save a new managed state with the SFC core, the default description is being set to a string of what looks to be hex numbers. I found the cause ... I'll fix this in the next release. Note: I'd also like to hide the "find codes..." button if cheats.bml isn't present, as well as update the SMP TEST register comment from smp/timing.cpp |
|
Tim Allen | 561c6413a4 |
Update to v103 final release.
byuu says (in the public annoucement): With this release, PC Engine, Master System, Game Gear, Mega Drive and the newly added SuperGrafx support are now quite usable! They're far from the best emulators for these systems, but with many bugfixes, full sound emulation, and save state support ... many games are now fully playable with decent accuracy. The Game Boy Advance emulation is also now substantially improved with vastly improved sound quality and a new dot-based PPU renderer. With that change, every single component in higan is now cycle-based. Regrettably, these changes do carry a ~20% performance penalty compared to GBA emulation in v102. Changelog (since the previous release): - added SuperGrafx emulation - improved audio band-pass filtering for all emulated systems - screen rotation is now a hotkey; automatically rotates control bindings - screen rotation now supported on the Game Boy Advance as well (used by a small number of games) - massive improvements to Mega Drive emulation - massive code cleanups and rewrites to many CPU emulation cores (MOS6502, WDC65816, SPC700, etc) - Famicom, Master System, Mega Drive: added PAL emulation support - PC Engine, SuperGrafx, Master System, Game Gear, Mega Drive: added save state support - PC Engine, SuperGrafx: added PSG sound emulation - Master System, Game Gear: added PSG sound emulation - Mega Drive: added Z80 APU emulation [with help from Cydrak] - Mega Drive: added PSG sound emulation - Mega Drive: added YM2612 sound emulation [Cydrak] - Super Famicom: fixed Super Game Boy emulation - PC Engine: added save RAM support (using per-game PCE-CD backup RAM) - Game Boy Advance: substantial improvements to audio emulation quality - Game Boy Advance: convert scanline-based PPU renderer to a dot-based renderer - Game Boy Advance: properly initialize CPU state (fixes Classic NES Series games) - Game Boy Advance: MUL timing corrected [Jonas Quinn] - Mega Drive: emulate special mappers for Phantasy Star IV, Super Street Fighter II, etc. - Super Famicom: use darker luma for INIDISP=0 (large improvement to Final Fantasy III opening) - Super Famicom: fixed bugs in SMP OR1,AND1 instructions - cheat code database regrettably removed from official releases; will be made available separately - Famicom: PAL emulation improvements [hex\_usr] |
|
Tim Allen | b7006822bf |
Update to v103 WIP release.
byuu says (in the WIP forum): Changelog: - higan: cheat codes accept = and ? separators now - the new preferred code format is: address=value or address=if-match?value - the old code format of address/value and address/if-match/value will continue to work - higan: cheats.bml is no longer included with the base distribution - mightymo stopped updating it in 2015, and it's not source code; it can still be pulled in from older releases - fc: improved PAL mode timing; use PAL APU timing tables; fix PAL noise period table [hex\_usr] - md: support aborting a Z80 bus wait in order to capture save states without freezing - note that this will violate accuracy; but in practice a slight desync is better than an emulator deadlock - sfc: revert DSP ENDX randomization for now (want to research it more before deploying in an official release) - sfc: fix Super Famicom.sys/manifest.bml APU RAM size [hex\_usr] - tomoko: cleaned up make install rules - hiro/cocoa: use ABGR for pixel data [Sintendo] Note: I forgot to change the command-line and drag-and-drop separator from : to | in this WIP. However, it is corrected in the v103 official binary and source published on download.byuu.org. Sorry about that, I know it makes the Git repository history more difficult. I'm not concerned whether the : → | change is part of v103 or v103r01 in the repository, and will leave this to your discretion, Screwtape. I also still need to set the VDP bit to indicate PAL mode in the Mega Drive core. This is what happens when I have 47 things I have to do, given how lousy my memory is. I miss things. |
|
Tim Allen | 8476f35153 |
Update to v102r28 release.
byuu says: Changelog: - higan: `Emulator::<Platform::load>()` now returns a struct containing both a path ID and a string option - higan: `Emulator::<Platform::load>()` now takes an optional final argument of string options - fc: added PAL emulation (finally, only took six years) - md: added PAL emulation - md: fixed address parameter to `VDP::Sprite::write()`; fixes missing sprites in Super Street Fighter II - md: emulated HIRQ counter; fixes many games - Super Street Fighter II - status bar - Altered Beast - status bar - Sonic the Hedgehog - Labyrinth Zone - water effect - etc. - ms: added PAL emulation - sfc: added the ability to override the default region auto-detection - sfc: removed "system.region" override setting from `Super Famicom.sys` - tomoko: added options list to game folder load dialog window - tomoko: added the ability to specify game folder load options on the command-line So, basically ... Sega forced a change with the way region detection works. You end up with games that can run on multiple regions, and the content changes accordingly. Bare Knuckle in NTSC-J mode will become Streets of Rage in NTSC-U mode. Some games can even run in both NTSC and PAL mode. In my view, there should be a separate ROM for each region a game was released in, even if the ROM content were identical. But unfortunately that's not how things were done by anyone else. So to support this, the higan load dialog now has a drop-down at the bottom-right, where you can choose the region to load games from. On the SNES, it defaults to "Auto", which will pull the region setting from the manifest, or fall back on NTSC. On the Mega Drive ... unfortunately, I can't auto-detect the region from the ROM header. $1f0 is supposed to contain a string like "JUE", but instead you get games like Maui Mallard that put an "A" there, and other such nonsense. Sega was far more lax than Nintendo with the ROM header validity. So for now at least, you have to manually select your region every time you play a Mega Drive game, thus you have "NTSC-J", "NTSC-U", and "PAL". The same goes for the Master System for the same reason, but there's only "NTSC" and "PAL" here. I'm not sure if games have a way to detect domestic vs international consoles. And for now ... the Famicom is the same as well, with no auto-detection. I'd sincerely hope iNES has a header bit for the region, but I didn't bother with updating icarus to support that yet. The way to pass these parameters on the command-line is to prefix the game path with "option:", so for example: higan "PAL:/path/to/Sonic the Hedgehog (USA, Europe).md" If you don't provide a prefix, it uses the default (NTSC-J, NTSC, or Auto.) Obviously, it's not possible to pass parameters with drag-and-drop, so you will always get the default option in said case. |
|
Tim Allen | 8af3e4a6e2 |
Update to v102r22 release.
byuu says: Changelog: - higan: Emulator::Interface::videoSize() renamed to videoResolution() - higan: Emulator::Interface::rtcsync() renamed to rtcSynchronize() - higan: added video display rotation support to Video - GBA: substantially improved audio mixing - fixed bug with FIFO 50%/100% volume setting - now properly using SOUNDBIAS amplitude to control output frequencies - reduced quantization noise - corrected relative volumes between PSG and FIFO channels - both PSG and FIFO values cached based on amplitude; resulting in cleaner PCM samples - treating PSG volume=3 as 200% volume instead of 0% volume now (unverified: to match mGBA) - GBA: properly initialize ALL CPU state; including the vital prefetch.wait=1 (fixes Classic NES series games) - GBA: added video rotation with automatic key translation support - PCE: reduced output resolution scalar from 285x242 to 285x240 - the extra two scanlines won't be visible on most TVs; and they make all other cores look worse - this is because all other cores output at 240p or less; so they were all receiving black bars in windowed mode - tomoko: added "Rotate Display" hotkey setting - tomoko: changed hotkey multi-key logic to OR instead of AND - left support for flipping it back inside the core; for those so inclined; by uncommenting one line in input.hpp - tomoko: when choosing Settings→Configuration, it will automatically select the currently loaded system - for instance, if you're playing a Game Gear game, it'll take you to the Game Gear input settings - if no games are loaded, it will take you to the hotkeys panel instead - WS(C): merged "Hardware-Vertical", "Hardware-Horizontal" controls into combined "Hardware" - WS(C): converted rotation support from being inside the core to using Emulator::Video - this lets WS(C) video content scale larger now that it's not bounded by a 224x224 square box - WS(C): added automatic key rotation support - WS(C): removed emulator "Rotate" key (use the general hotkey instead; I recommend F8 for this) - nall: added serializer support for nall::Boolean (boolean) types - although I will probably prefer the usage of uint1 in most cases |
|
Tim Allen | a4629e1f64 |
Update to v102r21 release.
byuu says: Changelog: - GBA: fixed WININ2 reads, BG3PB writes [Jonas Quinn] - R65816: added support for yielding/resuming from WAI/STP¹ - SFC: removed status.dmaCounter functionality (also fixes possible TAS desync issue) - tomoko: added support for combinatorial inputs [hex\_usr\]² - nall: fixed missing return value from Arithmetic::operator-- [Hendricks266] Now would be the time to start looking for major regressions with the new GBA PPU renderer, I suppose ... ¹: this doesn't matter for the master thread (SNES CPU), but is important for slave threads (SNES SA1). If you try to save a state and the SA1 is inside of a WAI instruction, it will get stuck there forever. This was causing attempts to create a save state in Super Bomberman - Panic Bomber W to deadlock the emulator and crash it. This is now finally fixed. Note that I still need to implement similar functionality into the Mega Drive 68K and Z80 cores. They still have the possibility of deadlocking. The SNES implementation was more a dry-run test for this new functionality. This possible crashing bug in the Mega Drive core is the major blocking bug for a new official release. ²: many, many thanks to hex\_usr for coming up with a really nice design. I mostly implemented it the exact same way, but with a few tiny differences that don't really matter (display " and ", " or " instead of " & ", " | " in the input settings windows; append → bind; assignmentName changed to displayName.) The actual functionality is identical to the old higan v094 and earlier builds. Emulated digital inputs let you combine multiple possible keys to trigger the buttons. This is OR logic, so you can map to eg keyboard.up OR gamepad.up for instance. Emulated analog inputs always sum together. Emulated rumble outputs will cause all mapped devices to rumble, which is probably not at all useful but whatever. Hotkeys use AND logic, so you have to press every key mapped to trigger them. Useful for eg Ctrl+F to trigger fullscreen. Obviously, there are cases where OR logic would be nice for hotkeys, too. Eg if you want both F11 and your gamepad's guide button to trigger the fullscreen toggle. Unfortunately, this isn't supported, and likely won't ever be in tomoko. Something I might consider is a throw switch in the configuration file to swap between AND or OR logic for hotkeys, but I'm not going to allow construction of mappings like "(Keyboard.Ctrl and Keyboard.F) or Gamepad.Guide", as that's just too complicated to code, and too complicated to make a nice GUI to set up the mappings for. |
|
Tim Allen | ee7662a8be |
Update to v102r04 release.
byuu says: Changelog: - Super Game Boy support is functional once again - new GameBoy::SuperGameBoyInterface class - system.(dmg,cgb,sgb) is now Model::(Super)GameBoy(Color) ala the PC Engine - merged WonderSwanInterface, WonderSwanColorInterface shared functions to WonderSwan::Interface - merged GameBoyInterface, GameBoyColorInterface shared functions to GameBoy::Interface - Interface::unload() now calls Interface::save() for Master System, Game Gear, Mega Drive, PC Engine, SuperGrafx - PCE: emulated PCE-CD backup RAM; stored per-game as save.ram (2KiB file) - this means you can now save your progress in games like Neutopia - the PCE-CD I/O registers like BRAM write protect are not emulated yet - PCE: IRQ sources now hold the IRQ line state, instead of the CPU holding it - this fixes most SuperGrafx games, which were fighting over the VDC IRQ line previously - PCE: CPU I/O $14xx should return the pending IRQ bits even if IRQs are disabled - PCE: VCE and the VDCs now synchronize to each other; fixes pixel widths in all games - PCE: greatly increased the accuracy of the VPC priority selection code (windows may be buggy still) - HuC6280: PLA, PLX, PLY should set Z, N flags; fixes many game bugs [Jonas Quinn] The big thing I wanted to do was enslave the VDC(s) to the VCE. But unfortunately, I forgot about the asynchronous DMA channels that each VDC supports, so this isn't going to be possible I'm afraid. In the most demanding case, Daimakaimura in-game, we're looking at 85fps on my Xeon E3 1276v3. So ... not great, and we don't even have sound connected yet. We are going to have to profile and optimize this code once sound emulation and save states are in. Basically, think of it like this: the VCE, VDC0, and VDC1 all have the same overhead, scheduling wise (which is the bulk of the performance loss) as the dot-renderer for the SNES core. So it's like there's three bsnes-accuracy PPU threads running just for video. ----- Oh, just a fair warning ... the hooks for the SGB are a work in progress. If anyone is working on higan or a fork and want to do something similar to it, don't use it as a template, at least not yet. Right now, higan looks like this: - Emulator::Video handles the platform→videoRefresh calls - Emulator::Audio handles the platform→audioSample calls - each core hard-codes the platform→inputPoll, inputRumble calls - each core hard-codes calls to path, open, load to process files - dipSettings and notify are specialty hacks, neither are even hooked up right now to anything With the SGB, it's an emulation core inside an emulation core, so ideally you want to hook all of those functions. Emulator::Video and Emulator::Audio aren't really abstractions over that, as the GB core calls them and we have to special case not calling them in SGB mode. The path, open, load can be implemented without hooks, thanks to the UI only using one instance of Emulator::Platform for all cores. All we have to do is override the folder path ID for the "Game Boy.sys" folder, so that it picks "Super Game Boy.sfc/" and loads its boot ROM instead. That's just a simple argument to GameBoy::System::load() and we're done. dipSettings, notify and inputRumble don't matter. But we do also have to hook inputPoll as well. The nice idea would be for SuperFamicom::ICD2 to inherit from Emulator::Platform and provide the desired functions that we need to overload. After that, we'd just need the GB core to keep an abstraction over the global Emulator::platform\* handle, to select between the UI version and the SFC::ICD2 version. However ... that doesn't work because of Emulator::Video and Emulator::Audio. They would also have to gain an abstraction over Emulator::platform\*, and even worse ... you'd have to constantly swap between the two so that the SFC core uses the UI, and the GB core uses the ICD2. And so, for right now, I'm checking Model::SuperGameBoy() -> bool everywhere, and choosing between the UI and ICD2 targets that way. And as such, the ICD2 doesn't really need Emulator::Platform inheritance, although it certainly could do that and just use the functions it needs. But the SGB is even weirder, because we need additional new signals beyond just Emulator::Platform, like joypWrite(), etc. I'd also like to work on the Emulator::Stream for the SGB core. I don't see why we can't have the GB core create its own stream, and let the ICD2 just use that instead. We just have to be careful about the ICD2's CPU soft reset function, to make sure the GB core's Stream object remains valid. What I think that needs is a way to release an Emulator::Stream individually, rather than calling Emulator::Audio::reset() to do it. They are shared\_pointer objects, so I think if I added a destructor function to remove it from Emulator::Audio::streams, then that should work. |
|
Tim Allen | 186f008574 |
Update to v102r03 release.
byuu says: Changelog: - PCE: split VCE from VDC - HuC6280: changed bus from (uint21 addr) to (uint8 bank, uint13 addr) - added SuperGrafx emulation (adds secondary VDC, plus new VPC) The VDC now has no concept of the actual display raster timing, and instead is driven by Vpulse (start of frame) and Hpulse (start of scanline) signals from the VCE. One still can't render the start of the next scanline onto the current scanline through overly aggressive timings, but it shouldn't be too much more difficult to allow that to occur now. This process incurs quite a major speed hit, so low-end systems with Atom CPUs can't run things at 60fps anymore. The timing needs a lot of work. The pixels end up very jagged if the VCE doesn't output batches of 2-4 pixels at a time. But this should not be a requirement at all, so I'm not sure what's going wrong there. Yo, Bro and the 512-width mode of TV Sports Basketball is now broken as a result of these changes, and I'm not sure why. To load SuperGrafx games, you're going to have to change the .pce extensions to .sg or .sgx. Or you can manually move the games from the PC Engine folder to the SuperGrafx folder and change the game folder extensions. I have no way to tell the games apart. Mednafen uses CRC32 comparisons, and I may consider that since there's only five games, but I'm not sure yet. The only SuperGrafx game that's playable right now is Aldynes. And the priorities are all screwed up. I don't understand how the windows or the priorities work at all from sgxtech.txt, so ... yeah. It's pretty broken, but it's a start. I could really use some help with this, as I'm very lost right now with rendering :/ ----- Note that the SuperGrafx is technically its own system, it's not an add-on. As such, I'm giving it a separate .sys folder, and a separate library. There's debate over how to name this thing. "SuperGrafx" appears more popular than "Super Grafx". And you might also call it the "PC Engine SuperGrafx", but I decided to leave off the prefix so it appears more distinct. |
|
Tim Allen | bdc100e123 |
Update to v102r02 release.
byuu says: Changelog: - I caved on the `samples[] = {0.0}` thing, but I'm very unhappy about it - if it's really invalid C++, then GCC needs to stop accepting it in strict `-std=c++14` mode - Emulator::Interface::Information::resettable is gone - Emulator::Interface::reset() is gone - FC, SFC, MD cores updated to remove soft reset behavior - split GameBoy::Interface into GameBoyInterface, GameBoyColorInterface - split WonderSwan::Interface into WonderSwanInterface, WonderSwanColorInterface - PCE: fixed off-by-one scanline error [hex_usr] - PCE: temporary hack to prevent crashing when VDS is set to < 2 - hiro: Cocoa: removed (u)int(#) constants; converted (u)int(#) types to (u)int_(#)t types - icarus: replaced usage of unique with strip instead (so we don't mess up frameworks on macOS) - libco: added macOS-specific section marker [Ryphecha] So ... the major news this time is the removal of the soft reset behavior. This is a major!! change that results in a 100KiB diff file, and it's very prone to accidental mistakes!! If anyone is up for testing, or even better -- looking over the code changes between v102r01 and v102r02 and looking for any issues, please do so. Ideally we'll want to test every NES mapper type and every SNES coprocessor type by loading said games and power cycling to make sure the games are all cleanly resetting. It's too big of a change for me to cover there not being any issues on my own, but this is truly critical code, so yeah ... please help if you can. We technically lose a bit of hardware documentation here. The soft reset events do all kinds of interesting things in all kinds of different chips -- or at least they do on the SNES. This is obviously not ideal. But in the process of removing these portions of code, I found a few mistakes I had made previously. It simplifies resetting the system state a lot when not trying to have all the power() functions call the reset() functions to share partial functionality. In the future, the goal will be to come up with a way to add back in the soft reset behavior via keyboard binding as with the Master System core. What's going to have to happen is that the key binding will have to send a "reset pulse" to every emulated chip, and those chips are going to have to act independently to power() instead of reusing functionality. We'll get there eventually, but there's many things of vastly greater importance to work on right now, so it'll be a while. The information isn't lost ... we'll just have to pull it out of v102 when we are ready. Note that I left the SNES reset vector simulation code in, even though it's not possible to trigger, for the time being. Also ... the Super Game Boy core is still disconnected. To be honest, it totally slipped my mind when I released v102 that it wasn't connected again yet. This one's going to be pretty tricky to be honest. I'm thinking about making a third GameBoy::Interface class just for SGB, and coming up with some way of bypassing platform-> calls when in this mode. |
|
Tim Allen | c40e9754bc |
Update to v102r01 release.
byuu says: Changelog: - MS, MD, PCE: remove controllers from scheduler in destructor [hex_usr] - PCE: no controller should return all bits set (still causing errant key presses when swapping gamepads) - PCE: emulate MDR for hardware I/O $0800-$17ff - PCE: change video resolution to 1140x242 - PCE: added tertiary background Vscroll register (secondary cache) - PCE: create classes out of VDC VRAM, SATB, CRAM for cleaner access and I/O registers - PCE: high bits of CRAM read should be set - PCE: partially emulated VCE display registers: color frequency, HDS, HDW, VDS, VDW - PCE: 32-width sprites now split to two 16-width sprites to handle overflow properly - PCE: hopefully emulated sprite zero hit correctly (it's not well documented, and not often used) - PCE: trigger line coincidence interrupts during the previous scanline's Hblank period - tomoko: raise viewport from 320x240 to 326x242 to accommodate PC Engine's max resolution - nall: workaround for Clang compilation bug that can't figure out that a char is an integral data type |
|
Tim Allen | 26bd7590ad |
Update to v101r32 release.
byuu says: Changelog: - SMS: fixed controller connection bug - SMS: fixed Z80 reset bug - PCE: emulated HuC6280 MMU - PCE: emulated HuC6280 RAM - PCE: emulated HuCard ROM reading - PCE: implemented 178 instructions - tomoko: removed "soft reset" functionality - tomoko: moved "power cycle" to just above "unload" option I'm not sure of the exact number of HuC6280 instructions, but it's less than 260. Many of the ones I skipped are HuC6280-originals that I don't know how to emulate just yet. I'm also really unsure about the zero page stuff. I believe we should be adding 0x2000 to the addresses to hit page 1, which is supposed to be mapped to the zero page (RAM). But when I look at turboEMU's source, I have no clue how the hell it could possibly be doing that. It looks to be reading from page 0, which is almost always ROM, which would be ... really weird. I also don't know if I've emulated the T mode opcodes correctly or not. The documentation on them is really confusing. |
|
Tim Allen | bf90bdfcc8 |
Update to v101r31 release.
byuu says: Changelog: - converted Emulator::Interface::Bind to Emulator::Platform - temporarily disabled SGB hooks - SMS: emulated Game Gear palette (latching word-write behavior not implemented yet) - SMS: emulated Master System 'Reset' button, Game Gear 'Start' button - SMS: removed reset() functionality, driven by the mappable input now instead - SMS: split interface class in two: one for Master System, one for Game Gear - SMS: emulated Game Gear video cropping to 160x144 - PCE: started on HuC6280 CPU core—so far only registers, NOP instruction has been implemented Errata: - Super Game Boy support is broken and thus disabled - if you switch between Master System and Game Gear without restarting, bad things happen: - SMS→GG, no video output on the GG - GG→SMS, no input on the SMS I'm not sure what's causing the SMS\<-\>GG switch bug, having a hard time debugging it. Help would be very much appreciated, if anyone's up for it. Otherwise I'll keep trying to track it down on my end. |
|
Tim Allen | 0ad70a30f8 |
Update to v101r30 release.
byuu says: Changelog: - SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd) - SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics) - Z80: emulated "ex (sp),hl" instruction - Z80: fixed INx NF (should be set instead of cleared) - Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes walking in Wonder Boy) - SFC: removed Debugger and sfc/debugger.hpp - icarus: connected MS, GG, MD importing to the scan dialog - PCE: added emulation skeleton to higan and icarus At this point, Master System games are fairly highly compatible, sans audio. Game Gear games are running, but I need to crop the resolution and support the higher color palette that they can utilize. It's really something else the way they handled the resolution shrink on that thing. The last change is obviously going to be the biggest news. I'm very well aware it's not an ideal time to start on a new emulation core, with the MS and MD cores only just now coming to life with no audio support. But, for whatever reason, my heart's really set on working on the PC Engine. I wanted to write the final higan skeleton core, and get things ready so that whenever I'm in the mood to work on the PCE, I can do so. The skeleton is far and away the most tedious and obnoxious part of the emulator development, because it's basically all just lots of boilerplate templated code, lots of new files to create, etc. I really don't know how things are going to proceed ... but I can say with 99.9% certainty that this will be the final brand new core ever added to higan -- at least one written by me, that is. This was basically the last system from my childhood that I ever cared about. It's the last 2D system with games that I really enjoy playing. No other system is worth dividing my efforts and reducing the quality and amount of time to work on the systems I have. In the future, there will be potential for FDS, Mega CD and PCE-CD support. But those will all be add-ons, and they'll all be really difficult and challenge the entire design of higan's UI (it's entirely cartridge-driven at this time.) None of them will be entirely new cores like this one. |
|
Tim Allen | 5bdf55f08f |
Update to v101r25 release.
byuu says: Changelog: - SMS: emulated VDP mode 4 graphical output (background, sprites) - added $(windres) to icarus as well I'm sure the VDP emulation is still really, really buggy, but essentially I handle: - mode 4 rendering - background scrolling - background hscroll lock - background vscroll lock - background nametable relocation - sprite nametable relocation - sprite tiledata relocation - sprite 192-line y=0xd0 edge case (end sprite rendering) - sprite 8-pixel x-coordinate displacement - sprite extended size (height only in mode 4) - sprite overflow - sprite collision - left column masking - display disable - backdrop color - 192, 224, 240 height I do not support: - mode 2 rendering - sprite zoom - disallowing 240 height in NTSC mode - PAL mode - probably lots more |
|
Tim Allen | e30780bb72 |
Update to v101r25 release.
byuu says: Changelog: - Makefile: added $(windres), -lpthread to Windows port - GBA: WAITCNT.prefetch is not writable (should fix Donkey Kong: King of Swing) \[endrift\] - SMS: fixed hcounter shift value \[hex\_usr\] - SMS: emulated interrupts (reset button isn't hooked up anywhere, not sure where to put it yet) This WIP actually took a really long time because the documentation on SMS interrupts was all over the place. I'm hoping I've emulated them correctly, but I honestly have no idea. It's based off my best understanding from four or five different sources. So it's probably quite buggy. However, a few interrupts fire in Sonic the Hedgehog, so that's something to start with. Now I just have to hope I've gotten some games far enough in that I can start seeing some data in the VDP VRAM. I need that before I can start emulating graphics mode 4 to get some actual screen output. Or I can just say to hell with it and use a "Hello World" test ROM. That'd probably be smarter. |
|
Tim Allen | 4d2e17f9c0 |
Update to v101r09 release.
byuu says: Sorry, two WIPs in one day. Got excited and couldn't wait. Changelog: - ADDQ, SUBQ shouldn't update flags when targeting an address register - ADDA should sign extend effective address reads - JSR was pushing the PC too early - some improvements to 8-bit register reads on the VDP (still needs work) - added H/V counter reads to the VDP IO port region - icarus: added support for importing Master System and Game Gear ROMs - tomoko: added library sub-menus for each manufacturer - still need to sort Game Gear after Mega Drive somehow ... The sub-menu system actually isn't all that bad. It is indeed a bit more annoying, but not as annoying as I thought it was going to be. However, it looks a hell of a lot nicer now. |
|
Tim Allen | 043f6a8b33 |
Update to v101r08 release.
byuu says: Changelog: - 68K: fixed read-modify-write instructions - 68K: fixed ADDX bug (using wrong target) - 68K: fixed major bug with SUB using wrong argument ordering - 68K: fixed sign extension when reading address registers from effective addressing - 68K: fixed sign extension on CMPA, SUBA instructions - VDP: improved OAM sprite attribute table caching behavior - VDP: improved DMA fill operation behavior - added Master System / Game Gear stubs (needed for developing the Z80 core) |
|
Tim Allen | ffd150735b |
Update to v101r07 release.
byuu says: Added VDP sprite rendering. Can't get any games far enough in to see if it actually works. So in other words, it doesn't work at all and is 100% completely broken. Also added 68K exceptions and interrupts. So far only the VDP interrupt is present. It definitely seems to be firing in commercial games, so that's promising. But the implementation is almost certainly completely wrong. There is fuck all of nothing for documentation on how interrupts actually work. I had to find out the interrupt vector numbers from reading the comments from the Sonic the Hedgehog disassembly. I have literally no fucking clue what I0-I2 (3-bit integer priority value in the status register) is supposed to do. I know that Vblank=6, Hblank=4, Ext(gamepad)=2. I know that at reset, SR.I=7. I don't know if I'm supposed to block interrupts when I is >, >=, <, <= to the interrupt level. I don't know what level CPU exceptions are supposed to be. Also implemented VDP regular DMA. No idea if it works correctly since none of the commercial games run far enough to use it. So again, it's horribly broken for usre. Also improved VDP fill mode. But I don't understand how it takes byte-lengths when the bus is 16-bit. The transfer times indicate it's actually transferring at the same speed as the 68K->VDP copy, strongly suggesting it's actually doing 16-bit transfers at a time. In which case, what happens when you set an odd transfer length? Also, both DMA modes can now target VRAM, VSRAM, CRAM. Supposedly there's all kinds of weird shit going on when you target VSRAM, CRAM with VDP fill/copy modes, but whatever. Get to that later. Also implemented a very lazy preliminary wait mechanism to to stall out a processor while another processor exerts control over the bus. This one's going to be a major work in progress. For one, it totally breaks the model I use to do save states with libco. For another, I don't know if a 68K->VDP DMA instantly locks the CPU, or if it the CPU could actually keep running if it was executing out of RAM when it started the DMA transfer from ROM (eg it's a bus busy stall, not a hard chip stall.) That'll greatly change how I handle the waiting. Also, the OSS driver now supports Audio::Latency. Sound should be even lower latency now. On FreeBSD when set to 0ms, it's absolutely incredible. Cannot detect latency whatsoever. The Mario jump sound seems to happen at the very instant I hear my cherry blue keyswitch activate. |
|
Tim Allen | 427bac3011 |
Update to v101r06 release.
byuu says: I reworked the video sizing code. Ended up wasting five fucking hours fighting GTK. When you call `gtk_widget_set_size_request`, it doesn't actually happen then. This is kind of a big deal because when I then go to draw onto the viewport, the actual viewport child window is still the old size, so the image gets distorted. It recovers in a frame or so with emulation, but if we were to put a still image on there, it would stay distorted. The first thought is, `while(gtk_events_pending()) gtk_main_iteration_do(false);` right after the `set_size_request`. But nope, it tells you there's no events pending. So then you think, go deeper, use `XPending()` instead. Same thing, GTK hasn't actually issued the command to Xlib yet. So then you think, if the widget is realized, just call a blocking `gtk_main_iteration`. One call does nothing, two calls results in a deadlock on the second one ... do it before program startup, and the main window will never appear. Great. Oh, and it's not just the viewport. It's also the widget container area of the windows, as well as the window itself, as well as the fullscreen mode toggle effect. They all do this. For the latter three, I couldn't find anything that worked, so I just added 20ms loops of constantly calling `gtk_main_iteration_do(false)` after each one of those things. The downside here is toggling the status bar takes 40ms, so you'll see it and it'll feel a tiny bit sluggish. But I can't have a 20ms wait on each widget resize, that would be catastrophic to performance on windows with lots of widgets. I tried hooking configure-event and size-allocate, but they were very unreliable. So instead I ended up with a loop that waits up to a maximm of 20ms that inspects the `widget->allocation.(width,height)` values directly and waits for them to be what we asked for with `set_size_request`. There was some extreme ugliness in GTK with calling `gtk_main_iteration_do` recursively (`hiro::Widget::setGeometry` is called recursively), so I had to lock it to only happen on the top level widgets (the child ones should get resized while waiting on the top-level ones, so it should be fine in practice), and also only run it on realized widgets. Even still, I'm getting ~3 timeouts when opening the settings dialog in higan, but no other windows. But, this is the best I can do for now. And the reason for all of this pain? Yeah, updated the video code. So the Emulator::Interface now has this: struct VideoSize { uint width, height; }; //or requiem for a tuple auto videoSize() -> VideoSize; auto videoSize(uint width, uint height, bool arc) -> VideoSize; The first function, for now, is just returning the literal surface size. I may remove this ... one thing I want to allow for is cores that send different texture sizes based on interlace/hires/overscan/etc settings. The second function is more interesting. Instead of having the UI trying to figure out sizing, I figure the emulation cores can do a better job and we can customize it per-core now. So it gets the window's width and height, and whether the user asked for aspect correction, and then computes the best width/height ratio possible. For now they're all just doing multiples of a 1x scale to the UI 2x,3x,4x modes. We still need a third function, which will probably be what I repurpose videoSize() for: to return the 'effective' size for pixel shaders, to then feed into ruby, to then feed into quark, to then feed into our shaders. Since shaders use normalized coordinates for pixel fetching, this should work out just fine. The real texture size will be exposed to quark shaders as well, of course. Now for the main window ... it's just hard-coded to be 640x480, 960x720, 1280x960 for now. It works nicely for some cores on some modes, not so much for others. Work in progress I guess. I also took the opportunity to draw the about dialog box logo on the main window. Got a bit fancy and used the old spherical gradient and impose functionality of nall/image on it. Very minor highlight, nothing garish. Just something nicer than a solid black window. If you guys want to mess around with sizes, placements, and gradient styles/colors/shapes ... feel free. If you come up with something nicer, do share. That's what led to all the GTK hell ... the logo wasn't drawing right as you resized the window. But now it is, though I am not at all happy with the hacking I had to do. I also had to improve the video update code as a result of this: - when you unload a game, it blacks out the screen - if you are not quitting the emulator, it'll draw the logo; if you are, it won't - when you load a game, it black out the logo These options prevent any unsightliness from resizing the viewport with image data on it already I need to redraw the logo when toggling fullscreen with no game loaded as well for Windows, it seems. |
|
Tim Allen | 1df2549d18 |
Update to v101r04 release.
byuu says: Changelog: - pulled the (u)intN type aliases into higan instead of leaving them in nall - added 68K LINEA, LINEF hooks for illegal instructions - filled the rest of the 68K lambda table with generic instance of ILLEGAL - completed the 68K disassembler effective addressing modes - still unsure whether I should use An to decode absolute addresses or not - pro: way easier to read where accesses are taking place - con: requires An to be valid; so as a disassembler it does a poor job - making it optional: too much work; ick - added I/O decoding for the VDP command-port registers - added skeleton timing to all five processor cores - output at 1280x480 (needed for mixed 256/320 widths; and to handle interlace modes) The VDP, PSG, Z80, YM2612 are all stepping one clock at a time and syncing; which is the pathological worst case for libco. But they also have no logic inside of them. With all the above, I'm averaging around 250fps with just the 68K core actually functional, and the VDP doing a dumb "draw white pixels" loop. Still way too early to tell how this emulator is going to perform. Also, the 320x240 mode of the Genesis means that we don't need an aspect correction ratio. But we do need to ensure the output window is a multiple 320x240 so that the scale values work correctly. I was hard-coding aspect correction to stretch the window an additional \*8/7. But that won't work anymore so ... the main higan window is now 640x480, 960x720, or 1280x960. Toggling aspect correction only changes the video width inside the window. It's a bit jarring ... the window is a lot wider, more black space now for most modes. But for now, it is what it is. |
|
Tim Allen | e39987a3e3 |
Update to v101 release.
byuu says (in the public announcement): Not a large changelog this time, sorry. This release is mostly to fix the SA-1 issue, and to get some real-world testing of the new scheduler model. Most of the work in the past month has gone into writing a 68000 CPU core; yet it's still only about half-way finished. Changelog (since the previous release): - fixed SNES SA-1 IRQ regression (fixes Super Mario RPG level-up screen) - new scheduler for all emulator cores (precision of 2^-127) - icarus database adds nine new SNES games - added Input/Frequency to settings file (allows simulation of latency) byuu says (in the WIP forum): Changelog: - in 32-bit mode, Thread uses uint64\_t with 2^-63 time units (10^-7 precision in the worst case) - nearly ten times the precision of an attosecond - in 64-bit mode, Thread uses uint128\_t with 2^-127 time units (10^-26 precision in the worst case) - far more accurate than yoctoseconds; almost closing in on planck time Note: a quartz crystal is accurate to 10^-4 or 10^-5. A cesium fountain atomic clock is accurate to 10^-15. So ... yeah. 2^-63 was perfectly fine; but there was no speed penalty whatsoever for using uint128\_t in 64-bit mode, so why not? |
|
Tim Allen | f5e5bf1772 |
Update to v100r16 release.
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. |
|
Tim Allen | ca277cd5e8 |
Update to v100r14 release.
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. |
|
Tim Allen | 3dd1aa9c1b |
Update to v100r02 release.
byuu says: Sigh ... I'm really not a good person. I'm inherently selfish. My responsibility and obligation right now is to work on loki, and then on the Tengai Makyou Zero translation, and then on improving the Famicom emulation. And yet ... it's not what I really want to do. That shouldn't matter; I should work on my responsibilities first. Instead, I'm going to be a greedy, self-centered asshole, and work on what I really want to instead. I'm really sorry, guys. I'm sure this will make a few people happy, and probably upset even more people. I'm also making zero guarantees that this ever gets finished. As always, I wish I could keep these things secret, so if I fail / give up, I could just drop it with no shame. But I would have to cut everyone out of the WIP process completely to make it happen. So, here goes ... This WIP adds the initial skeleton for Sega Mega Drive / Genesis emulation. God help us. (minor note: apparently the new extension for Mega Drive games is .md, neat. That's what I chose for the folders too. I thought it was .smd, so that'll be fixed in icarus for the next WIP.) (aside: this is why I wanted to get v100 out. I didn't want this code in a skeleton state in v100's source. Nor did I want really broken emulation, which the first release is sure to be, tarring said release.) ... So, basically, I've been ruminating on the legacy I want to leave behind with higan. 3D systems are just plain out. I'm never going to support them. They're too complex for my abilities, and they would run too slowly with my design style. I'm not willing to compromise my design ideals. And I would never want to play a 3D game system at native 240p/480i resolution ... but 1080p+ upscaling is not accurate, so that's a conflict I want to avoid entirely. It's also never going to emulate computer systems (X68K, PC-98, FM-Towns, etc) because holy shit that would completely destroy me. It's also never going emulate arcade machines. So I think of higan as a collection of 2D emulators for consoles and handhelds. I've gone over every major 2D gaming system there is, looking for ones with games I actually care about and enjoy. And I basically have five of those systems supported already. Looking at the remaining list, I see only three systems left that I have any interest in whatsoever: PC-Engine, Master System, Mega Drive. Again, I'm not in any way committing to emulating any of these, but ... if I had all of those in higan, I think I'd be content to really, truly, finally stop writing more emulators for the rest of my life. And so I decided to tackle the most difficult system first. If I'm successful, the Z80 core should cover a lot of the work on the SMS. And the HuC6280 should land somewhere between the NES and SNES in terms of difficulty ... closer to the NES. The systems that just don't appeal to me at all, which I will never touch, include, but are not limited to: * Atari 2600/5200/7800 * Lynx * Jaguar * Vectrex * Colecovision * Commodore 64 * Neo-Geo * Neo-Geo Pocket / Color * Virtual Boy * Super A'can * 32X * CD-i * etc, etc, etc. And really, even if something were mildly interesting in there ... we have to stop. I can't scale infinitely. I'm already way past my limit, but I'm doing this anyway. Too many cores bloats everything and kills quality on everything. I don't want higan to become MESS v2. I don't know what I'll do about the Famicom Disk System, PC-Engine CD, and Mega CD. I don't think I'll be able to achieve 60fps emulating the Mega CD, even if I tried to. I don't know what's going to happen here with even the Mega Drive. Maybe I'll get driven crazy with the documentation and quit. Maybe it'll end up being too complicated and I'll quit. Maybe the emulation will end up way too slow and I'll give up. Maybe it'll take me seven years to get any games playable at all. Maybe Steve Snake, AamirM and Mike Pavone will pool money to hire a hitman to come after me. Who knows. But this is what I want to do, so ... here goes nothing. |
|
Tim Allen | 13ad9644a2 |
Update to v099r16 release (public beta).
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. |
|
Tim Allen | 8d5cc0c35e |
Update to v099r15 release.
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 |
|
Tim Allen | 82293c95ae |
Update to v099r14 release.
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. |
|
Tim Allen | 67457fade4 |
Update to v099r13 release.
byuu says: Changelog: - GB core code cleanup completed - GBA core code cleanup completed - some more cleanup on missed processor/arm functions/variables - fixed FC loading icarus bug - "Load ROM File" icarus functionality restored - minor code unification efforts all around (not perfect yet) - MMIO->IO - mmio.cpp->io.cpp - read,write->readIO,writeIO It's been a very long work in progress ... starting all the way back with v094r09, but the major part of the higan code cleanup is now completed! Of course, it's very important to note that this is only for the basic style: - under_score functions and variables are now camelCase - return-type function-name() are now auto function-name() -> return-type - Natural<T>/Integer<T> replace (u)intT_n types where possible - signed/unsigned are now int/uint - most of the x==true,x==false tests changed to x,!x A lot of spot improvements to consistency, simplicity and quality have gone in along the way, of course. But we'll probably never fully finishing beautifying every last line of code in the entire codebase. Still, this is a really great start. Going forward, WIP diffs should start being smaller and of higher quality once again. I know the joke is, "until my coding style changes again", but ... this was way too stressful, way too time consuming, and way too risky. I'm too old and tired now for extreme upheavel like this again. The only major change I'm slowly mulling over would be renaming the using Natural<T>/Integer<T> = (u)intT; shorthand to something that isn't as easily confused with the (u)int_t types ... but we'll see. I'll definitely continue to change small things all the time, but for the larger picture, I need to just accept the style I have and live with it. |
|
Tim Allen | a816998122 |
Update to v099r10 release.
byuu says: Changelog: - higan/profile/ => higan/systems/ [temporary; unless we can't think of a better base folder name] - god-damn-better-have fixed the input polling bug - re-added command-line and drag-and-drop loading - command-line loading can now load multiple folders at once (SGB+GB game; Sufami Turbo+Slot A+Slot B; etc) - if you load just the base cart, it'll present you with a dialog to optionally load slotted cart(s) - MSU1 now goes through nall/vfs instead of directly accessing the filesystem - Famicom Cartridge, PPU cores updated to newer programming style - there's countless opportunity for BitField and .bits() in the PPU ... but I'm worried about breaking things If anyone has a working MSU1 game and can test the changes out, that'd be appreciated. I still don't have a test ROM on my dev box. I wouldn't worry too much about extensively testing the Famicom PPU changes just yet ... I'm still struggling with what to name the structs inside the classes between all of my emulators, and the BitField/.bits() changes will be much more important to test at a later date. The only use case left for Emulator::Interface::path(uint id) is for 21fx emulation. This peripheral loads a DLL/SO via LoadLibrary/dlopen, which do not have any official ways to open a file in RAM. I'm very hesitant to use the portable trick of writing the memory to a temporary file, loading it, and deleting the temporary file once done ... it's a real waste of disk activity. I might make something like vfs::file::isVirtual->bool,path()->string to get around this. But even once I do, the underlying LoadLibrary/dlopen call is still going to be direct disk access. |
|
Tim Allen | 3a9c7c6843 |
Update to v099r09 release.
byuu says: Changelog: - Emulator::Interface::Medium::bootable removed - Emulator::Interface::load(bool required) argument removed [File::Required makes no sense on a folder] - Super Famicom.sys now has user-configurable properties (CPU,PPU1,PPU2 version; PPU1 VRAM size, Region override) - old nall/property removed completely - volatile flags supported on coprocessor RAM files now (still not in icarus, though) - (hopefully) fixed SNES Multitap support (needs testing) - fixed an OAM tiledata range clipping limit in 128KiB VRAM mode (doesn't fix Yoshi's Island, sadly) - (hopefully, again) fixed the input polling bug hex_usr reported - re-added dialog box for when File::Required files are missing - really cool: if you're missing a boot ROM, BIOS ROM, or IPL ROM, it warns you immediately - you don't have to select a game before seeing the error message anymore - fixed cheats.bml load/save location |
|
Tim Allen | f48b332c83 |
Update to v099r08 release.
byuu says: Changelog: - nall/vfs work 100% completed; even SGB games load now - emulation cores now call load() for the base cartridges as well - updated port/device handling; portmask is gone; device ID bug should be resolved now - SNES controller port 1 multitap option was removed - added support for 128KiB SNES PPU VRAM (for now, edit sfc/ppu/ppu.hpp VRAM::size=0x10000; to enable) Overall, nall/vfs was a huge success!! We've substantially reduced the amount of boilerplate code everywhere, while still allowing (even easier than before) support for RAM-based game loading/saving. All of nall/stream is dead and buried. I am considering removing Emulator::Interface::Medium::id and/or bootable flag. Or at least, doing something different with it. The values for the non-bootable GB/BS/ST entries duplicate the ID that is supposed to be unique. They are for GB/GBC and WS/WSC. Maybe I'll use this as the hardware revision selection ID, and then gut non-bootable options. There's really no reason for that to be there. I think at one point I was using it to generate library tabs for non-bootable systems, but we don't do that anymore anyway. Emulator::Interface::load() may not need the required flag anymore ... it doesn't really do anything right now anyway. I have a few reasons for having the cores load the base cartridge. Most importantly, it is going to enable a special mode for the WonderSwan / WonderSwan Color in the future. If we ever get the IPLROMs dumped ... it's possible to boot these systems with no games inserted to set user profile information and such. There are also other systems that may accept being booted without a cartridge. To reach this state, you would load a game and then cancel the load dialog. Right now, this results in games not loading. The second reason is this prevents nasty crashes when loading fails. So if you're missing a required manifest, the emulator won't die a violent death anymore. It's able to back out at any point. The third reason is consistency: loading the base cartridge works the same as the slot cartridges. The fourth reason is Emulator::Interface::open(uint pathID) values. Before, the GB, SB, GBC modes were IDs 1,2,3 respectively. This complicated things because you had to pass the correct ID. But now instead, Emulator::Interface::load() returns maybe<uint> that is nothing when no game is selected, and a pathID for a valid game. And now open() can take this ID to access this game's folder contents. The downside, which is temporary, is that command-line loading is currently broken. But I do intend on restoring it. In fact, I want to do better than before and allow multi-cart booting from the command-line by specifying the base cartridge and then slot cartridges. The idea should be pretty simple: keep a queue of pending filenames that we fill from the command-line and/or drag-and-drop operations on the main window, and then empty out the queue or prompt for load dialogs from the UI when booting a system. This also might be a bit more unorthodox compared to the traditional emulator design of "loadGame(filename)", but ... oh well. It's easy enough still. The port/device changes are fun. We simplified things quite a bit. The portmask stuff is gone entirely. While ports and devices keep IDs, this is really just sugar-coating so UIs can use for(auto& port : emulator->ports) and access port.id; rather than having to use for(auto n : range(emulator->ports)) { auto& port = emulator->ports[n]; ... }; but they should otherwise generally be identical to the order they appear in their respective ranges. Still, don't rely on that. Input::id is gone. There was no point since we also got rid of the nasty Input::order vector. Since I was in here, I went ahead and caved on the pedantics and renamed Input::guid to Input::userData. I removed the SNES controller port 1 multitap option. Basically, the only game that uses this is N-warp Daisakusen and, no offense to d4s, it's not really a good game anyway. It's just a quick demo to show 8-players on the SNES. But in the UI, all it does is confuse people into wasting time mapping a controller they're never going to use, and they're going to wonder which port to use. If more compelling use cases for 8-players comes about, we can reconsider this. I left all the code to support this in place, so all you have to do is uncomment one line to enable it again. We now have dsnes emulation! :D If you change PPU::VRAM::size to 0x10000 (words), then you should now have 128KiB of VRAM. Even better, it serializes the used-VRAM size, so your save states shouldn't crash on you if you swap between the two (though if you try this, you're nuts.) Note that this option does break commercial software. Yoshi's Island in particular. This game is setting A15 on some PPU register writes, but not on others. The end result of this is things break horribly in-game. Also, this option is causing a very tiny speed hit for obvious reasons with the variable masking value (I'm even using size-1 for now.) Given how niche this is, I may just leave it a compile-time constant to avoid the overhead cost. Otherwise, if we keep the option, then it'll go into Super Famicom.sys/manifest.bml ... I'll flesh that out in the near-future. ---- Finally, some fun for my OCD ... my monitor suddenly cut out on me in the middle of working on this WIP, about six hours in of non-stop work. Had to hit a bunch of ctrl+alt+fN commands (among other things) and trying to log in headless on another TTY to do issue commands, trying to recover the display. Finally power cycled the monitor and it came back up. So all my typing ended up going to who knows where. Usually this sort of thing terrifies me enough that I scrap a WIP and start over to ensure I didn't screw anything up during the crashed screen when hitting keys randomly. Obviously, everything compiles and appears to work fine. And I know it's extremely paranoid, but OCD isn't logical, so ... I'm going to go over every line of the 100KiB r07->r08 diff looking for any corruption/errors/whatever. ---- Review finished. r08 diff review notes: - fc/controller/gamepad/gamepad.cpp: use uint device = ID::Device::Gamepad; not id = ...; - gb/cartridge/cartridge.hpp: remove redundant uint _pathID; (in Information::pathID already) - gb/cartridge/cartridge.hpp: pull sha256 inside Information - sfc/cartridge/load/cpp: add " - Slot (A,B)" to interface->load("Sufami Turbo"); to be more descriptive - sfc/controller/gamepad/gamepad.cpp: use uint device = ID::Device::Gamepad; not id = ...; - sfc/interface/interface.cpp: remove n variable from the Multitap device input generation loop (now unused) - sfc/interface/interface.hpp: put struct Port above struct Device like the other classes - ui-tomoko: cheats.bml is reading from/writing to mediumPaths(0) [system folder instead of game folder] - ui-tomoko: instead of mediumPaths(1) - call emulator->metadataPathID() or something like that |
|
Tim Allen | ccd8878d75 |
Update to v099r07 release.
byuu says: Changelog: - (hopefully) fixed BS Memory and Sufami Turbo slot loading - ported GB, GBA, WS cores to use nall/vfs - completely removed loadRequest, saveRequest functionality from Emulator::Interface and ui-tomoko - loadRequest(folder) is now load(folder) - save states now use a shared Emulator::SerializerVersion string - whenever this is bumped, all older states will break; but this makes bumping state versions way easier - also, the version string makes it a lot easier to identify compatibility windows for save states - SNES PPU now uses uint16 vram[32768] for memory accesses [hex_usr] NOTE: Super Game Boy loading is currently broken, and I'm not entirely sure how to fix it :/ The file loading handoff was -really- complicated, and so I'm kind of at a loss ... so for now, don't try it. Everything else should theoretically work, so please report any bugs you find. So, this is pretty much it. I'd be very curious to hear feedback from people who objected to the old nall/stream design, whether they are happy with the new file loading system or think it could use further improvements. The 16-bit VRAM turned out to be a wash on performance (roughly the same as before. 1fps slower on Zelda 3, 1fps faster on Yoshi's Island.) The main reason for this was because Yoshi's Island was breaking horribly until I changed the vramRead, vramWrite functions to take uint15 instead of uint16. I suspect the issue is we're using uint16s in some areas now that need to be uint15, and this game is setting the VRAM address to 0x8000+, causing us to go out of bounds on memory accesses. But ... I want to go ahead and do something cute for fun, and just because we can ... and this new interface is so incredibly perfect for it!! I want to support an SNES unit with 128KiB of VRAM. Not out of the box, but as a fun little tweakable thing. The SNES was clearly designed to support that, they just didn't use big enough VRAM chips, and left one of the lines disconnected. So ... let's connect it anyway! In the end, if we design it right, the only code difference should be one area where we mask by 15-bits instead of by 16-bits. |
|
Tim Allen | f04d9d58f5 |
Update to v099r05 release.
byuu says: Changelog: - added nall/vfs - converted Famicom core to use nall/vfs interface instead of nall/stream interface |
|
Tim Allen | 44a8c5a2b4 |
Update to v099r03 release.
byuu says: Changelog: - finished cleaning up the SFC core to my new coding conventions - removed sfc/controller/usart (superseded by 21fx) - hid Synchronize Video option from the menu (still in the configuration file) Pretty much the only minor detail left is some variable names in the SA-1 core that really won't look good at all if I move to camelCase, so I'll have to rethink how I handle those. It's probably a good area to attempt using BitFields, to see how it impacts performance. But I'll do that in a test branch first. But for the most part, this should be the end of the gigantic diffs (this one was 174KiB), at least for the SFC/WS cores. Still have the FC/GB/GBA cores to clean up more fully. Assuming we don't spot any new regressions, we should be ~95% out of the woods on code cleanups breaking things. |
|
Tim Allen | ae5b4c3bb3 |
Update to v099r01 release.
byuu says: Changelog: - massive cleanups and optimizations on the PPU core - ~9% speedup over v099 official This is pretty much it for the low-hanging fruit of speeding up higan. Any more gains from this point will be extremely hard-fought, unfortunately. |
|
Tim Allen | 3681961ca5 |
Update to v098r16 release.
byuu says: Changelog: - GNUmakefile: reverted $(call unique,) to $(strip) - processor/r6502: removed templates; reduces object size from 146.5kb to 107.6kb - processor/lr35902: removed templates; reduces object size from 386.2kb to 197.4kb - processor/spc700: merged op macros for switch table declarations - sfc/coprocessor/sa1: partial cleanups; flattened directory structure - sfc/coprocessor/superfx: partial cleanups; flattened directory structure - sfc/coprocessor/icd2: flattened directory structure - gb/ppu: changed behavior of STAT IRQs Major caveat! The GB/GBC STAT IRQ changes has a major bug in it somewhere that's seriously breaking most games. I'm pushing the WIP anyway, because I believe the changes to be mostly correct. I'd like to get more people looking at these changes, and also try more heavy-handed hacking and diff comparison logging between the previous WIP and this one. |
|
Tim Allen | fdc41611cf |
Update to v098r14 release.
byuu says: Changelog: - improved attenuation of biquad filter by computing butterworth Q coefficients correctly (instead of using the same constant) - adding 1e-25 to each input sample into the biquad filters to try and prevent denormalization - updated normalization from [0.0 to 1.0] to [-1.0 to +1.0]; volume/reverb happen in floating-point mode now - good amount of work to make the base Emulator::Audio support any number of output channels - so that we don't have to do separate work on left/right channels; and can instead share the code for each channel - Emulator::Interface::audioSample(int16 left, int16 right); changed to: - Emulator::Interface::audioSample(double* samples, uint channels); - samples are normalized [-1.0 to +1.0] - for now at least, channels will be the value given to Emulator::Audio::reset() - fixed GUI crash on startup when audio driver is set to None I'm probably going to be updating ruby to accept normalized doubles as well; but I'm not sure if I will try and support anything other 2-channel audio output. It'll depend on how easy it is to do so; perhaps it'll be a per-driver setting. The denormalization thing is fierce. If that happens, it drops the emulator framerate from 220fps to about 20fps for Game Boy emulation. And that happens basically whenever audio output is silent. I'm probably also going to make a nall/denormal.hpp file at some point with platform-specific functionality to set the CPU state to "denormals as zero" where applicable. I'll still add the 1e-25 offset (inaudible) as another fallback. |
|
Tim Allen | 839813d0f1 |
Update to v098r13 release.
byuu says: Changelog: - nall/dsp returns with new iir/biquad.hpp and resampler/cubic.hpp files - nall/queue.hpp added (simple ring buffer ... nall/vector wouldn't cause too many moves with FIFO) - audio streams now only buffer 20ms; so even if multiple audio streams desync, latency can never exceed 20ms - replaced blackman windwed sinc FIR hermite audio filter with transposed direct form II biquadratic sixth-order IIR butterworth filter (better attenuation of frequencies above 20KHz, faster, no need for decimation, less code) - put in experimental eight-tap echo filter (a lot better than what I had before, but still rather weak) - substantial cleanups to the SuperFX GSU processor core (slightly faster, 479KB->100KB object file, 42.7KB->33.4KB source code size, way less code duplication) We'll definitely want to test the whole SuperFX library (not many games) just to make sure there's no regressions caused by this one. Not sure what I want to do with audio processing effects yet. I've always really wanted lots of fun controls to customize audio, and now finally with this new biquad filter, I can finally start implementing real effects. For instance, an equalizer wouldn't be too complicated anymore. The new reverb effect is still a poor man's version. I need to find human readable source for implementing a comb-filter properly. I'm pretty sure I can already treat nall::queue as an all-pass filter since all that does is phase shift (fancy audio term for "delay audio"). What's really going to be hard is figuring out how to expose user-friendly settings for controlling it. It looks like you need a bunch of coprime coefficients, and I don't think casual users are going to be able to hand-enter coprime values to get the echo effect they want. I uh ... don't even know how to calculate coprime values dynamically right now >_> But we're going to have to, as they are correlated to the output sampling rate. We'll definitely want to make some audio profiles so that users can quickly select pre-configured themes that sound nice, but expose the underlying coefficients so that they can tweak stuff to their liking. This isn't just about higan, this is about me trying to learn digital signal processing, so please don't be too upset about feature creep or anything on this. Anyway ... I'm having some difficulties with my audio right now. When the reverb effect is enabled, there's a bunch of static on system reset for just a moment. But this should not be possible. nall::queue is initializing all previous reverb sample elements to 0.0. I don't understand where static is coming in from. Further, we have the same issue with both the windowed sinc and the biquad filters ... a bit of a popping sound when starting a game. Any help tracking this down would be appreciated. There's also one really annoying issue ... I can't seem to do reverb or volume adjustments with normalized samples. If I say "volume *= 0.5" in higan/audio/audio.cpp line 68, it doesn't just halve the volume, it adds a whole bunch of distortion. This makes absolutely zero sense to me. The sample values are between 0.0 (mute) and 1.0 (full volume) here, so multiplying a double by 0.5 shouldn't cause distortion. So right now, I'm doing these adjustments with less precision after denormalizing back to int16. Anyone ever see something like that? :/ |
|
Tim Allen | ae5d380d06 |
Update to v098r11 release.
byuu says: Changelog: - fixed nall/path.hpp compilation issue - fixed ruby/audio/xaudio header declaration compilation issue (again) - cleaned up xaudio2.hpp file to match my coding syntax (12.5% of the file was whitespace overkill) - added null terminator entry to nall/windows/utf8.hpp argc[] array - nall/windows/guid.hpp uses the Windows API for generating the GUID - this should stop all the bug reports where two nall users were generating GUIDs at the exact same second - fixed hiro/cocoa compilation issue with uint# types - fixed major higan/sfc Super Game Boy audio latency issue - fixed higan/sfc CPU core bug with pei, [dp], [dp]+y instructions - major cleanups to higan/processor/r65816 core - merged emulation/native-mode opcodes - use camel-case naming on memory.hpp functions - simplify address masking code for memory.hpp functions - simplify a few opcodes themselves (avoid redundant copies, etc) - rename regs.* to r.* to match modern convention of other CPU cores - removed device.order<> concept from Emulator::Interface - cores will now do the translation to make the job of the UI easier - fixed plurality naming of arrays in Emulator::Interface - example: emulator.ports[p].devices[d].inputs[i] - example: vector<Medium> media - probably more surprises Major show-stoppers to the next official release: - we need to work on GB core improvements: LY=153/0 case, multiple STAT IRQs case, GBC audio output regs, etc. - we need to re-add software cursors for light guns (Super Scope, Justifier) - after the above, we need to fix the turbo button for the Super Scope I really have no idea how I want to implement the light guns. Ideally, we'd want it in higan/video, so we can support the NES Zapper with the same code. But this isn't going to be easy, because only the SNES knows when its output is interlaced, and its resolutions can vary as {256,512}x{224,240,448,480} which requires pixel doubling that was hard-coded to the SNES-specific behavior, but isn't appropriate to be exposed in higan/video. |
|
Tim Allen | 3ebc77c148 |
Update to v098r10 release.
byuu says: Changelog: - synchronized tomoko, loki, icarus with extensive changes to nall (118KiB diff) |
|
Tim Allen | 6ae0abe3d3 |
Update to v098r09 release.
byuu says: Changelog: - fixed major nall/vector/prepend bug - renamed hiro/ListView to hiro/TableView - added new hiro/ListView control which is a simplified abstraction of hiro/TableView - updated higan's cheat database window and icarus' scan dialog to use the new ListView control - compilation works once again on all platforms (Windows, Cocoa, GTK, Qt) - the loki skeleton compiles once again (removed nall/DSP references; updated port/device ID names) Small catch: need to capture layout resize events internally in Windows to call resizeColumns. For now, just resize the icarus window to get it to use the full window width for list view items. |