2009-04-08 21:29:36 +02:00

219 lines
7.5 KiB
C++
Executable File

#include "cartridge.cpp"
#include "window.cpp"
//returns true if requested code is a button, and it has just been pressed down
bool Utility::isButtonDown(uint16_t inputCode, InputObject &object) {
if(inputCode != object.code) return false;
if(object.codetype != InputCode::KeyboardButton
&& object.codetype != InputCode::MouseButton
&& object.codetype != InputCode::JoypadHat
&& object.codetype != InputCode::JoypadAxis
&& object.codetype != InputCode::JoypadButton) return false;
int16_t state = inputManager.state(object.code);
int16_t lastState = inputManager.lastState(object.code);
if(object.codetype == InputCode::JoypadHat) {
switch(object.modifier) {
case InputObject::Up: return (state & joypad<>::hat_up ) && !(lastState & joypad<>::hat_up );
case InputObject::Down: return (state & joypad<>::hat_down ) && !(lastState & joypad<>::hat_down );
case InputObject::Left: return (state & joypad<>::hat_left ) && !(lastState & joypad<>::hat_left );
case InputObject::Right: return (state & joypad<>::hat_right) && !(lastState & joypad<>::hat_right);
}
} else if(object.codetype == InputCode::JoypadAxis) {
switch(object.modifier) {
case InputObject::Lo: return (state < -16384) && !(lastState < -16384);
case InputObject::Hi: return (state > +16384) && !(lastState > +16384);
case InputObject::Trigger: return (state < 0) && !(lastState < 0);
}
} else {
return (state == 1) && !(lastState == 1);
}
return false; //fall-through for modifier-less hats / axes
}
void Utility::inputEvent(uint16_t code) {
//forward key-press event
//(in case window is currently active and capturing a new button / axis assignment)
winInputCapture->inputEvent(code);
//if escape key is pressed on *any* keyboard; release the mouse if it is acquired
for(unsigned i = 0; i < keyboard<>::count; i++) {
if(code == keyboard<>::index(i, keyboard<>::escape) && inputManager.state(code) && input.acquired()) {
input.unacquire();
return; //do not trigger other UI actions that may be bound to escape key
}
}
if(winMain->window->isActiveWindow()) {
bool resizeWindow = false;
if(isButtonDown(code, inputUiGeneral.loadCartridge)) {
string filename = selectCartridge();
if(filename.length() > 0) loadCartridge(filename);
}
if(isButtonDown(code, inputUiGeneral.pauseEmulation)) {
application.pause = !application.pause;
}
if(isButtonDown(code, inputUiGeneral.resetSystem)) {
modifySystemState(Reset);
}
if(isButtonDown(code, inputUiGeneral.powerCycleSystem)) {
modifySystemState(PowerCycle);
}
if(isButtonDown(code, inputUiGeneral.lowerSpeed)) {
config.system.speed--;
updateEmulationSpeed();
winMain->syncUi();
}
if(isButtonDown(code, inputUiGeneral.raiseSpeed)) {
config.system.speed++;
updateEmulationSpeed();
winMain->syncUi();
}
if(isButtonDown(code, inputUiGeneral.toggleCheatSystem)) {
if(cheat.enabled() == false) {
cheat.enable();
showMessage("Cheat system enabled.");
} else {
cheat.disable();
showMessage("Cheat system disabled.");
}
}
if(isButtonDown(code, inputUiGeneral.toggleFullscreen)) {
config.video.isFullscreen = !config.video.isFullscreen;
updateFullscreenState();
winMain->syncUi();
}
if(isButtonDown(code, inputUiGeneral.toggleMenu)) {
winMain->window->menuBar()->setVisible(!winMain->window->menuBar()->isVisibleTo(winMain->window));
resizeWindow = true;
}
if(isButtonDown(code, inputUiGeneral.toggleStatus)) {
winMain->window->statusBar()->setVisible(!winMain->window->statusBar()->isVisibleTo(winMain->window));
resizeWindow = true;
}
//prevent calling twice when toggleMenu == toggleStatus
if(resizeWindow == true) {
resizeMainWindow();
}
if(isButtonDown(code, inputUiGeneral.exitEmulator)) {
application.terminate = true;
}
}
}
//display message in main window statusbar area for three seconds
void Utility::showMessage(const char *message) {
winMain->window->statusBar()->showMessage(utf8() << message, 3000);
}
//updates system state text at bottom-right of main window statusbar
void Utility::updateSystemState() {
string text;
if(cartridge.loaded() == false) {
text = "No cartridge loaded";
} else if(application.power == false) {
text = "Power off";
} else if(application.pause == true || application.autopause == true) {
text = "Paused";
} else if(ppu.status.frames_updated == true) {
ppu.status.frames_updated = false;
text << (int)ppu.status.frames_executed;
text << " fps";
} else {
//nothing to update
return;
}
winMain->systemState->setText(utf8() << text);
}
void Utility::acquireMouse() {
if(cartridge.loaded()) {
if(snes.config.controller_port1 == SNES::Input::DeviceMouse
|| snes.config.controller_port2 == SNES::Input::DeviceMouse
|| snes.config.controller_port2 == SNES::Input::DeviceSuperScope
|| snes.config.controller_port2 == SNES::Input::DeviceJustifier
|| snes.config.controller_port2 == SNES::Input::DeviceJustifiers
) input.acquire();
}
}
void Utility::unacquireMouse() {
input.unacquire();
}
void Utility::updateAvSync() {
video.set(Video::Synchronize, config.video.synchronize);
audio.set(Audio::Synchronize, config.audio.synchronize);
}
void Utility::updateVideoMode() {
if(config.video.context->region == 0) {
snes.video.set_mode(SNES::Video::ModeNTSC);
} else {
snes.video.set_mode(SNES::Video::ModePAL);
}
}
void Utility::updateColorFilter() {
libfilter::colortable.set_format(libfilter::Colortable::RGB888);
libfilter::colortable.set_contrast(config.video.contrastAdjust);
libfilter::colortable.set_brightness(config.video.brightnessAdjust);
libfilter::colortable.set_gamma(100 + config.video.gammaAdjust);
libfilter::colortable.enable_gamma_ramp(config.video.enableGammaRamp);
libfilter::colortable.update();
}
void Utility::updateHardwareFilter() {
video.set(Video::Filter, config.video.context->hwFilter);
}
void Utility::updateSoftwareFilter() {
libfilter::FilterInterface::FilterType type;
switch(config.video.context->swFilter) { default:
case 0: type = libfilter::FilterInterface::Direct; break;
case 1: type = libfilter::FilterInterface::Scanline; break;
case 2: type = libfilter::FilterInterface::Scale2x; break;
case 3: type = libfilter::FilterInterface::HQ2x; break;
case 4: type = libfilter::FilterInterface::NTSC; break;
}
libfilter::filter.set(type);
if(type == libfilter::FilterInterface::NTSC) {
libfilter::filter_ntsc.adjust(0, 0, 0, 0, 0, config.video.enableNtscMergeFields);
}
}
void Utility::updateEmulationSpeed() {
config.system.speed = max(0, min(4, (signed)config.system.speed));
double scale[] = { 0.50, 0.75, 1.00, 1.50, 2.00 };
unsigned outfreq = config.audio.outputFrequency;
unsigned infreq = config.audio.inputFrequency * scale[config.system.speed] + 0.5;
audio.set(Audio::Resample, outfreq != infreq); //only resample when necessary
audio.set(Audio::ResampleOutputFrequency, outfreq);
audio.set(Audio::ResampleInputFrequency, infreq);
}
void Utility::updateControllers() {
snes.input.port_set_device(0, snes.config.controller_port1);
snes.input.port_set_device(1, snes.config.controller_port2);
}