mirror of
https://github.com/Michael-Prince-Sharpe/bsnes-classic.git
synced 2025-04-02 10:21:42 -04:00
Compare commits
22 commits
Author | SHA1 | Date | |
---|---|---|---|
|
8b547f1c5d | ||
|
e93c847785 | ||
|
57d813f20e | ||
|
b795baab6d | ||
|
3adabb8bf3 | ||
|
ff735792d7 | ||
|
4b143b74e3 | ||
|
a47e32ce96 | ||
|
994b35cd30 | ||
|
04c29e5279 | ||
|
22e2e245c5 | ||
|
7463b0294f | ||
|
4d70efe386 | ||
|
c583f8eebf | ||
|
11888c6b6e | ||
|
de984287c0 | ||
|
2292635fa1 | ||
|
35376200d4 | ||
|
cc1c0e387b | ||
|
c80eea5392 | ||
|
546c443a9a | ||
|
9919878654 |
27 changed files with 227 additions and 199 deletions
52
README.md
Normal file
52
README.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# bsnes-classic
|
||||
|
||||
This fork of bsnes-classic also includes perfect emulation of Super FX and Super FX 2 games as well as an experimental upscaling 6xBRZ filter for OpenGL. All courtesy of Zenju, CarterLi and awjackson.
|
||||
|
||||
## Building on Windows (64-bit)
|
||||
|
||||
- Get mingw-w64 with 64-bit Qt 4.8.6 and do a full installation of the exe (https://sourceforge.net/projects/qt64ng/files/qt/x86-64/4.8.6/mingw-4.9/seh/)
|
||||
- Set following environment variables (right click on My Computer, then Properties, Advanced, Environment variables):
|
||||
QTDIR to C:\Qt\4.X.X (or whatever path you installed QT)
|
||||
QMAKESPEC to win32-g++
|
||||
and adjust PATH, add C:\Qt\4.X.X\bin and C:\MinGW\bin (or whatever path you installed MinGW)
|
||||
- Logout/login or restart after changing environment variables, otherwise it won't work
|
||||
- Run the terminal from minGW in the start menu and navigate to the Makefiles
|
||||
- Run `mingw32-make`
|
||||
|
||||
Building with the original MinGW used to be the preferred way to do it, but made building "out of the box" annoying for various reasons (including requiring outdated DirectX headers/libs and problems with some native Windows code) and is no longer supported.
|
||||
|
||||
## Building on OS X
|
||||
|
||||
- Install a C++ toolchain ([Xcode](https://developer.apple.com) is probably the easiest route)
|
||||
- Install Qt 4.8 (get [Brew](http://brew.sh) and run `brew install qt`)
|
||||
- Make sure the `qtpath` environment variable points to your Qt installation, ie. add `export qtpath=/usr/local/Cellar/qt/4.8.7_2` to .bash_profile.
|
||||
- Run `make`from the bsnes directory.
|
||||
|
||||
If you're running macOS 10.12 Sierra you will (probably not) be able to install Qt4 using brew. If so, try installing this unofficial branch:
|
||||
|
||||
```
|
||||
brew install cartr/qt4/qt
|
||||
brew linkapps qt
|
||||
```
|
||||
|
||||
## Building on Linux / other *nix
|
||||
|
||||
As there is no ``configure`` step, make sure necessary Qt4/X11 packages are installed. On a Debian/Ubuntu system, it would require a command like:
|
||||
|
||||
```
|
||||
apt-get install libqt4-dev libqt4-dev-bin libxv-dev libsdl1.2-dev libao-dev
|
||||
libopenal-dev g++
|
||||
```
|
||||
|
||||
Afterwards, run ``make`` and if everything works out correctly you will find the output binary in the ``out/`` directory.
|
||||
|
||||
The snesfilter, snesreader, and supergameboy plugins can all be built by running make (or mingw32-make) after you've configured your environment to build bsnes itself.
|
||||
After building, just copy the .dll, .so, or .dylib files into the same directory as bsnes itself.
|
||||
|
||||
This fork of bsnes doesn't include the alternate UI based on byuu's `phoenix` library. The purpose of this fork is primarily to add additional UI functionality and I have no intention of implementing every new feature twice using completely different libraries just to keep both versions of the UI at parity.
|
||||
|
||||
bsnes v073 and its derivatives are licensed under the GPL v2; see *Help > License ...* for more information.
|
||||
|
||||
## Contributors
|
||||
|
||||
See *Help > Documentation ...* for a list of authors.
|
|
@ -11,7 +11,7 @@
|
|||
namespace nall {
|
||||
|
||||
struct Keyboard;
|
||||
Keyboard& keyboard(unsigned = 0);
|
||||
Keyboard keyboard(unsigned = 0);
|
||||
|
||||
static const char KeyboardScancodeName[][64] = {
|
||||
"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
|
||||
|
@ -122,12 +122,9 @@ struct Keyboard {
|
|||
Keyboard(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Keyboard& keyboard(unsigned id) {
|
||||
static Keyboard kb0(0), kb1(1), kb2(2), kb3(3), kb4(4), kb5(5), kb6(6), kb7(7);
|
||||
switch(id) { default:
|
||||
case 0: return kb0; case 1: return kb1; case 2: return kb2; case 3: return kb3;
|
||||
case 4: return kb4; case 5: return kb5; case 6: return kb6; case 7: return kb7;
|
||||
}
|
||||
inline Keyboard keyboard(unsigned id) {
|
||||
assert(id < Keyboard::Count);
|
||||
return Keyboard(id);
|
||||
}
|
||||
|
||||
static const char MouseScancodeName[][64] = {
|
||||
|
@ -136,7 +133,7 @@ static const char MouseScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Mouse;
|
||||
Mouse& mouse(unsigned = 0);
|
||||
Mouse mouse(unsigned = 0);
|
||||
|
||||
struct Mouse {
|
||||
const unsigned ID;
|
||||
|
@ -220,12 +217,9 @@ struct Mouse {
|
|||
Mouse(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Mouse& mouse(unsigned id) {
|
||||
static Mouse ms0(0), ms1(1), ms2(2), ms3(3), ms4(4), ms5(5), ms6(6), ms7(7);
|
||||
switch(id) { default:
|
||||
case 0: return ms0; case 1: return ms1; case 2: return ms2; case 3: return ms3;
|
||||
case 4: return ms4; case 5: return ms5; case 6: return ms6; case 7: return ms7;
|
||||
}
|
||||
inline Mouse mouse(unsigned id) {
|
||||
assert(id < Mouse::Count);
|
||||
return Mouse(id);
|
||||
}
|
||||
|
||||
static const char JoypadScancodeName[][64] = {
|
||||
|
@ -239,7 +233,7 @@ static const char JoypadScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Joypad;
|
||||
Joypad& joypad(unsigned = 0);
|
||||
Joypad joypad(unsigned = 0);
|
||||
|
||||
struct Joypad {
|
||||
const unsigned ID;
|
||||
|
@ -345,12 +339,9 @@ struct Joypad {
|
|||
Joypad(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Joypad& joypad(unsigned id) {
|
||||
static Joypad jp0(0), jp1(1), jp2(2), jp3(3), jp4(4), jp5(5), jp6(6), jp7(7);
|
||||
switch(id) { default:
|
||||
case 0: return jp0; case 1: return jp1; case 2: return jp2; case 3: return jp3;
|
||||
case 4: return jp4; case 5: return jp5; case 6: return jp6; case 7: return jp7;
|
||||
}
|
||||
inline Joypad joypad(unsigned id) {
|
||||
assert(id < Joypad::Count);
|
||||
return Joypad(id);
|
||||
}
|
||||
|
||||
struct Scancode {
|
||||
|
|
|
@ -40,7 +40,7 @@ static BOOST::uint8_t const initial_regs [SPC_DSP::register_count] =
|
|||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
|
||||
|
||||
// 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80,
|
||||
// 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF,
|
||||
|
@ -856,6 +856,7 @@ void SPC_DSP::soft_reset_common()
|
|||
void SPC_DSP::soft_reset()
|
||||
{
|
||||
REG(flg) = 0xE0;
|
||||
REG(endx) = 0xFF;
|
||||
soft_reset_common();
|
||||
}
|
||||
|
||||
|
|
|
@ -111,8 +111,9 @@ void PPU::mmio_w210d(uint8 value) {
|
|||
regs.m7_hofs = (value << 8) | regs.m7_latch;
|
||||
regs.m7_latch = value;
|
||||
|
||||
regs.bg_hofs[BG1] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG1] >> 8) & 7);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_hofs[BG1] = (value << 8) | (regs.bg_ppu1ofslatch & ~7) | (regs.bg_ppu2ofslatch & 7);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
regs.bg_ppu2ofslatch = value;
|
||||
}
|
||||
|
||||
//BG1VOFS
|
||||
|
@ -120,44 +121,47 @@ void PPU::mmio_w210e(uint8 value) {
|
|||
regs.m7_vofs = (value << 8) | regs.m7_latch;
|
||||
regs.m7_latch = value;
|
||||
|
||||
regs.bg_vofs[BG1] = (value << 8) | (regs.bg_ofslatch);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_vofs[BG1] = (value << 8) | (regs.bg_ppu1ofslatch);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
}
|
||||
|
||||
//BG2HOFS
|
||||
void PPU::mmio_w210f(uint8 value) {
|
||||
regs.bg_hofs[BG2] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG2] >> 8) & 7);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_hofs[BG2] = (value << 8) | (regs.bg_ppu1ofslatch & ~7) | (regs.bg_ppu2ofslatch & 7);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
regs.bg_ppu2ofslatch = value;
|
||||
}
|
||||
|
||||
//BG2VOFS
|
||||
void PPU::mmio_w2110(uint8 value) {
|
||||
regs.bg_vofs[BG2] = (value << 8) | (regs.bg_ofslatch);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_vofs[BG2] = (value << 8) | (regs.bg_ppu1ofslatch);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
}
|
||||
|
||||
//BG3HOFS
|
||||
void PPU::mmio_w2111(uint8 value) {
|
||||
regs.bg_hofs[BG3] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG3] >> 8) & 7);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_hofs[BG3] = (value << 8) | (regs.bg_ppu1ofslatch & ~7) | (regs.bg_ppu2ofslatch & 7);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
regs.bg_ppu2ofslatch = value;
|
||||
}
|
||||
|
||||
//BG3VOFS
|
||||
void PPU::mmio_w2112(uint8 value) {
|
||||
regs.bg_vofs[BG3] = (value << 8) | (regs.bg_ofslatch);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_vofs[BG3] = (value << 8) | (regs.bg_ppu1ofslatch);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
}
|
||||
|
||||
//BG4HOFS
|
||||
void PPU::mmio_w2113(uint8 value) {
|
||||
regs.bg_hofs[BG4] = (value << 8) | (regs.bg_ofslatch & ~7) | ((regs.bg_hofs[BG4] >> 8) & 7);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_hofs[BG4] = (value << 8) | (regs.bg_ppu1ofslatch & ~7) | (regs.bg_ppu2ofslatch & 7);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
regs.bg_ppu2ofslatch = value;
|
||||
}
|
||||
|
||||
//BG4VOFS
|
||||
void PPU::mmio_w2114(uint8 value) {
|
||||
regs.bg_vofs[BG4] = (value << 8) | (regs.bg_ofslatch);
|
||||
regs.bg_ofslatch = value;
|
||||
regs.bg_vofs[BG4] = (value << 8) | (regs.bg_ppu1ofslatch);
|
||||
regs.bg_ppu1ofslatch = value;
|
||||
}
|
||||
|
||||
//VMAIN
|
||||
|
|
|
@ -45,7 +45,8 @@ struct {
|
|||
uint16 bg_tdaddr[4];
|
||||
|
||||
//$210d-$2114
|
||||
uint8 bg_ofslatch;
|
||||
uint8 bg_ppu1ofslatch;
|
||||
uint8 bg_ppu2ofslatch;
|
||||
uint16 m7_hofs, m7_vofs;
|
||||
uint16 bg_hofs[4];
|
||||
uint16 bg_vofs[4];
|
||||
|
|
|
@ -191,7 +191,8 @@ void PPU::power() {
|
|||
regs.bg_tdaddr[BG4] = 0x0000;
|
||||
|
||||
//$210d-$2114
|
||||
regs.bg_ofslatch = 0x00;
|
||||
regs.bg_ppu1ofslatch = 0x00;
|
||||
regs.bg_ppu2ofslatch = 0x00;
|
||||
regs.m7_hofs = regs.m7_vofs = 0x0000;
|
||||
regs.bg_hofs[BG1] = regs.bg_vofs[BG1] = 0x0000;
|
||||
regs.bg_hofs[BG2] = regs.bg_vofs[BG2] = 0x0000;
|
||||
|
|
|
@ -53,7 +53,8 @@ void PPU::serialize(serializer &s) {
|
|||
|
||||
for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_tdaddr[n]);
|
||||
|
||||
s.integer(regs.bg_ofslatch);
|
||||
s.integer(regs.bg_ppu1ofslatch);
|
||||
s.integer(regs.bg_ppu2ofslatch);
|
||||
s.integer(regs.m7_hofs);
|
||||
s.integer(regs.m7_vofs);
|
||||
for(unsigned n = 0; n < 4; n++) s.integer(regs.bg_hofs[n]);
|
||||
|
|
|
@ -383,8 +383,9 @@ void PPU::mmio_write(unsigned addr, uint8 data) {
|
|||
regs.mode7_hoffset = (data << 8) | regs.mode7_latchdata;
|
||||
regs.mode7_latchdata = data;
|
||||
|
||||
bg1.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg1.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
bg1.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata & 7);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -392,44 +393,47 @@ void PPU::mmio_write(unsigned addr, uint8 data) {
|
|||
regs.mode7_voffset = (data << 8) | regs.mode7_latchdata;
|
||||
regs.mode7_latchdata = data;
|
||||
|
||||
bg1.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg1.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x0f: { //BG2HOFS
|
||||
bg2.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg2.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
bg2.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata & 7);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x10: { //BG2VOFS
|
||||
bg2.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg2.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x11: { //BG3HOFS
|
||||
bg3.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg3.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
return;
|
||||
bg3.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata & 7);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x12: { //BG3VOFS
|
||||
bg3.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg3.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x13: { //BG4HOFS
|
||||
bg4.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg4.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
return;
|
||||
bg4.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata & 7);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
case 0x14: { //BG4VOFS
|
||||
bg4.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg4.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -688,7 +692,8 @@ void PPU::mmio_reset() {
|
|||
regs.vram_readbuffer = 0;
|
||||
regs.oam_latchdata = 0;
|
||||
regs.cgram_latchdata = 0;
|
||||
regs.bgofs_latchdata = 0;
|
||||
regs.bgofs_ppu1latchdata = 0;
|
||||
regs.bgofs_ppu2latchdata = 0;
|
||||
regs.mode7_latchdata = 0;
|
||||
|
||||
regs.counters_latched = 0;
|
||||
|
|
|
@ -6,7 +6,8 @@ struct Regs {
|
|||
uint16 vram_readbuffer;
|
||||
uint8 oam_latchdata;
|
||||
uint8 cgram_latchdata;
|
||||
uint8 bgofs_latchdata;
|
||||
uint8 bgofs_ppu1latchdata;
|
||||
uint8 bgofs_ppu2latchdata;
|
||||
uint8 mode7_latchdata;
|
||||
|
||||
bool counters_latched;
|
||||
|
|
|
@ -25,7 +25,8 @@ void PPU::serialize(serializer &s) {
|
|||
s.integer(regs.vram_readbuffer);
|
||||
s.integer(regs.oam_latchdata);
|
||||
s.integer(regs.cgram_latchdata);
|
||||
s.integer(regs.bgofs_latchdata);
|
||||
s.integer(regs.bgofs_ppu1latchdata);
|
||||
s.integer(regs.bgofs_ppu2latchdata);
|
||||
s.integer(regs.mode7_latchdata);
|
||||
|
||||
s.integer(regs.counters_latched);
|
||||
|
|
|
@ -100,6 +100,7 @@ void NECDSP::exec_op(uint24 opcode) {
|
|||
|
||||
flag.s0 = (r & 0x8000);
|
||||
flag.z = (r == 0);
|
||||
if (!flag.ov1) flag.s1 = flag.s0;
|
||||
|
||||
switch(alu) {
|
||||
case 1: case 2: case 3: case 10: case 13: case 14: case 15: {
|
||||
|
@ -111,17 +112,14 @@ void NECDSP::exec_op(uint24 opcode) {
|
|||
case 4: case 5: case 6: case 7: case 8: case 9: {
|
||||
if(alu & 1) {
|
||||
//addition
|
||||
flag.ov0 = (q ^ r) & ~(q ^ p) & 0x8000;
|
||||
flag.ov0 = (q ^ r) & (p ^ r) & 0x8000;
|
||||
flag.c = (r < q);
|
||||
} else {
|
||||
//subtraction
|
||||
flag.ov0 = (q ^ r) & (q ^ p) & 0x8000;
|
||||
flag.ov0 = (q ^ r) & (q ^ p) & 0x8000;
|
||||
flag.c = (r > q);
|
||||
}
|
||||
if(flag.ov0) {
|
||||
flag.s1 = flag.ov1 ^ !(r & 0x8000);
|
||||
flag.ov1 = !flag.ov1;
|
||||
}
|
||||
flag.ov1 = (flag.ov0 & flag.ov1) ? (flag.s1 == flag.s0) : (flag.ov0 | flag.ov1);
|
||||
break;
|
||||
}
|
||||
case 11: {
|
||||
|
@ -146,15 +144,16 @@ void NECDSP::exec_op(uint24 opcode) {
|
|||
|
||||
exec_ld((idb << 6) + dst);
|
||||
|
||||
switch(dpl) {
|
||||
case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC
|
||||
case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break; //DPDEC
|
||||
case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR
|
||||
if (dst != 4) {
|
||||
switch(dpl) {
|
||||
case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC
|
||||
case 2: regs.dp = (regs.dp & 0xf0) + ((regs.dp - 1) & 0x0f); break; //DPDEC
|
||||
case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR
|
||||
}
|
||||
regs.dp ^= dphm << 4;
|
||||
}
|
||||
|
||||
regs.dp ^= dphm << 4;
|
||||
|
||||
if(rpdcr) regs.rp--;
|
||||
if(rpdcr && dst != 5) regs.rp--;
|
||||
}
|
||||
|
||||
void NECDSP::exec_rt(uint24 opcode) {
|
||||
|
|
|
@ -337,6 +337,7 @@ void DSP::reset() {
|
|||
#endif
|
||||
|
||||
REG(flg) = 0xe0;
|
||||
REG(endx) = 0xff;
|
||||
|
||||
state.noise = 0x4000;
|
||||
state.echo_hist_pos = 0;
|
||||
|
|
|
@ -246,8 +246,9 @@ void PPU::mmio_w210d(uint8 data) {
|
|||
regs.mode7_hoffset = (data << 8) | regs.mode7_latchdata;
|
||||
regs.mode7_latchdata = data;
|
||||
|
||||
bg1.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg1.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
bg1.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
}
|
||||
|
||||
//BG1VOFS
|
||||
|
@ -255,44 +256,47 @@ void PPU::mmio_w210e(uint8 data) {
|
|||
regs.mode7_voffset = (data << 8) | regs.mode7_latchdata;
|
||||
regs.mode7_latchdata = data;
|
||||
|
||||
bg1.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg1.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
}
|
||||
|
||||
//BG2HOFS
|
||||
void PPU::mmio_w210f(uint8 data) {
|
||||
bg2.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg2.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
bg2.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
}
|
||||
|
||||
//BG2VOFS
|
||||
void PPU::mmio_w2110(uint8 data) {
|
||||
bg2.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg2.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
}
|
||||
|
||||
//BG3HOFS
|
||||
void PPU::mmio_w2111(uint8 data) {
|
||||
bg3.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg3.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
bg3.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
}
|
||||
|
||||
//BG3VOFS
|
||||
void PPU::mmio_w2112(uint8 data) {
|
||||
bg3.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg3.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
}
|
||||
|
||||
//BG4HOFS
|
||||
void PPU::mmio_w2113(uint8 data) {
|
||||
bg4.regs.hoffset = (data << 8) | (regs.bgofs_latchdata & ~7) | ((bg4.regs.hoffset >> 8) & 7);
|
||||
regs.bgofs_latchdata = data;
|
||||
bg4.regs.hoffset = (data << 8) | (regs.bgofs_ppu1latchdata & ~7) | (regs.bgofs_ppu2latchdata);
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
regs.bgofs_ppu2latchdata = data;
|
||||
}
|
||||
|
||||
//BG4VOFS
|
||||
void PPU::mmio_w2114(uint8 data) {
|
||||
bg4.regs.voffset = (data << 8) | regs.bgofs_latchdata;
|
||||
regs.bgofs_latchdata = data;
|
||||
bg4.regs.voffset = (data << 8) | regs.bgofs_ppu1latchdata;
|
||||
regs.bgofs_ppu1latchdata = data;
|
||||
}
|
||||
|
||||
//VMAIN
|
||||
|
@ -690,7 +694,8 @@ void PPU::mmio_reset() {
|
|||
regs.vram_readbuffer = 0x0000;
|
||||
regs.oam_latchdata = 0x00;
|
||||
regs.cgram_latchdata = 0x00;
|
||||
regs.bgofs_latchdata = 0x00;
|
||||
regs.bgofs_ppu1latchdata = 0x00;
|
||||
regs.bgofs_ppu2latchdata = 0x00;
|
||||
regs.mode7_latchdata = 0x00;
|
||||
regs.counters_latched = false;
|
||||
regs.latch_hcounter = 0;
|
||||
|
|
|
@ -5,7 +5,8 @@ struct {
|
|||
uint16 vram_readbuffer;
|
||||
uint8 oam_latchdata;
|
||||
uint8 cgram_latchdata;
|
||||
uint8 bgofs_latchdata;
|
||||
uint8 bgofs_ppu1latchdata;
|
||||
uint3 bgofs_ppu2latchdata;
|
||||
uint8 mode7_latchdata;
|
||||
bool counters_latched;
|
||||
bool latch_hcounter;
|
||||
|
|
|
@ -18,7 +18,8 @@ void PPU::serialize(serializer &s) {
|
|||
s.integer(regs.vram_readbuffer);
|
||||
s.integer(regs.oam_latchdata);
|
||||
s.integer(regs.cgram_latchdata);
|
||||
s.integer(regs.bgofs_latchdata);
|
||||
s.integer(regs.bgofs_ppu1latchdata);
|
||||
s.integer(regs.bgofs_ppu2latchdata);
|
||||
s.integer(regs.mode7_latchdata);
|
||||
s.integer(regs.counters_latched);
|
||||
s.integer(regs.latch_hcounter);
|
||||
|
|
|
@ -80,14 +80,12 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
|
|||
if(regs.p.p) break; //writes only valid when P flag is clear
|
||||
|
||||
status.clock_speed = (data >> 6) & 3;
|
||||
status.timer_speed = (data >> 4) & 3;
|
||||
status.ram_speed = (data >> 4) & 3;
|
||||
status.timers_enabled = data & 0x08;
|
||||
status.ram_disabled = data & 0x04;
|
||||
status.ram_writable = data & 0x02;
|
||||
status.timers_disabled = data & 0x01;
|
||||
|
||||
status.timer_step = (1 << status.clock_speed) + (2 << status.timer_speed);
|
||||
|
||||
t0.sync_stage1();
|
||||
t1.sync_stage1();
|
||||
t2.sync_stage1();
|
||||
|
@ -176,23 +174,29 @@ alwaysinline void SMP::op_buswrite(uint16 addr, uint8 data) {
|
|||
ram_write(addr, data);
|
||||
}
|
||||
|
||||
unsigned SMP::speed(uint16 addr) const {
|
||||
if((addr & 0xfff0) == 0x00f0) return status.clock_speed;
|
||||
if(addr >= 0xffc0 && status.iplrom_enabled) return status.clock_speed;
|
||||
return status.ram_speed;
|
||||
}
|
||||
|
||||
void SMP::op_io() {
|
||||
add_clocks(24);
|
||||
cycle_edge();
|
||||
cycle_edge(status.clock_speed);
|
||||
}
|
||||
|
||||
uint8 SMP::op_read(uint16 addr) {
|
||||
add_clocks(12);
|
||||
uint8 r = op_busread(addr);
|
||||
add_clocks(12);
|
||||
cycle_edge();
|
||||
cycle_edge(speed(addr));
|
||||
return r;
|
||||
}
|
||||
|
||||
void SMP::op_write(uint16 addr, uint8 data) {
|
||||
add_clocks(24);
|
||||
op_buswrite(addr, data);
|
||||
cycle_edge();
|
||||
cycle_edge(speed(addr));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,8 @@ void ram_write(uint16 addr, uint8 data);
|
|||
uint8 op_busread(uint16 addr);
|
||||
void op_buswrite(uint16 addr, uint8 data);
|
||||
|
||||
alwaysinline unsigned speed(uint16 addr) const;
|
||||
|
||||
void op_io();
|
||||
debugvirtual uint8 op_read(uint16 addr);
|
||||
debugvirtual void op_write(uint16 addr, uint8 data);
|
||||
|
|
|
@ -4,12 +4,8 @@ void SMP::serialize(serializer &s) {
|
|||
Processor::serialize(s);
|
||||
SMPcore::core_serialize(s);
|
||||
|
||||
s.integer(status.clock_counter);
|
||||
s.integer(status.dsp_counter);
|
||||
s.integer(status.timer_step);
|
||||
|
||||
s.integer(status.clock_speed);
|
||||
s.integer(status.timer_speed);
|
||||
s.integer(status.ram_speed);
|
||||
s.integer(status.timers_enabled);
|
||||
s.integer(status.ram_disabled);
|
||||
s.integer(status.ram_writable);
|
||||
|
|
|
@ -76,13 +76,9 @@ void SMP::reset() {
|
|||
memory::apuram.write(i, 0x00);
|
||||
}
|
||||
|
||||
status.clock_counter = 0;
|
||||
status.dsp_counter = 0;
|
||||
status.timer_step = 3;
|
||||
|
||||
//$00f0
|
||||
status.clock_speed = 0;
|
||||
status.timer_speed = 0;
|
||||
status.ram_speed = 0;
|
||||
status.timers_enabled = true;
|
||||
status.ram_disabled = false;
|
||||
status.ram_writable = true;
|
||||
|
|
|
@ -21,14 +21,9 @@ private:
|
|||
#include "timing/timing.hpp"
|
||||
|
||||
struct {
|
||||
//timing
|
||||
unsigned clock_counter;
|
||||
unsigned dsp_counter;
|
||||
unsigned timer_step;
|
||||
|
||||
//$00f0
|
||||
uint8 clock_speed;
|
||||
uint8 timer_speed;
|
||||
uint8 ram_speed;
|
||||
bool timers_enabled;
|
||||
bool ram_disabled;
|
||||
bool ram_writable;
|
||||
|
|
|
@ -9,25 +9,22 @@ void SMP::add_clocks(unsigned clocks) {
|
|||
if(clock > +(768 * 24 * (int64)24000000)) synchronize_cpu();
|
||||
}
|
||||
|
||||
void SMP::cycle_edge() {
|
||||
t0.tick();
|
||||
t1.tick();
|
||||
t2.tick();
|
||||
void SMP::cycle_edge(unsigned speed) {
|
||||
static const uint8 wait_states[] = {0, 24*1, 24*4, 24*9};
|
||||
|
||||
unsigned ticks = 1 << speed;
|
||||
t0.tick(ticks);
|
||||
t1.tick(ticks);
|
||||
t2.tick(ticks);
|
||||
|
||||
//TEST register S-SMP speed control
|
||||
//24 clocks have already been added for this cycle at this point
|
||||
switch(status.clock_speed) {
|
||||
case 0: break; //100% speed
|
||||
case 1: add_clocks(24); break; // 50% speed
|
||||
case 2: while(true) add_clocks(24); // 0% speed -- locks S-SMP
|
||||
case 3: add_clocks(24 * 9); break; // 10% speed
|
||||
}
|
||||
if(speed) add_clocks(wait_states[speed]);
|
||||
}
|
||||
|
||||
template<unsigned timer_frequency>
|
||||
void SMP::sSMPTimer<timer_frequency>::tick() {
|
||||
void SMP::sSMPTimer<timer_frequency>::tick(unsigned step) {
|
||||
//stage 0 increment
|
||||
stage0_ticks += smp.status.timer_step;
|
||||
stage0_ticks += step;
|
||||
if(stage0_ticks < timer_frequency) return;
|
||||
stage0_ticks -= timer_frequency;
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@ public:
|
|||
bool enabled;
|
||||
uint8 target;
|
||||
|
||||
void tick();
|
||||
void tick(unsigned step);
|
||||
void sync_stage1();
|
||||
};
|
||||
|
||||
sSMPTimer<192> t0;
|
||||
sSMPTimer<192> t1;
|
||||
sSMPTimer< 24> t2;
|
||||
sSMPTimer<64> t0;
|
||||
sSMPTimer<64> t1;
|
||||
sSMPTimer< 8> t2;
|
||||
|
||||
alwaysinline void add_clocks(unsigned clocks);
|
||||
alwaysinline void cycle_edge();
|
||||
alwaysinline void cycle_edge(unsigned speed);
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace SNES {
|
|||
static const char Name[] = "bsnes-classic";
|
||||
static const char Version[] = "073u1";
|
||||
static const unsigned SerializerSignature = 0x43545342; //'BSTC'
|
||||
static const unsigned SerializerVersion = 6;
|
||||
static const unsigned SerializerVersion = 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ link :=
|
|||
ifeq ($(DEBUG), 1)
|
||||
flags += -O0 -g -DDEBUG
|
||||
else
|
||||
flags += -O3 -fomit-frame-pointer -DNDEBUG -march=native
|
||||
flags += -O3 -fomit-frame-pointer -DNDEBUG
|
||||
endif
|
||||
|
||||
# silence warnings
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
namespace nall {
|
||||
|
||||
struct Keyboard;
|
||||
Keyboard& keyboard(unsigned = 0);
|
||||
Keyboard keyboard(unsigned = 0);
|
||||
|
||||
static const char KeyboardScancodeName[][64] = {
|
||||
"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
|
||||
|
@ -122,12 +122,9 @@ struct Keyboard {
|
|||
Keyboard(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Keyboard& keyboard(unsigned id) {
|
||||
static Keyboard kb0(0), kb1(1), kb2(2), kb3(3), kb4(4), kb5(5), kb6(6), kb7(7);
|
||||
switch(id) { default:
|
||||
case 0: return kb0; case 1: return kb1; case 2: return kb2; case 3: return kb3;
|
||||
case 4: return kb4; case 5: return kb5; case 6: return kb6; case 7: return kb7;
|
||||
}
|
||||
inline Keyboard keyboard(unsigned id) {
|
||||
assert(id < Keyboard::Count);
|
||||
return Keyboard(id);
|
||||
}
|
||||
|
||||
static const char MouseScancodeName[][64] = {
|
||||
|
@ -136,7 +133,7 @@ static const char MouseScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Mouse;
|
||||
Mouse& mouse(unsigned = 0);
|
||||
Mouse mouse(unsigned = 0);
|
||||
|
||||
struct Mouse {
|
||||
const unsigned ID;
|
||||
|
@ -220,12 +217,9 @@ struct Mouse {
|
|||
Mouse(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Mouse& mouse(unsigned id) {
|
||||
static Mouse ms0(0), ms1(1), ms2(2), ms3(3), ms4(4), ms5(5), ms6(6), ms7(7);
|
||||
switch(id) { default:
|
||||
case 0: return ms0; case 1: return ms1; case 2: return ms2; case 3: return ms3;
|
||||
case 4: return ms4; case 5: return ms5; case 6: return ms6; case 7: return ms7;
|
||||
}
|
||||
inline Mouse mouse(unsigned id) {
|
||||
assert(id < Mouse::Count);
|
||||
return Mouse(id);
|
||||
}
|
||||
|
||||
static const char JoypadScancodeName[][64] = {
|
||||
|
@ -239,7 +233,7 @@ static const char JoypadScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Joypad;
|
||||
Joypad& joypad(unsigned = 0);
|
||||
Joypad joypad(unsigned = 0);
|
||||
|
||||
struct Joypad {
|
||||
const unsigned ID;
|
||||
|
@ -345,12 +339,9 @@ struct Joypad {
|
|||
Joypad(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Joypad& joypad(unsigned id) {
|
||||
static Joypad jp0(0), jp1(1), jp2(2), jp3(3), jp4(4), jp5(5), jp6(6), jp7(7);
|
||||
switch(id) { default:
|
||||
case 0: return jp0; case 1: return jp1; case 2: return jp2; case 3: return jp3;
|
||||
case 4: return jp4; case 5: return jp5; case 6: return jp6; case 7: return jp7;
|
||||
}
|
||||
inline Joypad joypad(unsigned id) {
|
||||
assert(id < Joypad::Count);
|
||||
return Joypad(id);
|
||||
}
|
||||
|
||||
struct Scancode {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
namespace nall {
|
||||
|
||||
struct Keyboard;
|
||||
Keyboard& keyboard(unsigned = 0);
|
||||
Keyboard keyboard(unsigned = 0);
|
||||
|
||||
static const char KeyboardScancodeName[][64] = {
|
||||
"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
|
||||
|
@ -122,12 +122,9 @@ struct Keyboard {
|
|||
Keyboard(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Keyboard& keyboard(unsigned id) {
|
||||
static Keyboard kb0(0), kb1(1), kb2(2), kb3(3), kb4(4), kb5(5), kb6(6), kb7(7);
|
||||
switch(id) { default:
|
||||
case 0: return kb0; case 1: return kb1; case 2: return kb2; case 3: return kb3;
|
||||
case 4: return kb4; case 5: return kb5; case 6: return kb6; case 7: return kb7;
|
||||
}
|
||||
inline Keyboard keyboard(unsigned id) {
|
||||
assert(id < Keyboard::Count);
|
||||
return Keyboard(id);
|
||||
}
|
||||
|
||||
static const char MouseScancodeName[][64] = {
|
||||
|
@ -136,7 +133,7 @@ static const char MouseScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Mouse;
|
||||
Mouse& mouse(unsigned = 0);
|
||||
Mouse mouse(unsigned = 0);
|
||||
|
||||
struct Mouse {
|
||||
const unsigned ID;
|
||||
|
@ -220,12 +217,9 @@ struct Mouse {
|
|||
Mouse(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Mouse& mouse(unsigned id) {
|
||||
static Mouse ms0(0), ms1(1), ms2(2), ms3(3), ms4(4), ms5(5), ms6(6), ms7(7);
|
||||
switch(id) { default:
|
||||
case 0: return ms0; case 1: return ms1; case 2: return ms2; case 3: return ms3;
|
||||
case 4: return ms4; case 5: return ms5; case 6: return ms6; case 7: return ms7;
|
||||
}
|
||||
inline Mouse mouse(unsigned id) {
|
||||
assert(id < Mouse::Count);
|
||||
return Mouse(id);
|
||||
}
|
||||
|
||||
static const char JoypadScancodeName[][64] = {
|
||||
|
@ -239,7 +233,7 @@ static const char JoypadScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Joypad;
|
||||
Joypad& joypad(unsigned = 0);
|
||||
Joypad joypad(unsigned = 0);
|
||||
|
||||
struct Joypad {
|
||||
const unsigned ID;
|
||||
|
@ -345,12 +339,9 @@ struct Joypad {
|
|||
Joypad(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Joypad& joypad(unsigned id) {
|
||||
static Joypad jp0(0), jp1(1), jp2(2), jp3(3), jp4(4), jp5(5), jp6(6), jp7(7);
|
||||
switch(id) { default:
|
||||
case 0: return jp0; case 1: return jp1; case 2: return jp2; case 3: return jp3;
|
||||
case 4: return jp4; case 5: return jp5; case 6: return jp6; case 7: return jp7;
|
||||
}
|
||||
inline Joypad joypad(unsigned id) {
|
||||
assert(id < Joypad::Count);
|
||||
return Joypad(id);
|
||||
}
|
||||
|
||||
struct Scancode {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
namespace nall {
|
||||
|
||||
struct Keyboard;
|
||||
Keyboard& keyboard(unsigned = 0);
|
||||
Keyboard keyboard(unsigned = 0);
|
||||
|
||||
static const char KeyboardScancodeName[][64] = {
|
||||
"Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
|
||||
|
@ -122,12 +122,9 @@ struct Keyboard {
|
|||
Keyboard(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Keyboard& keyboard(unsigned id) {
|
||||
static Keyboard kb0(0), kb1(1), kb2(2), kb3(3), kb4(4), kb5(5), kb6(6), kb7(7);
|
||||
switch(id) { default:
|
||||
case 0: return kb0; case 1: return kb1; case 2: return kb2; case 3: return kb3;
|
||||
case 4: return kb4; case 5: return kb5; case 6: return kb6; case 7: return kb7;
|
||||
}
|
||||
inline Keyboard keyboard(unsigned id) {
|
||||
assert(id < Keyboard::Count);
|
||||
return Keyboard(id);
|
||||
}
|
||||
|
||||
static const char MouseScancodeName[][64] = {
|
||||
|
@ -136,7 +133,7 @@ static const char MouseScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Mouse;
|
||||
Mouse& mouse(unsigned = 0);
|
||||
Mouse mouse(unsigned = 0);
|
||||
|
||||
struct Mouse {
|
||||
const unsigned ID;
|
||||
|
@ -220,12 +217,9 @@ struct Mouse {
|
|||
Mouse(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Mouse& mouse(unsigned id) {
|
||||
static Mouse ms0(0), ms1(1), ms2(2), ms3(3), ms4(4), ms5(5), ms6(6), ms7(7);
|
||||
switch(id) { default:
|
||||
case 0: return ms0; case 1: return ms1; case 2: return ms2; case 3: return ms3;
|
||||
case 4: return ms4; case 5: return ms5; case 6: return ms6; case 7: return ms7;
|
||||
}
|
||||
inline Mouse mouse(unsigned id) {
|
||||
assert(id < Mouse::Count);
|
||||
return Mouse(id);
|
||||
}
|
||||
|
||||
static const char JoypadScancodeName[][64] = {
|
||||
|
@ -239,7 +233,7 @@ static const char JoypadScancodeName[][64] = {
|
|||
};
|
||||
|
||||
struct Joypad;
|
||||
Joypad& joypad(unsigned = 0);
|
||||
Joypad joypad(unsigned = 0);
|
||||
|
||||
struct Joypad {
|
||||
const unsigned ID;
|
||||
|
@ -345,12 +339,9 @@ struct Joypad {
|
|||
Joypad(unsigned ID_) : ID(ID_) {}
|
||||
};
|
||||
|
||||
inline Joypad& joypad(unsigned id) {
|
||||
static Joypad jp0(0), jp1(1), jp2(2), jp3(3), jp4(4), jp5(5), jp6(6), jp7(7);
|
||||
switch(id) { default:
|
||||
case 0: return jp0; case 1: return jp1; case 2: return jp2; case 3: return jp3;
|
||||
case 4: return jp4; case 5: return jp5; case 6: return jp6; case 7: return jp7;
|
||||
}
|
||||
inline Joypad joypad(unsigned id) {
|
||||
assert(id < Joypad::Count);
|
||||
return Joypad(id);
|
||||
}
|
||||
|
||||
struct Scancode {
|
||||
|
|
Loading…
Add table
Reference in a new issue