mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v050 release.
I always regret having to post new releases so quickly, but a semi-major bug crept into v049. I'd rather fix it now, before I start making major changes that will need testing again. The problem was that the S-PPU was not being synchronized as often as it should have been, resulting in titles such as F-Zero and Super Mario Kart showing flickering lines here and there. This release fixes that. This release also adds savestate support for Mega Man X2 and Mega Man X3, which utilize the Cx4 coprocessor; and it fixes a bug where input was still accepted even when the main window was minimized.
This commit is contained in:
parent
59b86cd3a8
commit
c2453cb634
|
@ -1,4 +1,4 @@
|
|||
static const char bsnesVersion[] = "0.049";
|
||||
static const char bsnesVersion[] = "0.050";
|
||||
static const char bsnesTitle[] = "bsnes";
|
||||
static const unsigned bsnesSaveStateVersion = 2;
|
||||
|
||||
|
|
|
@ -11,10 +11,11 @@ namespace SNES {
|
|||
|
||||
Cx4 cx4;
|
||||
|
||||
#include "cx4data.cpp"
|
||||
#include "cx4fn.cpp"
|
||||
#include "cx4oam.cpp"
|
||||
#include "cx4ops.cpp"
|
||||
#include "serialization.cpp"
|
||||
#include "data.cpp"
|
||||
#include "functions.cpp"
|
||||
#include "oam.cpp"
|
||||
#include "opcodes.cpp"
|
||||
|
||||
void Cx4::init() {
|
||||
}
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
class Cx4 : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read(unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
|
||||
void serialize(serializer&);
|
||||
|
||||
private:
|
||||
uint8 ram[0x0c00];
|
||||
uint8 reg[0x0100];
|
||||
|
@ -15,6 +26,7 @@ private:
|
|||
int16 C4WFXVal, C4WFYVal, C4WFZVal, C4WFX2Val, C4WFY2Val, C4WFDist, C4WFScale;
|
||||
int16 C41FXVal, C41FYVal, C41FAngleRes, C41FDist, C41FDistVal;
|
||||
|
||||
//todo: get rid of floating-point values, replace with integers
|
||||
double tanval;
|
||||
double c4x,c4y,c4z, c4x2,c4y2,c4z2;
|
||||
|
||||
|
@ -82,16 +94,6 @@ public:
|
|||
void writeb(uint16 addr, uint8 data);
|
||||
void writew(uint16 addr, uint16 data);
|
||||
void writel(uint16 addr, uint32 data);
|
||||
|
||||
//
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (unsigned addr);
|
||||
void write(unsigned addr, uint8 data);
|
||||
};
|
||||
|
||||
extern Cx4 cx4;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#ifdef CX4_CPP
|
||||
|
||||
void Cx4::serialize(serializer &s) {
|
||||
s.array(ram);
|
||||
s.array(reg);
|
||||
|
||||
s.integer(r0);
|
||||
s.integer(r1);
|
||||
s.integer(r2);
|
||||
s.integer(r3);
|
||||
s.integer(r4);
|
||||
s.integer(r5);
|
||||
s.integer(r6);
|
||||
s.integer(r7);
|
||||
s.integer(r8);
|
||||
s.integer(r9);
|
||||
s.integer(r10);
|
||||
s.integer(r11);
|
||||
s.integer(r12);
|
||||
s.integer(r13);
|
||||
s.integer(r14);
|
||||
s.integer(r15);
|
||||
|
||||
s.integer(C4WFXVal);
|
||||
s.integer(C4WFYVal);
|
||||
s.integer(C4WFZVal);
|
||||
s.integer(C4WFX2Val);
|
||||
s.integer(C4WFY2Val);
|
||||
s.integer(C4WFDist);
|
||||
s.integer(C4WFScale);
|
||||
|
||||
s.integer(C41FXVal);
|
||||
s.integer(C41FYVal);
|
||||
s.integer(C41FAngleRes);
|
||||
s.integer(C41FDist);
|
||||
s.integer(C41FDistVal);
|
||||
|
||||
s.floatingpoint(tanval);
|
||||
s.floatingpoint(c4x);
|
||||
s.floatingpoint(c4y);
|
||||
s.floatingpoint(c4z);
|
||||
s.floatingpoint(c4x2);
|
||||
s.floatingpoint(c4y2);
|
||||
s.floatingpoint(c4z2);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -17,7 +17,7 @@ namespace nall {
|
|||
//
|
||||
//caveats:
|
||||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point values are not supported.
|
||||
//- floating-point usage is not portable across platforms
|
||||
|
||||
class serializer {
|
||||
public:
|
||||
|
@ -33,6 +33,20 @@ namespace nall {
|
|||
return icapacity;
|
||||
}
|
||||
|
||||
template<typename T> void floatingpoint(T &value) {
|
||||
enum { size = sizeof(T) };
|
||||
//this is rather dangerous, and not cross-platform safe;
|
||||
//but there is no standardized way to export FP-values
|
||||
uint8_t *p = (uint8_t*)&value;
|
||||
if(mode == Save) {
|
||||
for(unsigned n = 0; n < size; n++) idata[isize++] = p[n];
|
||||
} else if(mode == Load) {
|
||||
for(unsigned n = 0; n < size; n++) p[n] = idata[isize++];
|
||||
} else {
|
||||
isize += size;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> void integer(T &value) {
|
||||
enum { size = is_bool<T>::value ? 1 : sizeof(T) };
|
||||
if(mode == Save) {
|
||||
|
|
|
@ -15,9 +15,7 @@ void bPPU::enter() {
|
|||
if(scheduler.sync == Scheduler::SyncAll) scheduler.exit();
|
||||
|
||||
//H = 0 (initialize)
|
||||
scheduler.sync_ppucpu();
|
||||
scanline();
|
||||
if(vcounter() == 0) frame();
|
||||
add_clocks(10);
|
||||
|
||||
//H = 10 (OAM address reset)
|
||||
|
@ -47,12 +45,15 @@ void bPPU::enter() {
|
|||
void bPPU::add_clocks(unsigned clocks) {
|
||||
tick(clocks);
|
||||
scheduler.addclocks_ppu(clocks);
|
||||
scheduler.sync_ppucpu();
|
||||
}
|
||||
|
||||
void bPPU::scanline() {
|
||||
line = vcounter();
|
||||
|
||||
if(line == 0) {
|
||||
frame();
|
||||
|
||||
//RTO flag reset
|
||||
regs.time_over = false;
|
||||
regs.range_over = false;
|
||||
|
|
|
@ -52,6 +52,7 @@ void System::serialize_all(serializer &s) {
|
|||
dsp.serialize(s);
|
||||
|
||||
if(cartridge.has_spc7110()) spc7110.serialize(s);
|
||||
if(cartridge.has_cx4()) cx4.serialize(s);
|
||||
if(cartridge.has_obc1()) obc1.serialize(s);
|
||||
}
|
||||
|
||||
|
|
|
@ -271,6 +271,10 @@ void MainWindow::syncUi() {
|
|||
settings_emulationSpeed_syncAudio->setChecked(config.audio.synchronize);
|
||||
}
|
||||
|
||||
bool MainWindow::isActive() {
|
||||
return window->isActiveWindow() && !window->isMinimized();
|
||||
}
|
||||
|
||||
void MainWindow::loadCartridge() {
|
||||
string filename = utility.selectCartridge();
|
||||
if(filename.length() > 0) utility.loadCartridge(filename);
|
||||
|
|
|
@ -86,6 +86,7 @@ public:
|
|||
|
||||
void setup();
|
||||
void syncUi();
|
||||
bool isActive();
|
||||
|
||||
public slots:
|
||||
void loadCartridge();
|
||||
|
|
|
@ -76,7 +76,7 @@ void InputManager::bind() {
|
|||
|
||||
void InputManager::poll() {
|
||||
if(config.input.focusPolicy == Configuration::Input::FocusPolicyIgnoreInput
|
||||
&& mainWindow->window->isActiveWindow() == false) {
|
||||
&& mainWindow->isActive() == false) {
|
||||
inputPool.clear();
|
||||
} else {
|
||||
inputPool.poll(stateTable[activeState]);
|
||||
|
|
|
@ -9,7 +9,6 @@ bool Utility::saveStatesSupported() {
|
|||
if(SNES::cartridge.has_sa1()) return false;
|
||||
if(SNES::cartridge.has_srtc()) return false;
|
||||
if(SNES::cartridge.has_sdd1()) return false;
|
||||
if(SNES::cartridge.has_cx4()) return false;
|
||||
if(SNES::cartridge.has_dsp1()) return false;
|
||||
if(SNES::cartridge.has_dsp2()) return false;
|
||||
if(SNES::cartridge.has_dsp3()) return false;
|
||||
|
|
|
@ -42,7 +42,7 @@ void Utility::inputEvent(uint16_t code) {
|
|||
|
||||
for(unsigned i = 0; i < keyboard<>::count; i++) {
|
||||
if(code == keyboard<>::index(i, keyboard<>::escape) && inputManager.state(code)) {
|
||||
if(mainWindow->window->isActiveWindow() && input.acquired()) {
|
||||
if(mainWindow->isActive() && input.acquired()) {
|
||||
//release mouse capture
|
||||
input.unacquire();
|
||||
return; //do not trigger other UI actions that may be bound to escape key
|
||||
|
@ -56,7 +56,7 @@ void Utility::inputEvent(uint16_t code) {
|
|||
}
|
||||
}
|
||||
|
||||
if(mainWindow->window->isActiveWindow()) {
|
||||
if(mainWindow->isActive()) {
|
||||
bool resizeWindow = false;
|
||||
|
||||
if(isButtonDown(code, inputUiGeneral.loadCartridge)) {
|
||||
|
|
Loading…
Reference in New Issue