2016-01-27 11:31:39 +00:00
|
|
|
#include <ws/ws.hpp>
|
|
|
|
|
|
|
|
namespace WonderSwan {
|
|
|
|
|
|
|
|
Interface* interface = nullptr;
|
|
|
|
Settings settings;
|
|
|
|
|
|
|
|
Interface::Interface() {
|
|
|
|
interface = this;
|
|
|
|
|
2016-01-30 06:40:35 +00:00
|
|
|
information.manufacturer = "Bandai";
|
|
|
|
information.name = "WonderSwan";
|
|
|
|
information.width = 224; //note: technically 224x144; but screen can be rotated
|
Update to v098r04 release.
byuu says:
Changelog:
- SFC: fixed behavior of 21fx $21fe register when no device is connected
(must return zero)
- SFC: reduced 21fx buffer size to 1024 bytes in both directions to
mirror the FT232H we are using
- SFC: eliminated dsp/modulo-array.hpp [1]
- higan: implemented higan/video interface and migrated all cores to it
[2]
[1] the echo history buffer was 8-bytes, so there was no need for it at
all here. Not sure what I was thinking. The BRR buffer was 12-bytes, and
has very weird behavior ... but there's only a single location in the
code where it actually writes to this buffer. It's much easier to just
write to the buffer three times there instead of implementing an entire
class just to abstract away two lines of code. This change actually
boosted the speed from ~124.5fps to around ~127.5fps, but that's within
the margin of error for GCC. I doubt it's actually faster this way.
The DSP core could really use a ton of work. It comes from a port of
blargg's spc_dsp to my coding style, but he was extremely fond of using
32-bit signed integers everywhere. There's a lot of opportunity to
remove red tape masking by resizing the variables to their actual state
sizes.
I really need to find where I put spc_dsp6.sfc from blargg. It's a great
test to verify if I've made any mistakes in my implementation that would
cause regressions. Don't suppose anyone has it?
[2] so again, the idea is that higan/audio and higan/video are going to
sit between the emulation cores and the user interfaces. The hope is to
output raw encoding data from the emulation cores without having to
worry about the video display format (generally 24-bit RGB) of the host
display. And also to avoid having to repeat myself with eg three
separate implementations of interframe blending, and so on.
Furthermore, the idea is that the user interface can configure its side
of the settings, and the emulation cores can configure their sides.
Thus, neither has to worry about the other end. And now we can spin off
new user interfaces much easier without having to mess with all of these
things.
Right now, I've implemented color emulation, interframe blending and
SNES horizontal color bleed. I did not implement scanlines (and
interlace effects for them) yet, but I probably will at some point.
Further, for right now, the WonderSwan/Color screen rotation is busted
and will only show games in the horizontal orientation. Obviously this
must be fixed before the next official release, but I'll want to think
about how to implement it.
Also, the SNES light gun pointers are missing for now.
Things are a bit messy right now as I've gone through several revisions
of how to handle these things, so a good house cleaning is in order once
everything is feature-complete again. I need to sit down and think
through how and where I want to handle things like light gun cursors,
LCD icons, and maybe even rasterized text messages.
And obviously ... higan/audio is still just nall::DSP's headers. I need
to revamp that whole interface. I want to make it quite powerful with
a true audio mixer so I can handle things like
SNES+SGB+MSU1+Voicer-Kun+SNES-CD (five separate audio streams at once.)
The video system has the concept of "effects" for things like color
bleed and interframe blending. I want to extend on this with useful
other effects, such as NTSC simulation, maybe bringing back my mini-HQ2x
filter, etc. I'd also like to restore the saturation/gamma/luma
adjustment sliders ... I always liked allowing people to compensate for
their displays without having to change settings system-wide. Lastly,
I've always wanted to see some audio effects. Although I doubt we'll
ever get my dream of CoreAudio-style profiles, I'd like to get some
basic equalizer settings and echo/reverb effects in there.
2016-04-11 21:29:56 +00:00
|
|
|
information.height = 144; //by using a square size; this can be done in the core
|
2016-01-30 06:40:35 +00:00
|
|
|
information.overscan = false;
|
|
|
|
information.aspectRatio = 1.0;
|
|
|
|
information.resettable = false;
|
2016-01-27 11:31:39 +00:00
|
|
|
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
information.capability.states = true;
|
|
|
|
information.capability.cheats = true;
|
2016-01-27 11:31:39 +00:00
|
|
|
|
|
|
|
media.append({ID::WonderSwan, "WonderSwan", "ws", true});
|
|
|
|
media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc", true});
|
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
{ Device device{0, ID::DeviceHorizontal, "Controller"};
|
2016-03-02 11:19:33 +00:00
|
|
|
device.input.append({ 0, 0, "Y1"});
|
|
|
|
device.input.append({ 1, 0, "Y2"});
|
|
|
|
device.input.append({ 2, 0, "Y3"});
|
|
|
|
device.input.append({ 3, 0, "Y4"});
|
|
|
|
device.input.append({ 4, 0, "X1"});
|
|
|
|
device.input.append({ 5, 0, "X2"});
|
|
|
|
device.input.append({ 6, 0, "X3"});
|
|
|
|
device.input.append({ 7, 0, "X4"});
|
2016-01-28 11:39:49 +00:00
|
|
|
device.input.append({ 8, 0, "B"});
|
|
|
|
device.input.append({ 9, 0, "A"});
|
|
|
|
device.input.append({10, 0, "Start"});
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
device.input.append({11, 0, "Rotate"});
|
|
|
|
device.order = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
2016-01-27 11:31:39 +00:00
|
|
|
this->device.append(device);
|
|
|
|
}
|
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
{ Device device{1, ID::DeviceVertical, "Controller"};
|
2016-03-02 11:19:33 +00:00
|
|
|
device.input.append({ 0, 0, "Y1"});
|
|
|
|
device.input.append({ 1, 0, "Y2"});
|
|
|
|
device.input.append({ 2, 0, "Y3"});
|
|
|
|
device.input.append({ 3, 0, "Y4"});
|
|
|
|
device.input.append({ 4, 0, "X1"});
|
|
|
|
device.input.append({ 5, 0, "X2"});
|
|
|
|
device.input.append({ 6, 0, "X3"});
|
|
|
|
device.input.append({ 7, 0, "X4"});
|
2016-01-28 11:39:49 +00:00
|
|
|
device.input.append({ 8, 0, "B"});
|
|
|
|
device.input.append({ 9, 0, "A"});
|
|
|
|
device.input.append({10, 0, "Start"});
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
device.input.append({11, 0, "Rotate"});
|
|
|
|
device.order = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
|
2016-01-28 11:39:49 +00:00
|
|
|
this->device.append(device);
|
|
|
|
}
|
|
|
|
|
|
|
|
port.append({0, "Horizontal Orientation", {device[0]}});
|
|
|
|
port.append({1, "Vertical Orientation", {device[1]}});
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::manifest() -> string {
|
|
|
|
return cartridge.information.manifest;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::title() -> string {
|
|
|
|
return cartridge.information.title;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::videoFrequency() -> double {
|
|
|
|
return 3072000.0 / (159.0 * 256.0); //~75.47hz
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::audioFrequency() -> double {
|
Update to v097r27 release.
byuu says:
Absolutely major improvements to the WS/C emulation today.
Changelog: (all WS/C related)
- fixed channel 3 sweep pitch adjustment
- fixed channel 3 sweep value sign extension
- removed errant channel 5 speed setting (not what's really going on)
- fixed sign extension on channel 5 samples
- improved DAC mixing of all five audio channels
- fixed r26 regression with PPU timing loop
- fixed sprite windowing behavior (sprite attribute flag is window mode;
not window enable)
- added per-scanline register latching to the PPU
- IRQs should terminate HLT even when the IRQ enable register bits are
clear
- fixed PALMONO reads
- added blur emulation
- added color emulation (based on GBA, so it heavily desaturates colors;
not entirely correct, but it helps a lot)
- no longer decimating audio to 24KHz; running at full 3.072MHz through
the windowed sinc filter [1]
- cleaned up PPU portRead / portWrite functions significantly
- emulated a weird quirk as mentioned by trap15 regarding timer
frequency writes enabling said timers [2]
- emulated LCD_CTRL sleep bit; screen can now be disabled (always draws
black in this case for now)
- improved OAM caching; but it's still disabled because it causes huge
amounts of sprite glitches (unsure why)
- fixed rendering of sprites that wrap around the screen edges back to
the top/left of the display
- emulated keypad interrupts
- icarus: detect orientation bit in game header
- higan: use orientation setting in manifest to set default screen
rotation
[1] the 24KHz -> 3.072MHz sound change is huge. Sound is substantially
improved over the previous WIPs. It does come at a pretty major speed
penalty, though. This is the highest frequency of any system in higan
running through an incredibly (amazing, yet) demanding sinc resampler.
Frame rate dropped from around 240fps to 150fps with the sinc filter on.
If you choose a different audio filter, you'll get most of that speed
back, but audio will sound worse again.
[2] we aren't sure if this is correct hardware behavior or not. It seems
to very slightly help Magical Drop, but not much.
The blur emulation is brutal. It's absolutely required for Riviera's
translucency simulation of selected menu items, but it causes serious
headaches due to the WS's ~75hz refresh rate running on ~60hz monitors
without vsync. It's probably best to leave it off and just deal with the
awful flickering on Riviera's menu options.
Overall, WS/C emulation is starting to get quite usable indeed. Couple
of major bugs that I'd really like to get fixed before releasing it,
though. But they're getting harder and harder to fix ...
Major Bugs:
- Final Fantasy battle background music is absent. Sound effects still
work. Very weird.
- Final Fantasy IV scrolling during airship flight opening sequence is
horribly broken. Scrolls one screen at a time.
- Magical Drop flickers like crazy in-game. Basically unplayable like
this.
- Star Hearts character names don't appear in the smaller dialog box
that pops up.
Minor Bugs:
- Occasional flickering during Riviera opening scenes.
- One-frame flicker of Leda's sprite at the start of the first stage.
2016-03-19 07:35:25 +00:00
|
|
|
return 3072000.0;
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::loaded() -> bool {
|
Update to v097r12 release.
byuu says:
Nothing WS-related this time.
First, I fixed expansion port device mapping. On first load, it was
mapping the expansion port device too late, so it ended up not taking
effect. I had to spin out the logic for that into
Program::connectDevices(). This was proving to be quite annoying while
testing eBoot (SNES-Hook simulation.)
Second, I fixed the audio->set(Frequency, Latency) functions to take
(uint) parameters from the configuration file, so the weird behavior
around changing settings in the audio panel should hopefully be gone
now.
Third, I rewrote the interface->load,unload functions to call into the
(Emulator)::System::load,unload functions. And I have those call out to
Cartridge::load,unload. Before, this was inverted, and Cartridge::load()
was invoking System::load(), which I felt was kind of backward.
The Super Game Boy really didn't like this change, however. And it took
me a few hours to power through it. Before, I had the Game Boy core
dummying out all the interface->(load,save)Request calls, and having the
SNES core make them for it. This is because the folder paths and IDs
will be different between the two cores.
I've redesigned things so that ICD2's Emulator::Interface overloads
loadRequest and saveRequest, and translates the requests into new
requests for the SuperFamicom core. This allows the Game Boy code to do
its own loading for everything without a bunch of Super Game Boy special
casing, and without any awkwardness around powering on with no cartridge
inserted.
This also lets the SNES side of things simply call into higher-level
GameBoy::interface->load,save(id, stream) functions instead of stabbing
at the raw underlying state inside of various Game Boy core emulation
classes. So things are a lot better abstracted now.
2016-02-08 03:17:59 +00:00
|
|
|
return system.loaded();
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::sha256() -> string {
|
|
|
|
return cartridge.information.sha256;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::group(uint id) -> uint {
|
|
|
|
switch(id) {
|
|
|
|
case ID::SystemManifest:
|
2016-02-18 10:32:22 +00:00
|
|
|
case ID::SystemIPLROM:
|
|
|
|
case ID::SystemEEPROM:
|
2016-01-27 11:31:39 +00:00
|
|
|
return 0;
|
|
|
|
case ID::Manifest:
|
|
|
|
case ID::ROM:
|
|
|
|
case ID::RAM:
|
2016-02-18 10:32:22 +00:00
|
|
|
case ID::EEPROM:
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
case ID::RTC:
|
2016-03-08 11:34:00 +00:00
|
|
|
switch(system.model()) {
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
case Model::WonderSwan:
|
2016-01-27 11:31:39 +00:00
|
|
|
return ID::WonderSwan;
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
case Model::WonderSwanColor:
|
|
|
|
case Model::SwanCrystal:
|
2016-01-27 11:31:39 +00:00
|
|
|
return ID::WonderSwanColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::load(uint id) -> void {
|
Update to v097r24 release.
byuu says:
Changelog:
- WS: fixed bug when IRQs triggered during a rep string instruction
- WS: added sprite attribute caching (per-scanline); absolutely massive
speed-up
- WS: emulated limit of 32 sprites per scanline
- WS: emulated the extended PPU register bit behavior based on the
DISP_CTRL tile bit-depth setting
- WS: added "Rotate" key binding; can be used to flip the WS display
between horizontal and vertical in real-time
The prefix emulation may not be 100% hardware-accurate, but the edge
cases should be extreme enough to not come up in the WS library. No way
to get the emulation 100% down without intensive hardware testing.
trap15 pointed me at a workflow diagram for it, but that diagram is
impossible without a magic internal stack frame that grows with every
IRQ, and can thus grow infinitely large.
The rotation thing isn't exactly the most friendly set-up, but oh well.
I'll see about adding a default rotation setting to manifests, so that
games like GunPey can start in the correct orientation. After that, if
the LCD orientation icon turns out to be reliable, then I'll start using
that. But if there are cases where it's not reliable, then I'll leave it
to manual button presses.
Speaking of icons, I'll need a set of icons to render on the screen.
Going to put them to the top right on vertical orientation, and on the
bottom left for horizontal orientation. Just outside of the video
output, of course.
Overall, WS is getting pretty far along, but still some major bugs in
various games. I really need sound emulation, though. Nobody's going to
use this at all without that.
2016-03-12 13:27:41 +00:00
|
|
|
if(id == ID::WonderSwan) system.load(Model::WonderSwan);
|
|
|
|
if(id == ID::WonderSwanColor) system.load(Model::WonderSwanColor);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::save() -> void {
|
2016-02-18 10:32:22 +00:00
|
|
|
if(auto name = system.eeprom.name()) interface->saveRequest(ID::SystemEEPROM, name);
|
|
|
|
if(auto name = cartridge.ram.name) interface->saveRequest(ID::RAM, name);
|
|
|
|
if(auto name = cartridge.eeprom.name()) interface->saveRequest(ID::EEPROM, name);
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
if(auto name = cartridge.rtc.name) interface->saveRequest(ID::RTC, name);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::load(uint id, const stream& stream) -> void {
|
|
|
|
if(id == ID::SystemManifest) {
|
|
|
|
system.information.manifest = stream.text();
|
|
|
|
}
|
|
|
|
|
2016-02-18 10:32:22 +00:00
|
|
|
if(id == ID::SystemEEPROM) {
|
|
|
|
stream.read((uint8_t*)system.eeprom.data(), min(system.eeprom.size() * sizeof(uint16), stream.size()));
|
|
|
|
}
|
|
|
|
|
2016-01-27 11:31:39 +00:00
|
|
|
if(id == ID::Manifest) {
|
|
|
|
cartridge.information.manifest = stream.text();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(id == ID::ROM) {
|
2016-02-16 09:27:55 +00:00
|
|
|
stream.read((uint8_t*)cartridge.rom.data, min(cartridge.rom.size, stream.size()));
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(id == ID::RAM) {
|
2016-02-16 09:27:55 +00:00
|
|
|
stream.read((uint8_t*)cartridge.ram.data, min(cartridge.ram.size, stream.size()));
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
2016-02-18 10:32:22 +00:00
|
|
|
|
|
|
|
if(id == ID::EEPROM) {
|
|
|
|
stream.read((uint8_t*)cartridge.eeprom.data(), min(cartridge.eeprom.size() * sizeof(uint16), stream.size()));
|
|
|
|
}
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
|
|
|
|
if(id == ID::RTC) {
|
|
|
|
stream.read((uint8_t*)cartridge.rtc.data, min(cartridge.rtc.size, stream.size()));
|
|
|
|
cartridge.rtcLoad();
|
|
|
|
}
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::save(uint id, const stream& stream) -> void {
|
2016-02-18 10:32:22 +00:00
|
|
|
if(id == ID::SystemEEPROM) {
|
|
|
|
stream.write((uint8_t*)system.eeprom.data(), system.eeprom.size() * sizeof(uint16));
|
|
|
|
}
|
|
|
|
|
2016-01-27 11:31:39 +00:00
|
|
|
if(id == ID::RAM) {
|
2016-02-16 09:27:55 +00:00
|
|
|
stream.write((uint8_t*)cartridge.ram.data, cartridge.ram.size);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
2016-02-18 10:32:22 +00:00
|
|
|
|
|
|
|
if(id == ID::EEPROM) {
|
|
|
|
stream.write((uint8_t*)cartridge.eeprom.data(), cartridge.eeprom.size() * sizeof(uint16));
|
|
|
|
}
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
|
|
|
|
if(id == ID::RTC) {
|
|
|
|
cartridge.rtcSave();
|
|
|
|
stream.write((uint8_t*)cartridge.rtc.data, cartridge.rtc.size);
|
|
|
|
}
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::unload() -> void {
|
|
|
|
save();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::power() -> void {
|
|
|
|
system.power();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::run() -> void {
|
|
|
|
system.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::serialize() -> serializer {
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
system.runToSave();
|
|
|
|
return system.serialize();
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::unserialize(serializer& s) -> bool {
|
Update to v097r28 release.
byuu says:
Changelog: (all WSC unless otherwise noted)
- fixed LINECMP=0 interrupt case (fixes FF4 world map during airship
sequence)
- improved CPU timing (fixes Magical Drop flickering and FF1 battle
music)
- added per-frame OAM caching (fixes sprite glitchiness in Magical Drop,
Riviera, etc.)
- added RTC emulation (fixes Dicing Knight and Judgement Silversword)
- added save state support
- added cheat code support (untested because I don't know of any cheat
codes that exist for this system)
- icarus: can now detect games with RTC chips
- SFC: bugfix to SharpRTC emulation (Dai Kaijuu Monogatari II)
- ( I was adding the extra leap year day to all 12 months instead of
just February ... >_< )
Note that the RTC emulation is very incomplete. It's not really
documented at all, and the two games I've tried that use it never even
ask you to set the date/time (so they're probably just using it to count
seconds.) I'm not even sure if I've implement the level-sensitive
behavior correctly (actually, now that I think about it, I need to mask
the clear bit in INT_ACK for the level-sensitive interrupts ...)
A bit worried about the RTC alarm, because it seems like it'll fire
continuously for a full minute. Or even if you turn it off after it
fires, then that doesn't seem to be lowering the line until the next
second ticks on the RTC, so that likely needs to happen when changing
the alarm flag.
Also not sure on this RTC's weekday byte. On the SharpRTC, it actually
computes this for you. Because it's not at all an easy thing to
calculate yourself in 65816 or V30MZ assembler. About 40 lines of code
to do it in C. For now, I'm requiring the program to calculate the value
itself.
Also note that there's some gibberish tiles in Judgement Silversword,
sadly. Not sure what's up there, but the game's still fully playable at
least.
Finally, no surprise: Beat-Mania doesn't run :P
2016-03-25 06:19:08 +00:00
|
|
|
return system.unserialize(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::cheatSet(const lstring& list) -> void {
|
|
|
|
cheat.reset();
|
|
|
|
for(auto& codeset : list) {
|
|
|
|
lstring codes = codeset.split("+");
|
|
|
|
for(auto& code : codes) {
|
|
|
|
lstring part = code.split("/");
|
|
|
|
if(part.size() == 2) cheat.append(hex(part[0]), hex(part[1]));
|
|
|
|
if(part.size() == 3) cheat.append(hex(part[0]), hex(part[1]), hex(part[2]));
|
|
|
|
}
|
|
|
|
}
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::cap(const string& name) -> bool {
|
Update to v097r27 release.
byuu says:
Absolutely major improvements to the WS/C emulation today.
Changelog: (all WS/C related)
- fixed channel 3 sweep pitch adjustment
- fixed channel 3 sweep value sign extension
- removed errant channel 5 speed setting (not what's really going on)
- fixed sign extension on channel 5 samples
- improved DAC mixing of all five audio channels
- fixed r26 regression with PPU timing loop
- fixed sprite windowing behavior (sprite attribute flag is window mode;
not window enable)
- added per-scanline register latching to the PPU
- IRQs should terminate HLT even when the IRQ enable register bits are
clear
- fixed PALMONO reads
- added blur emulation
- added color emulation (based on GBA, so it heavily desaturates colors;
not entirely correct, but it helps a lot)
- no longer decimating audio to 24KHz; running at full 3.072MHz through
the windowed sinc filter [1]
- cleaned up PPU portRead / portWrite functions significantly
- emulated a weird quirk as mentioned by trap15 regarding timer
frequency writes enabling said timers [2]
- emulated LCD_CTRL sleep bit; screen can now be disabled (always draws
black in this case for now)
- improved OAM caching; but it's still disabled because it causes huge
amounts of sprite glitches (unsure why)
- fixed rendering of sprites that wrap around the screen edges back to
the top/left of the display
- emulated keypad interrupts
- icarus: detect orientation bit in game header
- higan: use orientation setting in manifest to set default screen
rotation
[1] the 24KHz -> 3.072MHz sound change is huge. Sound is substantially
improved over the previous WIPs. It does come at a pretty major speed
penalty, though. This is the highest frequency of any system in higan
running through an incredibly (amazing, yet) demanding sinc resampler.
Frame rate dropped from around 240fps to 150fps with the sinc filter on.
If you choose a different audio filter, you'll get most of that speed
back, but audio will sound worse again.
[2] we aren't sure if this is correct hardware behavior or not. It seems
to very slightly help Magical Drop, but not much.
The blur emulation is brutal. It's absolutely required for Riviera's
translucency simulation of selected menu items, but it causes serious
headaches due to the WS's ~75hz refresh rate running on ~60hz monitors
without vsync. It's probably best to leave it off and just deal with the
awful flickering on Riviera's menu options.
Overall, WS/C emulation is starting to get quite usable indeed. Couple
of major bugs that I'd really like to get fixed before releasing it,
though. But they're getting harder and harder to fix ...
Major Bugs:
- Final Fantasy battle background music is absent. Sound effects still
work. Very weird.
- Final Fantasy IV scrolling during airship flight opening sequence is
horribly broken. Scrolls one screen at a time.
- Magical Drop flickers like crazy in-game. Basically unplayable like
this.
- Star Hearts character names don't appear in the smaller dialog box
that pops up.
Minor Bugs:
- Occasional flickering during Riviera opening scenes.
- One-frame flicker of Leda's sprite at the start of the first stage.
2016-03-19 07:35:25 +00:00
|
|
|
if(name == "Blur Emulation") return true;
|
|
|
|
if(name == "Color Emulation") return true;
|
2016-01-27 11:31:39 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::get(const string& name) -> any {
|
Update to v097r27 release.
byuu says:
Absolutely major improvements to the WS/C emulation today.
Changelog: (all WS/C related)
- fixed channel 3 sweep pitch adjustment
- fixed channel 3 sweep value sign extension
- removed errant channel 5 speed setting (not what's really going on)
- fixed sign extension on channel 5 samples
- improved DAC mixing of all five audio channels
- fixed r26 regression with PPU timing loop
- fixed sprite windowing behavior (sprite attribute flag is window mode;
not window enable)
- added per-scanline register latching to the PPU
- IRQs should terminate HLT even when the IRQ enable register bits are
clear
- fixed PALMONO reads
- added blur emulation
- added color emulation (based on GBA, so it heavily desaturates colors;
not entirely correct, but it helps a lot)
- no longer decimating audio to 24KHz; running at full 3.072MHz through
the windowed sinc filter [1]
- cleaned up PPU portRead / portWrite functions significantly
- emulated a weird quirk as mentioned by trap15 regarding timer
frequency writes enabling said timers [2]
- emulated LCD_CTRL sleep bit; screen can now be disabled (always draws
black in this case for now)
- improved OAM caching; but it's still disabled because it causes huge
amounts of sprite glitches (unsure why)
- fixed rendering of sprites that wrap around the screen edges back to
the top/left of the display
- emulated keypad interrupts
- icarus: detect orientation bit in game header
- higan: use orientation setting in manifest to set default screen
rotation
[1] the 24KHz -> 3.072MHz sound change is huge. Sound is substantially
improved over the previous WIPs. It does come at a pretty major speed
penalty, though. This is the highest frequency of any system in higan
running through an incredibly (amazing, yet) demanding sinc resampler.
Frame rate dropped from around 240fps to 150fps with the sinc filter on.
If you choose a different audio filter, you'll get most of that speed
back, but audio will sound worse again.
[2] we aren't sure if this is correct hardware behavior or not. It seems
to very slightly help Magical Drop, but not much.
The blur emulation is brutal. It's absolutely required for Riviera's
translucency simulation of selected menu items, but it causes serious
headaches due to the WS's ~75hz refresh rate running on ~60hz monitors
without vsync. It's probably best to leave it off and just deal with the
awful flickering on Riviera's menu options.
Overall, WS/C emulation is starting to get quite usable indeed. Couple
of major bugs that I'd really like to get fixed before releasing it,
though. But they're getting harder and harder to fix ...
Major Bugs:
- Final Fantasy battle background music is absent. Sound effects still
work. Very weird.
- Final Fantasy IV scrolling during airship flight opening sequence is
horribly broken. Scrolls one screen at a time.
- Magical Drop flickers like crazy in-game. Basically unplayable like
this.
- Star Hearts character names don't appear in the smaller dialog box
that pops up.
Minor Bugs:
- Occasional flickering during Riviera opening scenes.
- One-frame flicker of Leda's sprite at the start of the first stage.
2016-03-19 07:35:25 +00:00
|
|
|
if(name == "Blur Emulation") return settings.blurEmulation;
|
|
|
|
if(name == "Color Emulation") return settings.colorEmulation;
|
2016-01-27 11:31:39 +00:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::set(const string& name, const any& value) -> bool {
|
Update to v098r04 release.
byuu says:
Changelog:
- SFC: fixed behavior of 21fx $21fe register when no device is connected
(must return zero)
- SFC: reduced 21fx buffer size to 1024 bytes in both directions to
mirror the FT232H we are using
- SFC: eliminated dsp/modulo-array.hpp [1]
- higan: implemented higan/video interface and migrated all cores to it
[2]
[1] the echo history buffer was 8-bytes, so there was no need for it at
all here. Not sure what I was thinking. The BRR buffer was 12-bytes, and
has very weird behavior ... but there's only a single location in the
code where it actually writes to this buffer. It's much easier to just
write to the buffer three times there instead of implementing an entire
class just to abstract away two lines of code. This change actually
boosted the speed from ~124.5fps to around ~127.5fps, but that's within
the margin of error for GCC. I doubt it's actually faster this way.
The DSP core could really use a ton of work. It comes from a port of
blargg's spc_dsp to my coding style, but he was extremely fond of using
32-bit signed integers everywhere. There's a lot of opportunity to
remove red tape masking by resizing the variables to their actual state
sizes.
I really need to find where I put spc_dsp6.sfc from blargg. It's a great
test to verify if I've made any mistakes in my implementation that would
cause regressions. Don't suppose anyone has it?
[2] so again, the idea is that higan/audio and higan/video are going to
sit between the emulation cores and the user interfaces. The hope is to
output raw encoding data from the emulation cores without having to
worry about the video display format (generally 24-bit RGB) of the host
display. And also to avoid having to repeat myself with eg three
separate implementations of interframe blending, and so on.
Furthermore, the idea is that the user interface can configure its side
of the settings, and the emulation cores can configure their sides.
Thus, neither has to worry about the other end. And now we can spin off
new user interfaces much easier without having to mess with all of these
things.
Right now, I've implemented color emulation, interframe blending and
SNES horizontal color bleed. I did not implement scanlines (and
interlace effects for them) yet, but I probably will at some point.
Further, for right now, the WonderSwan/Color screen rotation is busted
and will only show games in the horizontal orientation. Obviously this
must be fixed before the next official release, but I'll want to think
about how to implement it.
Also, the SNES light gun pointers are missing for now.
Things are a bit messy right now as I've gone through several revisions
of how to handle these things, so a good house cleaning is in order once
everything is feature-complete again. I need to sit down and think
through how and where I want to handle things like light gun cursors,
LCD icons, and maybe even rasterized text messages.
And obviously ... higan/audio is still just nall::DSP's headers. I need
to revamp that whole interface. I want to make it quite powerful with
a true audio mixer so I can handle things like
SNES+SGB+MSU1+Voicer-Kun+SNES-CD (five separate audio streams at once.)
The video system has the concept of "effects" for things like color
bleed and interframe blending. I want to extend on this with useful
other effects, such as NTSC simulation, maybe bringing back my mini-HQ2x
filter, etc. I'd also like to restore the saturation/gamma/luma
adjustment sliders ... I always liked allowing people to compensate for
their displays without having to change settings system-wide. Lastly,
I've always wanted to see some audio effects. Although I doubt we'll
ever get my dream of CoreAudio-style profiles, I'd like to get some
basic equalizer settings and echo/reverb effects in there.
2016-04-11 21:29:56 +00:00
|
|
|
if(name == "Blur Emulation" && value.is<bool>()) {
|
|
|
|
settings.blurEmulation = value.get<bool>();
|
|
|
|
system.configureVideoEffects();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(name == "Color Emulation" && value.is<bool>()) {
|
|
|
|
settings.colorEmulation = value.get<bool>();
|
|
|
|
system.configureVideoPalette();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-27 11:31:39 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|