Update to bsnes v059r05 release.

Funny, much more effective changes but in a lot less time. The file
dialog is just a major pain in the ass, I guess. Had to sit and think
for at least two hours just to handle the differences between activate
(double-click an item) and accept (click accept button.) Eg if it's a
folder, double-clicking needs to go into the folder, but the accept
button needs to use that folder. But files act differently, load has
the open-folder thing that overrides the default entering of folders,
and saving doesn't have any such concept at all. Fun fun fun, but done
now.

libqb (QbWindow, QbCheckAction, QbRadioAction) is dead; DiskBrowser is
dead; HexEditor is dead. They've all been merged into nall/qt now.
nall/Makefile-qt goes to the more logical nall/qt/Makefile. The last
thing to do is export style sheet defaults into nall/qt to get the
spacing of the new file dialog under control.

Improved the save dialog, instead of putting the entire path in the
box, it only puts the non-directory part, and pulls the directory from
the file system mode's root path. I decided not to allow .. and /
commands inside the save text box. I just strip all that out. Go to
the damn folder you want to save in, sheesh. And before anyone
complains about that, note that bsnes doesn't even use the save dialog
mode :P

Still have to hook up the new folder button to an actual dialog,
haven't bothered yet. Since there's plenty of room with the extended
width, I'm just going to leave them both visible.

nall/qt/hex-editor is pretty much a direct port, no changes. But I
intend to make the height programmable, and fork that into a stand-
alone, super light-weight hex editor to replace bless (so that I can
remove Mono.) Same for check-action and radio-action, direct ports.

nall/qt/window is a bit different, binds the geometry outside the
constructor. This fixes some issues where certain windows weren't
saving their geometry properly, like the debugger properties window.
And I think there's some other advantage to it not needing a
complicated constructor, but I don't recall what at the moment.

Modified GL_CLAMP_TO_EDGE to GL_CLAMP_TO_BORDER, so everyone can try
out the curvature pixel shader now. Added it to my pixelshaders pack,
but I haven't uploaded a new pack yet, so get it from the other thread
for now.

I mainly need testing on the new file dialog stuff. Please let me know
if something strange is broken, other than the new folder button.
This commit is contained in:
byuu 2010-01-18 16:25:02 +00:00
parent b538c13aad
commit 4517c0249f
67 changed files with 622 additions and 1238 deletions

BIN
bsnes.exe

Binary file not shown.

View File

@ -2,7 +2,7 @@ include lib/nall/Makefile
ui := ui_qt
qtlibs := $(strip QtCore QtGui $(if $(findstring osx,$(platform)),QtOpenGL))
include lib/nall/Makefile-qt
include lib/nall/qt/Makefile
################
### compiler ###

View File

@ -1,4 +1,4 @@
static const char bsnesVersion[] = "059.04";
static const char bsnesVersion[] = "059.05";
static const char bsnesTitle[] = "bsnes";
static const unsigned bsnesSerializerVersion = 4;

View File

@ -0,0 +1,41 @@
#ifndef NALL_QT_CHECKACTION_HPP
#define NALL_QT_CHECKACTION_HPP
namespace nall {
class CheckAction : public QAction {
Q_OBJECT
public:
bool isChecked() const;
void setChecked(bool);
void toggleChecked();
CheckAction(const QString&, QObject*);
protected slots:
protected:
bool checked;
};
inline bool CheckAction::isChecked() const {
return checked;
}
inline void CheckAction::setChecked(bool checked_) {
checked = checked_;
if(checked) setIcon(QIcon(":/16x16/item-check-on.png"));
else setIcon(QIcon(":/16x16/item-check-off.png"));
}
inline void CheckAction::toggleChecked() {
setChecked(!isChecked());
}
inline CheckAction::CheckAction(const QString &text, QObject *parent) : QAction(text, parent) {
setChecked(false);
}
}
#endif

View File

@ -2,6 +2,7 @@
#define NALL_QT_FILEDIALOG_HPP
#include <nall/string.hpp>
#include <nall/qt/window.moc.hpp>
namespace nall {
@ -19,16 +20,14 @@ protected slots:
void currentChanged(const QModelIndex&, const QModelIndex&);
};
class FileDialog : public QWidget {
class FileDialog : public Window {
Q_OBJECT
public:
void showLoad();
void showOpen();
void showSave();
void showFolder();
void rejectSignal();
void setPath(string path);
void setNameFilters(const string &filters);
FileDialog();
@ -66,7 +65,6 @@ protected:
QPushButton *rejectButton;
bool lock;
bool signalRejected;
};
inline void FileView::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
@ -98,13 +96,6 @@ inline void FileDialog::showLoad() {
show();
}
inline void FileDialog::showOpen() {
acceptButton->setText("Open");
fileNameEdit->hide();
filterBox->show();
show();
}
inline void FileDialog::showSave() {
acceptButton->setText("Save");
fileNameEdit->show();
@ -122,20 +113,19 @@ inline void FileDialog::showFolder() {
inline void FileDialog::fileViewChange(const QModelIndex &index) {
string path = fileSystemModel->filePath(index).toUtf8().constData();
fileNameEdit->setText(path);
if(path == fileSystemModel->rootPath().toUtf8().constData()) path = "";
fileNameEdit->setText(notdir(path));
emit changed(path);
}
inline void FileDialog::fileViewActivate(const QModelIndex &index) {
string path = fileSystemModel->filePath(index).toUtf8().constData();
if(fileSystemModel->isDir(index)) {
signalRejected = false;
emit activated(path);
if(signalRejected == false) setPath(path);
setPath(path);
} else {
signalRejected = false;
emit activated(path);
if(signalRejected == false) close();
close();
}
}
@ -165,10 +155,6 @@ inline void FileDialog::browseUp() {
if(pathBox->count() > 1) pathBox->setCurrentIndex(1);
}
inline void FileDialog::rejectSignal() {
signalRejected = true;
}
inline void FileDialog::setPath(string path) {
lock = true;
@ -194,6 +180,7 @@ inline void FileDialog::setPath(string path) {
}
}
pathBox->addItem("<root>");
fileNameEdit->setText("");
lock = false;
}
@ -214,15 +201,15 @@ inline void FileDialog::setNameFilters(const string &filters) {
}
inline void FileDialog::acceptAction() {
string path = fileNameEdit->text().toUtf8().constData();
string path = fileSystemModel->rootPath().toUtf8().constData();
path << "/" << notdir(fileNameEdit->text().toUtf8().constData());
rtrim(path, "/");
if(QDir(path).exists()) {
signalRejected = false;
emit accepted(path);
if(signalRejected == false) setPath(path);
setPath(path);
} else {
signalRejected = false;
emit accepted(path);
if(signalRejected == false) close();
close();
}
}

View File

@ -0,0 +1,157 @@
#ifndef NALL_QT_HEXEDITOR_HPP
#define NALL_QT_HEXEDITOR_HPP
#include <nall/function.hpp>
#include <nall/stdint.hpp>
#include <nall/string.hpp>
namespace nall {
class HexEditor : public QTextEdit {
Q_OBJECT
public:
enum {
LineWidth = 59,
};
function<uint8_t (unsigned)> reader;
function<void (unsigned, uint8_t)> writer;
void setOffset(unsigned offset);
void setSize(unsigned size);
void refresh();
HexEditor();
protected slots:
void scrolled();
protected:
QHBoxLayout *layout;
QScrollBar *scrollBar;
unsigned editorOffset;
unsigned editorSize;
bool lock;
void keyPressEvent(QKeyEvent*);
};
inline void HexEditor::keyPressEvent(QKeyEvent *event) {
QTextCursor cursor = textCursor();
unsigned x = cursor.position() % LineWidth;
unsigned y = cursor.position() / LineWidth;
int hexCode = -1;
switch(event->key()) {
case Qt::Key_0: hexCode = 0; break;
case Qt::Key_1: hexCode = 1; break;
case Qt::Key_2: hexCode = 2; break;
case Qt::Key_3: hexCode = 3; break;
case Qt::Key_4: hexCode = 4; break;
case Qt::Key_5: hexCode = 5; break;
case Qt::Key_6: hexCode = 6; break;
case Qt::Key_7: hexCode = 7; break;
case Qt::Key_8: hexCode = 8; break;
case Qt::Key_9: hexCode = 9; break;
case Qt::Key_A: hexCode = 10; break;
case Qt::Key_B: hexCode = 11; break;
case Qt::Key_C: hexCode = 12; break;
case Qt::Key_D: hexCode = 13; break;
case Qt::Key_E: hexCode = 14; break;
case Qt::Key_F: hexCode = 15; break;
}
if(cursor.hasSelection() == false && hexCode != -1) {
bool cursorOffsetValid = (x >= 11 && ((x - 11) % 3) != 2);
if(cursorOffsetValid) {
bool nibble = (x - 11) % 3; //0 = top nibble, 1 = bottom nibble
unsigned cursorOffset = y * 16 + ((x - 11) / 3);
unsigned effectiveOffset = editorOffset + cursorOffset;
if(effectiveOffset >= editorSize) effectiveOffset %= editorSize;
uint8_t data = reader ? reader(effectiveOffset) : 0x00;
data &= (nibble == 0 ? 0x0f : 0xf0);
data |= (nibble == 0 ? (hexCode << 4) : (hexCode << 0));
if(writer) writer(effectiveOffset, data);
refresh();
cursor.setPosition(y * LineWidth + x + 1); //advance cursor
setTextCursor(cursor);
}
} else {
//allow navigation keys to move cursor, but block text input
setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
QTextEdit::keyPressEvent(event);
setTextInteractionFlags(Qt::TextEditorInteraction);
}
}
inline void HexEditor::setOffset(unsigned offset) {
lock = true;
editorOffset = offset;
scrollBar->setSliderPosition(editorOffset / 16);
lock = false;
}
inline void HexEditor::setSize(unsigned size) {
editorSize = size;
scrollBar->setRange(0, editorSize / 16 - 16);
}
inline void HexEditor::refresh() {
string output;
char temp[256];
unsigned offset = editorOffset;
for(unsigned y = 0; y < 16; y++) {
if(offset >= editorSize) break;
sprintf(temp, "%.4x:%.4x", (offset >> 16) & 0xffff, (offset >> 0) & 0xffff);
output << "<font color='#808080'>" << temp << "</font>&nbsp;&nbsp;";
for(unsigned x = 0; x < 16; x++) {
if(offset >= editorSize) break;
sprintf(temp, "%.2x", reader ? reader(offset) : 0x00);
offset++;
output << "<font color='" << ((x & 1) ? "#000080" : "#0000ff") << "'>" << temp << "</font>";
if(x != 15) output << "&nbsp;";
}
if(y != 15) output << "<br>";
}
setHtml(output);
}
inline void HexEditor::scrolled() {
if(lock) return;
unsigned offset = scrollBar->sliderPosition();
editorOffset = offset * 16;
refresh();
}
inline HexEditor::HexEditor() {
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
layout = new QHBoxLayout;
layout->setAlignment(Qt::AlignRight);
layout->setMargin(0);
layout->setSpacing(0);
setLayout(layout);
scrollBar = new QScrollBar(Qt::Vertical);
scrollBar->setSingleStep(1);
scrollBar->setPageStep(16);
layout->addWidget(scrollBar);
lock = false;
connect(scrollBar, SIGNAL(actionTriggered(int)), this, SLOT(scrolled()));
setSize(0);
setOffset(0);
}
}
#endif

View File

@ -0,0 +1,41 @@
#ifndef NALL_QT_RADIOACTION_HPP
#define NALL_QT_RADIOACTION_HPP
namespace nall {
class RadioAction : public QAction {
Q_OBJECT
public:
bool isChecked() const;
void setChecked(bool);
void toggleChecked();
RadioAction(const QString&, QObject*);
protected slots:
protected:
bool checked;
};
inline bool RadioAction::isChecked() const {
return checked;
}
inline void RadioAction::setChecked(bool checked_) {
checked = checked_;
if(checked) setIcon(QIcon(":/16x16/item-radio-on.png"));
else setIcon(QIcon(":/16x16/item-radio-off.png"));
}
inline void RadioAction::toggleChecked() {
setChecked(!isChecked());
}
inline RadioAction::RadioAction(const QString &text, QObject *parent) : QAction(text, parent) {
setChecked(false);
}
}
#endif

View File

@ -0,0 +1,105 @@
#ifndef NALL_QT_WINDOW_HPP
#define NALL_QT_WINDOW_HPP
#include <nall/base64.hpp>
#include <nall/string.hpp>
namespace nall {
class Window : public QWidget {
Q_OBJECT
public:
void setGeometryString(string *geometryString);
void setCloseOnEscape(bool);
void show();
void hide();
void shrink();
Window();
protected slots:
protected:
string *geometryString;
bool closeOnEscape;
void keyReleaseEvent(QKeyEvent *event);
void closeEvent(QCloseEvent *event);
};
inline void Window::setGeometryString(string *geometryString_) {
geometryString = geometryString_;
if(geometryString && isVisible() == false) {
uint8_t *data;
unsigned length;
base64::decode(data, length, *geometryString);
QByteArray array((const char*)data, length);
delete[] data;
restoreGeometry(array);
}
}
inline void Window::setCloseOnEscape(bool value) {
closeOnEscape = value;
}
inline void Window::show() {
if(geometryString && isVisible() == false) {
uint8_t *data;
unsigned length;
base64::decode(data, length, *geometryString);
QByteArray array((const char*)data, length);
delete[] data;
restoreGeometry(array);
}
QWidget::show();
QApplication::processEvents();
activateWindow();
raise();
}
inline void Window::hide() {
if(geometryString && isVisible() == true) {
char *data;
QByteArray geometry = saveGeometry();
base64::encode(data, (const uint8_t*)geometry.data(), geometry.length());
*geometryString = data;
delete[] data;
}
QWidget::hide();
}
inline void Window::shrink() {
if(isFullScreen()) return;
for(unsigned i = 0; i < 2; i++) {
resize(0, 0);
usleep(2000);
QApplication::processEvents();
}
}
inline void Window::keyReleaseEvent(QKeyEvent *event) {
if(closeOnEscape && (event->key() == Qt::Key_Escape)) close();
QWidget::keyReleaseEvent(event);
}
inline void Window::closeEvent(QCloseEvent *event) {
if(geometryString) {
char *data;
QByteArray geometry = saveGeometry();
base64::encode(data, (const uint8_t*)geometry.data(), geometry.length());
*geometryString = data;
delete[] data;
}
QWidget::closeEvent(event);
}
inline Window::Window() {
geometryString = 0;
closeOnEscape = true;
}
}
#endif

View File

@ -83,8 +83,8 @@ public:
glUniform2fv(location, 1, textureSize);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, smooth ? GL_LINEAR : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, smooth ? GL_LINEAR : GL_NEAREST);

View File

@ -34,8 +34,8 @@ public:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
}
}

View File

@ -2,7 +2,6 @@
Application application;
#include "init.cpp"
#include "qb.cpp"
void Application::initPaths(const char *basename) {
char temp[PATH_MAX];
@ -85,9 +84,9 @@ int Application::main(int &argc, char **argv) {
timer->start(0);
app->exec();
//QbWindow::hide() saves window geometry for next run
//QbWindow::close() saves window geometry for next run
for(unsigned i = 0; i < windowList.size(); i++) {
windowList[i]->hide();
windowList[i]->close();
}
cartridge.unload();

View File

@ -1,5 +1,3 @@
#include "qb.hpp"
class Application : public QObject {
Q_OBJECT
@ -29,7 +27,7 @@ public:
string configFilename;
string styleSheetFilename;
array<QbWindow*> windowList;
array<QWidget*> windowList;
int main(int &argc, char **argv);
void locateFile(string &filename, bool createDataDirectory = false);

View File

@ -27,7 +27,6 @@ void Application::init() {
loaderWindow = new LoaderWindow;
htmlViewerWindow = new HtmlViewerWindow;
aboutWindow = new AboutWindow;
diskBrowser = new DiskBrowser;
fileBrowser = new FileBrowser;
//window must be onscreen and visible before initializing video interface

View File

@ -1,101 +0,0 @@
void QbWindow::setCloseOnEscape(bool state) {
closeOnEscape = state;
}
void QbWindow::shrink() {
if(config().video.isFullscreen == false) {
for(unsigned i = 0; i < 2; i++) {
resize(0, 0);
usleep(2000);
QApplication::processEvents();
}
}
}
void QbWindow::show() {
if(isVisible() == false) {
uint8_t *data;
unsigned length;
base64::decode(data, length, geometryString);
QByteArray array((const char*)data, length);
delete[] data;
restoreGeometry(array);
QWidget::show();
}
QApplication::processEvents();
activateWindow();
raise();
}
void QbWindow::hide() {
if(isVisible() == true) {
char *data;
QByteArray geometry = saveGeometry();
base64::encode(data, (const uint8_t*)geometry.data(), geometry.length());
geometryString = data;
delete[] data;
QWidget::hide();
}
}
void QbWindow::closeEvent(QCloseEvent *event) {
char *data;
QByteArray geometry = saveGeometry();
base64::encode(data, (const uint8_t*)geometry.data(), geometry.length());
geometryString = data;
delete[] data;
QWidget::hide();
}
void QbWindow::keyReleaseEvent(QKeyEvent *event) {
if((closeOnEscape == true) && (event->key() == Qt::Key_Escape)) close();
QWidget::keyReleaseEvent(event);
}
QbWindow::QbWindow(string &geometryString_) : geometryString(geometryString_) {
closeOnEscape = true;
//keep track of all created windows (for geometry save on exit, always-on-top control, etc)
application.windowList.add(this);
}
//
bool QbCheckAction::isChecked() const {
return checked;
}
void QbCheckAction::setChecked(bool checked_) {
checked = checked_;
if(checked) setIcon(QIcon(":/16x16/item-check-on.png"));
else setIcon(QIcon(":/16x16/item-check-off.png"));
}
void QbCheckAction::toggleChecked() {
setChecked(!isChecked());
}
QbCheckAction::QbCheckAction(const QString &text, QObject *parent) : QAction(text, parent) {
setChecked(false);
}
//
bool QbRadioAction::isChecked() const {
return checked;
}
void QbRadioAction::setChecked(bool checked_) {
checked = checked_;
if(checked) setIcon(QIcon(":/16x16/item-radio-on.png"));
else setIcon(QIcon(":/16x16/item-radio-off.png"));
}
void QbRadioAction::toggleChecked() {
setChecked(!isChecked());
}
QbRadioAction::QbRadioAction(const QString &text, QObject *parent) : QAction(text, parent) {
setChecked(false);
}

View File

@ -1,36 +0,0 @@
class QbWindow : public QWidget {
public:
void setCloseOnEscape(bool);
void shrink();
void show();
void hide();
void closeEvent(QCloseEvent*);
void keyReleaseEvent(QKeyEvent*);
QbWindow(string&);
private:
string &geometryString;
bool closeOnEscape;
};
class QbCheckAction : public QAction {
public:
bool isChecked() const;
void setChecked(bool);
void toggleChecked();
QbCheckAction(const QString&, QObject*);
private:
bool checked;
};
class QbRadioAction : public QAction {
public:
bool isChecked() const;
void setChecked(bool);
void toggleChecked();
QbRadioAction(const QString&, QObject*);
private:
bool checked;
};

View File

@ -1,9 +1,11 @@
#include "about.moc"
AboutWindow *aboutWindow;
AboutWindow::AboutWindow() : QbWindow(config().geometry.aboutWindow) {
AboutWindow::AboutWindow() {
setObjectName("about-window");
setWindowTitle("About bsnes ...");
setGeometryString(&config().geometry.aboutWindow);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);

View File

@ -1,4 +1,4 @@
class AboutWindow : public QbWindow {
class AboutWindow : public Window {
Q_OBJECT
public:

View File

@ -1,7 +1,6 @@
#include "../ui-base.hpp"
#include "about.cpp"
#include "diskbrowser.cpp"
#include "filebrowser.cpp"
#include "htmlviewer.cpp"
#include "loader.cpp"

View File

@ -1,615 +0,0 @@
#include "diskbrowser.moc"
FolderCreator *folderCreator;
DiskBrowser *diskBrowser;
//=============
//FolderCreator
//=============
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);
setLayout(layout);
label = new QLabel("Folder name:");
layout->addWidget(label);
name = new QLineEdit;
layout->addWidget(name);
controlLayout = new QHBoxLayout;
controlLayout->setAlignment(Qt::AlignRight);
layout->addLayout(controlLayout);
ok = new QPushButton("Ok");
controlLayout->addWidget(ok);
cancel = new QPushButton("Cancel");
controlLayout->addWidget(cancel);
connect(name, SIGNAL(returnPressed()), this, SLOT(createFolder()));
connect(ok, SIGNAL(released()), this, SLOT(createFolder()));
connect(cancel, SIGNAL(released()), this, SLOT(close()));
}
void FolderCreator::show() {
name->setText("");
QbWindow::show();
name->setFocus();
}
void FolderCreator::createFolder() {
if(name->text().length() == 0) {
QMessageBox::warning(0, "Create New Folder", "<b>Note:</b> you must enter a folder name.");
} else {
string folderName = string()
<< diskBrowser->model->rootPath().toUtf8().constData()
<< "/"
<< name->text().toUtf8().constData();
if(mkdir(folderName) == 0) {
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.");
}
}
}
//===============
//DiskBrowserView
//===============
void DiskBrowserView::keyPressEvent(QKeyEvent *event) {
//enhance consistency: OS X by default doesn't activate items for these keypresses
if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
emit activated(currentIndex());
return;
}
//simulate popular file managers; backspace = go up one directory
if(event->key() == Qt::Key_Backspace) {
emit cdUp();
return;
}
//fallback: unrecognized keypresses get handled by the widget itself
QTreeView::keyPressEvent(event);
}
void DiskBrowserView::currentChanged(const QModelIndex &current, const QModelIndex &previous) {
QAbstractItemView::currentChanged(current, previous);
emit changed(current);
}
//================
//DiskBrowserImage
//================
void DiskBrowserImage::paintEvent(QPaintEvent*) {
QPainter painter(this);
if(name != "") {
QImage image(QString::fromUtf8(name));
painter.drawImage(0, 0, image);
}
}
//===========
//DiskBrowser
//===========
void DiskBrowser::inputEvent(uint16_t scancode) {
if(!isActiveWindow() || isMinimized()) return;
//provide very simple support for controlling the window via gamepads
if(Joypad::isAnyHat(scancode)) {
int16_t state = mapper().state(scancode);
if(state == Joypad::HatUp) {
QKeyEvent event((QEvent::Type)6, Qt::Key_Up, Qt::NoModifier);
view->keyPressEvent(&event);
}
if(state == Joypad::HatDown) {
QKeyEvent event((QEvent::Type)6, Qt::Key_Down, Qt::NoModifier);
view->keyPressEvent(&event);
}
if(state == Joypad::HatLeft) {
QKeyEvent event((QEvent::Type)6, Qt::Key_Backspace, Qt::NoModifier);
view->keyPressEvent(&event);
}
if(state == Joypad::HatRight) {
QKeyEvent event((QEvent::Type)6, Qt::Key_Return, Qt::NoModifier);
view->keyPressEvent(&event);
}
}
}
void DiskBrowser::chooseFolder(const function<void (string)> &callback_, string &currentPath_, const char *title) {
callback = callback_;
currentPath = &currentPath_;
browseMode = Folder;
hide();
newFolder->show();
group->hide();
ok->setText("Choose");
setWindowTitle(string() << title);
setPath(*currentPath);
setNameFilters("Folders ()");
show();
}
void DiskBrowser::chooseFile(const function<void (string)> &callback_, string &currentPath_, const char *title) {
callback = callback_;
currentPath = &currentPath_;
browseMode = File;
hide();
newFolder->hide();
group->hide();
ok->setText("Choose");
setWindowTitle(string() << title);
setPath(*currentPath);
setNameFilters("All Files (*)");
show();
}
void DiskBrowser::loadCartridge() {
currentPath = &config().path.current.cartridge;
browseMode = Cartridge;
hide();
newFolder->hide();
group->setVisible(config().diskBrowser.showPanel);
ok->setText("Load");
setWindowTitle("Load Cartridge");
setPath(config().path.rom == "" ? *currentPath : config().path.rom);
setNameFilters(string()
<< "SNES cartridges (*.sfc" << reader.extensionList << reader.compressionList << ");;"
<< "BS-X cartridges (*.bs" << reader.compressionList << ");;"
<< "Sufami Turbo cartridges (*.st" << reader.compressionList << ");;"
<< "Game Boy cartridges (*.gb *.sgb *.gbc" << reader.compressionList << ");;"
<< "All files (*)"
);
filter->setCurrentIndex(config().path.current.filter);
show();
}
void DiskBrowser::loadBaseCartridge() {
currentPath = &config().path.current.cartridge;
browseMode = BaseCartridge;
hide();
newFolder->hide();
group->setVisible(config().diskBrowser.showPanel);
ok->setText("Load");
setWindowTitle("Load Base Cartridge");
setPath(config().path.rom == "" ? *currentPath : config().path.rom);
setNameFilters(string()
<< "SNES cartridges (*.sfc" << reader.extensionList << reader.compressionList << ");;"
<< "All files (*)"
);
show();
}
void DiskBrowser::loadBsxCartridge() {
currentPath = &config().path.current.bsx;
browseMode = BsxCartridge;
hide();
newFolder->hide();
group->setVisible(config().diskBrowser.showPanel);
ok->setText("Load");
setWindowTitle("Load BS-X Cartridge");
setPath(config().path.rom == "" ? *currentPath : config().path.rom);
setNameFilters(string()
<< "BS-X cartridges (*.bs" << reader.compressionList << ");;"
<< "All files (*)"
);
show();
}
void DiskBrowser::loadSufamiTurboCartridge1() {
currentPath = &config().path.current.st;
browseMode = SufamiTurboCartridge1;
hide();
newFolder->hide();
group->setVisible(config().diskBrowser.showPanel);
ok->setText("Load");
setWindowTitle("Load Slot-A Sufami Turbo Cartridge");
setPath(config().path.rom == "" ? *currentPath : config().path.rom);
setNameFilters(string()
<< "Sufami Turbo cartridges (*.st" << reader.compressionList << ");;"
<< "All files (*)"
);
show();
}
void DiskBrowser::loadSufamiTurboCartridge2() {
currentPath = &config().path.current.st;
browseMode = SufamiTurboCartridge2;
hide();
newFolder->hide();
group->setVisible(config().diskBrowser.showPanel);
ok->setText("Load");
setWindowTitle("Load Slot-B Sufami Turbo Cartridge");
setPath(config().path.rom == "" ? *currentPath : config().path.rom);
setNameFilters(string()
<< "Sufami Turbo Cartridges (*.st" << reader.compressionList << ");;"
<< "All files (*)"
);
show();
}
void DiskBrowser::loadSuperGameBoyCartridge() {
currentPath = &config().path.current.sgb;
browseMode = SuperGameBoyCartridge;
hide();
newFolder->hide();
group->setVisible(config().diskBrowser.showPanel);
ok->setText("Load");
setWindowTitle("Load Super Game Boy Cartridge");
setPath(config().path.rom == "" ? *currentPath : config().path.rom);
setNameFilters(string()
<< "Game Boy cartridges (*.gb *.sgb *.gbc" << reader.compressionList << ");;"
<< "All files (*)"
);
show();
}
string DiskBrowser::queryImageInformation() {
string text;
string filename;
if(currentFilename(filename) == true) {
Cartridge::Information info;
if(cartridge.information(filename, info)) {
unsigned size = file::size(filename);
text << "<small><table>";
text << "<tr><td><b>Title: </b></td><td>" << info.name << "</td></tr>";
text << "<tr><td><b>Region: </b></td><td>" << info.region << "</td></tr>";
text << "<tr><td><b>ROM: </b></td><td>" << info.romSize * 8 / 1024 / 1024 << "mbit</td></tr>";
text << "<tr><td><b>RAM: </b></td><td>";
info.ramSize ? text << info.ramSize * 8 / 1024 << "kbit</td></tr>" : text << "None</td></tr>";
text << "</table></small>";
}
}
return text;
}
void DiskBrowser::activateItem(const QModelIndex &item) {
if(browseMode == Folder) {
setPath(model->filePath(item));
} else {
loadSelected();
}
}
void DiskBrowser::changeItem(const QModelIndex &item) {
if(browseMode == Folder) {
ok->setEnabled(model->isDir(item));
image->name = "";
info->setText("");
applyPatch->setVisible(false);
} else {
string filename;
currentFilename(filename);
if(filename.length() == 0) {
//nothing selected?
ok->setEnabled(false);
image->name = "";
info->setText("");
applyPatch->setVisible(false);
} else {
ok->setEnabled(true);
image->name = nall::basename(filename) << ".png";
if(file::exists(image->name) == false) image->name = "";
info->setText(string() << queryImageInformation());
string patch = nall::basename(filename) << ".ups";
applyPatch->setVisible(file::exists(patch));
}
}
image->update();
}
void DiskBrowser::loadSelected() {
string filename;
bool loadable = currentFilename(filename);
if(browseMode == Folder || loadable == true) {
QModelIndex item = view->currentIndex();
if(currentPath) *currentPath = dir(model->filePath(item).toUtf8().constData());
hide();
if(browseMode == Folder || browseMode == File) {
callback(filename);
} else if(browseMode == Cartridge) {
//quick-loading mode: determine load type via active filter
config().path.current.filter = filter->currentIndex();
if(config().path.current.filter == 1) { //"BS-X cartridges"
if(config().path.bsx == "") {
loaderWindow->loadBsxCartridge("", filename);
} else {
cartridge.loadBsx(config().path.bsx, filename);
}
} else if(config().path.current.filter == 2) { //"Sufami Turbo cartridges"
if(config().path.st == "") {
loaderWindow->loadSufamiTurboCartridge("", filename, "");
} else {
cartridge.loadSufamiTurbo(config().path.st, filename, "");
}
} else if(config().path.current.filter == 3) { //"Game Boy cartridges"
if(SNES::supergameboy.opened() == false) {
QMessageBox::warning(0, "Warning", "Super Game Boy support missing - cartridge cannot be loaded.");
} else if(config().path.sgb == "") {
loaderWindow->loadSuperGameBoyCartridge("", filename);
} else {
cartridge.loadSuperGameBoy(config().path.sgb, filename);
}
} else { //"SNES cartridges" (0) or "All files" (4)
cartridge.loadNormal(filename);
}
} else if(browseMode == BaseCartridge) {
loaderWindow->selectBaseCartridge(filename);
} else if(browseMode == BsxCartridge) {
loaderWindow->selectSlot1Cartridge(filename);
} else if(browseMode == SufamiTurboCartridge1) {
loaderWindow->selectSlot1Cartridge(filename);
} else if(browseMode == SufamiTurboCartridge2) {
loaderWindow->selectSlot2Cartridge(filename);
} else if(browseMode == SuperGameBoyCartridge) {
loaderWindow->selectSlot1Cartridge(filename);
}
} else {
//this is a standard folder in ROM loading mode; enter into the folder
QModelIndex item = view->currentIndex();
setPath(model->filePath(item));
}
}
//
void DiskBrowser::setPath(const QString &reqPath) {
disconnect(path, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePath()));
QString effectivePath = reqPath;
if(effectivePath == "") {
effectivePath = QString::fromUtf8(config().path.startup);
}
if(effectivePath == "<root>" || QDir(reqPath).exists() == false) {
effectivePath = "";
newFolder->setEnabled(false);
} else {
newFolder->setEnabled(true);
}
path->clear();
model->setRootPath(effectivePath);
view->setRootIndex(model->index(effectivePath));
view->setCurrentIndex(view->rootIndex());
view->setFocus();
if(effectivePath.length() > 0) {
QDir directory(effectivePath);
while(true) {
path->addItem(directory.absolutePath());
if(directory.isRoot()) break;
directory.cdUp();
}
}
path->addItem("<root>");
connect(path, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePath()));
}
void DiskBrowser::setNameFilters(const QString &filters) {
disconnect(filter, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFilter()));
filter->clear();
string filterData = filters.toUtf8().constData();
lstring filterPart;
filterPart.split(";;", filterData);
for(unsigned i = 0; i < filterPart.size(); i++) {
filter->addItem(filterPart[i]);
}
connect(filter, SIGNAL(currentIndexChanged(int)), this, SLOT(updateFilter()));
updateFilter();
}
void DiskBrowser::cdUp() {
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);
}
void DiskBrowser::updatePath() {
setPath(path->currentText());
}
void DiskBrowser::updateFilter() {
QString currentText = filter->currentText();
if(currentText.length() == 0) {
model->setNameFilters(QStringList() << "*");
} else {
string filters = currentText.toUtf8().constData();
filters = substr(filters, strpos(filters, "("));
ltrim(filters, "(");
rtrim(filters, ")");
lstring filterPart;
filterPart.split(" ", filters);
QStringList filterList;
for(unsigned i = 0; i < filterPart.size(); i++) filterList << (const char*)filterPart[i];
model->setNameFilters(filterList);
}
}
//true means filename can be loaded directly
//false means it cannot (eg this is a folder and we are attempting to load a ROM)
bool DiskBrowser::currentFilename(string &filename) {
bool loadable = false;
QModelIndex item = view->currentIndex();
filename = model->filePath(item).toUtf8().constData();
if(browseMode != Folder) {
if(model->isDir(item)) {
if(browseMode != File) {
//folders ending in ".sfc" are treated as "packages", and loaded directly
if(striend(filename, ".sfc")) {
QDir directory(filename);
directory.setNameFilters(QStringList() << "*.sfc");
QStringList list = directory.entryList(QDir::Files | QDir::NoDotAndDotDot);
if(list.count() == 1) {
filename << "/" << list[0].toUtf8().constData();
loadable = true;
}
}
}
} else {
loadable = true;
}
}
return loadable;
}
void DiskBrowser::toggleApplyPatches() {
config().file.applyPatches = applyPatch->isChecked();
}
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);
setLayout(layout);
topLayout = new QHBoxLayout;
layout->addLayout(topLayout);
browseLayout = new QVBoxLayout;
topLayout->addLayout(browseLayout);
pathLayout = new QHBoxLayout;
browseLayout->addLayout(pathLayout);
path = new QComboBox;
path->setEditable(true);
path->setMinimumContentsLength(16);
path->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
path->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
pathLayout->addWidget(path);
newFolder = new QPushButton;
newFolder->setIconSize(QSize(16, 16));
newFolder->setIcon(QIcon(":/16x16/folder-new.png"));
pathLayout->addWidget(newFolder);
upFolder = new QPushButton;
upFolder->setIconSize(QSize(16, 16));
upFolder->setIcon(QIcon(":/16x16/go-up.png"));
pathLayout->addWidget(upFolder);
view = new DiskBrowserView;
view->setIconSize(QSize(16, 16));
browseLayout->addWidget(view);
panelLayout = new QVBoxLayout;
topLayout->addLayout(panelLayout);
group = new QGroupBox;
panelLayout->addWidget(group);
groupLayout = new QVBoxLayout;
group->setLayout(groupLayout);
info = new QLabel;
info->setFixedWidth(256);
groupLayout->addWidget(info);
image = new DiskBrowserImage;
image->setFixedSize(256, 239);
groupLayout->addWidget(image);
spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
groupLayout->addWidget(spacer);
applyPatch = new QCheckBox("Apply UPS patch");
applyPatch->setChecked(config().file.applyPatches);
groupLayout->addWidget(applyPatch);
controlLayout = new QHBoxLayout;
layout->addLayout(controlLayout);
filter = new QComboBox;
filter->setMinimumContentsLength(16);
filter->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLength);
filter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
controlLayout->addWidget(filter);
options = new QPushButton("Options");
controlLayout->addWidget(options);
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);
cancel = new QPushButton("Cancel");
controlLayout->addWidget(cancel);
model = new QFileSystemModel;
model->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
model->setNameFilterDisables(false);
view->setModel(model);
view->setExpandsOnDoubleClick(false);
view->setAllColumnsShowFocus(true);
view->setUniformRowHeights(true);
view->setSortingEnabled(true);
view->sortByColumn(0, Qt::AscendingOrder);
view->setColumnHidden(1, true);
view->setColumnHidden(2, true);
view->setColumnHidden(3, true);
view->setHeaderHidden(true);
folderCreator = new FolderCreator;
connect(newFolder, SIGNAL(released()), folderCreator, SLOT(show()));
connect(upFolder, SIGNAL(released()), this, SLOT(cdUp()));
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(ok, SIGNAL(released()), this, SLOT(loadSelected()));
connect(cancel, SIGNAL(released()), this, SLOT(close()));
connect(applyPatch, SIGNAL(stateChanged(int)), this, SLOT(toggleApplyPatches()));
connect(showPanel, SIGNAL(triggered()), this, SLOT(toggleShowPanel()));
}

View File

@ -1,118 +0,0 @@
class FolderCreator : public QbWindow {
Q_OBJECT
public:
QVBoxLayout *layout;
QLabel *label;
QLineEdit *name;
QHBoxLayout *controlLayout;
QPushButton *ok;
QPushButton *cancel;
FolderCreator();
public slots:
void show();
void createFolder();
};
extern FolderCreator *folderCreator;
class DiskBrowserView : public QTreeView {
Q_OBJECT
public:
void keyPressEvent(QKeyEvent*);
signals:
void cdUp();
void changed(const QModelIndex&);
public slots:
void currentChanged(const QModelIndex&, const QModelIndex&);
};
class DiskBrowserImage : public QWidget {
public:
string name;
void paintEvent(QPaintEvent*);
};
class DiskBrowser : public QbWindow {
Q_OBJECT
public:
QVBoxLayout *layout;
QHBoxLayout *topLayout;
QVBoxLayout *browseLayout;
QHBoxLayout *pathLayout;
QComboBox *path;
QPushButton *newFolder;
QPushButton *upFolder;
DiskBrowserView *view;
QVBoxLayout *panelLayout;
QGroupBox *group;
QVBoxLayout *groupLayout;
QLabel *info;
DiskBrowserImage *image;
QWidget *spacer;
QCheckBox *applyPatch;
QHBoxLayout *controlLayout;
QComboBox *filter;
QPushButton *options;
QPushButton *ok;
QPushButton *cancel;
QFileSystemModel *model;
QMenu *menu;
QbCheckAction *showPanel;
void inputEvent(uint16_t scancode);
void chooseFolder(const function<void (string)>&, string&, const char*);
void chooseFile(const function<void (string)>&, string&, const char*);
void loadCartridge();
void loadBaseCartridge();
void loadBsxCartridge();
void loadSufamiTurboCartridge1();
void loadSufamiTurboCartridge2();
void loadSuperGameBoyCartridge();
string queryImageInformation();
void setPath(const QString&);
void setNameFilters(const QString&);
DiskBrowser();
public slots:
void cdUp();
void updatePath();
void updateFilter();
void activateItem(const QModelIndex&);
void changeItem(const QModelIndex&);
void loadSelected();
void toggleApplyPatches();
void toggleShowPanel();
private:
function<void (string)> callback;
string *currentPath;
enum BrowseMode {
Folder,
File,
Cartridge,
BaseCartridge,
BsxCartridge,
SufamiTurboCartridge1,
SufamiTurboCartridge2,
SuperGameBoyCartridge,
} browseMode;
bool currentFilename(string&);
};
extern DiskBrowser *diskBrowser;

View File

@ -6,12 +6,12 @@ void FileBrowser::chooseFolder() {
showFolder();
}
void FileBrowser::loadCartridge() {
void FileBrowser::loadCartridge(CartridgeMode mode, signed filterIndex) {
cartridgeMode = mode;
onChange = bind(&FileBrowser::onChangeCartridge, this);
onActivate = bind(&FileBrowser::onAcceptCartridge, this);
onAccept = bind(&FileBrowser::onAcceptCartridge, this);
setWindowTitle("Load Cartridge");
setPath(config().path.rom == "" ? config().path.current.cartridge : config().path.rom);
setNameFilters(string()
<< "SNES cartridges (*.sfc" << reader.extensionList << reader.compressionList << ")\n"
@ -21,7 +21,7 @@ void FileBrowser::loadCartridge() {
<< "All files (*)"
);
previewFrame->show();
filterBox->setCurrentIndex(config().path.current.filter);
filterBox->setCurrentIndex(filterIndex == -1 ? config().path.current.filter : filterIndex);
showLoad();
}
@ -42,7 +42,10 @@ void FileBrowser::toggleApplyPatch() {
}
FileBrowser::FileBrowser() {
setObjectName("file-browser");
resize(800, 480);
setGeometryString(&config().geometry.fileBrowser);
application.windowList.add(this);
previewLayout = new QVBoxLayout;
previewLayout->setAlignment(Qt::AlignTop);
@ -55,6 +58,10 @@ FileBrowser::FileBrowser() {
previewImage->setFixedSize(256, 239);
previewLayout->addWidget(previewImage);
previewSpacer = new QWidget;
previewSpacer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
previewLayout->addWidget(previewSpacer);
previewApplyPatch = new QCheckBox("Apply Patch");
previewApplyPatch->setVisible(false);
previewApplyPatch->setChecked(config().file.applyPatches);
@ -122,33 +129,42 @@ void FileBrowser::onAcceptCartridge(const string &path) {
}
if(file::exists(filename)) {
config().path.current.filter = filterBox->currentIndex();
config().path.current.cartridge = fileSystemModel->rootPath().toUtf8().constData();
close();
config().path.current.cartridge = fileSystemModel->rootPath().toUtf8().constData();
string filter = filterBox->currentText().toUtf8().constData();
if(strbegin(filter, "SNES cartridges")) {
cartridge.loadNormal(filename);
} else if(strbegin(filter, "BS-X cartridges")) {
if(config().path.bsx == "") {
loaderWindow->loadBsxCartridge("", filename);
if(cartridgeMode == LoadDirect) {
config().path.current.filter = filterBox->currentIndex();
string filter = filterBox->currentText().toUtf8().constData();
if(strbegin(filter, "SNES cartridges")) {
cartridge.loadNormal(filename);
} else if(strbegin(filter, "BS-X cartridges")) {
if(config().path.bsx == "") {
loaderWindow->loadBsxCartridge("", filename);
} else {
cartridge.loadBsx(config().path.bsx, filename);
}
} else if(strbegin(filter, "Sufami Turbo cartridges")) {
if(config().path.st == "") {
loaderWindow->loadSufamiTurboCartridge("", filename, "");
} else {
cartridge.loadSufamiTurbo(config().path.st, filename, "");
}
} else if(strbegin(filter, "Game Boy cartridges")) {
if(config().path.sgb == "") {
loaderWindow->loadSuperGameBoyCartridge("", filename);
} else {
cartridge.loadSuperGameBoy(config().path.sgb, filename);
}
} else {
cartridge.loadBsx(config().path.bsx, filename);
cartridge.loadNormal(filename);
}
} else if(strbegin(filter, "Sufami Turbo cartridges")) {
if(config().path.st == "") {
loaderWindow->loadSufamiTurboCartridge("", filename, "");
} else {
cartridge.loadSufamiTurbo(config().path.st, filename, "");
}
} else if(strbegin(filter, "Game Boy cartridges")) {
if(config().path.sgb == "") {
loaderWindow->loadSuperGameBoyCartridge("", filename);
} else {
cartridge.loadSuperGameBoy(config().path.sgb, filename);
}
} else {
cartridge.loadNormal(filename);
} else if(cartridgeMode == LoadBase) {
loaderWindow->selectBaseCartridge(filename);
} else if(cartridgeMode == LoadSlot1) {
loaderWindow->selectSlot1Cartridge(filename);
} else if(cartridgeMode == LoadSlot2) {
loaderWindow->selectSlot2Cartridge(filename);
}
}
}

View File

@ -7,7 +7,8 @@ public:
function<void (const string&)> onAccept;
void chooseFolder();
void loadCartridge();
enum CartridgeMode { LoadDirect, LoadBase, LoadSlot1, LoadSlot2 } cartridgeMode;
void loadCartridge(CartridgeMode, signed = -1);
FileBrowser();
@ -21,6 +22,7 @@ private:
QVBoxLayout *previewLayout;
QLabel *previewInfo;
QWidget *previewImage;
QWidget *previewSpacer;
QCheckBox *previewApplyPatch;
string resolveFilename(const string&);

View File

@ -1,9 +1,11 @@
#include "htmlviewer.moc"
HtmlViewerWindow *htmlViewerWindow;
HtmlViewerWindow::HtmlViewerWindow() : QbWindow(config().geometry.htmlViewerWindow) {
HtmlViewerWindow::HtmlViewerWindow() {
setObjectName("html-window");
resize(560, 480);
setGeometryString(&config().geometry.htmlViewerWindow);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
@ -17,5 +19,5 @@ HtmlViewerWindow::HtmlViewerWindow() : QbWindow(config().geometry.htmlViewerWind
void HtmlViewerWindow::show(const char *title, const char *htmlData) {
document->setHtml(string() << htmlData);
setWindowTitle(title);
QbWindow::show();
Window::show();
}

View File

@ -1,4 +1,4 @@
class HtmlViewerWindow : public QbWindow {
class HtmlViewerWindow : public Window {
Q_OBJECT
public:

View File

@ -1,9 +1,11 @@
#include "loader.moc"
LoaderWindow *loaderWindow;
LoaderWindow::LoaderWindow() : QbWindow(config().geometry.loaderWindow) {
LoaderWindow::LoaderWindow() {
setObjectName("loader-window");
setMinimumWidth(520);
setGeometryString(&config().geometry.loaderWindow);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);
@ -163,7 +165,8 @@ void LoaderWindow::selectSlot2Cartridge(const char *filename) {
}
void LoaderWindow::selectBaseCartridge() {
diskBrowser->loadBaseCartridge();
fileBrowser->setWindowTitle("Load Base Cartridge");
fileBrowser->loadCartridge(FileBrowser::LoadBase, 0);
}
void LoaderWindow::clearBaseCartridge() {
@ -175,13 +178,16 @@ void LoaderWindow::selectSlot1Cartridge() {
switch(mode) {
case SNES::Cartridge::ModeBsx:
case SNES::Cartridge::ModeBsxSlotted:
diskBrowser->loadBsxCartridge();
fileBrowser->setWindowTitle("Load BS-X Cartridge");
fileBrowser->loadCartridge(FileBrowser::LoadSlot1, 1);
break;
case SNES::Cartridge::ModeSufamiTurbo:
diskBrowser->loadSufamiTurboCartridge1();
fileBrowser->setWindowTitle("Load Sufami Turbo Cartridge A");
fileBrowser->loadCartridge(FileBrowser::LoadSlot1, 2);
break;
case SNES::Cartridge::ModeSuperGameBoy:
diskBrowser->loadSuperGameBoyCartridge();
fileBrowser->setWindowTitle("Load Game Boy Cartridge");
fileBrowser->loadCartridge(FileBrowser::LoadSlot1, 3);
break;
}
}
@ -192,7 +198,8 @@ void LoaderWindow::clearSlot1Cartridge() {
}
void LoaderWindow::selectSlot2Cartridge() {
diskBrowser->loadSufamiTurboCartridge2();
fileBrowser->setWindowTitle("Load Sufami Turbo Cartridge B");
fileBrowser->loadCartridge(FileBrowser::LoadSlot2, 2);
}
void LoaderWindow::clearSlot2Cartridge() {

View File

@ -1,4 +1,4 @@
class LoaderWindow : public QbWindow {
class LoaderWindow : public Window {
Q_OBJECT
public:

View File

@ -1,10 +1,12 @@
#include "main.moc"
MainWindow *mainWindow;
MainWindow::MainWindow() : QbWindow(config().geometry.mainWindow) {
MainWindow::MainWindow() {
setObjectName("main-window");
setWindowTitle(string() << bsnesTitle << " v" << bsnesVersion);
setCloseOnEscape(false);
setGeometryString(&config().geometry.mainWindow);
application.windowList.add(this);
//menu bar
#if defined(PLATFORM_OSX)
@ -35,7 +37,7 @@ MainWindow::MainWindow() : QbWindow(config().geometry.mainWindow) {
system->addSeparator();
system->addAction(system_power = new QbCheckAction("&Power", 0));
system->addAction(system_power = new CheckAction("&Power", 0));
system_reset = system->addAction("&Reset");
system_reset->setIcon(QIcon(":/16x16/view-refresh.png"));
@ -44,22 +46,22 @@ MainWindow::MainWindow() : QbWindow(config().geometry.mainWindow) {
system_port1 = system->addMenu("Controller Port &1");
system_port1->setIcon(QIcon(":/16x16/input-gaming.png"));
system_port1->addAction(system_port1_none = new QbRadioAction("&None", 0));
system_port1->addAction(system_port1_gamepad = new QbRadioAction("&Gamepad", 0));
system_port1->addAction(system_port1_asciipad = new QbRadioAction("&asciiPad", 0));
system_port1->addAction(system_port1_multitap = new QbRadioAction("&Multitap", 0));
system_port1->addAction(system_port1_mouse = new QbRadioAction("&Mouse", 0));
system_port1->addAction(system_port1_none = new RadioAction("&None", 0));
system_port1->addAction(system_port1_gamepad = new RadioAction("&Gamepad", 0));
system_port1->addAction(system_port1_asciipad = new RadioAction("&asciiPad", 0));
system_port1->addAction(system_port1_multitap = new RadioAction("&Multitap", 0));
system_port1->addAction(system_port1_mouse = new RadioAction("&Mouse", 0));
system_port2 = system->addMenu("Controller Port &2");
system_port2->setIcon(QIcon(":/16x16/input-gaming.png"));
system_port2->addAction(system_port2_none = new QbRadioAction("&None", 0));
system_port2->addAction(system_port2_gamepad = new QbRadioAction("&Gamepad", 0));
system_port2->addAction(system_port2_asciipad = new QbRadioAction("&asciiPad", 0));
system_port2->addAction(system_port2_multitap = new QbRadioAction("&Multitap", 0));
system_port2->addAction(system_port2_mouse = new QbRadioAction("&Mouse", 0));
system_port2->addAction(system_port2_superscope = new QbRadioAction("&Super Scope", 0));
system_port2->addAction(system_port2_justifier = new QbRadioAction("&Justifier", 0));
system_port2->addAction(system_port2_justifiers = new QbRadioAction("Two &Justifiers", 0));
system_port2->addAction(system_port2_none = new RadioAction("&None", 0));
system_port2->addAction(system_port2_gamepad = new RadioAction("&Gamepad", 0));
system_port2->addAction(system_port2_asciipad = new RadioAction("&asciiPad", 0));
system_port2->addAction(system_port2_multitap = new RadioAction("&Multitap", 0));
system_port2->addAction(system_port2_mouse = new RadioAction("&Mouse", 0));
system_port2->addAction(system_port2_superscope = new RadioAction("&Super Scope", 0));
system_port2->addAction(system_port2_justifier = new RadioAction("&Justifier", 0));
system_port2->addAction(system_port2_justifiers = new RadioAction("Two &Justifiers", 0));
#if !defined(PLATFORM_OSX)
system->addSeparator();
@ -74,24 +76,24 @@ MainWindow::MainWindow() : QbWindow(config().geometry.mainWindow) {
settings_videoMode = settings->addMenu("Video &Mode");
settings_videoMode->setIcon(QIcon(":/16x16/video-display.png"));
settings_videoMode->addAction(settings_videoMode_1x = new QbRadioAction("Scale &1x", 0));
settings_videoMode->addAction(settings_videoMode_1x = new RadioAction("Scale &1x", 0));
settings_videoMode->addAction(settings_videoMode_2x = new QbRadioAction("Scale &2x", 0));
settings_videoMode->addAction(settings_videoMode_2x = new RadioAction("Scale &2x", 0));
settings_videoMode->addAction(settings_videoMode_3x = new QbRadioAction("Scale &3x", 0));
settings_videoMode->addAction(settings_videoMode_3x = new RadioAction("Scale &3x", 0));
settings_videoMode->addAction(settings_videoMode_4x = new QbRadioAction("Scale &4x", 0));
settings_videoMode->addAction(settings_videoMode_4x = new RadioAction("Scale &4x", 0));
settings_videoMode->addAction(settings_videoMode_5x = new QbRadioAction("Scale &5x", 0));
settings_videoMode->addAction(settings_videoMode_5x = new RadioAction("Scale &5x", 0));
settings_videoMode->addSeparator();
settings_videoMode->addAction(settings_videoMode_correctAspectRatio = new QbCheckAction("Correct &Aspect Ratio", 0));
settings_videoMode->addAction(settings_videoMode_correctAspectRatio = new CheckAction("Correct &Aspect Ratio", 0));
settings_videoMode->addSeparator();
settings_videoMode->addAction(settings_videoMode_ntsc = new QbRadioAction("&NTSC", 0));
settings_videoMode->addAction(settings_videoMode_pal = new QbRadioAction("&PAL", 0));
settings_videoMode->addAction(settings_videoMode_ntsc = new RadioAction("&NTSC", 0));
settings_videoMode->addAction(settings_videoMode_pal = new RadioAction("&PAL", 0));
if(filter.opened()) {
settings_videoFilter = settings->addMenu("Video &Filter");
@ -101,44 +103,44 @@ MainWindow::MainWindow() : QbWindow(config().geometry.mainWindow) {
settings_videoFilter_configure->setIcon(QIcon(":/16x16/preferences-desktop.png"));
settings_videoFilter->addSeparator();
settings_videoFilter->addAction(settings_videoFilter_none = new QbRadioAction("&None", 0));
settings_videoFilter->addAction(settings_videoFilter_none = new RadioAction("&None", 0));
settings_videoFilter_list.add(settings_videoFilter_none);
lstring filterlist;
filterlist.split(";", filter.dl_supported());
for(unsigned i = 0; i < filterlist.size(); i++) {
QbRadioAction *action = new QbRadioAction(filterlist[i], 0);
RadioAction *action = new RadioAction(filterlist[i], 0);
settings_videoFilter->addAction(action);
settings_videoFilter_list.add(action);
}
}
settings->addAction(settings_smoothVideo = new QbCheckAction("&Smooth Video Output", 0));
settings->addAction(settings_smoothVideo = new CheckAction("&Smooth Video Output", 0));
settings->addSeparator();
settings->addAction(settings_muteAudio = new QbCheckAction("&Mute Audio Output", 0));
settings->addAction(settings_muteAudio = new CheckAction("&Mute Audio Output", 0));
settings->addSeparator();
settings_emulationSpeed = settings->addMenu("Emulation &Speed");
settings_emulationSpeed->setIcon(QIcon(":/16x16/appointment-new.png"));
settings_emulationSpeed->addAction(settings_emulationSpeed_slowest = new QbRadioAction("Slowest", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_slowest = new RadioAction("Slowest", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_slow = new QbRadioAction("Slow", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_slow = new RadioAction("Slow", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_normal = new QbRadioAction("Normal", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_normal = new RadioAction("Normal", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_fast = new QbRadioAction("Fast", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_fast = new RadioAction("Fast", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_fastest = new QbRadioAction("Fastest", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_fastest = new RadioAction("Fastest", 0));
settings_emulationSpeed->addSeparator();
settings_emulationSpeed->addAction(settings_emulationSpeed_syncVideo = new QbCheckAction("Sync &Video", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_syncVideo = new CheckAction("Sync &Video", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_syncAudio = new QbCheckAction("Sync &Audio", 0));
settings_emulationSpeed->addAction(settings_emulationSpeed_syncAudio = new CheckAction("Sync &Audio", 0));
settings_configuration = settings->addAction("&Configuration ...");
settings_configuration->setIcon(QIcon(":/16x16/preferences-desktop.png"));
@ -367,7 +369,8 @@ bool MainWindow::isActive() {
}
void MainWindow::loadCartridge() {
fileBrowser->loadCartridge();
fileBrowser->setWindowTitle("Load Cartridge");
fileBrowser->loadCartridge(FileBrowser::LoadDirect);
}
void MainWindow::loadBsxSlottedCartridge() {
@ -587,7 +590,7 @@ void MainWindow::showAbout() {
}
void MainWindow::closeEvent(QCloseEvent *event) {
QbWindow::closeEvent(event);
Window::closeEvent(event);
quit();
}

View File

@ -13,7 +13,7 @@ public:
void paintEvent(QPaintEvent*);
};
class MainWindow : public QbWindow {
class MainWindow : public Window {
Q_OBJECT
public:
@ -27,48 +27,48 @@ public:
QAction *system_loadSpecial_bsx;
QAction *system_loadSpecial_sufamiTurbo;
QAction *system_loadSpecial_superGameBoy;
QbCheckAction *system_power;
CheckAction *system_power;
QAction *system_reset;
QMenu *system_port1;
QbRadioAction *system_port1_none;
QbRadioAction *system_port1_gamepad;
QbRadioAction *system_port1_asciipad;
QbRadioAction *system_port1_multitap;
QbRadioAction *system_port1_mouse;
RadioAction *system_port1_none;
RadioAction *system_port1_gamepad;
RadioAction *system_port1_asciipad;
RadioAction *system_port1_multitap;
RadioAction *system_port1_mouse;
QMenu *system_port2;
QbRadioAction *system_port2_none;
QbRadioAction *system_port2_gamepad;
QbRadioAction *system_port2_asciipad;
QbRadioAction *system_port2_multitap;
QbRadioAction *system_port2_mouse;
QbRadioAction *system_port2_superscope;
QbRadioAction *system_port2_justifier;
QbRadioAction *system_port2_justifiers;
RadioAction *system_port2_none;
RadioAction *system_port2_gamepad;
RadioAction *system_port2_asciipad;
RadioAction *system_port2_multitap;
RadioAction *system_port2_mouse;
RadioAction *system_port2_superscope;
RadioAction *system_port2_justifier;
RadioAction *system_port2_justifiers;
QAction *system_exit;
QMenu *settings;
QMenu *settings_videoMode;
QbRadioAction *settings_videoMode_1x;
QbRadioAction *settings_videoMode_2x;
QbRadioAction *settings_videoMode_3x;
QbRadioAction *settings_videoMode_4x;
QbRadioAction *settings_videoMode_5x;
QbCheckAction *settings_videoMode_correctAspectRatio;
QbRadioAction *settings_videoMode_ntsc;
QbRadioAction *settings_videoMode_pal;
RadioAction *settings_videoMode_1x;
RadioAction *settings_videoMode_2x;
RadioAction *settings_videoMode_3x;
RadioAction *settings_videoMode_4x;
RadioAction *settings_videoMode_5x;
CheckAction *settings_videoMode_correctAspectRatio;
RadioAction *settings_videoMode_ntsc;
RadioAction *settings_videoMode_pal;
QMenu *settings_videoFilter;
QAction *settings_videoFilter_configure;
QbRadioAction *settings_videoFilter_none;
array<QbRadioAction*> settings_videoFilter_list;
QbCheckAction *settings_smoothVideo;
QbCheckAction *settings_muteAudio;
RadioAction *settings_videoFilter_none;
array<RadioAction*> settings_videoFilter_list;
CheckAction *settings_smoothVideo;
CheckAction *settings_muteAudio;
QMenu *settings_emulationSpeed;
QbRadioAction *settings_emulationSpeed_slowest;
QbRadioAction *settings_emulationSpeed_slow;
QbRadioAction *settings_emulationSpeed_normal;
QbRadioAction *settings_emulationSpeed_fast;
QbRadioAction *settings_emulationSpeed_fastest;
QbCheckAction *settings_emulationSpeed_syncVideo;
QbCheckAction *settings_emulationSpeed_syncAudio;
RadioAction *settings_emulationSpeed_slowest;
RadioAction *settings_emulationSpeed_slow;
RadioAction *settings_emulationSpeed_normal;
RadioAction *settings_emulationSpeed_fast;
RadioAction *settings_emulationSpeed_fastest;
CheckAction *settings_emulationSpeed_syncVideo;
CheckAction *settings_emulationSpeed_syncAudio;
QAction *settings_configuration;
QMenu *tools;
QMenu *tools_movies;

View File

@ -73,9 +73,6 @@ Configuration::Configuration() {
attach(path.current.movie = "", "path.current.movie");
attach(path.current.shader = "", "path.current.shader");
attach(path.current.cartridge = "", "path.current.cartridge");
attach(path.current.bsx = "", "path.current.bsx");
attach(path.current.st = "", "path.current.st");
attach(path.current.sgb = "", "path.current.sgb");
attach(path.current.filter = 0, "path.current.filter");
video.context = &video.windowed;
@ -125,7 +122,6 @@ Configuration::Configuration() {
attach(geometry.loaderWindow = "", "geometry.loaderWindow");
attach(geometry.htmlViewerWindow = "", "geometry.htmlViewerWindow");
attach(geometry.aboutWindow = "", "geometry.aboutWindow");
attach(geometry.diskBrowser = "", "geometry.diskBrowser");
attach(geometry.fileBrowser = "", "geometry.fileBrowser");
attach(geometry.folderCreator = "", "geometry.folderCreator");
attach(geometry.settingsWindow = "", "geometry.settingsWindow");

View File

@ -31,7 +31,7 @@ public:
string fragmentShader, vertexShader;
struct Current {
string folder, movie, shader, cartridge, bsx, st, sgb;
string folder, movie, shader, cartridge;
unsigned filter; //current active filter for "Load Cartridge"
} current;
} path;
@ -74,7 +74,6 @@ public:
string loaderWindow;
string htmlViewerWindow;
string aboutWindow;
string diskBrowser;
string fileBrowser;
string folderCreator;
string settingsWindow;

View File

@ -5,7 +5,6 @@
#include "debugger.moc"
Debugger *debugger;
#include "hexeditor.cpp"
#include "tracer.cpp"
#include "tools/disassembler.cpp"
@ -20,9 +19,11 @@ Debugger *debugger;
#include "misc/debugger-options.cpp"
Debugger::Debugger() : QbWindow(config().geometry.debugger) {
Debugger::Debugger() {
setObjectName("debugger");
setWindowTitle("Debugger");
setGeometryString(&config().geometry.debugger);
application.windowList.add(this);
layout = new QHBoxLayout;
layout->setMargin(Style::WindowMargin);

View File

@ -1,4 +1,4 @@
class Debugger : public QbWindow {
class Debugger : public Window {
Q_OBJECT
public:

View File

@ -1,120 +0,0 @@
#include "hexeditor.moc"
void HexEditor::keyPressEvent(QKeyEvent *event) {
QTextCursor cursor = textCursor();
unsigned x = cursor.position() % 56;
unsigned y = cursor.position() / 56;
int hexCode = -1;
switch(event->key()) {
case Qt::Key_0: hexCode = 0; break;
case Qt::Key_1: hexCode = 1; break;
case Qt::Key_2: hexCode = 2; break;
case Qt::Key_3: hexCode = 3; break;
case Qt::Key_4: hexCode = 4; break;
case Qt::Key_5: hexCode = 5; break;
case Qt::Key_6: hexCode = 6; break;
case Qt::Key_7: hexCode = 7; break;
case Qt::Key_8: hexCode = 8; break;
case Qt::Key_9: hexCode = 9; break;
case Qt::Key_A: hexCode = 10; break;
case Qt::Key_B: hexCode = 11; break;
case Qt::Key_C: hexCode = 12; break;
case Qt::Key_D: hexCode = 13; break;
case Qt::Key_E: hexCode = 14; break;
case Qt::Key_F: hexCode = 15; break;
}
if(cursor.hasSelection() == false && hexCode != -1) {
bool cursorOffsetValid = (x >= 8 && ((x - 8) % 3) != 2);
if(cursorOffsetValid) {
bool nibble = (x - 8) % 3; //0 = top nibble, 1 = bottom nibble
unsigned cursorOffset = y * 16 + ((x - 8) / 3);
unsigned effectiveOffset = hexOffset + cursorOffset;
if(effectiveOffset >= hexSize) effectiveOffset %= hexSize;
uint8 data = reader(effectiveOffset);
data &= (nibble == 0 ? 0x0f : 0xf0);
data |= (nibble == 0 ? (hexCode << 4) : (hexCode << 0));
writer(effectiveOffset, data);
update();
cursor.setPosition(y * 56 + x + 1); //advance cursor
setTextCursor(cursor);
}
} else {
//allow navigation keys to move cursor, but block text input
setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
QTextEdit::keyPressEvent(event);
setTextInteractionFlags(Qt::TextEditorInteraction);
}
}
void HexEditor::setOffset(unsigned newOffset) {
slotLock = true;
hexOffset = newOffset;
scrollbar->setSliderPosition(hexOffset / 16);
slotLock = false;
}
void HexEditor::setSize(unsigned newSize) {
hexSize = newSize;
scrollbar->setRange(0, hexSize / 16 - 16);
}
void HexEditor::update() {
string output;
char temp[256];
unsigned offset = hexOffset;
for(unsigned y = 0; y < 16; y++) {
if(offset >= hexSize) break;
sprintf(temp, "%.6x", offset & 0xffffff);
output << "<font color='#606060'>" << temp << "</font>&nbsp;&nbsp;";
for(unsigned x = 0; x < 16; x++) {
if(offset >= hexSize) break;
sprintf(temp, "%.2x", reader(offset++));
output << "<font color='" << ((x & 1) ? "#000080" : "#0000ff") << "'>" << temp << "</font>";
if(x != 15) output << "&nbsp;";
}
if(y != 15) output << "<br>";
}
setHtml(output);
}
void HexEditor::sliderMoved() {
if(slotLock) return;
unsigned offset = scrollbar->sliderPosition();
hexOffset = offset * 16;
update();
}
HexEditor::HexEditor() {
hexOffset = 0;
hexSize = 0;
QFont font(Style::Monospace);
setFont(font);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setMinimumWidth((57 + 2) * fontMetrics().width(' '));
setMinimumHeight((16 + 1) * fontMetrics().height());
layout = new QHBoxLayout;
layout->setAlignment(Qt::AlignRight);
layout->setMargin(0);
layout->setSpacing(0);
setLayout(layout);
scrollbar = new QScrollBar(Qt::Vertical);
scrollbar->setSingleStep(1);
scrollbar->setPageStep(16);
layout->addWidget(scrollbar);
slotLock = false;
connect(scrollbar, SIGNAL(actionTriggered(int)), this, SLOT(sliderMoved()));
}

View File

@ -1,25 +0,0 @@
class HexEditor : public QTextEdit {
Q_OBJECT
public:
QHBoxLayout *layout;
QScrollBar *scrollbar;
function<uint8 (unsigned)> reader;
function<void (unsigned, uint8)> writer;
void keyPressEvent(QKeyEvent*);
unsigned hexOffset;
unsigned hexSize;
void setOffset(unsigned newOffset);
void setSize(unsigned newSize);
void update();
HexEditor();
private slots:
void sliderMoved();
private:
bool slotLock;
};

View File

@ -1,9 +1,11 @@
#include "debugger-options.moc"
DebuggerOptions *debuggerOptions;
DebuggerOptions::DebuggerOptions() : QbWindow(config().geometry.debuggerOptions) {
DebuggerOptions::DebuggerOptions() {
setObjectName("debugger-options");
setWindowTitle("Debugger Options");
setGeometryString(&config().geometry.debuggerOptions);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);

View File

@ -1,4 +1,4 @@
class DebuggerOptions : public QbWindow {
class DebuggerOptions : public Window {
Q_OBJECT
public:

View File

@ -2,7 +2,7 @@
CgramViewer *cgramViewer;
void CgramViewer::show() {
QbWindow::show();
Window::show();
refresh();
}
@ -75,11 +75,13 @@ void CgramViewer::setSelection(unsigned index) {
refresh();
}
CgramViewer::CgramViewer() : QbWindow(config().geometry.cgramViewer) {
currentSelection = 0;
CgramViewer::CgramViewer() {
setObjectName("cgram-viewer");
setWindowTitle("Palette Viewer");
setGeometryString(&config().geometry.cgramViewer);
application.windowList.add(this);
currentSelection = 0;
layout = new QHBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);

View File

@ -1,4 +1,4 @@
class CgramViewer : public QbWindow {
class CgramViewer : public Window {
Q_OBJECT
public:

View File

@ -1,9 +1,11 @@
#include "layer-toggle.moc"
LayerToggle *layerToggle;
LayerToggle::LayerToggle() : QbWindow(config().geometry.layerToggle) {
LayerToggle::LayerToggle() {
setObjectName("layer-toggle");
setWindowTitle("S-PPU Layer Toggle");
setGeometryString(&config().geometry.layerToggle);
application.windowList.add(this);
layout = new QGridLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);

View File

@ -1,4 +1,4 @@
class LayerToggle : public QbWindow {
class LayerToggle : public Window {
Q_OBJECT
public:

View File

@ -2,7 +2,7 @@
OamViewer *oamViewer;
void OamViewer::show() {
QbWindow::show();
Window::show();
refresh();
}
@ -62,9 +62,11 @@ void OamViewer::autoUpdate() {
if(autoUpdateBox->isChecked()) refresh();
}
OamViewer::OamViewer() : QbWindow(config().geometry.oamViewer) {
OamViewer::OamViewer() {
setObjectName("oam-viewer");
setWindowTitle("Sprite Viewer");
setGeometryString(&config().geometry.oamViewer);
application.windowList.add(this);
layout = new QHBoxLayout;
layout->setAlignment(Qt::AlignLeft);

View File

@ -1,4 +1,4 @@
class OamViewer : public QbWindow {
class OamViewer : public Window {
Q_OBJECT
public:

View File

@ -1,9 +1,11 @@
#include "vram-viewer.moc"
VramViewer *vramViewer;
VramViewer::VramViewer() : QbWindow(config().geometry.vramViewer) {
VramViewer::VramViewer() {
setObjectName("vram-viewer");
setWindowTitle("Video RAM Viewer");
setGeometryString(&config().geometry.vramViewer);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);
@ -54,7 +56,7 @@ void VramViewer::autoUpdate() {
}
void VramViewer::show() {
QbWindow::show();
Window::show();
refresh();
}

View File

@ -1,4 +1,4 @@
class VramViewer : public QbWindow {
class VramViewer : public Window {
Q_OBJECT
public:

View File

@ -61,9 +61,11 @@ void BreakpointItem::toggle() {
}
}
BreakpointEditor::BreakpointEditor() : QbWindow(config().geometry.breakpointEditor) {
BreakpointEditor::BreakpointEditor() {
setObjectName("breakpoint-editor");
setWindowTitle("Breakpoint Editor");
setGeometryString(&config().geometry.breakpointEditor);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setSizeConstraint(QLayout::SetFixedSize);

View File

@ -17,7 +17,7 @@ private:
const unsigned id;
};
class BreakpointEditor : public QbWindow {
class BreakpointEditor : public Window {
Q_OBJECT
public:

View File

@ -31,9 +31,11 @@ SMPDisassembler::SMPDisassembler() {
layout->addWidget(view);
}
Disassembler::Disassembler() : QbWindow(config().geometry.disassembler) {
Disassembler::Disassembler() {
setObjectName("disassembler");
setWindowTitle("Disassembler");
setGeometryString(&config().geometry.disassembler);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);

View File

@ -12,7 +12,7 @@ public:
SMPDisassembler();
};
class Disassembler : public QbWindow {
class Disassembler : public Window {
Q_OBJECT
public:

View File

@ -1,9 +1,11 @@
#include "memory.moc"
MemoryEditor *memoryEditor;
MemoryEditor::MemoryEditor() : QbWindow(config().geometry.memoryEditor) {
MemoryEditor::MemoryEditor() {
setObjectName("memory-editor");
setWindowTitle("Memory Editor");
setGeometryString(&config().geometry.memoryEditor);
application.windowList.add(this);
layout = new QHBoxLayout;
layout->setMargin(Style::WindowMargin);
@ -13,6 +15,9 @@ MemoryEditor::MemoryEditor() : QbWindow(config().geometry.memoryEditor) {
editor = new HexEditor;
editor->reader = bind(&MemoryEditor::reader, this);
editor->writer = bind(&MemoryEditor::writer, this);
editor->setFont(QFont(Style::Monospace));
editor->setMinimumWidth((HexEditor::LineWidth + 3) * editor->fontMetrics().width(' '));
editor->setMinimumHeight((16 + 1) * editor->fontMetrics().height());
editor->setSize(16 * 1024 * 1024);
memorySource = SNES::Debugger::CPUBus;
layout->addWidget(editor);
@ -58,13 +63,12 @@ MemoryEditor::MemoryEditor() : QbWindow(config().geometry.memoryEditor) {
}
void MemoryEditor::autoUpdate() {
if(SNES::cartridge.loaded() && autoUpdateBox->isChecked()) editor->update();
if(SNES::cartridge.loaded() && autoUpdateBox->isChecked()) editor->refresh();
}
void MemoryEditor::synchronize() {
if(SNES::cartridge.loaded() == false) {
editor->setHtml("");
editor->scrollbar->setEnabled(false);
source->setEnabled(false);
addr->setEnabled(false);
autoUpdateBox->setEnabled(false);
@ -72,7 +76,6 @@ void MemoryEditor::synchronize() {
exportButton->setEnabled(false);
importButton->setEnabled(false);
} else {
editor->scrollbar->setEnabled(true);
source->setEnabled(true);
addr->setEnabled(true);
autoUpdateBox->setEnabled(true);
@ -83,7 +86,7 @@ void MemoryEditor::synchronize() {
}
void MemoryEditor::show() {
QbWindow::show();
Window::show();
refresh();
}
@ -97,14 +100,14 @@ void MemoryEditor::sourceChanged(int index) {
}
editor->setOffset(strhex(addr->text().toUtf8().data()));
editor->update();
editor->refresh();
}
void MemoryEditor::refresh() {
if(SNES::cartridge.loaded() == false) {
editor->setHtml("");
} else {
editor->update();
editor->refresh();
}
}

View File

@ -1,4 +1,4 @@
class MemoryEditor : public QbWindow {
class MemoryEditor : public Window {
Q_OBJECT
public:

View File

@ -52,7 +52,7 @@ void PropertiesViewer::refresh() {
}
void PropertiesViewer::show() {
QbWindow::show();
Window::show();
refresh();
}
@ -60,9 +60,11 @@ void PropertiesViewer::autoUpdate() {
if(autoUpdateBox->isChecked()) refresh();
}
PropertiesViewer::PropertiesViewer() : QbWindow(config().geometry.propertiesViewer) {
PropertiesViewer::PropertiesViewer() {
setObjectName("properties-viewer");
setWindowTitle("Properties");
setGeometryString(&config().geometry.propertiesViewer);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);

View File

@ -14,7 +14,7 @@ private:
SNES::ChipDebugger &object;
};
class PropertiesViewer : public QbWindow {
class PropertiesViewer : public Window {
Q_OBJECT
public:

View File

@ -208,7 +208,6 @@ void InputMapper::poll() {
for(unsigned i = 0; i < Scancode::Limit; i++) {
if(state(i) != previousState(i)) {
utility.inputEvent(i);
diskBrowser->inputEvent(i);
inputSettingsWindow->inputEvent(i);
}
}

View File

@ -4,7 +4,8 @@ namespace UserInterfaceSystem {
struct LoadCartridge : HotkeyInput {
void pressed() {
diskBrowser->loadCartridge();
fileBrowser->setWindowTitle("Load Cartridge");
fileBrowser->loadCartridge(FileBrowser::LoadDirect);
}
LoadCartridge() : HotkeyInput("Load Cartridge", "input.userInterface.system.loadCartridge") {

View File

@ -22,7 +22,11 @@ const char defaultStylesheet[] =
" background: #000000;"
"}\n";
#include "check-action.moc"
#include "file-dialog.moc"
#include "hex-editor.moc"
#include "radio-action.moc"
#include "window.moc"
#include "application/application.cpp"
#include "link/filter.cpp"

View File

@ -3,14 +3,19 @@
Movie movie;
void Movie::chooseFile() {
diskBrowser->chooseFile(
bind(&Movie::play, this),
config().path.current.movie,
"Select Movie"
);
fileBrowser->onChange = (void*)0;
fileBrowser->onActivate = bind(&Movie::play, this);
fileBrowser->onChange = bind(&Movie::play, this);
fileBrowser->setWindowTitle("Select Movie");
fileBrowser->setPath(config().path.current.movie);
fileBrowser->setNameFilters("bsnes Movies (*.bsv)");
fileBrowser->showLoad();
}
void Movie::play(string filename) {
void Movie::play(const string &filename) {
if(QDir(filename).exists()) return; //ignore folders
config().path.current.movie = dir(filename);
if(Movie::state != Inactive) stop();
if(fp.open(filename, file::mode_read)) {

View File

@ -3,7 +3,7 @@ public:
enum State { Inactive, Playback, Record } state;
void chooseFile();
void play(string filename);
void play(const string &filename);
void record();
void stop();

View File

@ -35,6 +35,7 @@ PathSettingWidget::PathSettingWidget(string &pathValue_, const char *labelText,
void PathSettingWidget::acceptPath(const string &newPath) {
fileBrowser->close();
pathValue = string() << newPath << "/";
config().path.current.folder = dir(pathValue);
updatePath();
}

View File

@ -50,32 +50,42 @@ void PixelShaderWindow::synchronize() {
}
void PixelShaderWindow::selectFragmentShader() {
diskBrowser->chooseFile(
bind(&PixelShaderWindow::assignFragmentShader, this),
config().path.current.shader,
"Select Fragment Shader"
);
fileBrowser->onChange = (void*)0;
fileBrowser->onActivate = bind(&PixelShaderWindow::assignFragmentShader, this);
fileBrowser->onAccept = bind(&PixelShaderWindow::assignFragmentShader, this);
fileBrowser->setWindowTitle("Select Fragment Shader");
fileBrowser->setPath(config().path.current.shader);
fileBrowser->setNameFilters("All files (*)");
fileBrowser->showLoad();
}
void PixelShaderWindow::selectVertexShader() {
diskBrowser->chooseFile(
bind(&PixelShaderWindow::assignVertexShader, this),
config().path.current.shader,
"Select Vertex Shader"
);
fileBrowser->onChange = (void*)0;
fileBrowser->onActivate = bind(&PixelShaderWindow::assignVertexShader, this);
fileBrowser->onAccept = bind(&PixelShaderWindow::assignVertexShader, this);
fileBrowser->setWindowTitle("Select Vertex Shader");
fileBrowser->setPath(config().path.current.shader);
fileBrowser->setNameFilters("All files (*)");
fileBrowser->showLoad();
}
void PixelShaderWindow::defaultFragmentShader() { assignFragmentShader(""); }
void PixelShaderWindow::defaultVertexShader() { assignVertexShader(""); }
void PixelShaderWindow::assignFragmentShader(string filename) {
config().path.fragmentShader = filename;
synchronize();
utility.updatePixelShader();
void PixelShaderWindow::assignFragmentShader(const string &filename) {
if(filename == "" || QDir(filename).exists() == false) {
config().path.fragmentShader = filename;
if(filename != "") config().path.current.shader = dir(filename);
synchronize();
utility.updatePixelShader();
}
}
void PixelShaderWindow::assignVertexShader(string filename) {
config().path.vertexShader = filename;
synchronize();
utility.updatePixelShader();
void PixelShaderWindow::assignVertexShader(const string &filename) {
if(filename == "" || QDir(filename).exists() == false) {
config().path.vertexShader = filename;
if(filename != "") config().path.current.shader = dir(filename);
synchronize();
utility.updatePixelShader();
}
}

View File

@ -22,8 +22,8 @@ public slots:
void defaultFragmentShader();
void defaultVertexShader();
void assignFragmentShader(string);
void assignVertexShader(string);
void assignFragmentShader(const string&);
void assignVertexShader(const string&);
};
extern PixelShaderWindow *pixelShaderWindow;

View File

@ -10,10 +10,12 @@
#include "settings.moc"
SettingsWindow *settingsWindow;
SettingsWindow::SettingsWindow() : QbWindow(config().geometry.settingsWindow) {
SettingsWindow::SettingsWindow() {
setObjectName("settings-window");
setWindowTitle("Configuration Settings");
resize(600, 360);
setGeometryString(&config().geometry.settingsWindow);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);

View File

@ -1,4 +1,4 @@
class SettingsWindow : public QbWindow {
class SettingsWindow : public Window {
Q_OBJECT
public:

View File

@ -7,10 +7,12 @@ ToolsWindow *toolsWindow;
#include "cheatfinder.cpp"
#include "statemanager.cpp"
ToolsWindow::ToolsWindow() : QbWindow(config().geometry.toolsWindow) {
ToolsWindow::ToolsWindow() {
setObjectName("tools-window");
setWindowTitle("Tools");
resize(600, 360);
setGeometryString(&config().geometry.toolsWindow);
application.windowList.add(this);
layout = new QVBoxLayout;
layout->setMargin(Style::WindowMargin);

View File

@ -1,4 +1,4 @@
class ToolsWindow : public QbWindow {
class ToolsWindow : public Window {
Q_OBJECT
public:

View File

@ -15,7 +15,11 @@
#include <nall/config.hpp>
#include <nall/input.hpp>
#include <nall/ups.hpp>
#include <nall/qt/check-action.moc.hpp>
#include <nall/qt/file-dialog.moc.hpp>
#include <nall/qt/hex-editor.moc.hpp>
#include <nall/qt/radio-action.moc.hpp>
#include <nall/qt/window.moc.hpp>
using namespace nall;
#include <ruby/ruby.hpp>
@ -27,7 +31,6 @@ using namespace ruby;
#include "application/application.moc.hpp"
#include "base/about.moc.hpp"
#include "base/diskbrowser.moc.hpp"
#include "base/filebrowser.moc.hpp"
#include "base/htmlviewer.moc.hpp"
#include "base/loader.moc.hpp"
@ -37,7 +40,6 @@ using namespace ruby;
#if defined(DEBUGGER)
#include "debugger/debugger.moc.hpp"
#include "debugger/hexeditor.moc.hpp"
#include "debugger/tracer.moc.hpp"
#include "debugger/tools/disassembler.moc.hpp"

View File

@ -1,5 +1,5 @@
void Utility::modifySystemState(system_state_t systemState) {
diskBrowser->hide(); //avoid edge case oddities (eg movie playback window still open from previous game)
fileBrowser->close(); //avoid edge case oddities (eg movie playback window still open from previous game)
state.resetHistory(); //do not allow rewinding past a destructive system action
movie.stop(); //movies cannot continue to record after destructive system actions