mirror of https://github.com/bsnes-emu/bsnes.git
Update to v081 release.
byuu says: This release polishes up the GUI, adds some more features, and fixes a few minor issues. Changelog (since v080): - rewrote S-DD1 module to decompress individual bytes at a time - simplified SPC7110 deinterleaving code - OBC1 should not clear RAM on reset [Jonas Quinn] - fixed enum-cast compilation errors with the latest GCC 4.6.x releases - added bsnes logo to about screen - make phoenix=gtk will now build the GTK+ port on Linux - added settings.startFullScreen to the config file for front-end users - added advanced settings option to disable window compositor (only works on Windows and Xfce) - merged settings windows into the panel approach used by bsnes/Qt in the past - fixed a crashing bug on input settings window - fixed GTK+ auto-geometry sizing - added screenshot capture capability - added exit emulator hotkey (defaults to being unmapped) - Xorg keyboard polling now uses cached Display variable [Bisqwit] - cheat code database updated [mightymo]
This commit is contained in:
parent
10906d8418
commit
064ca4c626
File diff suppressed because it is too large
Load Diff
|
@ -11,7 +11,7 @@ namespace nall {
|
|||
|
||||
struct bmp {
|
||||
inline static bool read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height);
|
||||
inline static bool write(const string &filename, const uint32_t *data, unsigned width, unsigned height, bool alpha = false);
|
||||
inline static bool write(const string &filename, const uint32_t *data, unsigned width, unsigned height, unsigned pitch, bool alpha = false);
|
||||
};
|
||||
|
||||
bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height) {
|
||||
|
@ -56,7 +56,7 @@ bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigne
|
|||
return true;
|
||||
}
|
||||
|
||||
bool bmp::write(const string &filename, const uint32_t *data, unsigned width, unsigned height, bool alpha) {
|
||||
bool bmp::write(const string &filename, const uint32_t *data, unsigned width, unsigned height, unsigned pitch, bool alpha) {
|
||||
file fp;
|
||||
if(fp.open(filename, file::mode::write) == false) return false;
|
||||
|
||||
|
@ -87,7 +87,7 @@ bool bmp::write(const string &filename, const uint32_t *data, unsigned width, un
|
|||
fp.writel(0, 4); //important color count
|
||||
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
const uint32_t *p = data + y * width;
|
||||
const uint32_t *p = (const uint32_t*)((const uint8_t*)data + y * pitch);
|
||||
for(unsigned x = 0; x < width; x++) fp.writel(*p++, bytesPerPixel);
|
||||
if(paddingLength) fp.writel(0, paddingLength);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ struct pInputSDL {
|
|||
//Keyboard
|
||||
//========
|
||||
|
||||
x_poll(table);
|
||||
x_poll(device.display, table);
|
||||
|
||||
//=====
|
||||
//Mouse
|
||||
|
@ -172,7 +172,6 @@ struct pInputSDL {
|
|||
}
|
||||
|
||||
bool init() {
|
||||
x_init();
|
||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
|
||||
|
@ -182,6 +181,7 @@ struct pInputSDL {
|
|||
XGetWindowAttributes(device.display, device.rootwindow, &attributes);
|
||||
device.screenwidth = attributes.width;
|
||||
device.screenheight = attributes.height;
|
||||
x_init(device.display);
|
||||
|
||||
//Xlib: "because XShowCursor(false) would be too easy."
|
||||
//create a fully transparent cursor named InvisibleCursor,
|
||||
|
|
|
@ -30,13 +30,13 @@ public:
|
|||
|
||||
bool poll(int16_t *table) {
|
||||
memset(table, 0, Scancode::Limit * sizeof(int16_t));
|
||||
x_poll(table);
|
||||
x_poll(display, table);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool init() {
|
||||
x_init();
|
||||
display = XOpenDisplay(0);
|
||||
x_init(display);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@ enum XScancode {
|
|||
LeftShift, RightShift, LeftControl, RightControl, LeftAlt, RightAlt, LeftSuper, RightSuper,
|
||||
};
|
||||
|
||||
void x_poll(int16_t *table) {
|
||||
void x_poll(Display *display, int16_t *table) {
|
||||
if(!display) return;
|
||||
|
||||
char state[32];
|
||||
Display *display = XOpenDisplay(0);
|
||||
XQueryKeymap(display, state);
|
||||
XCloseDisplay(display);
|
||||
|
||||
#define key(id) table[keyboard(0)[id]]
|
||||
#define pressed(id) (bool)(state[scancode[id] >> 3] & (1 << (scancode[id] & 7)))
|
||||
|
@ -139,8 +139,9 @@ void x_poll(int16_t *table) {
|
|||
#undef pressed
|
||||
}
|
||||
|
||||
void x_init() {
|
||||
Display *display = XOpenDisplay(0);
|
||||
void x_init(Display *display) {
|
||||
if(!display) return;
|
||||
|
||||
memset(&scancode, 0, sizeof scancode);
|
||||
|
||||
#define assign(x, y) scancode[x] = XKeysymToKeycode(display, y)
|
||||
|
@ -259,6 +260,4 @@ void x_init() {
|
|||
assign(Menu, XK_Menu);
|
||||
|
||||
#undef assign
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ void OBC1::power() {
|
|||
}
|
||||
|
||||
void OBC1::reset() {
|
||||
for(unsigned i = 0x0000; i <= 0x1fff; i++) ram_write(i, 0xff);
|
||||
|
||||
status.baseptr = (ram_read(0x1ff5) & 1) ? 0x1800 : 0x1c00;
|
||||
status.address = (ram_read(0x1ff6) & 0x7f);
|
||||
status.shift = (ram_read(0x1ff6) & 3) << 1;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace SNES {
|
||||
namespace Info {
|
||||
static const char Name[] = "bsnes";
|
||||
static const char Version[] = "080.08";
|
||||
static const char Version[] = "081";
|
||||
static const unsigned SerializerVersion = 21;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ void Application::main(int argc, char **argv) {
|
|||
mainWindow.setVisible();
|
||||
OS::processEvents();
|
||||
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
#if defined(PLATFORM_WIN)
|
||||
video.driver("Direct3D");
|
||||
#else
|
||||
video.driver("OpenGL");
|
||||
|
@ -44,7 +44,7 @@ void Application::main(int argc, char **argv) {
|
|||
video.set(Video::Filter, (unsigned)0);
|
||||
video.init();
|
||||
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
#if defined(PLATFORM_WIN)
|
||||
audio.driver("XAudio2");
|
||||
#else
|
||||
audio.driver("ALSA");
|
||||
|
@ -58,7 +58,7 @@ void Application::main(int argc, char **argv) {
|
|||
audio.set(Audio::ResampleRatio, 4194304.0 / 44100.0);
|
||||
audio.init();
|
||||
|
||||
#if defined(PHOENIX_WINDOWS)
|
||||
#if defined(PLATFORM_WIN)
|
||||
input.driver("RawInput");
|
||||
#else
|
||||
input.driver("SDL");
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <snes/snes.hpp>
|
||||
|
||||
#include <nall/base64.hpp>
|
||||
#include <nall/bmp.hpp>
|
||||
#include <nall/compositor.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/directory.hpp>
|
||||
|
|
|
@ -197,6 +197,9 @@ void MainWindow::create() {
|
|||
|
||||
tools.append(toolsSeparator1);
|
||||
|
||||
toolsCaptureScreenshot.setText("Capture Screenshot");
|
||||
tools.append(toolsCaptureScreenshot);
|
||||
|
||||
toolsCheatEditor.setText("Cheat Editor ...");
|
||||
tools.append(toolsCheatEditor);
|
||||
|
||||
|
@ -345,6 +348,7 @@ void MainWindow::create() {
|
|||
toolsStateLoad4.onTick = [] { utility.loadState(4); };
|
||||
toolsStateLoad5.onTick = [] { utility.loadState(5); };
|
||||
|
||||
toolsCaptureScreenshot.onTick = [] { interface.captureScreenshot = true; };
|
||||
toolsCheatEditor.onTick = [] { cheatEditor.setVisible(); };
|
||||
toolsStateManager.onTick = [] { stateManager.setVisible(); };
|
||||
|
||||
|
@ -364,17 +368,12 @@ void MainWindow::create() {
|
|||
}
|
||||
|
||||
void MainWindow::synchronize() {
|
||||
if(SNES::cartridge.loaded() == false) {
|
||||
systemPower.setEnabled(false);
|
||||
systemReset.setEnabled(false);
|
||||
toolsStateSave.setEnabled(false);
|
||||
toolsStateLoad.setEnabled(false);
|
||||
} else {
|
||||
systemPower.setEnabled(true);
|
||||
systemReset.setEnabled(true);
|
||||
toolsStateSave.setEnabled(true);
|
||||
toolsStateLoad.setEnabled(true);
|
||||
}
|
||||
bool loaded = SNES::cartridge.loaded();
|
||||
systemPower.setEnabled(loaded);
|
||||
systemReset.setEnabled(loaded);
|
||||
toolsStateSave.setEnabled(loaded);
|
||||
toolsStateLoad.setEnabled(loaded);
|
||||
toolsCaptureScreenshot.setEnabled(loaded);
|
||||
}
|
||||
|
||||
void MainWindow::setupFiltersAndShaders() {
|
||||
|
|
|
@ -72,6 +72,7 @@ struct MainWindow : TopLevelWindow {
|
|||
Item toolsStateLoad4;
|
||||
Item toolsStateLoad5;
|
||||
Separator toolsSeparator1;
|
||||
Item toolsCaptureScreenshot;
|
||||
Item toolsCheatEditor;
|
||||
Item toolsStateManager;
|
||||
#if defined(DEBUGGER)
|
||||
|
|
|
@ -27,6 +27,11 @@ void InputMapper::poll_hotkeys(unsigned scancode, int16_t value) {
|
|||
utility.showMessage({ "Slot ", activeSlot, " selected" });
|
||||
}
|
||||
|
||||
//capture screenshot
|
||||
if(scancode == hotkeysGeneral.captureScreenshot.scancode) {
|
||||
interface.captureScreenshot = true;
|
||||
}
|
||||
|
||||
//fullscreen
|
||||
if(scancode == hotkeysGeneral.fullscreenToggle.scancode) {
|
||||
utility.setFullScreen(!utility.fullScreen);
|
||||
|
@ -66,6 +71,11 @@ void InputMapper::poll_hotkeys(unsigned scancode, int16_t value) {
|
|||
if(scancode == hotkeysGeneral.reset.scancode) {
|
||||
mainWindow.systemReset.onTick();
|
||||
}
|
||||
|
||||
//exit emulator
|
||||
if(scancode == hotkeysGeneral.exitEmulator.scancode) {
|
||||
application.quit = true;
|
||||
}
|
||||
} else {
|
||||
//key released
|
||||
if(mainWindow.focused() == false) return;
|
||||
|
@ -88,34 +98,40 @@ void InputMapper::HotkeysGeneral::create(const char *deviceName, const char *con
|
|||
stateLoad.name = "Load State";
|
||||
stateDecrement.name = "Decrement State";
|
||||
stateIncrement.name = "Increment State";
|
||||
captureScreenshot.name = "Capture Screenshot";
|
||||
fullscreenToggle.name = "Fullscreen";
|
||||
mouseCaptureToggle.name = "Mouse Capture";
|
||||
pauseToggle.name = "Pause Emulation";
|
||||
fastForward.name = "Fast-Forward";
|
||||
power.name = "Power Cycle";
|
||||
reset.name = "Reset";
|
||||
exitEmulator.name = "Exit Emulator";
|
||||
|
||||
append(&stateSave);
|
||||
append(&stateLoad);
|
||||
append(&stateDecrement);
|
||||
append(&stateIncrement);
|
||||
append(&captureScreenshot);
|
||||
append(&fullscreenToggle);
|
||||
append(&mouseCaptureToggle);
|
||||
append(&pauseToggle);
|
||||
append(&fastForward);
|
||||
append(&power);
|
||||
append(&reset);
|
||||
append(&exitEmulator);
|
||||
|
||||
config.attach(stateSave.mapping = "KB0::F5", string("input.", configName, ".stateSave"));
|
||||
config.attach(stateLoad.mapping = "KB0::F7", string("input.", configName, ".stateLoad"));
|
||||
config.attach(stateDecrement.mapping = "KB0::F6", string("input.", configName, ".stateDecrement"));
|
||||
config.attach(stateIncrement.mapping = "KB0::F8", string("input.", configName, ".stateIncrement"));
|
||||
config.attach(captureScreenshot.mapping = "", string("input.", configName, ".captureScreenshot"));
|
||||
config.attach(fullscreenToggle.mapping = "KB0::F11", string("input.", configName, ".fullscreenToggle"));
|
||||
config.attach(mouseCaptureToggle.mapping = "KB0::F12", string("input.", configName, ".mouseCaptureToggle"));
|
||||
config.attach(pauseToggle.mapping = "KB0::P", string("input.", configName, ".pauseToggle"));
|
||||
config.attach(fastForward.mapping = "KB0::Tilde", string("input.", configName, ".fastForward"));
|
||||
config.attach(power.mapping = "", string("input.", configName, ".power"));
|
||||
config.attach(reset.mapping = "", string("input.", configName, ".reset"));
|
||||
config.attach(exitEmulator.mapping = "", string("input.", configName, ".exitEmulator"));
|
||||
}
|
||||
|
||||
void InputMapper::create_hotkeys() {
|
||||
|
|
|
@ -3,12 +3,14 @@ struct HotkeysGeneral : Controller {
|
|||
DigitalInput stateLoad;
|
||||
DigitalInput stateDecrement;
|
||||
DigitalInput stateIncrement;
|
||||
DigitalInput captureScreenshot;
|
||||
DigitalInput fullscreenToggle;
|
||||
DigitalInput mouseCaptureToggle;
|
||||
DigitalInput pauseToggle;
|
||||
DigitalInput fastForward;
|
||||
DigitalInput power;
|
||||
DigitalInput reset;
|
||||
DigitalInput exitEmulator;
|
||||
void create(const char *deviceName, const char *configName);
|
||||
} hotkeysGeneral;
|
||||
|
||||
|
|
|
@ -122,6 +122,18 @@ void Interface::video_refresh(const uint16_t *data, bool hires, bool interlace,
|
|||
frameCounter = 0;
|
||||
previous = current;
|
||||
}
|
||||
|
||||
if(captureScreenshot) {
|
||||
captureScreenshot = false;
|
||||
time_t currentTime = time(0);
|
||||
tm *info = localtime(¤tTime);
|
||||
string filename = { "-",
|
||||
decimal<4, '0'>(info->tm_year + 1900), "-", decimal<2, '0'>(info->tm_mon + 1), "-", decimal<2, '0'>(info->tm_mday), " ",
|
||||
decimal<2, '0'>(info->tm_hour), ":", decimal<2, '0'>(info->tm_min), ":", decimal<2, '0'>(info->tm_sec), ".bmp"
|
||||
};
|
||||
bmp::write(path(utility.slotPath(), filename), buffer, outwidth, outheight, outpitch, false);
|
||||
utility.showMessage("Screenshot captured");
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::audio_sample(uint16_t left, uint16_t right) {
|
||||
|
@ -141,3 +153,7 @@ void Interface::message(const string &text) {
|
|||
string Interface::path(SNES::Cartridge::Slot slot, const string &hint) {
|
||||
return ::path.load(slot, hint);
|
||||
}
|
||||
|
||||
Interface::Interface() {
|
||||
captureScreenshot = false;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ struct Interface : public SNES::Interface {
|
|||
|
||||
void message(const string &text);
|
||||
string path(SNES::Cartridge::Slot slot, const string &hint);
|
||||
Interface();
|
||||
|
||||
bool captureScreenshot;
|
||||
};
|
||||
|
||||
extern Palette palette;
|
||||
|
|
|
@ -69,6 +69,7 @@ string Path::load(SNES::Cartridge::Slot slot, const string &hint) {
|
|||
if(hint.endswith(".bst") && bst != "") filePath = bst;
|
||||
if(hint.endswith(".cht") && cht != "") filePath = cht;
|
||||
if(hint.endswith(".log") && log != "") filePath = log;
|
||||
if(hint.endswith(".bmp") && bmp != "") filePath = bmp;
|
||||
|
||||
filePath = decode(filePath, basePath);
|
||||
return { filePath, baseName, hint };
|
||||
|
@ -168,4 +169,5 @@ Path::Path() {
|
|||
attach(bst = "", "bst");
|
||||
attach(cht = "", "cht");
|
||||
attach(log = "", "log");
|
||||
attach(bmp = "", "bmp");
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ struct Path : public configuration {
|
|||
string bst;
|
||||
string cht;
|
||||
string log;
|
||||
string bmp;
|
||||
|
||||
string home(const string &filename);
|
||||
string load(const string &path);
|
||||
|
|
|
@ -4,7 +4,7 @@ void AdvancedSettings::create() {
|
|||
title.setText("Advanced Settings");
|
||||
title.setFont(application.titleFont);
|
||||
|
||||
driverSelectionLabel.setText("Driver Selection:");
|
||||
driverSelectionLabel.setText("Driver selection:");
|
||||
driverSelectionLabel.setFont(application.proportionalFontBold);
|
||||
videoDriverLabel.setText("Video:");
|
||||
audioDriverLabel.setText("Audio:");
|
||||
|
@ -18,7 +18,7 @@ void AdvancedSettings::create() {
|
|||
if(config.settings.focusPolicy == 0) focusPolicyPause.setChecked();
|
||||
if(config.settings.focusPolicy == 1) focusPolicyIgnore.setChecked();
|
||||
if(config.settings.focusPolicy == 2) focusPolicyAllow.setChecked();
|
||||
compositorPolicyLabel.setText("Disable Compositor:");
|
||||
compositorPolicyLabel.setText("Disable window compositor:");
|
||||
compositorPolicyLabel.setFont(application.proportionalFontBold);
|
||||
compositorPolicyNever.setText("Never");
|
||||
compositorPolicyFullScreen.setText("Fullscreen");
|
||||
|
|
|
@ -4,7 +4,7 @@ void VideoSettings::create() {
|
|||
title.setText("Video Settings");
|
||||
title.setFont(application.titleFont);
|
||||
|
||||
colorAdjustmentLabel.setText("Color Adjustment:");
|
||||
colorAdjustmentLabel.setText("Color adjustment:");
|
||||
colorAdjustmentLabel.setFont(application.proportionalFontBold);
|
||||
brightnessLabel.setText("Brightness:");
|
||||
brightnessSlider.setLength(201);
|
||||
|
|
|
@ -7,4 +7,5 @@ synchronize() {
|
|||
|
||||
synchronize "nall"
|
||||
synchronize "phoenix"
|
||||
rm -r nall/test
|
||||
rm -r phoenix/test*
|
||||
|
|
Loading…
Reference in New Issue