Update to bsnes v055 release.

Happy Halloween, this release adds full Super Game Boy support ... but is it a trick, or a treat? ;) ::cough::, lameness aside ...
The Game Boy emulation core is courtesy of gambatte, and excellent, accuracy-focused, open source, and lightning fast Game Boy Color emulator. Now I know what you're thinking, using a Game Boy Color emulator with the Super Game Boy? The truth is, gambatte was just such an amazingly perfect fit that nothing else compared. I fully believe that even as a CGB emulator, gambatte will do a better job than any pure DMG emulator could.
The emulation of the ICD2 chip (aka the Super Game Boy) was fully reverse engineered by myself. Eventually I'll get an updated document put up explaining how it works.
The next question might be, "why emulate the Super Game Boy when existing Game Boy emulators do?"; well, they can only simulate part of the SGB. Features such as custom SNES sound effects, hand-drawn borders, multi-tap support and custom SNES code execution can only be accomplished by a true SNES emulator. Space Invaders is perhaps the most impressive demonstration, as it contains an entire SNES game embedded inside the Game Boy cartridge.
bsnes' SGB emulation supports virtually every command, full sound mixing from both the SNES and Game Boy sides, both BIOS revisions, etc. The only thing that is not fully functional yet is the multi-player support, but it should be in due time. Save state support is also planned for a later date.
Changelog:
    - added Super Game Boy emulation (thanks to gambatte for the Game Boy core)
    - extended hybrid scanline/cycle PPU renderer to support Mode7 register caching; fixes scanline flickering on NHL '94 title screen
    - all windows (other than the main window) can be closed with the escape key now
    - file dialog path selection now accepts typed paths; can be used to access hidden directories and network shares
    - file dialog's game information panel can now be disabled
    - fixed a crashing issue when the file dialog was given an invalid path
    - fixed screenshot capture save location
    - added screenshot capture option to tools menu
    - state manager now auto-closes when loading a state; it can be reopened quickly with F3
    - fixed GZip archive loading
    - fixed NTSC off-by-one filter bug on hires screens
    - extended Scale2x, LQ2x and HQ2x to properly filter hires screens
    - added Pixellate2x filter
This commit is contained in:
byuu 2009-11-01 14:30:51 +00:00
parent 6a17b5ed4f
commit 4c66de6f27
73 changed files with 922 additions and 770 deletions

View File

@ -79,7 +79,7 @@ link += $(call ifhas,input.rawinput,$(ruby),-ldinput8 -ldxguid)
objects := libco ruby
objects += system cartridge cheat
objects += memory smemory cpu cpucore scpu smp smpcore ssmp sdsp ppu bppu
objects += sgb superfx sa1
objects += supergameboy superfx sa1
objects += bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010 st011 st018
######################
@ -166,22 +166,22 @@ obj/system.o: system/system.cpp $(call rwildcard,system/)
### special chips ###
#####################
obj/sgb.o : chip/sgb/sgb.cpp $(call rwildcard,chip/sgb/)
obj/superfx.o: chip/superfx/superfx.cpp $(call rwildcard,chip/superfx/)
obj/sa1.o : chip/sa1/sa1.cpp $(call rwildcard,chip/sa1/)
obj/bsx.o : chip/bsx/bsx.cpp chip/bsx/*
obj/srtc.o : chip/srtc/srtc.cpp chip/srtc/*
obj/sdd1.o : chip/sdd1/sdd1.cpp chip/sdd1/*
obj/spc7110.o: chip/spc7110/spc7110.cpp chip/spc7110/*
obj/cx4.o : chip/cx4/cx4.cpp chip/cx4/*
obj/dsp1.o : chip/dsp1/dsp1.cpp chip/dsp1/*
obj/dsp2.o : chip/dsp2/dsp2.cpp chip/dsp2/*
obj/dsp3.o : chip/dsp3/dsp3.cpp chip/dsp3/*
obj/dsp4.o : chip/dsp4/dsp4.cpp chip/dsp4/*
obj/obc1.o : chip/obc1/obc1.cpp chip/obc1/*
obj/st010.o : chip/st010/st010.cpp chip/st010/*
obj/st011.o : chip/st011/st011.cpp chip/st011/*
obj/st018.o : chip/st018/st018.cpp chip/st018/*
obj/supergameboy.o: chip/supergameboy/supergameboy.cpp $(call rwildcard,chip/supergameboy/)
obj/superfx.o : chip/superfx/superfx.cpp $(call rwildcard,chip/superfx/)
obj/sa1.o : chip/sa1/sa1.cpp $(call rwildcard,chip/sa1/)
obj/bsx.o : chip/bsx/bsx.cpp chip/bsx/*
obj/srtc.o : chip/srtc/srtc.cpp chip/srtc/*
obj/sdd1.o : chip/sdd1/sdd1.cpp chip/sdd1/*
obj/spc7110.o : chip/spc7110/spc7110.cpp chip/spc7110/*
obj/cx4.o : chip/cx4/cx4.cpp chip/cx4/*
obj/dsp1.o : chip/dsp1/dsp1.cpp chip/dsp1/*
obj/dsp2.o : chip/dsp2/dsp2.cpp chip/dsp2/*
obj/dsp3.o : chip/dsp3/dsp3.cpp chip/dsp3/*
obj/dsp4.o : chip/dsp4/dsp4.cpp chip/dsp4/*
obj/obc1.o : chip/obc1/obc1.cpp chip/obc1/*
obj/st010.o : chip/st010/st010.cpp chip/st010/*
obj/st011.o : chip/st011/st011.cpp chip/st011/*
obj/st018.o : chip/st018/st018.cpp chip/st018/*
###############
### targets ###

View File

@ -1,4 +1,4 @@
static const char bsnesVersion[] = "0.054";
static const char bsnesVersion[] = "0.055";
static const char bsnesTitle[] = "bsnes";
static const unsigned bsnesSaveStateVersion = 3;

View File

@ -6,13 +6,14 @@
namespace SNES {
#include "header.cpp"
#include "gameboyheader.cpp"
namespace memory {
MappedRAM cartrom, cartram, cartrtc;
MappedRAM bsxflash, bsxram, bsxpram;
MappedRAM stArom, stAram;
MappedRAM stBrom, stBram;
MappedRAM gbrom, gbram;
MappedRAM gbrom, gbram, gbrtc;
};
Cartridge cartridge;
@ -43,7 +44,13 @@ void Cartridge::load(Mode cartridge_mode) {
}
if(mode() == ModeSuperGameBoy) {
if(memory::gbrom.data()) memory::gbram.map(allocate<uint8_t>(64 * 1024, 0xff), 64 * 1024);
if(memory::gbrom.data()) {
unsigned ram_size = gameboy_ram_size();
unsigned rtc_size = gameboy_rtc_size();
if(ram_size) memory::gbram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
if(rtc_size) memory::gbrtc.map(allocate<uint8_t>(rtc_size, 0x00), rtc_size);
}
}
memory::cartrom.write_protect(true);
@ -58,6 +65,7 @@ void Cartridge::load(Mode cartridge_mode) {
memory::stBram.write_protect(false);
memory::gbrom.write_protect(true);
memory::gbram.write_protect(false);
memory::gbrtc.write_protect(false);
unsigned checksum = ~0;
for(unsigned n = 0; n < memory::cartrom.size(); n++) checksum = crc32_adjust(checksum, memory::cartrom[n]);
@ -104,6 +112,7 @@ void Cartridge::unload() {
memory::stBram.reset();
memory::gbrom.reset();
memory::gbram.reset();
memory::gbrtc.reset();
if(loaded() == false) return;
bus.unload_cart();
@ -144,6 +153,10 @@ void Cartridge::serialize(serializer &s) {
if(memory::gbram.size() != 0 && memory::gbram.size() != ~0) {
s.array(memory::gbram.data(), memory::gbram.size());
}
if(memory::gbrtc.size() != 0 && memory::gbrtc.size() != ~0) {
s.array(memory::gbrtc.data(), memory::gbrtc.size());
}
}
Cartridge::Cartridge() {
@ -213,5 +226,4 @@ Cartridge::cartinfo_t::cartinfo_t() {
reset();
}
};
}

View File

@ -118,6 +118,9 @@ private:
unsigned find_header(const uint8_t *data, unsigned size) const;
unsigned score_header(const uint8_t *data, unsigned size, unsigned addr) const;
void set_cartinfo(const cartinfo_t&);
unsigned gameboy_ram_size() const;
unsigned gameboy_rtc_size() const;
};
namespace memory {
@ -125,7 +128,7 @@ namespace memory {
extern MappedRAM bsxflash, bsxram, bsxpram;
extern MappedRAM stArom, stAram;
extern MappedRAM stBrom, stBram;
extern MappedRAM gbrom, gbram;
extern MappedRAM gbrom, gbram, gbrtc;
};
extern Cartridge cartridge;

View File

@ -0,0 +1,22 @@
#ifdef CARTRIDGE_CPP
unsigned Cartridge::gameboy_ram_size() const {
if(memory::gbrom.size() < 512) return 0;
switch(memory::gbrom[0x0149]) {
case 0x00: return 0 * 1024;
case 0x01: return 8 * 1024;
case 0x02: return 8 * 1024;
case 0x03: return 32 * 1024;
case 0x04: return 128 * 1024;
case 0x05: return 128 * 1024;
default: return 128 * 1024;
}
}
unsigned Cartridge::gameboy_rtc_size() const {
if(memory::gbrom.size() < 512) return 0;
if(memory::gbrom[0x0147] == 0x0f || memory::gbrom[0x0147] == 0x10) return 4;
return 0;
}
#endif

View File

@ -1,4 +1,4 @@
#include "sgb/sgb.hpp"
#include "supergameboy/supergameboy.hpp"
#include "superfx/superfx.hpp"
#include "sa1/sa1.hpp"
#include "bsx/bsx.hpp"

View File

@ -1,65 +0,0 @@
#include <../base.hpp>
#define SGB_CPP
namespace SNES {
SuperGameBoy sgb;
void SuperGameBoy::enter() {
while(true) {
if(sgb_run) {
unsigned samples = sgb_run(samplebuffer, 16);
scheduler.addclocks_cop(samples * 10);
scheduler.sync_copcpu();
} else {
scheduler.addclocks_cop(64 * 1024 * 1024);
scheduler.sync_copcpu();
}
}
}
uint8_t SuperGameBoy::read(unsigned addr) {
addr &= 0xffff;
if(sgb_read) return sgb_read(addr);
return 0x00;
}
void SuperGameBoy::write(unsigned addr, uint8_t data) {
addr &= 0xffff;
if(sgb_write) return sgb_write(addr, data);
}
void SuperGameBoy::init() {
if(libsgb.open("SuperGameBoy")) {
sgb_init = libsgb.sym("sgb_init");
sgb_term = libsgb.sym("sgb_term");
sgb_power = libsgb.sym("sgb_power");
sgb_reset = libsgb.sym("sgb_reset");
sgb_read = libsgb.sym("sgb_read");
sgb_write = libsgb.sym("sgb_write");
sgb_run = libsgb.sym("sgb_run");
}
}
void SuperGameBoy::enable() {
}
void SuperGameBoy::power() {
bus.map(Bus::MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, *this);
bus.map(Bus::MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, *this);
if(sgb_init) {
sgb_init(SGB2,
memory::gbrom.data(), memory::gbrom.size(),
memory::gbram.data(), memory::gbram.size()
);
}
if(sgb_power) sgb_power();
}
void SuperGameBoy::reset() {
if(sgb_reset) sgb_reset();
}
};

View File

@ -1,27 +0,0 @@
class SuperGameBoy : public Memory {
public:
void enter();
uint8_t read(unsigned addr);
void write(unsigned addr, uint8_t data);
void init();
void enable();
void power();
void reset();
private:
library libsgb;
uint32_t samplebuffer[4096];
enum { SGB1 = 0, SGB2 = 1 };
function<bool (bool, uint8_t*, unsigned, uint8_t*, unsigned)> sgb_init;
function<void ()> sgb_term;
function<void ()> sgb_power;
function<void ()> sgb_reset;
function<uint8_t (unsigned)> sgb_read;
function<void (unsigned, uint8_t)> sgb_write;
function<unsigned (uint32_t*, unsigned)> sgb_run;
};
extern SuperGameBoy sgb;

View File

@ -0,0 +1,117 @@
#include <../base.hpp>
#define SUPERGAMEBOY_CPP
namespace SNES {
SuperGameBoy supergameboy;
void SuperGameBoy::enter() {
if(!sgb_run) while(true) {
audio.coprocessor_sample(0, 0);
scheduler.addclocks_cop(10);
scheduler.sync_copcpu();
}
while(true) {
unsigned samples = sgb_run(samplebuffer, 16);
for(unsigned i = 0; i < samples; i++) {
audio.coprocessor_sample(samplebuffer[i] >> 0, samplebuffer[i] >> 16);
}
scheduler.addclocks_cop(samples * 10);
scheduler.sync_copcpu();
}
}
uint8 SuperGameBoy::mmio_read(unsigned addr) {
addr &= 0xffff;
if(addr == 0x2181) return mmio[0]->mmio_read(addr);
if(addr == 0x2182) return mmio[1]->mmio_read(addr);
if(addr == 0x420b) return mmio[2]->mmio_read(addr);
return 0x00;
}
void SuperGameBoy::mmio_write(unsigned addr, uint8 data) {
addr &= 0xffff;
if(addr == 0x2181) {
row = (row & 0xff00) | (data << 0);
mmio[0]->mmio_write(addr, data);
}
if(addr == 0x2182) {
row = (row & 0x00ff) | (data << 8);
mmio[1]->mmio_write(addr, data);
}
if(addr == 0x420b) {
if(data == 0x10 && sgb_row) {
if(row >= 0x5000 && row <= 0x6540) sgb_row((row - 0x5000) / 320);
if(row >= 0x6800 && row <= 0x7d40) sgb_row((row - 0x6800) / 320);
}
mmio[2]->mmio_write(addr, data);
}
}
uint8 SuperGameBoy::read(unsigned addr) {
if(sgb_read) return sgb_read(addr);
return 0x00;
}
void SuperGameBoy::write(unsigned addr, uint8 data) {
if(sgb_write) sgb_write(addr, data);
}
void SuperGameBoy::init() {
if(open("supergameboy")) {
sgb_rom = sym("sgb_rom");
sgb_ram = sym("sgb_ram");
sgb_rtc = sym("sgb_rtc");
sgb_init = sym("sgb_init");
sgb_term = sym("sgb_term");
sgb_power = sym("sgb_power");
sgb_reset = sym("sgb_reset");
sgb_row = sym("sgb_row");
sgb_read = sym("sgb_read");
sgb_write = sym("sgb_write");
sgb_run = sym("sgb_run");
sgb_save = sym("sgb_save");
}
}
void SuperGameBoy::enable() {
mmio[0] = memory::mmio.mmio[0x2181 - 0x2000];
mmio[1] = memory::mmio.mmio[0x2182 - 0x2000];
mmio[2] = memory::mmio.mmio[0x420b - 0x2000];
memory::mmio.map(0x2181, *this);
memory::mmio.map(0x2182, *this);
memory::mmio.map(0x420b, *this);
}
void SuperGameBoy::power() {
audio.coprocessor_enable(true);
audio.coprocessor_frequency(2147727.2);
bus.map(Bus::MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, *this);
bus.map(Bus::MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, *this);
sgb_rom(memory::gbrom.data(), memory::gbrom.size() == -1U ? 0 : memory::gbrom.size());
sgb_ram(memory::gbram.data(), memory::gbram.size() == -1U ? 0 : memory::gbram.size());
sgb_rtc(memory::gbrtc.data(), memory::gbrtc.size() == -1U ? 0 : memory::gbrtc.size());
//determine whether to use SGB1 or SGB2 mode based on the cartridge title (look for the '2')
if(sgb_init) sgb_init(memory::cartrom[0x7fcd] != 0x32 ? SuperGameBoy1 : SuperGameBoy2);
if(sgb_power) sgb_power();
}
void SuperGameBoy::reset() {
if(sgb_reset) sgb_reset();
}
void SuperGameBoy::unload() {
if(sgb_term) sgb_term();
}
}

View File

@ -0,0 +1,37 @@
class SuperGameBoy : public MMIO, public Memory, public library {
public:
void enter();
MMIO *mmio[3];
uint8 mmio_read(unsigned addr);
void mmio_write(unsigned addr, uint8 data);
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
void init();
void enable();
void power();
void reset();
void unload();
private:
uint32_t samplebuffer[4096];
unsigned row;
enum { SuperGameBoy1 = 0, SuperGameBoy2 = 1 };
function<void (uint8_t*, unsigned)> sgb_rom;
function<void (uint8_t*, unsigned)> sgb_ram;
function<void (uint8_t*, unsigned)> sgb_rtc;
function<bool (bool)> sgb_init;
function<void ()> sgb_term;
function<void ()> sgb_power;
function<void ()> sgb_reset;
function<void (unsigned)> sgb_row;
function<uint8 (uint16)> sgb_read;
function<void (uint16, uint8)> sgb_write;
function<unsigned (uint32_t*, unsigned)> sgb_run;
function<void ()> sgb_save;
};
extern SuperGameBoy supergameboy;

View File

@ -32,7 +32,7 @@ configuration data.
<h3>Supported Filetypes</h3><br>
<b>SFC, SMC:</b> SNES cartridge &mdash; ROM image.<br>
<b>SFC:</b> SNES cartridge &mdash; ROM image.<br>
<b>BS:</b> Satellaview BS-X flash cartridge &mdash; EEPROM image.<br>
<b>ST:</b> Sufami Turbo cartridge &mdash; ROM image.<br>
<b>SRM, PSR:</b> non-volatile memory, often used to save game data &mdash; (P)SRAM image.<br>

View File

@ -31,6 +31,11 @@ namespace nall {
inline string basename(char const *name) {
string result = name;
for(signed i = strlen(result); i >= 0; i--) {
if(result[i] == '/' || result[i] == '\\') {
//file has no extension
break;
}
if(result[i] == '.') {
result[i] = 0;
break;

View File

@ -23,7 +23,15 @@ void bPPU::enter() {
scanline();
add_clocks(10);
//H = 10 (OAM address reset)
//H = 10 (cache mode7 registers + OAM address reset)
cache.m7_hofs = regs.m7_hofs;
cache.m7_vofs = regs.m7_vofs;
cache.m7a = regs.m7a;
cache.m7b = regs.m7b;
cache.m7c = regs.m7c;
cache.m7d = regs.m7d;
cache.m7x = regs.m7x;
cache.m7y = regs.m7y;
if(vcounter() == (!overscan() ? 225 : 240)) {
if(regs.display_disabled == false) {
regs.oam_addr = regs.oam_baseaddr << 1;

View File

@ -24,6 +24,12 @@ public:
uint8 oam_basesize;
uint8 oam_nameselect;
uint16 oam_tdaddr;
//$210d-$210e
uint16 m7_hofs, m7_vofs;
//$211b-$2120
uint16 m7a, m7b, m7c, m7d, m7x, m7y;
} cache;
alwaysinline bool interlace() const { return display.interlace; }

View File

@ -19,15 +19,15 @@ void bPPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) {
int32 px, py;
int32 tx, ty, tile, palette;
int32 a = sclip<16>(regs.m7a);
int32 b = sclip<16>(regs.m7b);
int32 c = sclip<16>(regs.m7c);
int32 d = sclip<16>(regs.m7d);
int32 a = sclip<16>(cache.m7a);
int32 b = sclip<16>(cache.m7b);
int32 c = sclip<16>(cache.m7c);
int32 d = sclip<16>(cache.m7d);
int32 cx = sclip<13>(regs.m7x);
int32 cy = sclip<13>(regs.m7y);
int32 hofs = sclip<13>(regs.m7_hofs);
int32 vofs = sclip<13>(regs.m7_vofs);
int32 cx = sclip<13>(cache.m7x);
int32 cy = sclip<13>(cache.m7y);
int32 hofs = sclip<13>(cache.m7_hofs);
int32 vofs = sclip<13>(cache.m7_vofs);
int _pri, _x;
bool _bg_enabled = regs.bg_enabled[bg];

View File

@ -2,11 +2,116 @@
Audio audio;
void Audio::sample(uint16 l_sample, uint16 r_sample) {
system.interface->audio_sample(l_sample, r_sample);
void Audio::coprocessor_enable(bool state) {
coprocessor = state;
dsp_rdoffset = cop_rdoffset = 0;
dsp_wroffset = cop_wroffset = 0;
dsp_length = cop_length = 0;
for(unsigned i = 0; i < 4; i++) r_left[i] = r_right[i] = 0;
}
void Audio::coprocessor_frequency(double input_frequency) {
double output_frequency;
if(system.region() == System::NTSC) {
output_frequency = config.smp.ntsc_clock_rate / 768.0;
} else /* (system.region() == System::PAL) */ {
output_frequency = config.smp.pal_clock_rate / 768.0;
}
r_step = input_frequency / output_frequency;
r_frac = 0;
}
void Audio::sample(uint16 left, uint16 right) {
if(coprocessor == false) {
system.interface->audio_sample(left, right);
} else {
dsp_buffer[dsp_wroffset] = (left << 0) + (right << 16);
dsp_wroffset = (dsp_wroffset + 1) & 32767;
dsp_length = (dsp_length + 1) & 32767;
flush();
}
}
void Audio::coprocessor_sample(uint16 left, uint16 right) {
r_left [0] = r_left [1];
r_left [1] = r_left [2];
r_left [2] = r_left [3];
r_left [3] = (int16)left;
r_right[0] = r_right[1];
r_right[1] = r_right[2];
r_right[2] = r_right[3];
r_right[3] = (int16)right;
while(r_frac <= 1.0) {
left = sclamp<16>(hermite(r_frac, r_left [0], r_left [1], r_left [2], r_left [3]));
right = sclamp<16>(hermite(r_frac, r_right[0], r_right[1], r_right[2], r_right[3]));
r_frac += r_step;
cop_buffer[cop_wroffset] = (left << 0) + (right << 16);
cop_wroffset = (cop_wroffset + 1) & 32767;
cop_length = (cop_length + 1) & 32767;
flush();
}
r_frac -= 1.0;
}
void Audio::init() {
}
//========
//private:
//========
//4-tap hermite interpolation
double Audio::hermite(double mu1, double a, double b, double c, double d) {
const double tension = 0.0; //-1 = low, 0 = normal, 1 = high
const double bias = 0.0; //-1 = left, 0 = even, 1 = right
double mu2, mu3, m0, m1, a0, a1, a2, a3;
mu2 = mu1 * mu1;
mu3 = mu2 * mu1;
m0 = (b - a) * (1 + bias) * (1 - tension) / 2;
m0 += (c - b) * (1 - bias) * (1 - tension) / 2;
m1 = (c - b) * (1 + bias) * (1 - tension) / 2;
m1 += (d - c) * (1 - bias) * (1 - tension) / 2;
a0 = +2 * mu3 - 3 * mu2 + 1;
a1 = mu3 - 2 * mu2 + mu1;
a2 = mu3 - mu2;
a3 = -2 * mu3 + 3 * mu2;
return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c);
}
void Audio::flush() {
while(dsp_length > 0 && cop_length > 0) {
uint32 dsp_sample = dsp_buffer[dsp_rdoffset];
uint32 cop_sample = cop_buffer[cop_rdoffset];
dsp_rdoffset = (dsp_rdoffset + 1) & 32767;
cop_rdoffset = (cop_rdoffset + 1) & 32767;
dsp_length--;
cop_length--;
int dsp_left = (int16)(dsp_sample >> 0);
int dsp_right = (int16)(dsp_sample >> 16);
int cop_left = (int16)(cop_sample >> 0);
int cop_right = (int16)(cop_sample >> 16);
system.interface->audio_sample(
sclamp<16>((dsp_left + cop_left ) / 2),
sclamp<16>((dsp_right + cop_right) / 2)
);
}
}
#endif

View File

@ -1,7 +1,23 @@
class Audio {
public:
void sample(uint16 l_sample, uint16 r_sample);
void coprocessor_enable(bool state);
void coprocessor_frequency(double frequency);
void sample(uint16 left, uint16 right);
void coprocessor_sample(uint16 left, uint16 right);
void init();
private:
bool coprocessor;
uint32 dsp_buffer[32768], cop_buffer[32768];
unsigned dsp_rdoffset, cop_rdoffset;
unsigned dsp_wroffset, cop_wroffset;
unsigned dsp_length, cop_length;
double hermite(double mu, double a, double b, double c, double d);
double r_step, r_frac;
int r_left[4], r_right[4];
void flush();
};
extern Audio audio;

View File

@ -16,7 +16,7 @@ System system;
#include "input/input.cpp"
void System::coprocessor_enter() {
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.enter();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) supergameboy.enter();
if(cartridge.has_superfx()) superfx.enter();
if(cartridge.has_sa1()) sa1.enter();
@ -60,7 +60,7 @@ void System::init(Interface *interface_) {
interface = interface_;
assert(interface != 0);
sgb.init();
supergameboy.init();
sa1.init();
superfx.init();
bsxbase.init();
@ -95,6 +95,8 @@ void System::power() {
snes_region = (cartridge.region() == Cartridge::NTSC ? NTSC : PAL);
}
audio.coprocessor_enable(false);
scheduler.init();
bus.power();
@ -108,7 +110,7 @@ void System::power() {
if(expansion() == ExpansionBSX) bsxbase.enable();
if(memory::bsxflash.data()) bsxflash.enable();
if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.enable();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.enable();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) supergameboy.enable();
if(cartridge.has_superfx()) superfx.enable();
if(cartridge.has_sa1()) sa1.enable();
@ -128,7 +130,7 @@ void System::power() {
if(expansion() == ExpansionBSX) bsxbase.power();
if(memory::bsxflash.data()) bsxflash.power();
if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.power();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.power();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) supergameboy.power();
if(cartridge.has_superfx()) superfx.power();
if(cartridge.has_sa1()) sa1.power();
@ -170,7 +172,7 @@ void System::reset() {
if(expansion() == ExpansionBSX) bsxbase.reset();
if(memory::bsxflash.data()) bsxflash.reset();
if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.reset();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.reset();
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) supergameboy.reset();
if(cartridge.has_superfx()) superfx.reset();
if(cartridge.has_sa1()) sa1.reset();
@ -193,6 +195,10 @@ void System::reset() {
video.update();
}
void System::unload() {
if(cartridge.mode() == Cartridge::ModeSuperGameBoy) supergameboy.unload();
}
void System::scanline() {
video.scanline();
if(cpu.vcounter() == 241) scheduler.exit();

View File

@ -24,6 +24,7 @@ public:
virtual void term();
virtual void power();
virtual void reset();
virtual void unload();
virtual void frame();
virtual void scanline();

View File

@ -69,6 +69,7 @@ int Application::main(int &argc, char **argv) {
config.load(configFilename);
init();
SNES::system.init(&interface);
mainWindow->system_loadSpecial_superGameBoy->setVisible(SNES::supergameboy.opened());
if(argc == 2) {
//if valid file was specified on the command-line, attempt to load it now
@ -81,20 +82,9 @@ int Application::main(int &argc, char **argv) {
app->exec();
//QbWindow::hide() saves window geometry for next run
loaderWindow->window->hide();
htmlViewerWindow->window->hide();
aboutWindow->window->hide();
diskBrowser->window->hide();
folderCreator->window->hide();
settingsWindow->window->hide();
inputCaptureWindow->window->hide();
inputMouseCaptureWindow->window->hide();
inputCalibrationWindow->window->hide();
toolsWindow->window->hide();
debugger->window->hide();
breakpointEditor->window->hide();
memoryEditor->window->hide();
vramViewer->window->hide();
for(unsigned i = 0; i < windowList.size(); i++) {
windowList[i]->hide();
}
utility.unloadCartridge();
config.save(configFilename);

View File

@ -29,6 +29,8 @@ public:
string configFilename;
string styleSheetFilename;
array<QbWindow*> windowList;
int main(int &argc, char **argv);
void locateFile(string &filename, bool createDataDirectory = false);
void initPaths(const char *basename);

View File

@ -42,7 +42,14 @@ void QbWindow::closeEvent(QCloseEvent *event) {
QWidget::hide();
}
void QbWindow::keyReleaseEvent(QKeyEvent *event) {
if(event->key() == Qt::Key_Escape) close();
QWidget::keyReleaseEvent(event);
}
QbWindow::QbWindow(string &geometryString_) : geometryString(geometryString_) {
//keep track of all created windows (for geometry save on exit, always-on-top control, etc)
application.windowList.add(this);
}
//

View File

@ -4,6 +4,7 @@ public:
void show();
void hide();
void closeEvent(QCloseEvent*);
void keyReleaseEvent(QKeyEvent*);
QbWindow(string&);
private:

View File

@ -1,13 +1,12 @@
AboutWindow::AboutWindow() {
window = new QbWindow(config.geometry.aboutWindow);
window->setObjectName("about-window");
window->setWindowTitle("About bsnes ...");
AboutWindow::AboutWindow() : QbWindow(config.geometry.aboutWindow) {
setObjectName("about-window");
setWindowTitle("About bsnes ...");
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
logo = new Logo;
logo->setFixedSize(600, 106);

View File

@ -1,15 +1,12 @@
class AboutWindow : public QObject {
class AboutWindow : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
struct Logo : public QWidget {
void paintEvent(QPaintEvent*);
} *logo;
QLabel *info;
struct Logo : public QWidget {
void paintEvent(QPaintEvent*);
} *logo;
QLabel *info;
AboutWindow();
public slots:
} *aboutWindow;

View File

@ -2,16 +2,15 @@
//FolderCreator
//=============
FolderCreator::FolderCreator() {
window = new QbWindow(config.geometry.folderCreator);
window->setObjectName("folder-creator");
window->setWindowTitle("Create New Folder");
FolderCreator::FolderCreator() : QbWindow(config.geometry.folderCreator) {
setObjectName("folder-creator");
setWindowTitle("Create New Folder");
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
layout->setAlignment(Qt::AlignTop);
window->setLayout(layout);
setLayout(layout);
label = new QLabel("Folder name:");
layout->addWidget(label);
@ -31,12 +30,12 @@ FolderCreator::FolderCreator() {
connect(name, SIGNAL(returnPressed()), this, SLOT(createFolder()));
connect(ok, SIGNAL(released()), this, SLOT(createFolder()));
connect(cancel, SIGNAL(released()), window, SLOT(hide()));
connect(cancel, SIGNAL(released()), this, SLOT(close()));
}
void FolderCreator::show() {
name->setText("");
window->show();
QbWindow::show();
name->setFocus();
}
@ -45,12 +44,12 @@ void FolderCreator::createFolder() {
QMessageBox::warning(0, "Create New Folder", "<b>Note:</b> you must enter a folder name.");
} else {
string folderName = string()
<< diskBrowser->path->currentText().toUtf8().constData()
<< diskBrowser->model->rootPath().toUtf8().constData()
<< "/"
<< name->text().toUtf8().constData();
if(mkdir(folderName) == 0) {
window->hide();
hide();
} else {
QMessageBox::warning(0, "Create new Folder", "<b>Error:</b> failed to create folder. Please ensure only valid characters were used in the folder name.");
}
@ -78,17 +77,6 @@ void DiskBrowserView::keyPressEvent(QKeyEvent *event) {
QTreeView::keyPressEvent(event);
}
void DiskBrowserView::keyReleaseEvent(QKeyEvent *event) {
//act like a modal dialog; close window on escape keypress
if(event->key() == Qt::Key_Escape) {
emit escape();
return;
}
//fallback: unrecognized keypresses get handled by the widget itself
QTreeView::keyReleaseEvent(event);
}
void DiskBrowserView::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
QAbstractItemView::currentChanged(current, previous);
emit changed(current);
@ -113,79 +101,79 @@ void DiskBrowserImage::paintEvent(QPaintEvent*) {
void DiskBrowser::chooseFolder(PathSettingWidget *widget, const char *title) {
browseMode = Folder;
activePath = widget;
window->hide();
hide();
group->hide();
ok->setText("Choose");
window->setWindowTitle(utf8() << title);
setWindowTitle(utf8() << title);
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters("Folders ()");
window->show();
show();
}
void DiskBrowser::loadCartridge() {
browseMode = Cartridge;
window->hide();
group->show();
hide();
group->setVisible(config.diskBrowser.showPanel);
ok->setText("Load");
window->setWindowTitle("Load Cartridge");
setWindowTitle("Load Cartridge");
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters(utf8() << "SNES cartridges (*.sfc *.smc" << reader.filterList << ");;All files (*)");
window->show();
setNameFilters(utf8() << "SNES cartridges (*.sfc" << reader.filterList << ");;All files (*)");
show();
}
void DiskBrowser::loadBaseCartridge() {
browseMode = BaseCartridge;
window->hide();
group->show();
hide();
group->setVisible(config.diskBrowser.showPanel);
ok->setText("Load");
window->setWindowTitle("Load Base Cartridge");
setWindowTitle("Load Base Cartridge");
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters(utf8() << "SNES cartridges (*.sfc *.smc" << reader.filterList << ");;All files (*)");
window->show();
setNameFilters(utf8() << "SNES cartridges (*.sfc" << reader.filterList << ");;All files (*)");
show();
}
void DiskBrowser::loadBsxCartridge() {
browseMode = BsxCartridge;
window->hide();
group->show();
hide();
group->setVisible(config.diskBrowser.showPanel);
ok->setText("Load");
window->setWindowTitle("Load BS-X Cartridge");
setWindowTitle("Load BS-X Cartridge");
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters(utf8() << "BS-X cartridges (*.bs" << reader.filterList << ");;All files (*)");
window->show();
show();
}
void DiskBrowser::loadSufamiTurboCartridge1() {
browseMode = SufamiTurboCartridge1;
window->hide();
group->show();
hide();
group->setVisible(config.diskBrowser.showPanel);
ok->setText("Load");
window->setWindowTitle("Load Slot-A Sufami Turbo Cartridge");
setWindowTitle("Load Slot-A Sufami Turbo Cartridge");
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters(utf8() << "Sufami Turbo cartridges (*.st" << reader.filterList << ");;All files (*)");
window->show();
show();
}
void DiskBrowser::loadSufamiTurboCartridge2() {
browseMode = SufamiTurboCartridge2;
window->hide();
group->show();
hide();
group->setVisible(config.diskBrowser.showPanel);
ok->setText("Load");
window->setWindowTitle("Load Slot-B Sufami Turbo Cartridge");
setWindowTitle("Load Slot-B Sufami Turbo Cartridge");
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters(utf8() << "Sufami Turbo Cartridges (*.st" << reader.filterList << ");;All files (*)");
window->show();
show();
}
void DiskBrowser::loadSuperGameBoyCartridge() {
browseMode = SuperGameBoyCartridge;
window->hide();
group->show();
hide();
group->setVisible(config.diskBrowser.showPanel);
ok->setText("Load");
window->setWindowTitle("Load Super Game Boy Cartridge");
setWindowTitle("Load Super Game Boy Cartridge");
setPath(utf8() << (config.path.rom != "" ? config.path.rom : config.path.current));
setNameFilters(utf8() << "Game Boy cartridges (*.gb *.gbc" << reader.filterList << ");;All files (*)");
window->show();
show();
}
string DiskBrowser::queryImageInformation() {
@ -247,7 +235,7 @@ void DiskBrowser::loadSelected() {
if(browseMode == Folder || loadable == true) {
QModelIndex item = view->currentIndex();
config.path.current = dir(model->filePath(item).toUtf8().constData());
window->hide();
hide();
switch(browseMode) { default:
case Folder: activePath->selectPath(filename); break;
@ -271,7 +259,7 @@ void DiskBrowser::setPath(const QString &reqPath) {
disconnect(path, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePath()));
QString effectivePath = reqPath;
if(effectivePath == "<root>") {
if(effectivePath == "<root>" || QDir(reqPath).exists() == false) {
effectivePath = "";
newFolder->setEnabled(false);
} else {
@ -314,7 +302,7 @@ void DiskBrowser::setNameFilters(const QString &filters) {
}
void DiskBrowser::cdUp() {
folderCreator->window->hide();
folderCreator->hide();
//if we aren't already at the root node, select the second node, which is one path higher than the current
if(path->count() > 1) path->setCurrentIndex(1);
}
@ -350,7 +338,7 @@ bool DiskBrowser::currentFilename(string &filename) {
if(browseMode != Folder) {
if(model->isDir(item) == true) {
QDir directory(utf8() << filename);
directory.setNameFilters(QStringList() << "*.sfc" << "*.smc");
directory.setNameFilters(QStringList() << "*.sfc");
QStringList list = directory.entryList(QDir::Files | QDir::NoDotAndDotDot);
if(list.count() == 1) {
filename << "/" << list[0].toUtf8().constData();
@ -364,15 +352,20 @@ bool DiskBrowser::currentFilename(string &filename) {
return loadable;
}
DiskBrowser::DiskBrowser() {
window = new QbWindow(config.geometry.diskBrowser);
window->setObjectName("disk-browser");
window->resize(720, 480);
void DiskBrowser::toggleShowPanel() {
showPanel->setChecked(!showPanel->isChecked());
config.diskBrowser.showPanel = showPanel->isChecked();
group->setVisible(config.diskBrowser.showPanel);
}
DiskBrowser::DiskBrowser() : QbWindow(config.geometry.diskBrowser) {
setObjectName("disk-browser");
resize(720, 480);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
topLayout = new QHBoxLayout;
layout->addLayout(topLayout);
@ -384,6 +377,7 @@ DiskBrowser::DiskBrowser() {
browseLayout->addLayout(pathLayout);
path = new QComboBox;
path->setEditable(true);
path->setMinimumContentsLength(16);
path->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
path->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
@ -434,12 +428,14 @@ DiskBrowser::DiskBrowser() {
controlLayout->addWidget(filter);
options = new QPushButton("Options");
options->setEnabled(false);
controlLayout->addWidget(options);
QMenu *menu = new QMenu;
menu = new QMenu;
options->setMenu(menu);
menu->addAction(showPanel = new QbCheckAction("Show Side Panel", 0));
showPanel->setChecked(config.diskBrowser.showPanel);
ok = new QPushButton("Ok");
ok->setEnabled(false);
controlLayout->addWidget(ok);
@ -468,7 +464,8 @@ DiskBrowser::DiskBrowser() {
connect(view, SIGNAL(cdUp()), this, SLOT(cdUp()));
connect(view, SIGNAL(activated(const QModelIndex&)), this, SLOT(activateItem(const QModelIndex&)));
connect(view, SIGNAL(changed(const QModelIndex&)), this, SLOT(changeItem(const QModelIndex&)));
connect(view, SIGNAL(escape()), window, SLOT(hide()));
connect(ok, SIGNAL(released()), this, SLOT(loadSelected()));
connect(cancel, SIGNAL(released()), window, SLOT(hide()));
connect(cancel, SIGNAL(released()), this, SLOT(close()));
connect(showPanel, SIGNAL(triggered()), this, SLOT(toggleShowPanel()));
}

View File

@ -1,10 +1,9 @@
class PathSettingWidget;
class FolderCreator : public QObject {
class FolderCreator : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
QLabel *label;
QLineEdit *name;
@ -24,12 +23,10 @@ class DiskBrowserView : public QTreeView {
public:
void keyPressEvent(QKeyEvent*);
void keyReleaseEvent(QKeyEvent*);
signals:
void cdUp();
void changed(const QModelIndex&);
void escape();
public slots:
void currentChanged(const QModelIndex&, const QModelIndex&);
@ -41,11 +38,10 @@ public:
void paintEvent(QPaintEvent*);
};
class DiskBrowser : public QObject {
class DiskBrowser : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
QHBoxLayout *topLayout;
QVBoxLayout *browseLayout;
@ -68,6 +64,9 @@ public:
QFileSystemModel *model;
PathSettingWidget *activePath;
QMenu *menu;
QbCheckAction *showPanel;
void chooseFolder(PathSettingWidget*, const char*);
void loadCartridge();
void loadBaseCartridge();
@ -90,6 +89,8 @@ public slots:
void changeItem(const QModelIndex&);
void loadSelected();
void toggleShowPanel();
private:
enum BrowseMode {
Folder,

View File

@ -1,12 +1,11 @@
HtmlViewerWindow::HtmlViewerWindow() {
window = new QbWindow(config.geometry.htmlViewerWindow);
window->setObjectName("html-window");
window->resize(560, 480);
HtmlViewerWindow::HtmlViewerWindow() : QbWindow(config.geometry.htmlViewerWindow) {
setObjectName("html-window");
resize(560, 480);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(0);
window->setLayout(layout);
setLayout(layout);
document = new QTextBrowser;
layout->addWidget(document);
@ -14,6 +13,6 @@ HtmlViewerWindow::HtmlViewerWindow() {
void HtmlViewerWindow::show(const char *title, const char *htmlData) {
document->setHtml(utf8() << htmlData);
window->setWindowTitle(title);
window->show();
setWindowTitle(title);
QbWindow::show();
}

View File

@ -1,10 +1,9 @@
class HtmlViewerWindow : public QObject {
class HtmlViewerWindow : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
QTextBrowser *document;
QTextBrowser *document;
void show(const char *title, const char *htmlData);
HtmlViewerWindow();

View File

@ -1,70 +1,60 @@
LoaderWindow::LoaderWindow() {
window = new QbWindow(config.geometry.loaderWindow);
window->setObjectName("loader-window");
window->setMinimumWidth(520);
LoaderWindow::LoaderWindow() : QbWindow(config.geometry.loaderWindow) {
setObjectName("loader-window");
setMinimumWidth(520);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(0);
window->setLayout(layout);
layout->setSpacing(Style::WidgetSpacing);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
grid = new QGridLayout; {
baseLabel = new QLabel("Base cartridge:");
grid->addWidget(baseLabel, 0, 0);
baseFile = new QLineEdit;
baseFile->setReadOnly(true);
grid->addWidget(baseFile, 0, 1);
baseBrowse = new QPushButton("Browse ...");
grid->addWidget(baseBrowse, 0, 2);
baseClear = new QPushButton("Clear");
grid->addWidget(baseClear, 0, 3);
slot1Label = new QLabel("Slot A cartridge:");
grid->addWidget(slot1Label, 1, 0);
slot1File = new QLineEdit;
slot1File->setReadOnly(true);
grid->addWidget(slot1File, 1, 1);
slot1Browse = new QPushButton("Browse ...");
grid->addWidget(slot1Browse, 1, 2);
slot1Clear = new QPushButton("Clear");
grid->addWidget(slot1Clear, 1, 3);
slot2Label = new QLabel("Slot B cartridge:");
grid->addWidget(slot2Label, 2, 0);
slot2File = new QLineEdit;
slot2File->setReadOnly(true);
grid->addWidget(slot2File, 2, 1);
slot2Browse = new QPushButton("Browse ...");
grid->addWidget(slot2Browse, 2, 2);
slot2Clear = new QPushButton("Clear");
grid->addWidget(slot2Clear, 2, 3);
}
grid->setSpacing(Style::WidgetSpacing);
grid = new QGridLayout;
layout->addLayout(grid);
layout->addSpacing(Style::WidgetSpacing);
controls = new QHBoxLayout; {
load = new QPushButton("Load");
controls->addWidget(load);
baseLabel = new QLabel("Base cartridge:");
grid->addWidget(baseLabel, 0, 0);
cancel = new QPushButton("Cancel");
controls->addWidget(cancel);
}
controls->setSpacing(Style::WidgetSpacing);
layout->addLayout(controls);
baseFile = new QLineEdit;
baseFile->setReadOnly(true);
grid->addWidget(baseFile, 0, 1);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
baseBrowse = new QPushButton("Browse ...");
grid->addWidget(baseBrowse, 0, 2);
baseClear = new QPushButton("Clear");
grid->addWidget(baseClear, 0, 3);
slot1Label = new QLabel("Slot A cartridge:");
grid->addWidget(slot1Label, 1, 0);
slot1File = new QLineEdit;
slot1File->setReadOnly(true);
grid->addWidget(slot1File, 1, 1);
slot1Browse = new QPushButton("Browse ...");
grid->addWidget(slot1Browse, 1, 2);
slot1Clear = new QPushButton("Clear");
grid->addWidget(slot1Clear, 1, 3);
slot2Label = new QLabel("Slot B cartridge:");
grid->addWidget(slot2Label, 2, 0);
slot2File = new QLineEdit;
slot2File->setReadOnly(true);
grid->addWidget(slot2File, 2, 1);
slot2Browse = new QPushButton("Browse ...");
grid->addWidget(slot2Browse, 2, 2);
slot2Clear = new QPushButton("Clear");
grid->addWidget(slot2Clear, 2, 3);
load = new QPushButton("Load");
grid->addWidget(load, 3, 2);
cancel = new QPushButton("Cancel");
grid->addWidget(cancel, 3, 3);
connect(baseBrowse, SIGNAL(released()), this, SLOT(selectBaseCartridge()));
connect(baseClear, SIGNAL(released()), this, SLOT(clearBaseCartridge()));
@ -73,7 +63,7 @@ LoaderWindow::LoaderWindow() {
connect(slot2Browse, SIGNAL(released()), this, SLOT(selectSlot2Cartridge()));
connect(slot2Clear, SIGNAL(released()), this, SLOT(clearSlot2Cartridge()));
connect(load, SIGNAL(released()), this, SLOT(onLoad()));
connect(cancel, SIGNAL(released()), this, SLOT(onCancel()));
connect(cancel, SIGNAL(released()), this, SLOT(close()));
}
void LoaderWindow::syncUi() {
@ -82,7 +72,7 @@ void LoaderWindow::syncUi() {
}
void LoaderWindow::loadBsxSlottedCartridge(const char *filebase, const char *fileSlot1) {
window->hide();
hide();
baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show();
slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show();
slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide();
@ -98,7 +88,7 @@ void LoaderWindow::loadBsxSlottedCartridge(const char *filebase, const char *fil
}
void LoaderWindow::loadBsxCartridge(const char *fileBase, const char *fileSlot1) {
window->hide();
hide();
baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show();
slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show();
slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide();
@ -114,7 +104,7 @@ void LoaderWindow::loadBsxCartridge(const char *fileBase, const char *fileSlot1)
}
void LoaderWindow::loadSufamiTurboCartridge(const char *fileBase, const char *fileSlot1, const char *fileSlot2) {
window->hide();
hide();
baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show();
slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show();
slot2Label->show(), slot2File->show(), slot2Browse->show(), slot2Clear->show();
@ -132,7 +122,7 @@ void LoaderWindow::loadSufamiTurboCartridge(const char *fileBase, const char *fi
}
void LoaderWindow::loadSuperGameBoyCartridge(const char *fileBase, const char *fileSlot1) {
window->hide();
hide();
baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show();
slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show();
slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide();
@ -148,9 +138,9 @@ void LoaderWindow::loadSuperGameBoyCartridge(const char *fileBase, const char *f
}
void LoaderWindow::showWindow(const char *title) {
window->setWindowTitle(title);
window->show();
window->shrink();
setWindowTitle(title);
show();
shrink();
load->setFocus();
}
@ -208,7 +198,7 @@ void LoaderWindow::clearSlot2Cartridge() {
}
void LoaderWindow::onLoad() {
window->hide();
hide();
string base = baseFile->text().toUtf8().data();
string slot1 = slot1File->text().toUtf8().data();
string slot2 = slot2File->text().toUtf8().data();
@ -234,7 +224,3 @@ void LoaderWindow::onLoad() {
} break;
}
}
void LoaderWindow::onCancel() {
window->hide();
}

View File

@ -1,26 +1,23 @@
class LoaderWindow : public QObject {
class LoaderWindow : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
QGridLayout *grid;
QLabel *baseLabel;
QLineEdit *baseFile;
QPushButton *baseBrowse;
QPushButton *baseClear;
QLabel *slot1Label;
QLineEdit *slot1File;
QPushButton *slot1Browse;
QPushButton *slot1Clear;
QLabel *slot2Label;
QLineEdit *slot2File;
QPushButton *slot2Browse;
QPushButton *slot2Clear;
QHBoxLayout *controls;
QPushButton *load;
QPushButton *cancel;
QWidget *spacer;
QGridLayout *grid;
QLabel *baseLabel;
QLineEdit *baseFile;
QPushButton *baseBrowse;
QPushButton *baseClear;
QLabel *slot1Label;
QLineEdit *slot1File;
QPushButton *slot1Browse;
QPushButton *slot1Clear;
QLabel *slot2Label;
QLineEdit *slot2File;
QPushButton *slot2Browse;
QPushButton *slot2Clear;
QPushButton *load;
QPushButton *cancel;
void syncUi();
void loadBsxSlottedCartridge(const char*, const char*);
@ -40,9 +37,7 @@ public slots:
void clearSlot1Cartridge();
void selectSlot2Cartridge();
void clearSlot2Cartridge();
void onLoad();
void onCancel();
private:
SNES::Cartridge::Mode mode;

View File

@ -1,7 +1,6 @@
MainWindow::MainWindow() {
window = new Window(config.geometry.mainWindow);
window->setObjectName("main-window");
window->setWindowTitle(utf8() << bsnesTitle << " v" << bsnesVersion);
MainWindow::MainWindow() : QbWindow(config.geometry.mainWindow) {
setObjectName("main-window");
setWindowTitle(utf8() << bsnesTitle << " v" << bsnesVersion);
//menu bar
#if defined(PLATFORM_OSX)
@ -23,7 +22,6 @@ MainWindow::MainWindow() {
system_loadSpecial_sufamiTurbo->setIcon(QIcon(":/16x16/document-open.png"));
system_loadSpecial_superGameBoy = system_loadSpecial->addAction("Load Super Game Boy Cartridge ...");
system_loadSpecial_superGameBoy->setIcon(QIcon(":/16x16/document-open.png"));
system_loadSpecial_superGameBoy->setVisible(false);
system->addSeparator();
system->addAction(system_power = new QbCheckAction("Power", 0));
system_reset = system->addAction("Reset");
@ -111,9 +109,9 @@ MainWindow::MainWindow() {
tools_cheatFinder->setIcon(QIcon(":/16x16/system-search.png"));
tools_stateManager = tools->addAction("State Manager ...");
tools_stateManager->setIcon(QIcon(":/16x16/system-file-manager.png"));
#if defined(DEBUGGER)
tools->addSeparator();
#endif
tools_captureScreenshot = tools->addAction("Capture Screenshot");
tools_captureScreenshot->setIcon(QIcon(":/16x16/image-x-generic.png"));
tools_debugger = tools->addAction("Debugger ...");
tools_debugger->setIcon(QIcon(":/16x16/utilities-terminal.png"));
#if !defined(DEBUGGER)
@ -171,7 +169,7 @@ MainWindow::MainWindow() {
#endif
layout->addWidget(canvasContainer);
layout->addWidget(statusBar);
window->setLayout(layout);
setLayout(layout);
//slots
connect(system_load, SIGNAL(triggered()), this, SLOT(loadCartridge()));
@ -221,6 +219,7 @@ MainWindow::MainWindow() {
connect(tools_cheatEditor, SIGNAL(triggered()), this, SLOT(showCheatEditor()));
connect(tools_cheatFinder, SIGNAL(triggered()), this, SLOT(showCheatFinder()));
connect(tools_stateManager, SIGNAL(triggered()), this, SLOT(showStateManager()));
connect(tools_captureScreenshot, SIGNAL(triggered()), this, SLOT(saveScreenshot()));
connect(tools_debugger, SIGNAL(triggered()), this, SLOT(showDebugger()));
connect(help_documentation, SIGNAL(triggered()), this, SLOT(showDocumentation()));
connect(help_license, SIGNAL(triggered()), this, SLOT(showLicense()));
@ -281,7 +280,7 @@ void MainWindow::syncUi() {
}
bool MainWindow::isActive() {
return window->isActiveWindow() && !window->isMinimized();
return isActiveWindow() && !isMinimized();
}
void MainWindow::loadCartridge() {
@ -330,7 +329,7 @@ void MainWindow::setPort2Justifier() { SNES::config.controller_port2 = SNES::In
void MainWindow::setPort2Justifiers() { SNES::config.controller_port2 = SNES::Input::DeviceJustifiers; utility.updateControllers(); syncUi(); }
void MainWindow::quit() {
window->hide();
hide();
application.terminate = true;
}
@ -407,12 +406,18 @@ void MainWindow::syncAudio() {
utility.updateAvSync();
}
void MainWindow::showConfigWindow() { settingsWindow->window->show(); }
void MainWindow::showConfigWindow() { settingsWindow->show(); }
void MainWindow::showCheatEditor() { toolsWindow->showCheatEditor(); }
void MainWindow::showCheatFinder() { toolsWindow->showCheatFinder(); }
void MainWindow::showStateManager() { toolsWindow->showStateManager(); }
void MainWindow::showDebugger() { debugger->window->show(); }
void MainWindow::saveScreenshot() {
//tell SNES::Interface to save a screenshot at the next video_refresh() event
interface.saveScreenshot = true;
}
void MainWindow::showDebugger() { debugger->show(); }
void MainWindow::showDocumentation() {
QFile file(":/documentation.html");
@ -430,14 +435,12 @@ void MainWindow::showLicense() {
}
}
void MainWindow::showAbout() {
aboutWindow->window->show();
aboutWindow->show();
}
void MainWindow::Window::closeEvent(QCloseEvent*) {
mainWindow->quit();
}
MainWindow::Window::Window(string &geometry) : QbWindow(geometry) {
void MainWindow::closeEvent(QCloseEvent *event) {
QbWindow::closeEvent(event);
quit();
}
//============

View File

@ -13,14 +13,10 @@ public:
void paintEvent(QPaintEvent*);
};
class MainWindow : public QObject {
class MainWindow : public QbWindow {
Q_OBJECT
public:
struct Window : public QbWindow {
void closeEvent(QCloseEvent*);
Window(string&);
} *window;
QMenuBar *menuBar;
QStatusBar *statusBar;
QVBoxLayout *layout;
@ -77,6 +73,7 @@ public:
QAction *tools_cheatEditor;
QAction *tools_cheatFinder;
QAction *tools_stateManager;
QAction *tools_captureScreenshot;
QAction *tools_debugger;
QMenu *help;
QAction *help_documentation;
@ -90,6 +87,7 @@ public:
void syncUi();
bool isActive();
void closeEvent(QCloseEvent*);
MainWindow();
public slots:
@ -136,6 +134,7 @@ public slots:
void showCheatEditor();
void showCheatFinder();
void showStateManager();
void saveScreenshot();
void showDebugger();
void showDocumentation();
void showLicense();

View File

@ -57,6 +57,8 @@ Configuration::Configuration() {
attach(system.autoSaveMemory = false, "system.autoSaveMemory", "Automatically save cartridge back-up RAM once every minute");
attach(system.autoHideMenus = false, "system.autoHideMenus", "Automatically hide the menu and status bars when entering fullscreen mode");
attach(diskBrowser.showPanel = true, "diskBrowser.showPanel");
attach(file.autodetect_type = false, "file.autodetectType");
attach(file.bypass_patch_crc32 = false, "file.bypassPatchCrc32");
@ -166,8 +168,8 @@ Configuration::Configuration() {
attach(input.uiGeneral.resetSystem = "none", "input.uiGeneral.resetSystem");
attach(input.uiGeneral.powerCycleSystem = "none", "input.uiGeneral.powerCycleSystem");
attach(input.uiGeneral.saveScreenshot = "none", "input.uiGeneral.saveScreenshot");
attach(input.uiGeneral.showStateManager = "keyboard00.f3", "input.uiGeneral.showStateManager");
attach(input.uiGeneral.captureScreenshot = "none", "input.uiGeneral.captureScreenshot");
attach(input.uiGeneral.showStateManager = "keyboard00.f3", "input.uiGeneral.showStateManager");
attach(input.uiGeneral.quickLoad1 = "keyboard00.f4", "input.uiGeneral.quickLoad1");
attach(input.uiGeneral.quickLoad2 = "none", "input.uiGeneral.quickLoad2");

View File

@ -13,6 +13,10 @@ public:
bool bypass_patch_crc32;
} file;
struct DiskBrowser {
bool showPanel;
} diskBrowser;
struct Path {
string base; //binary path
string user; //user profile path (bsnes.cfg, ...)
@ -69,7 +73,7 @@ public:
string pauseEmulation;
string resetSystem;
string powerCycleSystem;
string saveScreenshot;
string captureScreenshot;
string showStateManager;
string quickLoad1;
string quickLoad2;

View File

@ -58,16 +58,15 @@ void BreakpointItem::toggle() {
}
}
BreakpointEditor::BreakpointEditor() {
window = new QbWindow(config.geometry.breakpointEditor);
window->setObjectName("breakpoint-editor");
window->setWindowTitle("Breakpoint Editor");
BreakpointEditor::BreakpointEditor() : QbWindow(config.geometry.breakpointEditor) {
setObjectName("breakpoint-editor");
setWindowTitle("Breakpoint Editor");
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
for(unsigned n = 0; n < SNES::Debugger::Breakpoints; n++) {
breakpoint[n] = new BreakpointItem(n);

View File

@ -17,11 +17,10 @@ private:
const unsigned id;
};
class BreakpointEditor : public QObject {
class BreakpointEditor : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
BreakpointItem *breakpoint[SNES::Debugger::Breakpoints];

View File

@ -3,15 +3,14 @@
#include "memory.cpp"
#include "vramviewer.cpp"
Debugger::Debugger() {
window = new QbWindow(config.geometry.debugger);
window->setObjectName("debugger");
window->setWindowTitle("Debugger");
Debugger::Debugger() : QbWindow(config.geometry.debugger) {
setObjectName("debugger");
setWindowTitle("Debugger");
layout = new QHBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
menu = new QMenuBar;
layout->setMenuBar(menu);
@ -87,7 +86,7 @@ Debugger::Debugger() {
frameCounter = 0;
synchronize();
window->resize(855, 425);
resize(855, 425);
}
void Debugger::synchronize() {
@ -109,15 +108,15 @@ void Debugger::clear() {
}
void Debugger::showBreakpointEditor() {
breakpointEditor->window->show();
breakpointEditor->show();
}
void Debugger::showMemoryEditor() {
memoryEditor->window->show();
memoryEditor->show();
}
void Debugger::showVramViewer() {
vramViewer->window->show();
vramViewer->show();
vramViewer->refresh();
}

View File

@ -3,29 +3,29 @@
#include "memory.moc"
#include "vramviewer.moc"
class Debugger : public QObject {
class Debugger : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QMenuBar *menu;
QMenu *tools;
QAction *tools_breakpoint;
QAction *tools_memory;
QAction *tools_vramViewer;
QMenu *miscOptions;
QAction *miscOptions_clear;
QMenu *tools;
QAction *tools_breakpoint;
QAction *tools_memory;
QAction *tools_vramViewer;
QMenu *miscOptions;
QAction *miscOptions_clear;
QHBoxLayout *layout;
QTextEdit *console;
QVBoxLayout *controlLayout;
QHBoxLayout *commandLayout;
QPushButton *runBreak;
QPushButton *stepInstruction;
QCheckBox *stepCPU;
QCheckBox *stepSMP;
QCheckBox *traceCPU;
QCheckBox *traceSMP;
QWidget *spacer;
QTextEdit *console;
QVBoxLayout *controlLayout;
QHBoxLayout *commandLayout;
QPushButton *runBreak;
QPushButton *stepInstruction;
QCheckBox *stepCPU;
QCheckBox *stepSMP;
QCheckBox *traceCPU;
QCheckBox *traceSMP;
QWidget *spacer;
void echo(const char *message);
void tracerUpdate();

View File

@ -1,12 +1,11 @@
MemoryEditor::MemoryEditor() {
window = new QbWindow(config.geometry.memoryEditor);
window->setObjectName("memory-editor");
window->setWindowTitle("Memory Editor");
MemoryEditor::MemoryEditor() : QbWindow(config.geometry.memoryEditor) {
setObjectName("memory-editor");
setWindowTitle("Memory Editor");
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
controlLayout = new QHBoxLayout;
controlLayout->setSpacing(Style::WidgetSpacing);

View File

@ -1,16 +1,15 @@
class MemoryEditor : public QObject {
class MemoryEditor : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
QHBoxLayout *controlLayout;
QWidget *spacer;
QLineEdit *addr;
QComboBox *source;
QCheckBox *autoUpdateBox;
QPushButton *refreshButton;
HexEditor *editor;
QHBoxLayout *controlLayout;
QWidget *spacer;
QLineEdit *addr;
QComboBox *source;
QCheckBox *autoUpdateBox;
QPushButton *refreshButton;
HexEditor *editor;
void autoUpdate();
void synchronize();

View File

@ -1,14 +1,13 @@
VramViewer::VramViewer() {
window = new QbWindow(config.geometry.vramViewer);
window->setObjectName("vram-viewer");
window->setWindowTitle("Video RAM Viewer");
VramViewer::VramViewer() : QbWindow(config.geometry.vramViewer) {
setObjectName("vram-viewer");
setWindowTitle("Video RAM Viewer");
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);
layout->setAlignment(Qt::AlignCenter);
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
controlLayout = new QHBoxLayout;
controlLayout->setSizeConstraint(QLayout::SetMinimumSize);

View File

@ -1,21 +1,20 @@
class VramViewer : public QObject {
class VramViewer : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QVBoxLayout *layout;
QHBoxLayout *controlLayout;
QRadioButton *depth2bpp;
QRadioButton *depth4bpp;
QRadioButton *depth8bpp;
QRadioButton *depthMode7;
QCheckBox *autoUpdateBox;
QPushButton *refreshButton;
struct Canvas : public QWidget {
QImage *image;
void paintEvent(QPaintEvent*);
Canvas();
} *canvas;
QHBoxLayout *controlLayout;
QRadioButton *depth2bpp;
QRadioButton *depth4bpp;
QRadioButton *depth8bpp;
QRadioButton *depthMode7;
QCheckBox *autoUpdateBox;
QPushButton *refreshButton;
struct Canvas : public QWidget {
QImage *image;
void paintEvent(QPaintEvent*);
Canvas();
} *canvas;
void autoUpdate();
VramViewer();

View File

@ -32,7 +32,7 @@ pauseEmulation(InputObject::Button, "Pause emulation", config.input.uiGeneral.pa
resetSystem(InputObject::Button, "Reset system", config.input.uiGeneral.resetSystem),
powerCycleSystem(InputObject::Button, "Power cycle system", config.input.uiGeneral.powerCycleSystem),
saveScreenshot(InputObject::Button, "Save screenshot", config.input.uiGeneral.saveScreenshot),
captureScreenshot(InputObject::Button, "Capture screenshot", config.input.uiGeneral.captureScreenshot),
showStateManager(InputObject::Button, "Show state manager window", config.input.uiGeneral.showStateManager),
quickLoad1(InputObject::Button, "Load from temporary state 1", config.input.uiGeneral.quickLoad1),
quickLoad2(InputObject::Button, "Load from temporary state 2", config.input.uiGeneral.quickLoad2),
@ -53,7 +53,7 @@ exitEmulator(InputObject::Button, "Exit emulator", config.input.uiGeneral.exitEm
attach(resetSystem);
attach(powerCycleSystem);
attach(saveScreenshot);
attach(captureScreenshot);
attach(showStateManager);
attach(quickLoad1);
attach(quickLoad2);

View File

@ -3,7 +3,7 @@ struct InputUiGeneral : public InputGroup {
InputObject pauseEmulation;
InputObject resetSystem;
InputObject powerCycleSystem;
InputObject saveScreenshot;
InputObject captureScreenshot;
InputObject showStateManager;
InputObject quickLoad1;
InputObject quickLoad2;

View File

@ -41,7 +41,7 @@ void Interface::captureScreenshot(uint32_t *data, unsigned pitch, unsigned width
filename << t << ".png";
string path = config.path.data;
if(path == "") path = config.path.current;
if(path == "") path = dir(utility.cartridge.baseName);
image.save(utf8() << path << filename);
utility.showMessage("Screenshot saved.");
}

View File

@ -90,7 +90,7 @@ void Filter::colortable_update() {
}
void Filter::size(unsigned &outwidth, unsigned &outheight, unsigned width, unsigned height) {
if(renderer > 0) {
if(opened() && renderer > 0) {
return dl_size(renderer - 1, outwidth, outheight, width, height);
}
@ -103,7 +103,7 @@ void Filter::render(
const uint16_t *input, unsigned pitch,
const unsigned *line, unsigned width, unsigned height
) {
if(renderer > 0) {
if(opened() && renderer > 0) {
return dl_render(renderer - 1, output, outpitch, input, pitch, line, width, height);
}
@ -130,7 +130,7 @@ void Filter::render(
}
QWidget* Filter::settings() {
if(renderer > 0) {
if(opened() && renderer > 0) {
return dl_settings(renderer - 1);
} else {
return 0;

View File

@ -34,7 +34,7 @@ Reader::Reader() {
filterList = supported();
if(filterList.length() > 0) {
filterList = string()
<< " *.swc *.fig"
<< " *.smc *.swc *.fig"
<< " *.ufo *.gd3 *.gd7 *.dx2 *.mgd *.mgh"
<< " *.048 *.058 *.068 *.078 *.bin"
<< " *.usa *.eur *.jap *.aus *.bsx"

View File

@ -1,9 +1,9 @@
AdvancedSettingsWindow::AdvancedSettingsWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
title = new QLabel("Advanced Configuration Settings");
title->setProperty("class", "title");
@ -42,7 +42,7 @@ AdvancedSettingsWindow::AdvancedSettingsWindow() {
regionLayout = new QHBoxLayout;
regionLayout->setSpacing(Style::WidgetSpacing); {
regionGroup = new QButtonGroup(panel);
regionGroup = new QButtonGroup(this);
regionAuto = new QRadioButton("Auto-detect");
regionAuto->setToolTip("Automatically select hardware region on cartridge load");
@ -67,7 +67,7 @@ AdvancedSettingsWindow::AdvancedSettingsWindow() {
portLayout = new QHBoxLayout;
portLayout->setSpacing(Style::WidgetSpacing); {
portGroup = new QButtonGroup(panel);
portGroup = new QButtonGroup(this);
portSatellaview = new QRadioButton("Satellaview");
portGroup->addButton(portSatellaview);
@ -88,7 +88,7 @@ AdvancedSettingsWindow::AdvancedSettingsWindow() {
focusLayout = new QHBoxLayout;
focusLayout->setSpacing(Style::WidgetSpacing); {
focusButtonGroup = new QButtonGroup(panel);
focusButtonGroup = new QButtonGroup(this);
focusPause = new QRadioButton("Pause emulation");
focusPause->setToolTip("Ideal for prolonged multi-tasking");
@ -107,11 +107,6 @@ AdvancedSettingsWindow::AdvancedSettingsWindow() {
}
layout->addLayout(focusLayout);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
panel->setLayout(layout);
initializeUi();
connect(videoDriver, SIGNAL(currentIndexChanged(int)), this, SLOT(videoDriverChange(int)));

View File

@ -1,40 +1,35 @@
class AdvancedSettingsWindow : public QObject {
class AdvancedSettingsWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QGridLayout *driverLayout;
QLabel *videoLabel;
QLabel *audioLabel;
QLabel *inputLabel;
QComboBox *videoDriver;
QComboBox *audioDriver;
QComboBox *inputDriver;
QLabel *driverInfo;
QLabel *regionTitle;
QHBoxLayout *regionLayout;
QButtonGroup *regionGroup;
QRadioButton *regionAuto;
QRadioButton *regionNTSC;
QRadioButton *regionPAL;
QLabel *portTitle;
QHBoxLayout *portLayout;
QButtonGroup *portGroup;
QRadioButton *portSatellaview;
QRadioButton *portNone;
QWidget *portSpacer;
QLabel *focusTitle;
QHBoxLayout *focusLayout;
QButtonGroup *focusButtonGroup;
QRadioButton *focusPause;
QRadioButton *focusIgnore;
QRadioButton *focusAllow;
QWidget *spacer;
QVBoxLayout *layout;
QLabel *title;
QGridLayout *driverLayout;
QLabel *videoLabel;
QLabel *audioLabel;
QLabel *inputLabel;
QComboBox *videoDriver;
QComboBox *audioDriver;
QComboBox *inputDriver;
QLabel *driverInfo;
QLabel *regionTitle;
QHBoxLayout *regionLayout;
QButtonGroup *regionGroup;
QRadioButton *regionAuto;
QRadioButton *regionNTSC;
QRadioButton *regionPAL;
QLabel *portTitle;
QHBoxLayout *portLayout;
QButtonGroup *portGroup;
QRadioButton *portSatellaview;
QRadioButton *portNone;
QWidget *portSpacer;
QLabel *focusTitle;
QHBoxLayout *focusLayout;
QButtonGroup *focusButtonGroup;
QRadioButton *focusPause;
QRadioButton *focusIgnore;
QRadioButton *focusAllow;
void initializeUi();
AdvancedSettingsWindow();

View File

@ -1,9 +1,9 @@
AudioSettingsWindow::AudioSettingsWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
title = new QLabel("Audio Settings");
title->setProperty("class", "title");
@ -65,11 +65,6 @@ AudioSettingsWindow::AudioSettingsWindow() {
sliders->setSpacing(Style::WidgetSpacing);
layout->addLayout(sliders);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
panel->setLayout(layout);
connect(frequency, SIGNAL(currentIndexChanged(int)), this, SLOT(frequencyChange(int)));
connect(latency, SIGNAL(currentIndexChanged(int)), this, SLOT(latencyChange(int)));
connect(volume, SIGNAL(valueChanged(int)), this, SLOT(volumeAdjust(int)));

View File

@ -1,21 +1,19 @@
class AudioSettingsWindow : public QObject {
class AudioSettingsWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QHBoxLayout *boxes;
QLabel *frequencyLabel;
QComboBox *frequency;
QLabel *latencyLabel;
QComboBox *latency;
QGridLayout *sliders;
QLabel *volumeLabel;
QSlider *volume;
QLabel *frequencySkewLabel;
QSlider *frequencySkew;
QWidget *spacer;
QVBoxLayout *layout;
QLabel *title;
QHBoxLayout *boxes;
QLabel *frequencyLabel;
QComboBox *frequency;
QLabel *latencyLabel;
QComboBox *latency;
QGridLayout *sliders;
QLabel *volumeLabel;
QSlider *volume;
QLabel *frequencySkewLabel;
QSlider *frequencySkew;
void syncUi();
AudioSettingsWindow();

View File

@ -1,9 +1,8 @@
InputSettingsWindow::InputSettingsWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
setLayout(layout);
title = new QLabel("Input Configuration Editor");
title->setProperty("class", "title");
@ -45,7 +44,6 @@ InputSettingsWindow::InputSettingsWindow() {
controls->setSpacing(Style::WidgetSpacing);
layout->addLayout(controls);
panel->setLayout(layout);
connect(port, SIGNAL(currentIndexChanged(int)), this, SLOT(portChanged()));
connect(device, SIGNAL(currentIndexChanged(int)), this, SLOT(reloadList()));
connect(list, SIGNAL(itemActivated(QTreeWidgetItem*, int)), this, SLOT(assignKey()));

View File

@ -1,18 +1,17 @@
class InputSettingsWindow : public QObject {
class InputSettingsWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QHBoxLayout *selection;
QComboBox *port;
QComboBox *device;
QTreeWidget *list;
QHBoxLayout *controls;
QPushButton *assign;
QPushButton *assignAll;
QPushButton *unassign;
QVBoxLayout *layout;
QLabel *title;
QHBoxLayout *selection;
QComboBox *port;
QComboBox *device;
QTreeWidget *list;
QHBoxLayout *controls;
QPushButton *assign;
QPushButton *assignAll;
QPushButton *unassign;
void syncUi();
InputSettingsWindow();

View File

@ -56,12 +56,11 @@ void PathSettingWidget::defaultPath() {
}
PathSettingsWindow::PathSettingsWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
panel->setLayout(layout);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
title = new QLabel("Default Folder Paths");
title->setProperty("class", "title");
@ -80,8 +79,4 @@ PathSettingsWindow::PathSettingsWindow() {
layout->addWidget(patchPath);
layout->addWidget(cheatPath);
layout->addWidget(dataPath);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
}

View File

@ -5,9 +5,9 @@ public:
QVBoxLayout *layout;
QLabel *label;
QHBoxLayout *controlLayout;
QLineEdit *path;
QPushButton *pathSelect;
QPushButton *pathDefault;
QLineEdit *path;
QPushButton *pathSelect;
QPushButton *pathDefault;
string &pathValue;
string pathDefaultLabel;
@ -21,20 +21,18 @@ public slots:
void defaultPath();
};
class PathSettingsWindow : public QObject {
class PathSettingsWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
PathSettingWidget *gamePath;
PathSettingWidget *savePath;
PathSettingWidget *statePath;
PathSettingWidget *patchPath;
PathSettingWidget *cheatPath;
PathSettingWidget *dataPath;
QWidget *spacer;
QVBoxLayout *layout;
QLabel *title;
PathSettingWidget *gamePath;
PathSettingWidget *savePath;
PathSettingWidget *statePath;
PathSettingWidget *patchPath;
PathSettingWidget *cheatPath;
PathSettingWidget *dataPath;
PathSettingsWindow();
} *pathSettingsWindow;

View File

@ -5,16 +5,15 @@
#include "advanced.cpp"
#include "utility/inputcapture.cpp"
SettingsWindow::SettingsWindow() {
window = new QbWindow(config.geometry.settingsWindow);
window->setObjectName("settings-window");
window->setWindowTitle("Configuration Settings");
window->resize(625, 360);
SettingsWindow::SettingsWindow() : QbWindow(config.geometry.settingsWindow) {
setObjectName("settings-window");
setWindowTitle("Configuration Settings");
resize(625, 360);
layout = new QHBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
splitter = new QSplitter;
layout->addWidget(splitter);
@ -56,11 +55,11 @@ SettingsWindow::SettingsWindow() {
inputCaptureWindow = new InputCaptureWindow;
panelLayout = new QStackedLayout(panel);
panelLayout->addWidget(videoSettingsWindow->panel);
panelLayout->addWidget(audioSettingsWindow->panel);
panelLayout->addWidget(inputSettingsWindow->panel);
panelLayout->addWidget(pathSettingsWindow->panel);
panelLayout->addWidget(advancedSettingsWindow->panel);
panelLayout->addWidget(videoSettingsWindow);
panelLayout->addWidget(audioSettingsWindow);
panelLayout->addWidget(inputSettingsWindow);
panelLayout->addWidget(pathSettingsWindow);
panelLayout->addWidget(advancedSettingsWindow);
panel->setLayout(panelLayout);
connect(list, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(itemChanged()));
@ -71,9 +70,9 @@ SettingsWindow::SettingsWindow() {
void SettingsWindow::itemChanged() {
QTreeWidgetItem *item = list->currentItem();
if(item == video) panelLayout->setCurrentWidget(videoSettingsWindow->panel);
if(item == audio) panelLayout->setCurrentWidget(audioSettingsWindow->panel);
if(item == input) panelLayout->setCurrentWidget(inputSettingsWindow->panel);
if(item == paths) panelLayout->setCurrentWidget(pathSettingsWindow->panel);
if(item == advanced) panelLayout->setCurrentWidget(advancedSettingsWindow->panel);
if(item == video) panelLayout->setCurrentWidget(videoSettingsWindow);
if(item == audio) panelLayout->setCurrentWidget(audioSettingsWindow);
if(item == input) panelLayout->setCurrentWidget(inputSettingsWindow);
if(item == paths) panelLayout->setCurrentWidget(pathSettingsWindow);
if(item == advanced) panelLayout->setCurrentWidget(advancedSettingsWindow);
}

View File

@ -5,21 +5,20 @@
#include "advanced.moc"
#include "utility/inputcapture.moc"
class SettingsWindow : public QObject {
class SettingsWindow : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QHBoxLayout *layout;
QSplitter *splitter;
QTreeWidget *list;
QTreeWidgetItem *video;
QTreeWidgetItem *audio;
QTreeWidgetItem *input;
QTreeWidgetItem *paths;
QTreeWidgetItem *advanced;
QWidget *panel;
QStackedLayout *panelLayout;
QTreeWidget *list;
QTreeWidgetItem *video;
QTreeWidgetItem *audio;
QTreeWidgetItem *input;
QTreeWidgetItem *paths;
QTreeWidgetItem *advanced;
QWidget *panel;
QStackedLayout *panelLayout;
SettingsWindow();

View File

@ -1,17 +1,17 @@
InputCaptureWindow::InputCaptureWindow() {
InputCaptureWindow::InputCaptureWindow() : QbWindow(config.geometry.inputCaptureWindow) {
activeObject = 0;
activeGroup = 0;
groupIndex = 0;
inputLock = false;
window = new Window(config.geometry.inputCaptureWindow);
window->setObjectName("input-capture-window");
window->setWindowTitle("Input Capture");
setObjectName("input-capture-window");
setWindowTitle("Input Capture");
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(0);
window->setLayout(layout);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
hlayout = new QHBoxLayout;
hlayout->setSpacing(Style::WidgetSpacing); {
@ -35,10 +35,6 @@ InputCaptureWindow::InputCaptureWindow() {
imageWidget = new ImageWidget;
layout->addWidget(imageWidget, 0, Qt::AlignHCenter);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
connect(mouseAxes, SIGNAL(released()), this, SLOT(assignMouseAxis()));
connect(mouseButtons, SIGNAL(released()), this, SLOT(assignMouseButton()));
@ -47,7 +43,7 @@ InputCaptureWindow::InputCaptureWindow() {
}
void InputCaptureWindow::activate(InputObject *object) {
if(!activeGroup) window->hide();
if(!activeGroup) hide();
utf8 info;
info << "<b>ID:</b> ";
@ -82,14 +78,14 @@ void InputCaptureWindow::activate(InputObject *object) {
}
title->setText(info);
window->show();
window->shrink();
show();
shrink();
}
void InputCaptureWindow::activate(InputGroup *group) {
activeGroup = group;
groupIndex = 0;
window->hide();
hide();
activate((*activeGroup)[groupIndex]);
}
@ -99,11 +95,11 @@ void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false *
//input polling is global, need to block mouse actions that may be UI interactions.
//custom controls on window allow mouse assignment instead.
if(forceAssign == false) {
if(inputMouseCaptureWindow->window->isActiveWindow()) {
if(inputMouseCaptureWindow->isActiveWindow()) {
inputMouseCaptureWindow->inputEvent(code);
return;
}
if(!window->isActiveWindow()) return;
if(!isActiveWindow()) return;
//get as much info as possible about this code
InputCode::type_t type = InputCode::type(code);
@ -207,8 +203,8 @@ void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false *
inputLock = false;
if(!activeGroup) {
window->hide();
inputMouseCaptureWindow->window->hide();
hide();
inputMouseCaptureWindow->hide();
} else {
//try and map the next code in this input group
groupIndex++;
@ -216,13 +212,24 @@ void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false *
activate((*activeGroup)[groupIndex]);
} else {
//all group codes mapped
window->hide();
inputMouseCaptureWindow->window->hide();
hide();
inputMouseCaptureWindow->hide();
activeGroup = 0;
}
}
}
void InputCaptureWindow::closeEvent(QCloseEvent *event) {
QbWindow::closeEvent(event);
//window closed by user, cancel key assignment
activeObject = 0;
activeGroup = 0;
inputMouseCaptureWindow->hide();
inputCalibrationWindow->dismiss();
}
void InputCaptureWindow::assignMouseAxis() {
//refresh input state so that mouse release event (from SIGNAL(released())
//is not sent immediately after window is visible.
@ -235,17 +242,6 @@ void InputCaptureWindow::assignMouseButton() {
inputMouseCaptureWindow->activate(InputMouseCaptureWindow::ButtonMode);
}
void InputCaptureWindow::Window::closeEvent(QCloseEvent*) {
//window closed by user, cancel key assignment
inputCaptureWindow->activeObject = 0;
inputCaptureWindow->activeGroup = 0;
inputMouseCaptureWindow->window->hide();
inputCalibrationWindow->dismiss();
}
InputCaptureWindow::Window::Window(string &geometry) : QbWindow(geometry) {}
void InputCaptureWindow::ImageWidget::paintEvent(QPaintEvent*) {
//currently, there is only an image available for the joypad.
//in the future, this routine should determine which type of
@ -259,15 +255,15 @@ void InputCaptureWindow::ImageWidget::paintEvent(QPaintEvent*) {
//InputMouseCaptureWindow
//=======================
InputMouseCaptureWindow::InputMouseCaptureWindow() {
window = new QbWindow(config.geometry.inputMouseCaptureWindow);
window->setObjectName("input-mouse-capture-window");
window->setWindowTitle("Mouse Input Capture");
InputMouseCaptureWindow::InputMouseCaptureWindow() : QbWindow(config.geometry.inputMouseCaptureWindow) {
setObjectName("input-mouse-capture-window");
setWindowTitle("Mouse Input Capture");
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(0);
window->setLayout(layout);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
info = new QLabel;
layout->addWidget(info);
@ -280,25 +276,22 @@ InputMouseCaptureWindow::InputMouseCaptureWindow() {
layout->addWidget(captureBox);
buttonLayout = new QHBoxLayout;
buttonLayout->setSpacing(Style::WidgetSpacing); {
xAxis = new QPushButton("X-axis");
buttonLayout->addWidget(xAxis);
yAxis = new QPushButton("Y-axis");
buttonLayout->addWidget(yAxis);
}
buttonLayout->setSpacing(Style::WidgetSpacing);
buttonLayout->setAlignment(Qt::AlignRight);
layout->addLayout(buttonLayout);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
xAxis = new QPushButton("X-axis");
buttonLayout->addWidget(xAxis);
yAxis = new QPushButton("Y-axis");
buttonLayout->addWidget(yAxis);
connect(xAxis, SIGNAL(released()), this, SLOT(assignAxisX()));
connect(yAxis, SIGNAL(released()), this, SLOT(assignAxisY()));
}
void InputMouseCaptureWindow::activate(InputMouseCaptureWindow::Mode mode_) {
window->hide();
hide();
activeMode = mode_;
if(activeMode == AxisMode) {
@ -307,8 +300,8 @@ void InputMouseCaptureWindow::activate(InputMouseCaptureWindow::Mode mode_) {
yAxis->show();
info->setText(utf8()
<< "To assign a mouse axis to this ID, please click the desired axis button below,<br>"
<< "using the mouse that you want the axis to be assigned to."
<< "To assign a mouse axis to this ID, please click the desired axis button<br>"
<< "below, using the mouse that you want the axis to be assigned to."
);
activeMouse = -1;
@ -323,7 +316,7 @@ void InputMouseCaptureWindow::activate(InputMouseCaptureWindow::Mode mode_) {
);
}
window->show();
show();
}
//this is only called when isActiveWindow() == true
@ -342,7 +335,7 @@ void InputMouseCaptureWindow::inputEvent(uint16_t code) {
//if this is a mouse button that is being released ...
if(type == InputCode::MouseButton && state == false) {
//ensure button was clicked inside active capture box
QRect windowRect = window->geometry();
QRect windowRect = geometry();
QRect widgetRect = captureBox->geometry();
unsigned wx = windowRect.left() + widgetRect.left();
unsigned wy = windowRect.top() + widgetRect.top();
@ -405,55 +398,54 @@ void InputMouseCaptureWindow::assignAxisY() {
void InputCalibrationWindow::activate(unsigned joy) {
//do not override an already active calibration window
if(window->isVisible()) return;
if(isVisible()) return;
activeJoypad = joy;
info->setText(utf8()
<< "Joypad #" << joy << " needs to be calibrated before it can be mapped. "
<< "Please ensure that<br>no buttons are pressed, "
<< "and all axes are centered before pressing okay."
<< "Please ensure<br>that no buttons are pressed, "
<< "and all axes are centered before pressing ok."
);
window->show();
show();
ok->setFocus();
}
InputCalibrationWindow::InputCalibrationWindow() {
InputCalibrationWindow::InputCalibrationWindow() : QbWindow(config.geometry.inputCalibrationWindow) {
activeJoypad = -1;
window = new Window(config.geometry.inputCalibrationWindow);
window->setObjectName("input-calibrate-window");
window->setWindowTitle("Joypad Calibration");
setObjectName("input-calibrate-window");
setWindowTitle("Joypad Calibration");
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(0);
window->setLayout(layout);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
info = new QLabel;
layout->addWidget(info);
layout->addSpacing(Style::WidgetSpacing);
ok = new QPushButton("Ok");
layout->addWidget(ok);
controlLayout = new QHBoxLayout;
controlLayout->setAlignment(Qt::AlignRight);
layout->addLayout(controlLayout);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
ok = new QPushButton("Ok");
controlLayout->addWidget(ok);
connect(ok, SIGNAL(released()), this, SLOT(dismiss()));
}
void InputCalibrationWindow::dismiss() {
window->hide();
hide();
if(activeJoypad != -1) {
inputManager.calibrate(activeJoypad);
activeJoypad = -1;
}
}
void InputCalibrationWindow::Window::closeEvent(QCloseEvent*) {
inputCalibrationWindow->dismiss();
void InputCalibrationWindow::closeEvent(QCloseEvent *event) {
QbWindow::closeEvent(event);
dismiss();
}
InputCalibrationWindow::Window::Window(string &geometry) : QbWindow(geometry) {}

View File

@ -1,26 +1,21 @@
class InputCaptureWindow : public QObject {
class InputCaptureWindow : public QbWindow {
Q_OBJECT
public:
class Window : public QbWindow {
public:
void closeEvent(QCloseEvent*);
Window(string&);
} *window;
QVBoxLayout *layout;
QHBoxLayout *hlayout;
QLabel *title;
QPushButton *mouseAxes;
QPushButton *mouseButtons;
QWidget *imageSpacer;
struct ImageWidget : public QWidget {
void paintEvent(QPaintEvent*);
} *imageWidget;
QWidget *spacer;
QHBoxLayout *hlayout;
QLabel *title;
QPushButton *mouseAxes;
QPushButton *mouseButtons;
QWidget *imageSpacer;
struct ImageWidget : public QWidget {
void paintEvent(QPaintEvent*);
} *imageWidget;
void activate(InputObject *object);
void activate(InputGroup *group);
void inputEvent(uint16_t code, bool forceAssign = false);
void closeEvent(QCloseEvent*);
InputCaptureWindow();
public slots:
@ -34,20 +29,18 @@ private:
bool inputLock;
} *inputCaptureWindow;
class InputMouseCaptureWindow : public QObject {
class InputMouseCaptureWindow : public QbWindow {
Q_OBJECT
public:
enum Mode { AxisMode, ButtonMode };
QbWindow *window;
QVBoxLayout *layout;
QLabel *info;
QLabel *captureBox;
QHBoxLayout *buttonLayout;
QPushButton *xAxis;
QPushButton *yAxis;
QWidget *spacer;
QLabel *info;
QLabel *captureBox;
QHBoxLayout *buttonLayout;
QPushButton *xAxis;
QPushButton *yAxis;
void activate(Mode);
void inputEvent(uint16_t code);
@ -62,21 +55,17 @@ private:
signed activeMouse;
} *inputMouseCaptureWindow;
class InputCalibrationWindow : public QObject {
class InputCalibrationWindow : public QbWindow {
Q_OBJECT
public:
class Window : public QbWindow {
public:
void closeEvent(QCloseEvent*);
Window(string&);
} *window;
QVBoxLayout *layout;
QLabel *info;
QPushButton *ok;
QWidget *spacer;
QLabel *info;
QHBoxLayout *controlLayout;
QPushButton *ok;
void activate(unsigned joy);
void closeEvent(QCloseEvent*);
InputCalibrationWindow();
public slots:

View File

@ -1,9 +1,9 @@
VideoSettingsWindow::VideoSettingsWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
title = new QLabel("Video Settings");
title->setProperty("class", "title");
@ -48,11 +48,6 @@ VideoSettingsWindow::VideoSettingsWindow() {
options->setSpacing(Style::WidgetSpacing);
layout->addLayout(options);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addWidget(spacer);
panel->setLayout(layout);
connect(contrast, SIGNAL(valueChanged(int)), this, SLOT(contrastAdjust(int)));
connect(brightness, SIGNAL(valueChanged(int)), this, SLOT(brightnessAdjust(int)));
connect(gamma, SIGNAL(valueChanged(int)), this, SLOT(gammaAdjust(int)));

View File

@ -1,20 +1,18 @@
class VideoSettingsWindow : public QObject {
class VideoSettingsWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QGridLayout *sliders;
QLabel *lcontrast;
QSlider *contrast;
QLabel *lbrightness;
QSlider *brightness;
QLabel *lgamma;
QSlider *gamma;
QHBoxLayout *options;
QCheckBox *enableGammaRamp;
QWidget *spacer;
QVBoxLayout *layout;
QLabel *title;
QGridLayout *sliders;
QLabel *lcontrast;
QSlider *contrast;
QLabel *lbrightness;
QSlider *brightness;
QLabel *lgamma;
QSlider *gamma;
QHBoxLayout *options;
QCheckBox *enableGammaRamp;
void syncUi();
VideoSettingsWindow();

View File

@ -1,10 +1,8 @@
CheatEditorWindow::CheatEditorWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
panel->setLayout(layout);
setLayout(layout);
title = new QLabel("Cheat Code Editor");
title->setProperty("class", "title");

View File

@ -1,23 +1,22 @@
class CheatEditorWindow : public QObject {
class CheatEditorWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QTreeWidget *list;
QGridLayout *controlLayout;
QLabel *descLabel;
QLineEdit *descEdit;
QLabel *codeLabel;
QLineEdit *codeEdit;
QHBoxLayout *buttonLayout;
QPushButton *addCode;
QPushButton *deleteCode;
QVBoxLayout *layout;
QLabel *title;
QTreeWidget *list;
QGridLayout *controlLayout;
QLabel *descLabel;
QLineEdit *descEdit;
QLabel *codeLabel;
QLineEdit *codeEdit;
QHBoxLayout *buttonLayout;
QPushButton *addCode;
QPushButton *deleteCode;
QMenu *menu;
QAction *deleteCodeItem;
QAction *addCodeItem;
QAction *deleteCodeItem;
QAction *addCodeItem;
void syncUi();
void updateItem(QTreeWidgetItem*);

View File

@ -1,10 +1,8 @@
CheatFinderWindow::CheatFinderWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
panel->setLayout(layout);
setLayout(layout);
title = new QLabel("Cheat Code Finder");
title->setProperty("class", "title");
@ -25,7 +23,7 @@ CheatFinderWindow::CheatFinderWindow() {
sizeLabel = new QLabel("Data size: ");
controlLayout->addWidget(sizeLabel, 0, 0);
sizeGroup = new QButtonGroup(panel);
sizeGroup = new QButtonGroup(this);
size8bit = new QRadioButton("8-bit");
size8bit->setChecked(true);
@ -47,7 +45,7 @@ CheatFinderWindow::CheatFinderWindow() {
compareLabel = new QLabel("Compare mode: ");
controlLayout->addWidget(compareLabel, 1, 0);
compareGroup = new QButtonGroup(panel);
compareGroup = new QButtonGroup(this);
compareEqual = new QRadioButton("Equal to");
compareEqual->setChecked(true);

View File

@ -1,8 +1,7 @@
class CheatFinderWindow : public QObject {
class CheatFinderWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QTreeWidget *list;

View File

@ -1,10 +1,8 @@
StateManagerWindow::StateManagerWindow() {
panel = new QWidget;
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setSpacing(0);
panel->setLayout(layout);
setLayout(layout);
title = new QLabel("Save State Manager");
title->setProperty("class", "title");
@ -164,6 +162,7 @@ void StateManagerWindow::loadSelectedState() {
QTreeWidgetItem *item = items[0];
unsigned n = item->data(0, Qt::UserRole).toUInt();
utility.loadState(n);
toolsWindow->close();
}
}

View File

@ -1,25 +1,24 @@
class StateManagerWindow : public QObject {
class StateManagerWindow : public QWidget {
Q_OBJECT
public:
QWidget *panel;
QVBoxLayout *layout;
QLabel *title;
QTreeWidget *list;
QHBoxLayout *controlLayout;
QLabel *descLabel;
QLineEdit *descEdit;
QHBoxLayout *buttonLayout;
QPushButton *loadState;
QPushButton *saveState;
QPushButton *createState;
QPushButton *deleteState;
QVBoxLayout *layout;
QLabel *title;
QTreeWidget *list;
QHBoxLayout *controlLayout;
QLabel *descLabel;
QLineEdit *descEdit;
QHBoxLayout *buttonLayout;
QPushButton *loadState;
QPushButton *saveState;
QPushButton *createState;
QPushButton *deleteState;
QMenu *menu;
QAction *loadStateItem;
QAction *saveStateItem;
QAction *createStateItem;
QAction *deleteStateItem;
QAction *loadStateItem;
QAction *saveStateItem;
QAction *createStateItem;
QAction *deleteStateItem;
void syncUi();
void reloadList();

View File

@ -2,16 +2,15 @@
#include "cheatfinder.cpp"
#include "statemanager.cpp"
ToolsWindow::ToolsWindow() {
window = new QbWindow(config.geometry.toolsWindow);
window->setObjectName("tools-window");
window->setWindowTitle("Tools");
window->resize(625, 360);
ToolsWindow::ToolsWindow() : QbWindow(config.geometry.toolsWindow) {
setObjectName("tools-window");
setWindowTitle("Tools");
resize(625, 360);
layout = new QHBoxLayout;
layout->setMargin(Style::WindowMargin);
layout->setSpacing(Style::WidgetSpacing);
window->setLayout(layout);
setLayout(layout);
splitter = new QSplitter;
layout->addWidget(splitter);
@ -43,9 +42,9 @@ ToolsWindow::ToolsWindow() {
stateManagerWindow = new StateManagerWindow;
panelLayout = new QStackedLayout(panel);
panelLayout->addWidget(cheatEditorWindow->panel);
panelLayout->addWidget(cheatFinderWindow->panel);
panelLayout->addWidget(stateManagerWindow->panel);
panelLayout->addWidget(cheatEditorWindow);
panelLayout->addWidget(cheatFinderWindow);
panelLayout->addWidget(stateManagerWindow);
panel->setLayout(panelLayout);
connect(list, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(itemChanged()));
@ -56,22 +55,22 @@ ToolsWindow::ToolsWindow() {
void ToolsWindow::itemChanged() {
QTreeWidgetItem *item = list->currentItem();
if(item == cheatEditor) panelLayout->setCurrentWidget(cheatEditorWindow->panel);
if(item == cheatFinder) panelLayout->setCurrentWidget(cheatFinderWindow->panel);
if(item == stateManager) panelLayout->setCurrentWidget(stateManagerWindow->panel);
if(item == cheatEditor) panelLayout->setCurrentWidget(cheatEditorWindow);
if(item == cheatFinder) panelLayout->setCurrentWidget(cheatFinderWindow);
if(item == stateManager) panelLayout->setCurrentWidget(stateManagerWindow);
}
void ToolsWindow::showCheatEditor() {
list->setCurrentItem(cheatEditor);
window->show();
show();
}
void ToolsWindow::showCheatFinder() {
list->setCurrentItem(cheatFinder);
window->show();
show();
}
void ToolsWindow::showStateManager() {
list->setCurrentItem(stateManager);
window->show();
show();
}

View File

@ -2,19 +2,18 @@
#include "cheatfinder.moc"
#include "statemanager.moc"
class ToolsWindow : public QObject {
class ToolsWindow : public QbWindow {
Q_OBJECT
public:
QbWindow *window;
QHBoxLayout *layout;
QSplitter *splitter;
QTreeWidget *list;
QTreeWidgetItem *cheatEditor;
QTreeWidgetItem *cheatFinder;
QTreeWidgetItem *stateManager;
QWidget *panel;
QStackedLayout *panelLayout;
QTreeWidget *list;
QTreeWidgetItem *cheatEditor;
QTreeWidgetItem *cheatFinder;
QTreeWidgetItem *stateManager;
QWidget *panel;
QStackedLayout *panelLayout;
void showCheatEditor();
void showCheatFinder();

View File

@ -71,6 +71,7 @@ bool Utility::loadCartridgeSuperGameBoy(const char *base, const char *slot) {
SNES::cartridge.load(SNES::Cartridge::ModeSuperGameBoy);
loadMemory(cartridge.slotAName, ".sav", SNES::memory::gbram);
loadMemory(cartridge.slotBName, ".rtc", SNES::memory::gbrtc);
cartridge.name = *slot
? notdir(nall::basename(cartridge.slotAName))
@ -102,13 +103,13 @@ void Utility::saveMemory() {
case SNES::Cartridge::ModeSuperGameBoy: {
saveMemory(cartridge.slotAName, ".sav", SNES::memory::gbram);
saveMemory(cartridge.slotAName, ".rtc", SNES::memory::gbrtc);
} break;
}
}
void Utility::unloadCartridge() {
if(SNES::cartridge.loaded() == false) return;
saveMemory();
modifySystemState(UnloadCartridge);
}
@ -133,7 +134,7 @@ void Utility::modifySystemState(system_state_t state) {
else if(SNES::cartridge.has_st011()) chip = "ST011";
else if(SNES::cartridge.has_st018()) chip = "ST018";
if(chip != "") {
QMessageBox::warning(mainWindow->window, "Warning", utf8()
QMessageBox::warning(mainWindow, "Warning", utf8()
<< "<p><b>Warning:</b><br> The " << chip << " chip was detected, which is not fully emulated yet.<br>"
<< "It is unlikely that this title will work properly.</p>");
}
@ -141,7 +142,7 @@ void Utility::modifySystemState(system_state_t state) {
showMessage(utf8()
<< "Loaded " << cartridge.name
<< (cartridge.patchApplied ? ", and applied UPS patch." : "."));
mainWindow->window->setWindowTitle(utf8() << bsnesTitle << " v" << bsnesVersion << " - " << cartridge.name);
mainWindow->setWindowTitle(utf8() << bsnesTitle << " v" << bsnesVersion << " - " << cartridge.name);
debugger->echo(utf8() << "Loaded " << cartridge.name << ".<br>");
} break;
@ -149,13 +150,15 @@ void Utility::modifySystemState(system_state_t state) {
if(SNES::cartridge.loaded() == false) break; //no cart to unload?
saveCheats();
SNES::cartridge.unload();
SNES::system.unload(); //flush all memory to memory::* devices
saveMemory(); //save memory to disk
SNES::cartridge.unload(); //deallocate memory
application.power = false;
application.pause = true;
showMessage(utf8() << "Unloaded " << cartridge.name << ".");
mainWindow->window->setWindowTitle(utf8() << bsnesTitle << " v" << bsnesVersion);
mainWindow->setWindowTitle(utf8() << bsnesTitle << " v" << bsnesVersion);
} break;
case PowerOn: {

View File

@ -46,12 +46,6 @@ void Utility::inputEvent(uint16_t code) {
//release mouse capture
input.unacquire();
return; //do not trigger other UI actions that may be bound to escape key
} else if(settingsWindow->window->isActiveWindow()) {
settingsWindow->window->hide();
return;
} else if(toolsWindow->window->isActiveWindow()) {
toolsWindow->window->hide();
return;
}
}
}
@ -76,7 +70,7 @@ void Utility::inputEvent(uint16_t code) {
modifySystemState(PowerCycle);
}
if(isButtonDown(code, inputUiGeneral.saveScreenshot)) {
if(isButtonDown(code, inputUiGeneral.captureScreenshot)) {
//tell SNES::Interface to save a screenshot at the next video_refresh() event
interface.saveScreenshot = true;
}
@ -122,12 +116,12 @@ void Utility::inputEvent(uint16_t code) {
}
if(isButtonDown(code, inputUiGeneral.toggleMenu)) {
mainWindow->menuBar->setVisible(!mainWindow->menuBar->isVisibleTo(mainWindow->window));
mainWindow->menuBar->setVisible(!mainWindow->menuBar->isVisibleTo(mainWindow));
resizeWindow = true;
}
if(isButtonDown(code, inputUiGeneral.toggleStatus)) {
mainWindow->statusBar->setVisible(!mainWindow->statusBar->isVisibleTo(mainWindow->window));
mainWindow->statusBar->setVisible(!mainWindow->statusBar->isVisibleTo(mainWindow));
resizeWindow = true;
}

View File

@ -3,12 +3,12 @@ void Utility::updateFullscreenState() {
if(config.video.isFullscreen == false) {
config.video.context = &config.video.windowed;
mainWindow->window->showNormal();
mainWindow->showNormal();
mainWindow->menuBar->setVisible(true);
mainWindow->statusBar->setVisible(true);
} else {
config.video.context = &config.video.fullscreen;
mainWindow->window->showFullScreen();
mainWindow->showFullScreen();
mainWindow->menuBar->setVisible(!config.system.autoHideMenus);
mainWindow->statusBar->setVisible(!config.system.autoHideMenus);
}
@ -52,14 +52,14 @@ void Utility::resizeMainWindow() {
if(config.video.isFullscreen == false) {
//get effective desktop work area region (ignore Windows taskbar, OS X dock, etc.)
QRect deskRect = QApplication::desktop()->availableGeometry(mainWindow->window);
QRect deskRect = QApplication::desktop()->availableGeometry(mainWindow);
//ensure window size will not be larger than viewable desktop area
constrainSize(height, width, deskRect.height()); //- frameHeight);
constrainSize(width, height, deskRect.width()); //- frameWidth );
mainWindow->canvas->setFixedSize(width, height);
mainWindow->window->show();
mainWindow->show();
} else {
for(unsigned i = 0; i < 2; i++) {
unsigned iWidth = width, iHeight = height;
@ -80,7 +80,7 @@ void Utility::resizeMainWindow() {
//workaround for Qt/Xlib bug:
//if window resize occurs with cursor over it, Qt shows Qt::Size*DiagCursor;
//so force it to show Qt::ArrowCursor, as expected
mainWindow->window->setCursor(Qt::ArrowCursor);
mainWindow->setCursor(Qt::ArrowCursor);
mainWindow->canvasContainer->setCursor(Qt::ArrowCursor);
mainWindow->canvas->setCursor(Qt::ArrowCursor);