Compare commits

...

20 Commits
v113 ... v114

Author SHA1 Message Date
byuu
55e78b03de Point to specific project. 2020-01-08 18:50:07 +09:00
byuu
47dcdc1b4f Added Windows binary release link. 2020-01-08 18:49:40 +09:00
byuu
e13ab011eb v114
Added fast PPU override for Marvelous (fixes text rendering)
Fixed disassembly of SNES CPU opcodes 0x74-0x76 [invertego]
2020-01-08 18:46:53 +09:00
byuu
892f202945 Updated SNES game databases 2020-01-01 18:45:11 +09:00
byuu
e575196abc . 2019-12-31 19:42:11 +09:00
byuu
404caeab50 The input workaround for Taikyoku Igo benefits:
Williams Arcade's Greatest Hits and World Masters Golf;
in very subtle ways, so enable it for those two titles as well.
2019-12-31 19:40:35 +09:00
byuu
dde9b4c2c7 v113.5
It seems auto-joypad poll timing is needed for most games.
So that's back in as before. Instead, I added an override for
Taikyoku Igo - Goliath specifically, until auto-joypad emulation
can be improved further.
2019-12-31 10:22:31 +09:00
byuu
793f2e5bf4 v113.4
Completely disabled auto-joypad timing (happens immediately)
(fixes World Masters until this can be emulated fully)
Disabled fast PPU for Winter Olympic Games
(changes OAM tiledata address mid-frame)
Disabled fast PPU for World Cup Striker
(I'm not sure yet why it's not compatible)
Cleared overscan region when disabling overscan
(fixes World Class Service SNES Tester)
Added override for invalid SNES header in Yuyu no Quiz de Go! Go!
2019-12-30 06:00:17 +09:00
byuu
cc4ab9bc25 Added workaround to reduce auto-joypad polling delays
(until we can emulate the behavior more faithfully)
2019-12-28 13:53:06 +09:00
byuu
2551f20f3a v113.3
Fixed region heuristics for the one Scandanavian SNES game release
2019-12-28 13:41:57 +09:00
byuu
5b29ddbcaa Add hotfix for Nichibutsu Arcade Classics (Japan)
* Frisky Tom hangs sometimes when memory is randomized
2019-12-27 08:58:09 +09:00
byuu
ac4d16c917 Revert gamepak firmware naming to use architecture instead of identifier
* identifier naming interferes with game ROM naming lookup
2019-12-27 08:51:05 +09:00
byuu
01c16dcf4d Fix Taikyoku Igo - Goliath
(clear $4218-421f to 1s instead of 0s at start of auto-joypad polling)
2019-12-27 08:32:18 +09:00
byuu
169c0871c7 Added Super SWIV fast PPU override 2019-12-27 08:17:39 +09:00
byuu
ffee61a1b1 Merge pull request #250 from Sintendo/xcode11-opengl-fix
ruby/CGL: explicitly set current OpenGL context
2019-12-24 18:51:01 +09:00
Sintendo
526df86ee6 ruby/CGL: explicitly set current OpenGL context
On builds made with Xcode 11+ the current OpenGL context wasn't being
properly configured anymore, resulting in shader compilation errors and
a red screen.

Explicitly calling makeCurrentContext fixes this.
2019-12-23 22:30:58 +01:00
byuu
748cf44f35 Added run-ahead support to libretro target [realnc]
Fixed typo in the GUI regarding HD mode 7 +/- hotkeys
2019-12-19 22:04:14 +09:00
byuu
a4f96f0648 Fix link. 2019-12-19 21:16:53 +09:00
byuu
2ca1bab9ed Updated links in readme file. 2019-12-19 21:16:06 +09:00
byuu
1e6a745f19 v113.1
Emergency hotfix for an issue affecting manually created save states.
Still need to determine root cause, but for now, reverting the code.
2019-12-16 01:59:39 +09:00
22 changed files with 1296 additions and 901 deletions

View File

@@ -1,10 +1,10 @@
bsnes
=====
![bsnes icon © byuu](https://images.byuu.org/bsnes/icon-128.png)
![bsnes logo © byuu](https://byuu.org/images/bsnes/github/byuu-bsnes-logo.png)
bsnes is a multi-platform Super Nintendo (Super Famicom) emulator that focuses
on performance, features, and ease of use.
bsnes is a multi-platform Super Nintendo (Super Famicom) emulator from
[byuu](https://byuu.org) that focuses on performance, features, and ease of use.
bsnes currently enjoys 100% known, bug-free compatibility with the entire SNES
library when configured to its most accurate settings, giving it the same
@@ -72,11 +72,16 @@ Standard Features
Links
-----
- [Official website](https://bsnes.byuu.org)
- [Official website](https://byuu.org/bsnes)
- [Official git repository](https://github.com/byuu/bsnes)
- [Developer resources](https://byuu.net)
- [Donations](https://patreon.com/byuu)
Release Builds
--------------
- [Windows binaries](https://byuu.itch.io/bsnes)
Nightly Builds
--------------
@@ -89,4 +94,6 @@ Nightly Builds
Preview
-------
![bsnes preview © byuu](https://images.byuu.org/bsnes/byuu-bsnes-bahamutlagoon.png)
![bsnes user interface © byuu](https://byuu.org/images/bsnes/github/byuu-bsnes-user-interface.png)
![bsnes running Bahamut Lagoon © byuu](https://byuu.org/images/bsnes/github/byuu-bsnes-bahamut-lagoon.png)
![bsnes running Tengai Makyou Zero © byuu](https://byuu.org/images/bsnes/github/byuu-bsnes-tengai-makyou-zero.png)

View File

@@ -1,5 +1,5 @@
database
revision: 2018-09-20
revision: 2020-01-01
//BS Memory (JPN)

View File

@@ -1,5 +1,5 @@
database
revision: 2018-09-20
revision: 2020-01-01
//Sufami Turbo (JPN)

View File

@@ -1,5 +1,5 @@
database
revision: 2018-09-20
revision: 2020-01-01
//Prototypes (JPN)
@@ -125,7 +125,7 @@ game
//Super Famicom (JPN)
database
revision: 2018-09-20
revision: 2020-01-01
game
sha256: 5c4e283efc338958b8dd45ebd6daf133a9eb280420a98e2e1df358ae0242c366
@@ -1277,7 +1277,7 @@ game
size: 0x100
content: Boot
manufacturer: Nintendo
architecture: LR35902
architecture: SM83
identifier: SGB1
game
@@ -1296,7 +1296,7 @@ game
size: 0x100
content: Boot
manufacturer: Nintendo
architecture: LR35902
architecture: SM83
identifier: SGB2
oscillator
frequency: 20971520
@@ -1705,7 +1705,7 @@ game
//Super Nintendo (ESP)
database
revision: 2018-04-14
revision: 2018-09-21
game
sha256: bd5e7a6bc08f64d39c54204b82c6c156f144c03e13c890128588c5faa560659c
@@ -1767,6 +1767,50 @@ game
size: 0x200000
content: Program
game
sha256: bd7e98db82d6b52307be1f3e1fd171e1e7204dc1f8810a95ee2cc64757087e4a
label: The Lost Vikings
name: Lost Vikings, The
region: SNSP-LV-ESP
revision: SESP-LV-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x100000
content: Program
game
sha256: 6eecabd46305ac95d9cf3a17e1392c24a1b68a7a313173ef0c5b5a3a24cf3353
label: Lufia
name: Lufia
region: SNSP-ANIS-ESP
revision: SPAL-ANIS-0
board: SHVC-1A3M-30
memory
type: ROM
size: 0x300000
content: Program
memory
type: RAM
size: 0x2000
content: Save
game
sha256: d70bc7916ed5132c3b0053f2adbb5004d78ccb986210c9440fedf642cac68554
label: MechWarrior
name: MechWarrior
region: SNSP-WM-ESP
revision: SESP-WM-0
board: SHVC-1A1M-10
memory
type: ROM
size: 0x100000
content: Program
memory
type: RAM
size: 0x800
content: Save
game
sha256: d2233d6310522bbf183b6ca9bbe3e2afaf24de0cc4304bff6d0d547d678aed6f
label: Sonic Blast Man
@@ -1779,6 +1823,18 @@ game
size: 0x100000
content: Program
game
sha256: a20d346da18ddabf70dc43f5095c4189c4a646ca8e6d4ed6c68c20e380f50332
label: Super Battletank 2
name: Super Battletank 2
region: SNSP-2X-ESP
revision: SESP-2X-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x200000
content: Program
game
sha256: 9eaf1c46d8a068c910d66f582e23b1155882ddfa4b9fd0813819fc5c008167e2
label: Super James Pond
@@ -1803,6 +1859,46 @@ game
size: 0x100000
content: Program
game
sha256: 7f731f4bb620e682132660da39641dda5762211dca4732f8192dd2411211b822
label: Terranigma
name: Terranigma
region: SNSP-AQTS-ESP
revision: SPAL-AQTS-0
board: SHVC-1J3M-20
memory
type: ROM
size: 0x400000
content: Program
memory
type: RAM
size: 0x2000
content: Save
game
sha256: 981128c93f0753dec7af29ec084f13e704cc5d02414be55bb477fc4b2fef5e58
label: Tiny Toon Adventures: Buster Busts Loose!
name: Tiny Toon Adventures - Buster Busts Loose!
region: SNSP-TA-ESP
revision: SESP-TA-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x100000
content: Program
game
sha256: ce2445ecd0a43f6025dc80857d91dae7c46d33f7821bf98232c2894ca1959da2
label: Turn and Burn: No-Fly Zone
name: Turn and Burn - No-Fly Zone
region: SNSP-ZN-ESP
revision: SESP-ZN-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x200000
content: Program
game
sha256: 9ed876a632aa699047e9efba8a64ab57abc55086a0aab6b5fa67d87ea4647f3f
label: Whirlo
@@ -1846,7 +1942,7 @@ game
//Super Nintendo (EUR)
database
revision: 2018-05-06
revision: 2018-09-21
game
sha256: ec3e81d628a293514e303b44e3b1ac03461ddd1da32764b10b7fab1e507602df
@@ -2904,6 +3000,18 @@ game
size: 0x100000
content: Program
game
sha256: 4ad736a9e1c7f34740afaa7777b8f1a31da4bb4a021e7ae341d1dafd74fa0acc
label: True Lies
name: True Lies
region: SNSP-ATLP-EUR
revision: SPAL-ATLP-0
board: SHVC-1A0N-30
memory
type: ROM
size: 0x200000
content: Program
game
sha256: dbf11d4c77b9aa3416f687201d57d71a23bb8fb0b8fe5e9e8212db3fac036631
label: Turbo Toons
@@ -2942,7 +3050,7 @@ game
game
sha256: 1217ddf2fe475661a54f50e111864102faf854397ce5aceea4297204ebd6cbb6
label: Val d'isére Championship
label: Val d'isère Championship
name: Val d'isere Championship
region: SNSP-8Z-EUR
revision: SPAL-8Z-0
@@ -3016,7 +3124,7 @@ game
//Super Nintendo (FAH)
database
revision: 2018-04-14
revision: 2018-09-21
game
sha256: 0aafd04a43ae29266e43920a7f9954d4a49f6fe43a5abffecc9c2fd5ad7d6cea
@@ -3110,6 +3218,18 @@ game
size: 0x800
content: Save
game
sha256: 826a328f401cdf5a9ee87aaa7a2784cbb21813b165a6c7ca3f702fe6ba8c0804
label: Eric Cantona: Football Challenge
name: Eric Cantona - Football Challenge
region: SNSP-EC-FAH
revision: SPAL-EC-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x80000
content: Program
game
sha256: ce09743d44a54f64862d8c53c11c2c84f2f861ec74c778bd8b05b0a3b07708d6
label: FIFA International Soccer
@@ -3423,10 +3543,22 @@ game
size: 0x180000
content: Program
game
sha256: 5a9103b04b9246f63af9018cbbd7934c6b79076dd9b0062887bd16077cd37c81
label: Val d'Isère Championship
name: Val d'Isere Championship
region: SNSP-8V-FAH
revision: SPAL-8V-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x100000
content: Program
//Super Nintendo (FRA)
database
revision: 2018-04-14
revision: 2018-09-21
game
sha256: 65df600780021f13ced52e7fbc507b7b2e6491b2c5c25fe78d0515dcbe669403
@@ -3660,6 +3792,22 @@ game
size: 0x180000
content: Program
game
sha256: b730adcbb34a19f8fd1c2abe27455cc3256329a9b8a021291e3009ea33004127
label: Secret of Mana
name: Secret of Mana
region: SNSP-K2-FRA
revision: SFRA-K2-1
board: SHVC-1J3M-11
memory
type: ROM
size: 0x200000
content: Program
memory
type: RAM
size: 0x2000
content: Save
game
sha256: f73e6da9e979c839c7c22ec487bea6667d3e65e7d8f9fcc97a2bcdeb4487cddf
label: SimCity
@@ -3676,6 +3824,38 @@ game
size: 0x8000
content: Save
game
sha256: 1f226553ba05fe738d085a88154469bbc9f9058f7dfc320a327259d84ae5f393
label: Soul Blazer
name: Soul Blazer
region: SNSP-SO-FRA
revision: SFRA-SO-0
board: SHVC-1J3M-20
memory
type: ROM
size: 0x100000
content: Program
memory
type: RAM
size: 0x2000
content: Save
game
sha256: 5d0a234a2fcb343d169206d9d7d578507c44f800ead9cc9ccfa0b1d4cb1cc9e5
label: Terranigma
name: Terranigma
region: SNSP-AQTF-FRA
revision: SPAL-AQTF-0
board: SHVC-1J3M-20
memory
type: ROM
size: 0x400000
content: Program
memory
type: RAM
size: 0x2000
content: Save
//Super Nintendo (FRG)
database
@@ -3762,7 +3942,23 @@ game
//Super Nintendo (ITA)
database
revision: 2018-04-14
revision: 2018-09-21
game
sha256: deab7aad7c168423e43eae14e9e31efa29c7341ab84f936be508911ce508b372
label: MechWarrior
name: MechWarrior
region: SNSP-WM-ITA
revision: SITA-WM-0
board: SHVC-1A1M-01
memory
type: ROM
size: 0x100000
content: Program
memory
type: RAM
size: 0x800
content: Save
game
sha256: aafbae4c2a7a5a35c81a183df0470027b4b5690f836592af21c15af6b259328d
@@ -3796,7 +3992,7 @@ game
//Super Nintendo (NOE)
database
revision: 2018-04-14
revision: 2020-01-01
game
sha256: b342d12d71729edebc1911725ea23d58c1a397b27253a5c8cd96cfb58af242a9
@@ -4394,6 +4590,18 @@ game
size: 0x80000
content: Program
game
sha256: 09299d142e485ba2fcdbd9b3a6d1a5acfbc7fc70b06cf22be28479686419a7a9
label: Jimmy Connors Pro Tennis Tour
name: Jimmy Connors Pro Tennis Tour
region: SNSP-JC-NOE
revision: SFRG-JC-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x80000
content: Program
game
sha256: 74c55ea3c9733bf263628a260df7492fc840d7de1c3fceebb7bcf6d99a8c81d6
label: Joe & Mac: Caveman Ninja
@@ -4470,6 +4678,18 @@ game
size: 0x100000
content: Program
game
sha256: 4a7444780a750f97943d974589586d4cf89d8957e396cc5a7ad565cd4c1b70a7
label: The Legend of the Mystical Ninja
name: Legend of the Mystical Ninja, The
region: SNSP-GG-NOE
revision: SFRG-GG-0
board: SHVC-1A0N-20
memory
type: ROM
size: 0x100000
content: Program
game
sha256: 5ec66298ddb579b35cc5d3df5bfeeee05bdf71347565c7c5f5f3869bf4f1e469
label: Looney Tunes Basketball
@@ -4820,7 +5040,7 @@ game
size: 0x100
content: Boot
manufacturer: Nintendo
architecture: LR35902
architecture: SM83
identifier: SGB1
game
@@ -4975,6 +5195,18 @@ game
size: 0x100000
content: Program
game
sha256: 94e6fe78bb1a1d89ccfd74ad92e2a489f8e2e257d6dfe62404155741763f962f
label: True Lies
name: True Lies
region: SNSP-ATLD-NOE
revision: SPAL-ATLD-0
board: SHVC-1A0N-30
memory
type: ROM
size: 0x200000
content: Program
game
sha256: a1105819d48c04d680c8292bbfa9abbce05224f1bc231afd66af43b7e0a1fd4e
label: Unirally
@@ -5054,7 +5286,7 @@ game
//Super Nintendo (SCN)
database
revision: 2018-04-14
revision: 2018-09-21
game
sha256: beb379ba48f63561c0f939ecd8f623ec06c1b5e06976eef9887e5c62f3df2766
@@ -5080,6 +5312,22 @@ game
size: 0x300000
content: Program
game
sha256: 4fb9eb8fa4d9c3a0b6c24bac5b0a0b0f079f083f5e6dfa937a161c8f4bcde853
label: Shadowrun
name: Shadowrun
region: SNSP-WR-SCN
revision: SSWE-WR-0
board: SHVC-1A3M-20
memory
type: ROM
size: 0x100000
content: Program
memory
type: RAM
size: 0x2000
content: Save
game
sha256: e15247495311e91db9431d61777a264d4b42def011291d512b273fc8acd1cbfa
label: Soul Blazer
@@ -5096,6 +5344,18 @@ game
size: 0x2000
content: Save
game
sha256: 687c4f9a14cc16605f5e92aa0fe33bf083fe8e39ba781676259fadf932480890
label: Tintin i Tibet
name: Tintin i Tibet
region: SNSP-AT6X-SCN
revision: SPAL-AT6X-0
board: SHVC-2A0N-20
memory
type: ROM
size: 0x180000
content: Program
game
sha256: a6297356fb06f1575b432fae463171f53e3b786fd77b841557547a9117fb52fe
label: X-Zone
@@ -5761,7 +6021,7 @@ game
//Super Nintendo (USA)
database
revision: 2018-09-20
revision: 2020-01-01
game
sha256: 2ffe8828480f943056fb1ab5c3c84d48a0bf8cbe3ed7c9960b349b59adb07f3b
@@ -6555,8 +6815,8 @@ game
sha256: 6fa6b8a8804ff6544bdedf94339a86ba64ce0b6dbf059605abb1cd6f102d3483
label: Bill Laimbeer's Combat Basketball
name: Bill Laimbeer's Combat Basketball
region: SNS-C8-USA
revision: SNS-C8-0
region: SNS-CB-USA
revision: SNS-CB-0
board: SHVC-1A3B-12
memory
type: ROM
@@ -13628,7 +13888,7 @@ game
size: 0x100
content: Boot
manufacturer: Nintendo
architecture: LR35902
architecture: SM83
identifier: SGB1
game
@@ -14516,8 +14776,8 @@ game
sha256: 3cdebbd8adc4bb6773a7995f542fdac49adefca71cba583255a1c1bf37ac3946
label: Tetris & Dr. Mario
name: Tetris & Dr. Mario
region: SNS-AFTE-USA
revision: SNS-AFTE-0
region: SNS-ATFE-USA
revision: SNS-ATFE-0
board: SHVC-1A0N-30
memory
type: ROM

View File

@@ -29,7 +29,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "bsnes";
static const string Version = "113";
static const string Version = "114";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "https://byuu.org";

View File

@@ -101,7 +101,6 @@ Game::Memory::Memory(Markup::Node node) {
}
auto Game::Memory::name() const -> string {
if(identifier) return string{identifier, ".", content, ".", type}.downcase();
if(architecture) return string{architecture, ".", content, ".", type}.downcase();
return string{content, ".", type}.downcase();
}

View File

@@ -169,7 +169,7 @@ auto SuperFamicom::region() const -> string {
if(D == 'P') region = {"SNSP-", code, "-EUR"};
if(D == 'S') region = {"SNSP-", code, "-ESP"};
if(D == 'U') region = {"SNSP-", code, "-AUS"};
if(D == 'W') region = {"SNSP-", code, "-SCN"};
if(D == 'X') region = {"SNSP-", code, "-SCN"};
}
if(!region) {
@@ -187,6 +187,7 @@ auto SuperFamicom::region() const -> string {
if(E == 0x0f) region = {"CAN"};
if(E == 0x10) region = {"BRA"};
if(E == 0x11) region = {"AUS"};
if(E == 0x12) region = {"SCN"};
}
return region ? region : "NTSC";
@@ -194,7 +195,13 @@ auto SuperFamicom::region() const -> string {
auto SuperFamicom::videoRegion() const -> string {
auto region = data[headerAddress + 0x29];
return (region <= 0x01 || region >= 0x0c) ? "NTSC" : "PAL";
if(region == 0x00) return "NTSC"; //JPN
if(region == 0x01) return "NTSC"; //USA
if(region == 0x0b) return "NTSC"; //ROC
if(region == 0x0d) return "NTSC"; //KOR
if(region == 0x0f) return "NTSC"; //CAN
if(region == 0x10) return "NTSC"; //BRA
return "PAL";
}
auto SuperFamicom::revision() const -> string {
@@ -223,7 +230,7 @@ auto SuperFamicom::revision() const -> string {
if(D == 'P') revision = {"SNSP-", code, "-", F};
if(D == 'S') revision = {"SNSP-", code, "-", F};
if(D == 'U') revision = {"SNSP-", code, "-", F};
if(D == 'W') revision = {"SNSP-", code, "-", F};
if(D == 'X') revision = {"SNSP-", code, "-", F};
}
if(!revision) {
@@ -259,6 +266,9 @@ auto SuperFamicom::board() const -> string {
if(headerAddress == 0x40ffb0) mode = "EXHIROM-";
}
//this game's title ovewrites the map mode with '!' (0x21), but is a LOROM game
if(title() == "YUYU NO QUIZ DE GO!GO") mode = "LOROM-";
if(mode == "LOROM-" && headerAddress == 0x407fb0) mode = "EXLOROM-";
bool epsonRTC = false;

View File

@@ -295,9 +295,9 @@ auto WDC65816::disassemble(uint24 address, bool e, bool m, bool x) -> string {
op(0x71, "adc", indirectIndexedY)
op(0x72, "adc", indirect)
op(0x73, "adc", stackIndirect)
op(0x74, "stz", absoluteX)
op(0x75, "adc", absoluteX)
op(0x76, "ror", absoluteX)
op(0x74, "stz", directX)
op(0x75, "adc", directX)
op(0x76, "ror", directX)
op(0x77, "adc", indirectLongY)
op(0x78, "sei", implied)
op(0x79, "adc", absoluteY)

View File

@@ -202,34 +202,73 @@ auto CPU::dmaEdge() -> void {
//called every 256 clocks; see CPU::step()
auto CPU::joypadEdge() -> void {
if(vcounter() >= ppu.vdisp()) {
//cache enable state at first iteration
if(status.autoJoypadCounter == 0) status.autoJoypadLatch = io.autoJoypadPoll;
status.autoJoypadActive = status.autoJoypadCounter <= 15;
//fast joypad polling is a hack to work around edge cases not currently emulated in auto-joypad polling.
//below is a list of games that have had input issues over the years.
//Nuke (PD): inputs do not work
//Super Conflict: sends random inputs even with no buttons pressed
//Super Star Wars: Start button auto-unpauses
//Taikyoku Igo - Goliath: start button not acknowledged
//Tatakae Genshijin 2: attract sequence ends early
//Williams Arcade's Greatest Hits: inputs fire on their own; or menu items sometimes skipped
//World Masters Golf: inputs fail to register; or holding D-pad should only move the cursor once, not continuously
if(status.autoJoypadActive && status.autoJoypadLatch) {
if(status.autoJoypadCounter == 0) {
controllerPort1.device->latch(1);
controllerPort2.device->latch(1);
controllerPort1.device->latch(0);
controllerPort2.device->latch(0);
if(configuration.hacks.cpu.fastJoypadPolling) {
//Taikyoku Igo - Goliath
//Williams Arcade's Greatest Hits
//World Masters Golf
if(!status.autoJoypadCounter && vcounter() >= ppu.vdisp()) {
controllerPort1.device->latch(1);
controllerPort2.device->latch(1);
controllerPort1.device->latch(0);
controllerPort2.device->latch(0);
//shift registers are cleared at start of auto joypad polling
io.joy1 = 0;
io.joy2 = 0;
io.joy3 = 0;
io.joy4 = 0;
io.joy1 = 0;
io.joy2 = 0;
io.joy3 = 0;
io.joy4 = 0;
for(uint index : range(16)) {
uint2 port0 = controllerPort1.device->data();
uint2 port1 = controllerPort2.device->data();
io.joy1 = io.joy1 << 1 | port0.bit(0);
io.joy2 = io.joy2 << 1 | port1.bit(0);
io.joy3 = io.joy3 << 1 | port0.bit(1);
io.joy4 = io.joy4 << 1 | port1.bit(1);
}
uint2 port0 = controllerPort1.device->data();
uint2 port1 = controllerPort2.device->data();
io.joy1 = io.joy1 << 1 | port0.bit(0);
io.joy2 = io.joy2 << 1 | port1.bit(0);
io.joy3 = io.joy3 << 1 | port0.bit(1);
io.joy4 = io.joy4 << 1 | port1.bit(1);
status.autoJoypadCounter = 16;
}
} else {
if(vcounter() >= ppu.vdisp()) {
//cache enable state at first iteration
if(status.autoJoypadCounter == 0) status.autoJoypadLatch = io.autoJoypadPoll;
status.autoJoypadActive = status.autoJoypadCounter <= 15;
status.autoJoypadCounter++;
if(status.autoJoypadActive && status.autoJoypadLatch) {
if(status.autoJoypadCounter == 0) {
controllerPort1.device->latch(1);
controllerPort2.device->latch(1);
controllerPort1.device->latch(0);
controllerPort2.device->latch(0);
//shift registers are cleared at start of auto joypad polling
io.joy1 = 0;
io.joy2 = 0;
io.joy3 = 0;
io.joy4 = 0;
}
uint2 port0 = controllerPort1.device->data();
uint2 port1 = controllerPort2.device->data();
io.joy1 = io.joy1 << 1 | port0.bit(0);
io.joy2 = io.joy2 << 1 | port1.bit(0);
io.joy3 = io.joy3 << 1 | port0.bit(1);
io.joy4 = io.joy4 << 1 | port1.bit(1);
}
status.autoJoypadCounter++;
}
}
}

View File

@@ -21,6 +21,7 @@ auto Configuration::process(Markup::Node document, bool load) -> void {
bind(text, "Hacks/Entropy", hacks.entropy);
bind(natural, "Hacks/CPU/Overclock", hacks.cpu.overclock);
bind(boolean, "Hacks/CPU/FastMath", hacks.cpu.fastMath);
bind(boolean, "Hacks/CPU/FastJoypadPolling", hacks.cpu.fastJoypadPolling);
bind(boolean, "Hacks/PPU/Fast", hacks.ppu.fast);
bind(boolean, "Hacks/PPU/Deinterlace", hacks.ppu.deinterlace);
bind(natural, "Hacks/PPU/RenderCycle", hacks.ppu.renderCycle);

View File

@@ -33,6 +33,7 @@ struct Configuration {
struct CPU {
uint overclock = 100;
bool fastMath = false;
bool fastJoypadPolling = false;
} cpu;
struct PPU {
bool fast = true;

View File

@@ -94,6 +94,15 @@ auto PPU::main() -> void {
auto PPU::scanline() -> void {
if(vcounter() == 0) {
if(latch.overscan && !io.overscan) {
//when disabling overscan, clear the overscan area that won't be rendered to:
for(uint y = 1; y <= 240; y++) {
if(y >= 8 && y <= 231) continue;
auto output = ppu.output + y * 1024;
memory::fill<uint16>(output, 1024);
}
}
ppubase.display.interlace = io.interlace;
ppubase.display.overscan = io.overscan;
latch.overscan = io.overscan;

View File

@@ -1,5 +1,13 @@
auto PPU::main() -> void {
if(vcounter() == 0) {
if(display.overscan && !io.overscan) {
//when disabling overscan, clear the overscan area that won't be rendered to:
for(uint y = 1; y <= 240; y++) {
if(y >= 8 && y <= 231) continue;
auto output = ppu.output + y * 1024;
memory::fill<uint16>(output, 1024);
}
}
display.interlace = io.interlace;
display.overscan = io.overscan;
bg1.frame();

View File

@@ -35,8 +35,9 @@ auto SMP::waitIdle(maybe<uint16> addr, bool half) -> void {
auto SMP::step(uint clocks) -> void {
clock += clocks * (uint64_t)cpu.frequency;
dsp.clock -= clocks;
synchronizeCPU();
synchronizeDSP();
//forcefully sync SMP to CPU in case chips are not communicating
if(clock > 768 * 24 * (int64_t)24'000'000) synchronizeCPU();
}
auto SMP::stepIdle(uint clocks) -> void {

View File

@@ -130,14 +130,14 @@ auto InputManager::bindHotkeys() -> void {
program.frameAdvanceLock = false;
}));
hotkeys.append(InputHotkey("Increase HD Mode 7").onPress([] {
hotkeys.append(InputHotkey("Decrease HD Mode 7").onPress([] {
int index = enhancementSettings.mode7Scale.selected().offset() - 1;
if(index < 0) return;
enhancementSettings.mode7Scale.item(index).setSelected();
enhancementSettings.mode7Scale.doChange();
}));
hotkeys.append(InputHotkey("Decrease HD Mode 7").onPress([] {
hotkeys.append(InputHotkey("Increase HD Mode 7").onPress([] {
int index = enhancementSettings.mode7Scale.selected().offset() + 1;
if(index >= enhancementSettings.mode7Scale.itemCount()) return;
enhancementSettings.mode7Scale.item(index).setSelected();

View File

@@ -179,7 +179,7 @@ auto Presentation::create() -> void {
helpMenu.setText(tr("Help"));
documentation.setIcon(Icon::Application::Browser).setText({tr("Documentation"), " ..."}).onActivate([&] {
invoke("https://doc.byuu.org/bsnes");
invoke("https://byuu.org/doc/bsnes");
});
aboutSameBoy.setIcon(Icon::Prompt::Question).setText({tr("About SameBoy"), " ..."}).onActivate([&] {
AboutDialog()

View File

@@ -1,5 +1,6 @@
auto Program::hackCompatibility() -> void {
string entropy = settings.emulator.hack.entropy;
bool fastJoypadPolling = false;
bool fastPPU = settings.emulator.hack.ppu.fast;
bool fastPPUNoSpriteLimit = settings.emulator.hack.ppu.noSpriteLimit;
bool fastDSP = settings.emulator.hack.dsp.fast;
@@ -9,12 +10,31 @@ auto Program::hackCompatibility() -> void {
auto title = superFamicom.title;
auto region = superFamicom.region;
//sometimes menu options are skipped over in the main menu with cycle-based joypad polling
if(title == "Arcades Greatest Hits") fastJoypadPolling = true;
//the start button doesn't work in this game with cycle-based joypad polling
if(title == "TAIKYOKU-IGO Goliath") fastJoypadPolling = true;
//holding up or down on the menu quickly cycles through options instead of stopping after each button press
if(title == "WORLD MASTERS GOLF") fastJoypadPolling = true;
//relies on mid-scanline rendering techniques
if(title == "AIR STRIKE PATROL" || title == "DESERT FIGHTER") fastPPU = false;
//the dialogue text is blurry due to an issue in the scanline-based renderer's color math support
if(title == "マーヴェラス") fastPPU = false;
//stage 2 uses pseudo-hires in a way that's not compatible with the scanline-based renderer
if(title == "SFC クレヨンシンチャン") fastPPU = false;
//title screen game select (after choosing a game) changes OAM tiledata address mid-frame
//this is only supported by the cycle-based PPU renderer
if(title == "Winter olympics") fastPPU = false;
//title screen shows remnants of the flag after choosing a language with the scanline-based renderer
if(title == "WORLD CUP STRIKER") fastPPU = false;
//relies on cycle-accurate writes to the echo buffer
if(title == "KOUSHIEN_2") fastDSP = false;
@@ -28,7 +48,7 @@ auto Program::hackCompatibility() -> void {
if(title == "ADVENTURES OF FRANKEN" && region == "PAL") renderCycle = 32;
//fixes an errant scanline on the title screen due to writing to PPU registers too late
if(title == "FIREPOWER 2000") renderCycle = 32;
if(title == "FIREPOWER 2000" || title == "SUPER SWIV") renderCycle = 32;
//fixes an errant scanline on the title screen due to writing to PPU registers too late
if(title == "NHL '94" || title == "NHL PROHOCKEY'94") renderCycle = 32;
@@ -41,9 +61,13 @@ auto Program::hackCompatibility() -> void {
//to appear in the background of stage 12. this one is a bug in the original game, so only enable
//it if the hotfixes option has been enabled.
if(title == "The Hurricanes") entropy = "None";
//Frisky Tom attract sequence sometimes hangs when WRAM is initialized to pseudo-random patterns
if(title == "ニチブツ・アーケード・クラシックス") entropy = "None";
}
emulator->configure("Hacks/Entropy", entropy);
emulator->configure("Hacks/CPU/FastJoypadPolling", fastJoypadPolling);
emulator->configure("Hacks/PPU/Fast", fastPPU);
emulator->configure("Hacks/PPU/NoSpriteLimit", fastPPUNoSpriteLimit);
emulator->configure("Hacks/PPU/RenderCycle", renderCycle);

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ extern const unsigned char Icon[3463];
extern const unsigned char Logo[23467];
extern const unsigned char SameBoy[32358];
namespace System {
extern const unsigned char Boards[31515];
extern const unsigned char Boards[31506];
extern const unsigned char IPLROM[64];
}
}

View File

@@ -109,7 +109,7 @@ board: SGB-R-10
map address=40-7d,c0-ff:0000-7fff mask=0x8000
processor identifier=ICD revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff
memory type=ROM content=Boot architecture=LR35902
memory type=ROM content=Boot architecture=SM83
slot type=GameBoy
board: SHVC-1A0N-(01,02,10,20,30)
@@ -548,7 +548,7 @@ board: SHVC-SGB2-01
map address=40-7d,c0-ff:0000-7fff mask=0x8000
processor identifier=ICD revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff
memory type=ROM content=Boot architecture=LR35902
memory type=ROM content=Boot architecture=SM83
oscillator
slot type=GameBoy
@@ -757,7 +757,7 @@ board: GB-LOROM
map address=40-7d,c0-ff:0000-7fff mask=0x8000
processor identifier=ICD revision=2
map address=00-3f,80-bf:6000-67ff,7000-7fff
memory type=ROM content=Boot architecture=LR35902
memory type=ROM content=Boot architecture=SM83
oscillator
slot type=GameBoy

View File

@@ -1,3 +1,4 @@
#include <cassert>
#include "libretro.h"
static retro_environment_t environ_cb;
@@ -14,6 +15,8 @@ static int16_t audio_buffer[AUDIOBUFSIZE];
static uint16_t audio_buffer_index = 0;
static uint16_t audio_buffer_max = AUDIOBUFSIZE;
static int run_ahead_frames = 0;
static void audio_queue(int16_t left, int16_t right)
{
audio_buffer[audio_buffer_index++] = left;
@@ -231,6 +234,15 @@ static void flush_variables()
{
sgb_bios = variable.value;
}
variable = { "bsnes_run_ahead_frames", nullptr };
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &variable) && variable.value)
{
if (strcmp(variable.value, "OFF") == 0)
run_ahead_frames = 0;
else
run_ahead_frames = atoi(variable.value);
}
}
static void check_variables()
@@ -409,6 +421,7 @@ static void set_environment_info(retro_environment_t cb)
{ "bsnes_coprocessor_delayed_sync", "Coprocessor Delayed Sync; ON|OFF" },
{ "bsnes_coprocessor_prefer_hle", "Coprocessor Prefer HLE; ON|OFF" },
{ "bsnes_sgb_bios", "Preferred Super GameBoy BIOS (restart); SGB1.sfc|SGB2.sfc" },
{ "bsnes_run_ahead_frames", "Amount of frames for run-ahead; OFF|1|2|3|4" },
{ nullptr },
};
cb(RETRO_ENVIRONMENT_SET_VARIABLES, const_cast<retro_variable *>(vars));
@@ -502,11 +515,33 @@ RETRO_API void retro_reset()
emulator->reset();
}
static void run_with_runahead(const int frames)
{
assert(frames > 0);
emulator->setRunAhead(true);
emulator->run();
auto state = emulator->serialize(0);
for (int i = 0; i < frames - 1; ++i) {
emulator->run();
}
emulator->setRunAhead(false);
emulator->run();
state.setMode(serializer::Mode::Load);
emulator->unserialize(state);
}
RETRO_API void retro_run()
{
check_variables();
input_poll();
emulator->run();
bool is_fast_forwarding = false;
environ_cb(RETRO_ENVIRONMENT_GET_FASTFORWARDING, &is_fast_forwarding);
if (is_fast_forwarding || run_ahead_frames == 0)
emulator->run();
else
run_with_runahead(run_ahead_frames);
}
RETRO_API size_t retro_serialize_size()

View File

@@ -145,6 +145,7 @@ private:
[view setWantsBestResolutionOpenGLSurface:YES];
[context addSubview:view];
[openGLContext setView:view];
[openGLContext makeCurrentContext];
[[view window] makeFirstResponder:view];
[view lockFocus];