mirror of
https://github.com/rodamaral/lsnes.git
synced 2025-04-02 10:42:15 -04:00
146 lines
3.6 KiB
C++
Executable file
146 lines
3.6 KiB
C++
Executable file
void InterfaceNES::initialize() {
|
|
NES::interface = this;
|
|
NES::system.init();
|
|
}
|
|
|
|
void InterfaceNES::setController(bool port, unsigned device) {
|
|
if(port == 0) config->nes.controllerPort1Device = device;
|
|
if(port == 1) config->nes.controllerPort2Device = device;
|
|
|
|
if(port == 0) switch(device) {
|
|
case 0: return NES::input.connect(0, NES::Input::Device::None);
|
|
case 1: return NES::input.connect(0, NES::Input::Device::Joypad);
|
|
}
|
|
|
|
if(port == 1) switch(device) {
|
|
case 0: return NES::input.connect(1, NES::Input::Device::None);
|
|
case 1: return NES::input.connect(1, NES::Input::Device::Joypad);
|
|
}
|
|
}
|
|
|
|
bool InterfaceNES::cartridgeLoaded() {
|
|
return NES::cartridge.loaded();
|
|
}
|
|
|
|
bool InterfaceNES::loadCartridge(const string &filename) {
|
|
uint8_t *data;
|
|
unsigned size;
|
|
if(interface->loadFile(filename, data, size) == false) return false;
|
|
|
|
interface->unloadCartridge();
|
|
interface->baseName = nall::basename(filename);
|
|
|
|
string markup;
|
|
markup.readfile({ interface->baseName, ".xml" });
|
|
|
|
NES::cartridge.load(markup, data, size);
|
|
NES::system.power();
|
|
delete[] data;
|
|
|
|
if(NES::cartridge.ram_size()) {
|
|
filemap fp;
|
|
if(fp.open(string{ interface->baseName, ".sav" }, filemap::mode::read)) {
|
|
memcpy(NES::cartridge.ram_data(), fp.data(), min(NES::cartridge.ram_size(), fp.size()));
|
|
}
|
|
}
|
|
|
|
interface->loadCartridge(::Interface::Mode::NES);
|
|
NES::video.generate(NES::Video::Format::RGB30);
|
|
return true;
|
|
}
|
|
|
|
void InterfaceNES::unloadCartridge() {
|
|
if(NES::cartridge.ram_size()) {
|
|
file::write({ interface->baseName, ".sav" }, NES::cartridge.ram_data(), NES::cartridge.ram_size());
|
|
}
|
|
NES::cartridge.unload();
|
|
interface->baseName = "";
|
|
}
|
|
|
|
//
|
|
|
|
void InterfaceNES::power() {
|
|
NES::system.power();
|
|
}
|
|
|
|
void InterfaceNES::reset() {
|
|
NES::system.reset();
|
|
}
|
|
|
|
void InterfaceNES::run() {
|
|
NES::system.run();
|
|
}
|
|
|
|
//
|
|
|
|
serializer InterfaceNES::serialize() {
|
|
NES::system.runtosave();
|
|
return NES::system.serialize();
|
|
}
|
|
|
|
bool InterfaceNES::unserialize(serializer &s) {
|
|
return NES::system.unserialize(s);
|
|
}
|
|
|
|
//
|
|
|
|
void InterfaceNES::setCheats(const lstring &list) {
|
|
NES::cheat.reset();
|
|
for(auto &code : list) {
|
|
lstring codelist;
|
|
codelist.split("+", code);
|
|
for(auto &part : codelist) {
|
|
unsigned addr, data, comp;
|
|
if(NES::Cheat::decode(part, addr, data, comp)) {
|
|
NES::cheat.append({ addr, data, comp });
|
|
}
|
|
}
|
|
}
|
|
NES::cheat.synchronize();
|
|
}
|
|
|
|
//
|
|
|
|
void InterfaceNES::videoRefresh(const uint16_t *data) {
|
|
static uint32_t output[256 * 240];
|
|
|
|
for(unsigned y = 0; y < 240; y++) {
|
|
const uint16_t *sp = data + y * 256;
|
|
uint32_t *dp = output + y * 256;
|
|
for(unsigned x = 0; x < 256; x++) {
|
|
uint32_t color = *sp++;
|
|
*dp++ = NES::video.palette[color];
|
|
}
|
|
}
|
|
|
|
if(config->video.maskOverscan) {
|
|
unsigned osw = config->video.maskOverscanHorizontal;
|
|
unsigned osh = config->video.maskOverscanVertical;
|
|
|
|
for(unsigned y = 0; y < 240; y++) {
|
|
uint32_t *dp = output + y * 256;
|
|
if(y < osh || y >= 240 - osh) {
|
|
memset(dp, 0, 256 * sizeof(uint32_t));
|
|
} else {
|
|
memset(dp + 0, 0, osw * sizeof(uint32_t));
|
|
memset(dp + 256 - osw, 0, osw * sizeof(uint32_t));
|
|
}
|
|
}
|
|
}
|
|
|
|
interface->videoRefresh(output, 256 * sizeof(uint32_t), 256, 240);
|
|
}
|
|
|
|
void InterfaceNES::audioSample(int16_t sample) {
|
|
signed samples[] = { sample };
|
|
dspaudio.sample(samples);
|
|
while(dspaudio.pending()) {
|
|
dspaudio.read(samples);
|
|
audio.sample(samples[0], samples[0]); //NES audio output is monaural; ruby only takes stereo audio
|
|
}
|
|
}
|
|
|
|
int16_t InterfaceNES::inputPoll(bool port, unsigned device, unsigned id) {
|
|
if(port == 0 && device == 0) return inputManager->nes.port1.gamepad.poll(id);
|
|
return 0;
|
|
}
|