mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v064rc1 release.
I'm posting a release candidate for v064, for which I am looking for beta testers. If you would like to help out, please give it a try and report any bugs or regressions on the forum. If all goes well, this will be posted as v064 official shortly. Note that you will need the Qt run-times from bsnes v063 official to use this. Also, this build does not use the new cycle-based PPU. Official builds are going to continue using the scanline-based renderer. This build should be about 10% faster than v063 was, which should lower the system requirements further.
This commit is contained in:
parent
717aa69d42
commit
65ff00e28a
|
@ -2,7 +2,7 @@ include nall/Makefile
|
|||
ui := ui_qt
|
||||
|
||||
# compiler
|
||||
c := $(compiler) --std=gnu99
|
||||
c := $(compiler) -std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -O3 -fomit-frame-pointer -I.
|
||||
link :=
|
||||
|
|
|
@ -85,18 +85,6 @@ namespace nall {
|
|||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
|
||||
//bind functions to ease construction and assignment of function() with more than one argument
|
||||
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...), C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
|
||||
template<typename C, typename R, typename... P>
|
||||
function<R (P...)> bind(R (C::*callback)(P...) const, C *object) {
|
||||
return function<R (P...)>(callback, object);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
snes_core = sMemory sCPU sSMP sDSP sPPU
|
||||
snes_core = sMemory sCPU sSMP aDSP bPPU
|
||||
|
||||
snes_objects := libco
|
||||
snes_objects += snes-system
|
||||
|
|
|
@ -37,8 +37,8 @@ void SuperFX::enter() {
|
|||
|
||||
void SuperFX::init() {
|
||||
initialize_opcode_table();
|
||||
regs.r[14].on_modify = bind(&SuperFX::r14_modify, this);
|
||||
regs.r[15].on_modify = bind(&SuperFX::r15_modify, this);
|
||||
regs.r[14].on_modify = { &SuperFX::r14_modify, this };
|
||||
regs.r[15].on_modify = { &SuperFX::r15_modify, this };
|
||||
}
|
||||
|
||||
void SuperFX::enable() {
|
||||
|
|
|
@ -12,11 +12,11 @@ void CPU::power() {
|
|||
}
|
||||
|
||||
void CPU::reset() {
|
||||
PPUcounter::reset();
|
||||
PPUCounter::reset();
|
||||
}
|
||||
|
||||
void CPU::serialize(serializer &s) {
|
||||
PPUcounter::serialize(s);
|
||||
PPUCounter::serialize(s);
|
||||
s.integer(cpu_version);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "cpu-debugger.hpp"
|
||||
#endif
|
||||
|
||||
class CPU : public PPUcounter, public MMIO {
|
||||
class CPU : public PPUCounter, public MMIO {
|
||||
public:
|
||||
virtual void enter() = 0;
|
||||
|
||||
|
|
|
@ -161,7 +161,6 @@ void sCPU::dma_run() {
|
|||
}
|
||||
|
||||
status.irq_lock = true;
|
||||
event.enqueue(2, EventIrqLockRelease);
|
||||
}
|
||||
|
||||
void sCPU::hdma_update(unsigned i) {
|
||||
|
@ -223,7 +222,6 @@ void sCPU::hdma_run() {
|
|||
}
|
||||
|
||||
status.irq_lock = true;
|
||||
event.enqueue(2, EventIrqLockRelease);
|
||||
}
|
||||
|
||||
void sCPU::hdma_init_reset() {
|
||||
|
@ -247,7 +245,6 @@ void sCPU::hdma_init() {
|
|||
}
|
||||
|
||||
status.irq_lock = true;
|
||||
event.enqueue(2, EventIrqLockRelease);
|
||||
}
|
||||
|
||||
//==============
|
||||
|
|
|
@ -103,8 +103,8 @@ void sCPU::reset() {
|
|||
apu_port[3] = 0x00;
|
||||
}
|
||||
|
||||
sCPU::sCPU() : event(512, bind(&sCPU::queue_event, this)) {
|
||||
PPUcounter::scanline = bind(&sCPU::scanline, this);
|
||||
sCPU::sCPU() {
|
||||
PPUCounter::scanline = { &sCPU::scanline, this };
|
||||
}
|
||||
|
||||
sCPU::~sCPU() {
|
||||
|
|
|
@ -10,8 +10,6 @@ public:
|
|||
#include "mmio/mmio.hpp"
|
||||
#include "timing/timing.hpp"
|
||||
|
||||
priority_queue<unsigned> event;
|
||||
|
||||
struct Status {
|
||||
bool interrupt_pending;
|
||||
uint16 interrupt_vector;
|
||||
|
@ -24,7 +22,15 @@ public:
|
|||
//======
|
||||
|
||||
bool irq_lock;
|
||||
|
||||
unsigned dram_refresh_position;
|
||||
bool dram_refreshed;
|
||||
|
||||
unsigned hdma_init_position;
|
||||
bool hdma_init_triggered;
|
||||
|
||||
unsigned hdma_position;
|
||||
bool hdma_triggered;
|
||||
|
||||
bool nmi_valid;
|
||||
bool nmi_line;
|
||||
|
|
|
@ -4,8 +4,6 @@ void sCPU::serialize(serializer &s) {
|
|||
CPU::serialize(s);
|
||||
CPUcore::core_serialize(s);
|
||||
|
||||
event.serialize(s);
|
||||
|
||||
s.integer(status.interrupt_pending);
|
||||
s.integer(status.interrupt_vector);
|
||||
|
||||
|
@ -13,7 +11,15 @@ void sCPU::serialize(serializer &s) {
|
|||
s.integer(status.line_clocks);
|
||||
|
||||
s.integer(status.irq_lock);
|
||||
|
||||
s.integer(status.dram_refresh_position);
|
||||
s.integer(status.dram_refreshed);
|
||||
|
||||
s.integer(status.hdma_init_position);
|
||||
s.integer(status.hdma_init_triggered);
|
||||
|
||||
s.integer(status.hdma_position);
|
||||
s.integer(status.hdma_triggered);
|
||||
|
||||
s.integer(status.nmi_valid);
|
||||
s.integer(status.nmi_line);
|
||||
|
@ -105,8 +111,6 @@ void sCPU::serialize(serializer &s) {
|
|||
s.integer(apu_port[1]);
|
||||
s.integer(apu_port[2]);
|
||||
s.integer(apu_port[3]);
|
||||
|
||||
s.integer(cycle_edge_state);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
void sCPU::queue_event(unsigned id) {
|
||||
switch(id) {
|
||||
//interrupts triggered during (H)DMA do not trigger immediately after
|
||||
case EventIrqLockRelease: {
|
||||
status.irq_lock = false;
|
||||
} break;
|
||||
|
||||
//S-CPU WRAM consists of two 64kbyte DRAM chips, which must be refreshed
|
||||
//once per scanline to avoid memory decay.
|
||||
case EventDramRefresh: {
|
||||
add_clocks(40);
|
||||
} break;
|
||||
|
||||
//HDMA init routine; occurs once per frame
|
||||
case EventHdmaInit: {
|
||||
cycle_edge_state |= EventFlagHdmaInit;
|
||||
} break;
|
||||
|
||||
//HDMA run routine; occurs once per scanline
|
||||
case EventHdmaRun: {
|
||||
cycle_edge_state |= EventFlagHdmaRun;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -70,7 +70,6 @@ void sCPU::nmitimen_update(uint8 data) {
|
|||
}
|
||||
|
||||
status.irq_lock = true;
|
||||
event.enqueue(2, EventIrqLockRelease);
|
||||
}
|
||||
|
||||
bool sCPU::rdnmi() {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
#include "event.cpp"
|
||||
#include "irq.cpp"
|
||||
#include "joypad.cpp"
|
||||
|
||||
|
@ -9,7 +8,6 @@ unsigned sCPU::dma_counter() {
|
|||
}
|
||||
|
||||
void sCPU::add_clocks(unsigned clocks) {
|
||||
event.tick(clocks);
|
||||
unsigned ticks = clocks >> 1;
|
||||
while(ticks--) {
|
||||
tick();
|
||||
|
@ -19,6 +17,11 @@ void sCPU::add_clocks(unsigned clocks) {
|
|||
}
|
||||
}
|
||||
scheduler.addclocks_cpu(clocks);
|
||||
|
||||
if(status.dram_refreshed == false && hcounter() >= status.dram_refresh_position) {
|
||||
status.dram_refreshed = true;
|
||||
add_clocks(40);
|
||||
}
|
||||
}
|
||||
|
||||
//called by ppu.tick() when Hcounter=0
|
||||
|
@ -33,17 +36,19 @@ void sCPU::scanline() {
|
|||
system.scanline();
|
||||
|
||||
if(vcounter() == 0) {
|
||||
//hdma init triggers once every frame
|
||||
event.enqueue(cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter(), EventHdmaInit);
|
||||
//HDMA init triggers once every frame
|
||||
status.hdma_init_position = (cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter());
|
||||
status.hdma_init_triggered = false;
|
||||
}
|
||||
|
||||
//dram refresh occurs once every scanline
|
||||
//DRAM refresh occurs once every scanline
|
||||
if(cpu_version == 2) status.dram_refresh_position = 530 + 8 - dma_counter();
|
||||
event.enqueue(status.dram_refresh_position, EventDramRefresh);
|
||||
status.dram_refreshed = false;
|
||||
|
||||
//hdma triggers once every visible scanline
|
||||
//HDMA triggers once every visible scanline
|
||||
if(vcounter() <= (ppu.overscan() == false ? 224 : 239)) {
|
||||
event.enqueue(1104, EventHdmaRun);
|
||||
status.hdma_position = 1104;
|
||||
status.hdma_triggered = false;
|
||||
}
|
||||
|
||||
if(status.auto_joypad_poll == true && vcounter() == (ppu.overscan() == false ? 227 : 242)) {
|
||||
|
@ -106,25 +111,21 @@ void sCPU::dma_edge() {
|
|||
}
|
||||
}
|
||||
|
||||
while(cycle_edge_state) {
|
||||
switch(bit::lowest(cycle_edge_state)) {
|
||||
case EventFlagHdmaInit: {
|
||||
hdma_init_reset();
|
||||
if(hdma_enabled_channels()) {
|
||||
status.hdma_pending = true;
|
||||
status.hdma_mode = 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case EventFlagHdmaRun: {
|
||||
if(hdma_active_channels()) {
|
||||
status.hdma_pending = true;
|
||||
status.hdma_mode = 1;
|
||||
}
|
||||
} break;
|
||||
if(status.hdma_init_triggered == false && hcounter() >= status.hdma_init_position) {
|
||||
status.hdma_init_triggered = true;
|
||||
hdma_init_reset();
|
||||
if(hdma_enabled_channels()) {
|
||||
status.hdma_pending = true;
|
||||
status.hdma_mode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cycle_edge_state = bit::clear_lowest(cycle_edge_state);
|
||||
if(status.hdma_triggered == false && hcounter() >= status.hdma_position) {
|
||||
status.hdma_triggered = true;
|
||||
if(hdma_active_channels()) {
|
||||
status.hdma_pending = true;
|
||||
status.hdma_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(status.dma_active == false) {
|
||||
|
@ -141,7 +142,9 @@ void sCPU::dma_edge() {
|
|||
//status.irq_lock is used to simulate hardware delay before interrupts can
|
||||
//trigger during certain events (immediately after DMA, writes to $4200, etc)
|
||||
void sCPU::last_cycle() {
|
||||
if(!status.irq_lock) {
|
||||
if(status.irq_lock) {
|
||||
status.irq_lock = false;
|
||||
} else {
|
||||
status.nmi_pending |= nmi_test();
|
||||
status.irq_pending |= irq_test();
|
||||
|
||||
|
@ -153,14 +156,18 @@ void sCPU::timing_power() {
|
|||
}
|
||||
|
||||
void sCPU::timing_reset() {
|
||||
event.reset();
|
||||
|
||||
status.clock_count = 0;
|
||||
status.line_clocks = lineclocks();
|
||||
|
||||
status.irq_lock = false;
|
||||
status.dram_refresh_position = (cpu_version == 1 ? 530 : 538);
|
||||
event.enqueue(status.dram_refresh_position, EventDramRefresh);
|
||||
status.dram_refreshed = false;
|
||||
|
||||
status.hdma_init_position = (cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter());
|
||||
status.hdma_init_triggered = false;
|
||||
|
||||
status.hdma_position = 1104;
|
||||
status.hdma_triggered = false;
|
||||
|
||||
status.nmi_valid = false;
|
||||
status.nmi_line = false;
|
||||
|
@ -184,8 +191,6 @@ void sCPU::timing_reset() {
|
|||
status.dma_pending = false;
|
||||
status.hdma_pending = false;
|
||||
status.hdma_mode = 0;
|
||||
|
||||
cycle_edge_state = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,3 @@
|
|||
enum {
|
||||
EventNone,
|
||||
EventIrqLockRelease,
|
||||
EventDramRefresh,
|
||||
EventHdmaInit,
|
||||
EventHdmaRun,
|
||||
|
||||
//cycle edge
|
||||
EventFlagHdmaInit = 1 << 0,
|
||||
EventFlagHdmaRun = 1 << 1,
|
||||
};
|
||||
unsigned cycle_edge_state;
|
||||
|
||||
//timing.cpp
|
||||
unsigned dma_counter();
|
||||
|
||||
|
@ -35,6 +22,3 @@ alwaysinline bool irq_test();
|
|||
|
||||
//joypad.cpp
|
||||
void run_auto_joypad_poll();
|
||||
|
||||
//event.cpp
|
||||
void queue_event(unsigned); //priorityqueue callback function
|
||||
|
|
|
@ -3,15 +3,27 @@
|
|||
#define ADSP_CPP
|
||||
namespace SNES {
|
||||
|
||||
aDSP dsp;
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
aDSPDebugger dsp;
|
||||
#else
|
||||
aDSP dsp;
|
||||
#endif
|
||||
|
||||
#include "tables.cpp"
|
||||
#include "serialization.cpp"
|
||||
|
||||
void aDSP::enter() {
|
||||
#if !defined(DSP_STATE_MACHINE)
|
||||
while(true)
|
||||
while(true) {
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
#endif
|
||||
run();
|
||||
#if !defined(DSP_STATE_MACHINE)
|
||||
}
|
||||
#endif
|
||||
run();
|
||||
}
|
||||
|
||||
uint8 aDSP::readb(uint16 addr) {
|
||||
|
|
|
@ -100,8 +100,8 @@ private:
|
|||
|
||||
int16 envx;
|
||||
uint16 env_ctr, env_rate, env_sustain;
|
||||
enum EnvelopeStates env_state;
|
||||
enum EnvelopeModes env_mode;
|
||||
uint32 env_state;
|
||||
uint32 env_mode;
|
||||
|
||||
int16 outx;
|
||||
|
||||
|
@ -167,8 +167,16 @@ public:
|
|||
void power();
|
||||
void reset();
|
||||
|
||||
void serialize(serializer&);
|
||||
aDSP();
|
||||
~aDSP();
|
||||
|
||||
friend class aDSPDebug;
|
||||
};
|
||||
|
||||
extern aDSP dsp;
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern aDSPDebugger dsp;
|
||||
#else
|
||||
extern aDSP dsp;
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#ifdef ADSP_CPP
|
||||
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
class aDSPDebugger : public aDSP, public DSPDebugger {
|
||||
public:
|
||||
};
|
|
@ -0,0 +1,71 @@
|
|||
#ifdef ADSP_CPP
|
||||
|
||||
void aDSP::serialize(serializer &s) {
|
||||
DSP::serialize(s);
|
||||
|
||||
s.array(dspram);
|
||||
s.integer(dsp_counter);
|
||||
|
||||
s.integer(status.MVOLL);
|
||||
s.integer(status.MVOLR);
|
||||
s.integer(status.EVOLL);
|
||||
s.integer(status.EVOLR);
|
||||
s.integer(status.KON);
|
||||
s.integer(status.KOFF);
|
||||
s.integer(status.FLG);
|
||||
s.integer(status.ENDX);
|
||||
s.integer(status.EFB);
|
||||
s.integer(status.PMON);
|
||||
s.integer(status.NON);
|
||||
s.integer(status.EON);
|
||||
s.integer(status.DIR);
|
||||
s.integer(status.ESA);
|
||||
s.integer(status.EDL);
|
||||
s.array(status.FIR);
|
||||
|
||||
s.integer(status.kon);
|
||||
s.integer(status.esa);
|
||||
|
||||
s.integer(status.noise_ctr);
|
||||
s.integer(status.noise_rate);
|
||||
s.integer(status.noise_sample);
|
||||
|
||||
s.integer(status.echo_index);
|
||||
s.integer(status.echo_length);
|
||||
s.array(status.fir_buffer[0]);
|
||||
s.array(status.fir_buffer[1]);
|
||||
s.integer(status.fir_buffer_index);
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
s.integer(voice[i].VOLL);
|
||||
s.integer(voice[i].VOLR);
|
||||
s.integer(voice[i].PITCH);
|
||||
s.integer(voice[i].SRCN);
|
||||
s.integer(voice[i].ADSR1);
|
||||
s.integer(voice[i].ADSR2);
|
||||
s.integer(voice[i].GAIN);
|
||||
s.integer(voice[i].ENVX);
|
||||
s.integer(voice[i].OUTX);
|
||||
|
||||
s.integer(voice[i].pitch_ctr);
|
||||
|
||||
s.integer(voice[i].brr_index);
|
||||
s.integer(voice[i].brr_ptr);
|
||||
s.integer(voice[i].brr_header);
|
||||
s.integer(voice[i].brr_looped);
|
||||
|
||||
s.array(voice[i].brr_data);
|
||||
s.integer(voice[i].brr_data_index);
|
||||
|
||||
s.integer(voice[i].envx);
|
||||
s.integer(voice[i].env_ctr);
|
||||
s.integer(voice[i].env_rate);
|
||||
s.integer(voice[i].env_sustain);
|
||||
s.integer(voice[i].env_state);
|
||||
s.integer(voice[i].env_mode);
|
||||
|
||||
s.integer(voice[i].outx);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -36,6 +36,22 @@ unsigned snes_library_revision() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void snes_set_video_refresh(snes_video_refresh_t video_refresh) {
|
||||
interface.pvideo_refresh = video_refresh;
|
||||
}
|
||||
|
||||
void snes_set_audio_sample(snes_audio_sample_t audio_sample) {
|
||||
interface.paudio_sample = audio_sample;
|
||||
}
|
||||
|
||||
void snes_set_input_poll(snes_input_poll_t input_poll) {
|
||||
interface.pinput_poll = input_poll;
|
||||
}
|
||||
|
||||
void snes_set_input_state(snes_input_state_t input_state) {
|
||||
interface.pinput_state = input_state;
|
||||
}
|
||||
|
||||
void snes_init() {
|
||||
SNES::system.init(&interface);
|
||||
SNES::input.port_set_device(0, SNES::Input::Device::Joypad);
|
||||
|
@ -54,24 +70,39 @@ void snes_run() {
|
|||
SNES::system.run();
|
||||
}
|
||||
|
||||
void snes_runtosave() {
|
||||
SNES::system.runtosave();
|
||||
}
|
||||
|
||||
void snes_set_controller_port_device(bool port, unsigned device) {
|
||||
SNES::input.port_set_device(port, (SNES::Input::Device)device);
|
||||
}
|
||||
|
||||
void snes_set_video_refresh(snes_video_refresh_t video_refresh) {
|
||||
interface.pvideo_refresh = video_refresh;
|
||||
unsigned snes_serialize_size() {
|
||||
return SNES::system.serialize_size();
|
||||
}
|
||||
|
||||
void snes_set_audio_sample(snes_audio_sample_t audio_sample) {
|
||||
interface.paudio_sample = audio_sample;
|
||||
bool snes_serialize(uint8_t *data, unsigned size) {
|
||||
serializer s = SNES::system.serialize();
|
||||
if(s.size() > size) return false;
|
||||
memcpy(data, s.data(), s.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
void snes_set_input_poll(snes_input_poll_t input_poll) {
|
||||
interface.pinput_poll = input_poll;
|
||||
bool snes_unserialize(const uint8_t *data, unsigned size) {
|
||||
serializer s(data, size);
|
||||
return SNES::system.unserialize(s);
|
||||
}
|
||||
|
||||
void snes_set_input_state(snes_input_state_t input_state) {
|
||||
interface.pinput_state = input_state;
|
||||
void snes_cheat_reset() {
|
||||
SNES::cheat.reset();
|
||||
SNES::cheat.synchronize();
|
||||
}
|
||||
|
||||
void snes_cheat_set(unsigned index, bool enabled, const char *code) {
|
||||
SNES::cheat[index] = code;
|
||||
SNES::cheat[index].enabled = enabled;
|
||||
SNES::cheat.synchronize();
|
||||
}
|
||||
|
||||
void snes_load_cartridge_normal(
|
||||
|
|
|
@ -5,11 +5,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
unsigned snes_library_revision();
|
||||
void snes_init();
|
||||
void snes_term();
|
||||
void snes_unload();
|
||||
void snes_run();
|
||||
void snes_set_controller_port_device(bool port, unsigned device);
|
||||
|
||||
typedef void (*snes_video_refresh_t)(uint16_t *data, unsigned pitch, unsigned *line, unsigned width, unsigned height);
|
||||
typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right);
|
||||
|
@ -21,6 +16,21 @@ void snes_set_audio_sample(snes_audio_sample_t);
|
|||
void snes_set_input_poll(snes_input_poll_t);
|
||||
void snes_set_input_state(snes_input_state_t);
|
||||
|
||||
void snes_init();
|
||||
void snes_term();
|
||||
void snes_unload();
|
||||
void snes_run();
|
||||
void snes_runtosave();
|
||||
|
||||
void snes_set_controller_port_device(bool port, unsigned device);
|
||||
|
||||
unsigned snes_serialize_size();
|
||||
bool snes_serialize(uint8_t *data, unsigned size);
|
||||
bool snes_unserialize(const uint8_t *data, unsigned size);
|
||||
|
||||
void snes_cheat_reset();
|
||||
void snes_cheat_set(unsigned index, bool enabled, const char *code);
|
||||
|
||||
void snes_load_cartridge_normal(
|
||||
const char *rom_xml, uint8_t *rom_data, unsigned rom_size
|
||||
);
|
||||
|
|
|
@ -89,11 +89,6 @@ void bPPU::scanline() {
|
|||
}
|
||||
|
||||
void bPPU::render_scanline() {
|
||||
#ifdef FAST_FRAMESKIP
|
||||
//note: this bypasses RTO status flag calculations, which is observable by software
|
||||
if(status.render_output == false) return;
|
||||
#endif
|
||||
|
||||
if(line >= 1 && line < (!overscan() ? 225 : 240)) {
|
||||
render_line_oam_rto();
|
||||
render_line();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//this should only be called by CPU::PPUcounter::tick();
|
||||
//keeps track of previous counter positions in history table
|
||||
void PPUcounter::tick() {
|
||||
void PPUCounter::tick() {
|
||||
status.hcounter += 2; //increment by smallest unit of time
|
||||
if(status.hcounter >= 1360 && status.hcounter == lineclocks()) {
|
||||
status.hcounter = 0;
|
||||
|
@ -15,7 +15,7 @@ void PPUcounter::tick() {
|
|||
|
||||
//this should only be called by PPU::PPUcounter::tick(n);
|
||||
//allows stepping by more than the smallest unit of time
|
||||
void PPUcounter::tick(unsigned clocks) {
|
||||
void PPUCounter::tick(unsigned clocks) {
|
||||
status.hcounter += clocks;
|
||||
if(status.hcounter >= lineclocks()) {
|
||||
status.hcounter -= lineclocks();
|
||||
|
@ -24,7 +24,7 @@ void PPUcounter::tick(unsigned clocks) {
|
|||
}
|
||||
|
||||
//internal
|
||||
void PPUcounter::vcounter_tick() {
|
||||
void PPUCounter::vcounter_tick() {
|
||||
if(++status.vcounter == 128) status.interlace = ppu.interlace();
|
||||
|
||||
if((system.region() == System::Region::NTSC && status.interlace == false && status.vcounter == 262)
|
||||
|
@ -40,13 +40,13 @@ void PPUcounter::vcounter_tick() {
|
|||
if(scanline) scanline();
|
||||
}
|
||||
|
||||
bool PPUcounter::field () const { return status.field; }
|
||||
uint16 PPUcounter::vcounter() const { return status.vcounter; }
|
||||
uint16 PPUcounter::hcounter() const { return status.hcounter; }
|
||||
bool PPUCounter::field () const { return status.field; }
|
||||
uint16 PPUCounter::vcounter() const { return status.vcounter; }
|
||||
uint16 PPUCounter::hcounter() const { return status.hcounter; }
|
||||
|
||||
bool PPUcounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; }
|
||||
uint16 PPUcounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; }
|
||||
uint16 PPUcounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; }
|
||||
bool PPUCounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; }
|
||||
uint16 PPUCounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; }
|
||||
uint16 PPUCounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; }
|
||||
|
||||
//one PPU dot = 4 CPU clocks
|
||||
//
|
||||
|
@ -57,7 +57,7 @@ uint16 PPUcounter::hcounter(unsigned offset) const { return history.hcounter[(hi
|
|||
//dot 323 range = { 1292, 1294, 1296 }
|
||||
//dot 327 range = { 1310, 1312, 1314 }
|
||||
|
||||
uint16 PPUcounter::hdot() const {
|
||||
uint16 PPUCounter::hdot() const {
|
||||
if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) {
|
||||
return (hcounter() >> 2);
|
||||
} else {
|
||||
|
@ -65,12 +65,12 @@ uint16 PPUcounter::hdot() const {
|
|||
}
|
||||
}
|
||||
|
||||
uint16 PPUcounter::lineclocks() const {
|
||||
uint16 PPUCounter::lineclocks() const {
|
||||
if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) return 1360;
|
||||
return 1364;
|
||||
}
|
||||
|
||||
void PPUcounter::reset() {
|
||||
void PPUCounter::reset() {
|
||||
status.interlace = false;
|
||||
status.field = 0;
|
||||
status.vcounter = 0;
|
||||
|
|
|
@ -9,25 +9,18 @@ namespace SNES {
|
|||
|
||||
#include "serialization.cpp"
|
||||
|
||||
void PPU::enable_renderer(bool r) { status.render_output = r; }
|
||||
bool PPU::renderer_enabled() { return status.render_output; }
|
||||
|
||||
void PPU::frame() {
|
||||
status.frame_executed = true;
|
||||
|
||||
static int32 fr = 0, fe = 0;
|
||||
static signed framecount = 0;
|
||||
static time_t prev, curr;
|
||||
fe++;
|
||||
if(status.render_output)fr++;
|
||||
framecount++;
|
||||
|
||||
time(&curr);
|
||||
if(curr != prev) {
|
||||
status.frames_updated = true;
|
||||
status.frames_rendered = fr;
|
||||
status.frames_executed = fe;
|
||||
fr = fe = 0;
|
||||
status.frames_updated = true;
|
||||
status.frames_executed = framecount;
|
||||
framecount = 0;
|
||||
prev = curr;
|
||||
}
|
||||
prev = curr;
|
||||
}
|
||||
|
||||
void PPU::power() {
|
||||
|
@ -36,16 +29,14 @@ void PPU::power() {
|
|||
}
|
||||
|
||||
void PPU::reset() {
|
||||
PPUcounter::reset();
|
||||
PPUCounter::reset();
|
||||
memset(output, 0, 512 * 480 * sizeof(uint16));
|
||||
}
|
||||
|
||||
PPU::PPU() {
|
||||
output = new uint16[512 * 480];
|
||||
|
||||
status.render_output = true;
|
||||
status.frames_updated = false;
|
||||
status.frames_rendered = 0;
|
||||
status.frames_updated = false;
|
||||
status.frames_executed = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "ppu-debugger.hpp"
|
||||
#endif
|
||||
|
||||
//PPUcounter emulates the H/V latch counters of the S-PPU2.
|
||||
//PPUCounter emulates the H/V latch counters of the S-PPU2.
|
||||
//
|
||||
//real hardware has the S-CPU maintain its own copy of these counters that are
|
||||
//updated based on the state of the S-PPU Vblank and Hblank pins. emulating this
|
||||
|
@ -14,7 +14,7 @@
|
|||
//point before this in the frame, which is handled internally by this class at
|
||||
//V=128.
|
||||
|
||||
class PPUcounter {
|
||||
class PPUCounter {
|
||||
public:
|
||||
alwaysinline void tick();
|
||||
alwaysinline void tick(unsigned clocks);
|
||||
|
@ -52,17 +52,14 @@ private:
|
|||
} history;
|
||||
};
|
||||
|
||||
class PPU : public PPUcounter, public MMIO {
|
||||
class PPU : public PPUCounter, public MMIO {
|
||||
public:
|
||||
virtual void enter() = 0;
|
||||
|
||||
uint16 *output;
|
||||
|
||||
struct {
|
||||
bool render_output;
|
||||
bool frame_executed;
|
||||
bool frames_updated;
|
||||
unsigned frames_rendered;
|
||||
unsigned frames_executed;
|
||||
} status;
|
||||
|
||||
|
@ -78,8 +75,6 @@ public:
|
|||
virtual void frame();
|
||||
virtual void power();
|
||||
virtual void reset();
|
||||
virtual void enable_renderer(bool r);
|
||||
virtual bool renderer_enabled();
|
||||
|
||||
virtual void serialize(serializer&);
|
||||
PPU();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifdef PPU_CPP
|
||||
|
||||
void PPUcounter::serialize(serializer &s) {
|
||||
void PPUCounter::serialize(serializer &s) {
|
||||
s.integer(status.interlace);
|
||||
s.integer(status.field);
|
||||
s.integer(status.vcounter);
|
||||
|
@ -13,12 +13,9 @@ void PPUcounter::serialize(serializer &s) {
|
|||
}
|
||||
|
||||
void PPU::serialize(serializer &s) {
|
||||
PPUcounter::serialize(s);
|
||||
PPUCounter::serialize(s);
|
||||
|
||||
s.integer(status.render_output);
|
||||
s.integer(status.frame_executed);
|
||||
s.integer(status.frames_updated);
|
||||
s.integer(status.frames_rendered);
|
||||
s.integer(status.frames_executed);
|
||||
|
||||
s.integer(ppu1_version);
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
struct {
|
||||
struct {
|
||||
unsigned priority; //0 = none (transparent)
|
||||
unsigned palette; //(direct_color_bits << 8) + index
|
||||
unsigned palette;
|
||||
unsigned tile;
|
||||
} main, sub;
|
||||
} output;
|
||||
|
@ -45,6 +45,8 @@ public:
|
|||
unsigned get_tile(unsigned x, unsigned y);
|
||||
unsigned get_color(unsigned x, unsigned y, uint16 offset);
|
||||
void reset();
|
||||
|
||||
void serialize(serializer&);
|
||||
Background(sPPU &self, unsigned id);
|
||||
|
||||
private:
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
void run();
|
||||
void reset();
|
||||
|
||||
void serialize(serializer&);
|
||||
Screen(sPPU &self);
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
#ifdef SPPU_CPP
|
||||
|
||||
void sPPU::serialize(serializer &s) {
|
||||
PPU::serialize(s);
|
||||
|
||||
s.integer(display.interlace);
|
||||
s.integer(display.overscan);
|
||||
|
||||
s.integer(regs.ppu1_mdr);
|
||||
s.integer(regs.ppu2_mdr);
|
||||
|
||||
s.integer(regs.vram_readbuffer);
|
||||
s.integer(regs.oam_latchdata);
|
||||
s.integer(regs.cgram_latchdata);
|
||||
s.integer(regs.bgofs_latchdata);
|
||||
s.integer(regs.mode7_latchdata);
|
||||
s.integer(regs.counters_latched);
|
||||
s.integer(regs.latch_hcounter);
|
||||
s.integer(regs.latch_vcounter);
|
||||
|
||||
s.integer(regs.display_disabled);
|
||||
s.integer(regs.display_brightness);
|
||||
|
||||
s.integer(regs.oam_baseaddr);
|
||||
s.integer(regs.oam_addr);
|
||||
s.integer(regs.oam_priority);
|
||||
|
||||
s.integer(regs.bg3_priority);
|
||||
s.integer(regs.bgmode);
|
||||
|
||||
s.integer(regs.mode7_hoffset);
|
||||
s.integer(regs.mode7_voffset);
|
||||
|
||||
s.integer(regs.vram_incmode);
|
||||
s.integer(regs.vram_mapping);
|
||||
s.integer(regs.vram_incsize);
|
||||
|
||||
s.integer(regs.vram_addr);
|
||||
|
||||
s.integer(regs.mode7_repeat);
|
||||
s.integer(regs.mode7_vflip);
|
||||
s.integer(regs.mode7_hflip);
|
||||
|
||||
s.integer(regs.m7a);
|
||||
s.integer(regs.m7b);
|
||||
s.integer(regs.m7c);
|
||||
s.integer(regs.m7d);
|
||||
s.integer(regs.m7x);
|
||||
s.integer(regs.m7y);
|
||||
|
||||
s.integer(regs.cgram_addr);
|
||||
|
||||
s.integer(regs.mode7_extbg);
|
||||
s.integer(regs.pseudo_hires);
|
||||
s.integer(regs.overscan);
|
||||
s.integer(regs.interlace);
|
||||
|
||||
s.integer(regs.hcounter);
|
||||
s.integer(regs.vcounter);
|
||||
|
||||
bg1.serialize(s);
|
||||
bg2.serialize(s);
|
||||
bg3.serialize(s);
|
||||
bg4.serialize(s);
|
||||
oam.serialize(s);
|
||||
window.serialize(s);
|
||||
screen.serialize(s);
|
||||
}
|
||||
|
||||
void sPPU::Background::serialize(serializer &s) {
|
||||
s.integer(id);
|
||||
|
||||
s.integer(t.x);
|
||||
s.integer(t.mosaic_y);
|
||||
s.integer(t.mosaic_countdown);
|
||||
|
||||
s.integer(regs.tiledata_addr);
|
||||
s.integer(regs.screen_addr);
|
||||
s.integer(regs.screen_size);
|
||||
s.integer(regs.mosaic);
|
||||
s.integer(regs.tile_size);
|
||||
|
||||
s.integer(regs.mode);
|
||||
s.integer(regs.priority0);
|
||||
s.integer(regs.priority1);
|
||||
|
||||
s.integer(regs.main_enabled);
|
||||
s.integer(regs.sub_enabled);
|
||||
|
||||
s.integer(regs.hoffset);
|
||||
s.integer(regs.voffset);
|
||||
|
||||
s.integer(output.main.priority);
|
||||
s.integer(output.main.palette);
|
||||
s.integer(output.main.tile);
|
||||
|
||||
s.integer(output.sub.priority);
|
||||
s.integer(output.sub.palette);
|
||||
s.integer(output.sub.tile);
|
||||
}
|
||||
|
||||
void sPPU::Sprite::serialize(serializer &s) {
|
||||
for(unsigned i = 0; i < 128; i++) {
|
||||
s.integer(list[i].width);
|
||||
s.integer(list[i].height);
|
||||
s.integer(list[i].x);
|
||||
s.integer(list[i].y);
|
||||
s.integer(list[i].character);
|
||||
s.integer(list[i].nameselect);
|
||||
s.integer(list[i].vflip);
|
||||
s.integer(list[i].hflip);
|
||||
s.integer(list[i].priority);
|
||||
s.integer(list[i].palette);
|
||||
}
|
||||
|
||||
s.integer(t.x);
|
||||
s.integer(t.y);
|
||||
s.integer(t.item_count);
|
||||
s.integer(t.tile_count);
|
||||
s.array(t.output_palette);
|
||||
s.array(t.output_priority);
|
||||
s.array(t.item_list);
|
||||
for(unsigned i = 0; i < 34; i++) {
|
||||
s.integer(t.tile_list[i].x);
|
||||
s.integer(t.tile_list[i].y);
|
||||
s.integer(t.tile_list[i].priority);
|
||||
s.integer(t.tile_list[i].palette);
|
||||
s.integer(t.tile_list[i].tile);
|
||||
s.integer(t.tile_list[i].hflip);
|
||||
}
|
||||
s.integer(t.active_sprite);
|
||||
|
||||
s.integer(regs.main_enabled);
|
||||
s.integer(regs.sub_enabled);
|
||||
s.integer(regs.interlace);
|
||||
|
||||
s.integer(regs.base_size);
|
||||
s.integer(regs.nameselect);
|
||||
s.integer(regs.tiledata_addr);
|
||||
s.integer(regs.first_sprite);
|
||||
|
||||
s.integer(regs.priority0);
|
||||
s.integer(regs.priority1);
|
||||
s.integer(regs.priority2);
|
||||
s.integer(regs.priority3);
|
||||
|
||||
s.integer(regs.time_over);
|
||||
s.integer(regs.range_over);
|
||||
|
||||
s.integer(output.main.priority);
|
||||
s.integer(output.main.palette);
|
||||
|
||||
s.integer(output.sub.priority);
|
||||
s.integer(output.sub.palette);
|
||||
}
|
||||
|
||||
void sPPU::Window::serialize(serializer &s) {
|
||||
s.integer(t.x);
|
||||
|
||||
s.integer(regs.bg1_one_enable);
|
||||
s.integer(regs.bg1_one_invert);
|
||||
s.integer(regs.bg1_two_enable);
|
||||
s.integer(regs.bg1_two_invert);
|
||||
|
||||
s.integer(regs.bg2_one_enable);
|
||||
s.integer(regs.bg2_one_invert);
|
||||
s.integer(regs.bg2_two_enable);
|
||||
s.integer(regs.bg2_two_invert);
|
||||
|
||||
s.integer(regs.bg3_one_enable);
|
||||
s.integer(regs.bg3_one_invert);
|
||||
s.integer(regs.bg3_two_enable);
|
||||
s.integer(regs.bg3_two_invert);
|
||||
|
||||
s.integer(regs.bg4_one_enable);
|
||||
s.integer(regs.bg4_one_invert);
|
||||
s.integer(regs.bg4_two_enable);
|
||||
s.integer(regs.bg4_two_invert);
|
||||
|
||||
s.integer(regs.oam_one_enable);
|
||||
s.integer(regs.oam_one_invert);
|
||||
s.integer(regs.oam_two_enable);
|
||||
s.integer(regs.oam_two_invert);
|
||||
|
||||
s.integer(regs.col_one_enable);
|
||||
s.integer(regs.col_one_invert);
|
||||
s.integer(regs.col_two_enable);
|
||||
s.integer(regs.col_two_invert);
|
||||
|
||||
s.integer(regs.one_left);
|
||||
s.integer(regs.one_right);
|
||||
s.integer(regs.two_left);
|
||||
s.integer(regs.two_right);
|
||||
|
||||
s.integer(regs.bg1_mask);
|
||||
s.integer(regs.bg2_mask);
|
||||
s.integer(regs.bg3_mask);
|
||||
s.integer(regs.bg4_mask);
|
||||
s.integer(regs.oam_mask);
|
||||
s.integer(regs.col_mask);
|
||||
|
||||
s.integer(regs.bg1_main_enable);
|
||||
s.integer(regs.bg1_sub_enable);
|
||||
s.integer(regs.bg2_main_enable);
|
||||
s.integer(regs.bg2_sub_enable);
|
||||
s.integer(regs.bg3_main_enable);
|
||||
s.integer(regs.bg3_sub_enable);
|
||||
s.integer(regs.bg4_main_enable);
|
||||
s.integer(regs.bg4_sub_enable);
|
||||
s.integer(regs.oam_main_enable);
|
||||
s.integer(regs.oam_sub_enable);
|
||||
|
||||
s.integer(regs.col_main_mask);
|
||||
s.integer(regs.col_sub_mask);
|
||||
|
||||
s.integer(output.main.color_enable);
|
||||
s.integer(output.sub.color_enable);
|
||||
|
||||
}
|
||||
|
||||
void sPPU::Screen::serialize(serializer &s) {
|
||||
s.integer(regs.addsub_mode);
|
||||
s.integer(regs.direct_color);
|
||||
|
||||
s.integer(regs.color_mode);
|
||||
s.integer(regs.color_halve);
|
||||
s.integer(regs.bg1_color_enable);
|
||||
s.integer(regs.bg2_color_enable);
|
||||
s.integer(regs.bg3_color_enable);
|
||||
s.integer(regs.bg4_color_enable);
|
||||
s.integer(regs.oam_color_enable);
|
||||
s.integer(regs.back_color_enable);
|
||||
|
||||
s.integer(regs.color_b);
|
||||
s.integer(regs.color_g);
|
||||
s.integer(regs.color_r);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -3,12 +3,6 @@
|
|||
#define SPPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "background/background.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "screen/screen.cpp"
|
||||
#include "sprite/sprite.cpp"
|
||||
#include "window/window.cpp"
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
sPPUDebugger ppu;
|
||||
|
@ -16,10 +10,20 @@ namespace SNES {
|
|||
sPPU ppu;
|
||||
#endif
|
||||
|
||||
#include "background/background.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "screen/screen.cpp"
|
||||
#include "sprite/sprite.cpp"
|
||||
#include "window/window.cpp"
|
||||
#include "serialization.cpp"
|
||||
|
||||
void sPPU::enter() {
|
||||
while(true) {
|
||||
scanline();
|
||||
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
|
||||
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
|
||||
}
|
||||
|
||||
scanline();
|
||||
add_clocks(88);
|
||||
|
||||
if(vcounter() >= 1 && vcounter() <= (!regs.overscan ? 224 : 239)) {
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
void scanline();
|
||||
void frame();
|
||||
|
||||
void serialize(serializer&);
|
||||
sPPU();
|
||||
};
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@ public:
|
|||
bool nameselect;
|
||||
bool vflip;
|
||||
bool hflip;
|
||||
uint8 palette;
|
||||
uint8 priority;
|
||||
uint8 palette;
|
||||
} list[128];
|
||||
|
||||
struct State {
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
struct {
|
||||
struct {
|
||||
unsigned priority; //0 = none (transparent)
|
||||
unsigned palette; //index
|
||||
unsigned palette;
|
||||
} main, sub;
|
||||
} output;
|
||||
|
||||
|
@ -69,6 +69,7 @@ public:
|
|||
void run();
|
||||
void reset();
|
||||
|
||||
void serialize(serializer&);
|
||||
Sprite(sPPU &self);
|
||||
|
||||
private:
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
void run();
|
||||
void reset();
|
||||
|
||||
void serialize(serializer&);
|
||||
Window(sPPU &self);
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
static const char bsnesVersion[] = "063.12";
|
||||
static const char bsnesVersion[] = "063.13";
|
||||
static const char bsnesTitle[] = "bsnes";
|
||||
static const unsigned bsnesSerializerVersion = 9;
|
||||
static const unsigned bsnesSerializerVersion = 10;
|
||||
|
||||
#define CORE_SMEMORY
|
||||
#define CORE_SCPU
|
||||
#define CORE_SSMP
|
||||
#define CORE_SDSP
|
||||
#define CORE_SPPU
|
||||
#define CORE_ADSP
|
||||
#define CORE_BPPU
|
||||
|
||||
//S-DSP can be encapsulated into a state machine using #define magic
|
||||
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
||||
|
@ -23,7 +23,6 @@ static const unsigned bsnesSerializerVersion = 9;
|
|||
#include <nall/algorithm.hpp>
|
||||
#include <nall/any.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
|
@ -32,7 +31,6 @@ static const unsigned bsnesSerializerVersion = 9;
|
|||
#include <nall/function.hpp>
|
||||
#include <nall/moduloarray.hpp>
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/priorityqueue.hpp>
|
||||
#include <nall/property.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
|
|
|
@ -8,9 +8,9 @@ void FileBrowser::chooseFolder() {
|
|||
|
||||
void FileBrowser::loadCartridge(CartridgeMode mode, signed filterIndex) {
|
||||
cartridgeMode = mode;
|
||||
onChange = bind(&FileBrowser::onChangeCartridge, this);
|
||||
onActivate = bind(&FileBrowser::onAcceptCartridge, this);
|
||||
onAccept = bind(&FileBrowser::onAcceptCartridge, this);
|
||||
onChange = { &FileBrowser::onChangeCartridge, this };
|
||||
onActivate = { &FileBrowser::onAcceptCartridge, this };
|
||||
onAccept = { &FileBrowser::onAcceptCartridge, this };
|
||||
|
||||
setPath(config().path.rom == "" ? config().path.current.cartridge : config().path.rom);
|
||||
setNameFilters(string()
|
||||
|
|
|
@ -27,8 +27,8 @@ Reader::Reader() {
|
|||
}
|
||||
|
||||
if(!supported || !load) {
|
||||
supported = bind(&Reader::direct_supported, this);
|
||||
load = bind(&Reader::direct_load, this);
|
||||
supported = { &Reader::direct_supported, this };
|
||||
load = { &Reader::direct_load, this };
|
||||
}
|
||||
|
||||
compressionList = supported();
|
||||
|
|
|
@ -4,8 +4,8 @@ Movie movie;
|
|||
|
||||
void Movie::chooseFile() {
|
||||
fileBrowser->onChange.reset();
|
||||
fileBrowser->onActivate = bind(&Movie::play, this);
|
||||
fileBrowser->onAccept = bind(&Movie::play, this);
|
||||
fileBrowser->onActivate = { &Movie::play, this };
|
||||
fileBrowser->onAccept = { &Movie::play, this };
|
||||
fileBrowser->setWindowTitle("Select Movie");
|
||||
fileBrowser->setPath(config().path.current.movie);
|
||||
fileBrowser->setNameFilters("bsnes Movies (*.bsv)");
|
||||
|
|
|
@ -52,7 +52,7 @@ void PathSettingWidget::updatePath() {
|
|||
void PathSettingWidget::selectPath() {
|
||||
fileBrowser->onChange.reset();
|
||||
fileBrowser->onActivate.reset();
|
||||
fileBrowser->onAccept = bind(&PathSettingWidget::acceptPath, this);
|
||||
fileBrowser->onAccept = { &PathSettingWidget::acceptPath, this };
|
||||
fileBrowser->setWindowTitle(pathBrowseLabel);
|
||||
fileBrowser->setPath(config().path.current.folder);
|
||||
fileBrowser->chooseFolder();
|
||||
|
|
|
@ -303,8 +303,8 @@ void VideoSettingsWindow::cropBottomAdjust(int state) {
|
|||
|
||||
void VideoSettingsWindow::selectFragmentShader() {
|
||||
fileBrowser->onChange.reset();
|
||||
fileBrowser->onActivate = bind(&VideoSettingsWindow::assignFragmentShader, this);
|
||||
fileBrowser->onAccept = bind(&VideoSettingsWindow::assignFragmentShader, this);
|
||||
fileBrowser->onActivate = { &VideoSettingsWindow::assignFragmentShader, this };
|
||||
fileBrowser->onAccept = { &VideoSettingsWindow::assignFragmentShader, this };
|
||||
fileBrowser->setWindowTitle("Select Fragment Shader");
|
||||
fileBrowser->setPath(config().path.current.shader);
|
||||
fileBrowser->setNameFilters("All files (*)");
|
||||
|
@ -313,8 +313,8 @@ void VideoSettingsWindow::selectFragmentShader() {
|
|||
|
||||
void VideoSettingsWindow::selectVertexShader() {
|
||||
fileBrowser->onChange.reset();
|
||||
fileBrowser->onActivate = bind(&VideoSettingsWindow::assignVertexShader, this);
|
||||
fileBrowser->onAccept = bind(&VideoSettingsWindow::assignVertexShader, this);
|
||||
fileBrowser->onActivate = { &VideoSettingsWindow::assignVertexShader, this };
|
||||
fileBrowser->onAccept = { &VideoSettingsWindow::assignVertexShader, this };
|
||||
fileBrowser->setWindowTitle("Select Vertex Shader");
|
||||
fileBrowser->setPath(config().path.current.shader);
|
||||
fileBrowser->setNameFilters("All files (*)");
|
||||
|
|
|
@ -86,13 +86,32 @@ int main(int argc, char *argv[]) {
|
|||
snes_load_cartridge_normal(0, rom_data, rom_size);
|
||||
delete[] rom_data;
|
||||
|
||||
unsigned serial_size = snes_serialize_size();
|
||||
uint8_t *serial_data = new uint8_t[serial_size];
|
||||
snes_runtosave();
|
||||
snes_serialize(serial_data, serial_size);
|
||||
|
||||
snes_cheat_reset();
|
||||
//snes_cheat_set(0, true, "DD32-6DAD");
|
||||
|
||||
while(true) {
|
||||
SDL_Event event;
|
||||
SDL_PollEvent(&event);
|
||||
if(event.type == SDL_QUIT) break;
|
||||
if(event.type == SDL_KEYDOWN) {
|
||||
if(event.key.keysym.sym == SDLK_ESCAPE) {
|
||||
break;
|
||||
} else if(event.key.keysym.sym == SDLK_F2) {
|
||||
snes_runtosave();
|
||||
snes_serialize(serial_data, serial_size);
|
||||
} else if(event.key.keysym.sym == SDLK_F4) {
|
||||
snes_unserialize(serial_data, serial_size);
|
||||
}
|
||||
}
|
||||
snes_run();
|
||||
}
|
||||
|
||||
delete[] serial_data;
|
||||
snes_unload();
|
||||
snes_term();
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue