diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9821e1b8..0cf16cc3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -430,6 +430,7 @@ set(SRC_DRIVERS_SDL ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/HotKeyConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/PaletteConf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MoviePlay.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MovieOptions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/LuaControl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/CheatsConf.cpp diff --git a/src/drivers/Qt/ConsoleDebugger.cpp b/src/drivers/Qt/ConsoleDebugger.cpp index 111aa93c..a01200f2 100644 --- a/src/drivers/Qt/ConsoleDebugger.cpp +++ b/src/drivers/Qt/ConsoleDebugger.cpp @@ -2734,15 +2734,45 @@ QAsmView::QAsmView(QWidget *parent) { QPalette pal; QColor fg("black"), bg("white"); + QColor c; + + useDarkTheme = false; font.setFamily("Courier New"); font.setStyle( QFont::StyleNormal ); font.setStyleHint( QFont::Monospace ); pal = this->palette(); - pal.setColor(QPalette::Base , bg ); - pal.setColor(QPalette::Background, bg ); - pal.setColor(QPalette::WindowText, fg ); + + //c = pal.color(QPalette::Base); + //printf("Base: R:%i G:%i B:%i \n", c.red(), c.green(), c.blue() ); + + //c = pal.color(QPalette::Background); + //printf("BackGround: R:%i G:%i B:%i \n", c.red(), c.green(), c.blue() ); + + // Figure out if we are using a light or dark theme by checking the + // default window text grayscale color. If more white, then we will + // use white text on black background, else we do the opposite. + c = pal.color(QPalette::WindowText); + + if ( qGray( c.red(), c.green(), c.blue() ) > 128 ) + { + useDarkTheme = true; + } + //printf("WindowText: R:%i G:%i B:%i \n", c.red(), c.green(), c.blue() ); + + if ( useDarkTheme ) + { + pal.setColor(QPalette::Base , fg ); + pal.setColor(QPalette::Background, fg ); + pal.setColor(QPalette::WindowText, bg ); + } + else + { + pal.setColor(QPalette::Base , bg ); + pal.setColor(QPalette::Background, bg ); + pal.setColor(QPalette::WindowText, fg ); + } this->parent = (ConsoleDebugger*)parent; this->setPalette(pal); @@ -3047,6 +3077,8 @@ void QAsmView::paintEvent(QPaintEvent *event) { int x,y,l, row, nrow, selAddr; QPainter painter(this); + QColor black("black"); + bool forceDarkColor = false; painter.setFont(font); viewWidth = event->rect().width(); @@ -3087,13 +3119,15 @@ void QAsmView::paintEvent(QPaintEvent *event) { x = -pxLineXScroll; l = lineOffset + row; - painter.setPen( this->palette().color(QPalette::WindowText)); + + forceDarkColor = false; if ( asmPC != NULL ) { if ( l == asmPC->line ) { painter.fillRect( 0, y - pxLineSpacing + pxLineLead, viewWidth, pxLineSpacing, QColor("pink") ); + forceDarkColor = true; } } @@ -3102,6 +3136,16 @@ void QAsmView::paintEvent(QPaintEvent *event) if ( asmEntry[l]->type != dbg_asm_entry_t::ASM_TEXT ) { painter.fillRect( 0, y - pxLineSpacing + pxLineLead, viewWidth, pxLineSpacing, QColor("light blue") ); + forceDarkColor = true; + } + + if ( forceDarkColor ) + { + painter.setPen( black ); + } + else + { + painter.setPen( this->palette().color(QPalette::WindowText)); } painter.drawText( x, y, tr(asmEntry[l]->text.c_str()) ); diff --git a/src/drivers/Qt/ConsoleDebugger.h b/src/drivers/Qt/ConsoleDebugger.h index 8b71c345..3e5e97e4 100644 --- a/src/drivers/Qt/ConsoleDebugger.h +++ b/src/drivers/Qt/ConsoleDebugger.h @@ -148,6 +148,7 @@ class QAsmView : public QWidget dbg_asm_entry_t *asmPC; std::vector asmEntry; + bool useDarkTheme; bool displayROMoffsets; bool symbolicDebugEnable; bool registerNameEnable; diff --git a/src/drivers/Qt/ConsoleUtilities.cpp b/src/drivers/Qt/ConsoleUtilities.cpp index e0ffe679..b4a345d4 100644 --- a/src/drivers/Qt/ConsoleUtilities.cpp +++ b/src/drivers/Qt/ConsoleUtilities.cpp @@ -198,6 +198,12 @@ fceuDecIntValidtor::fceuDecIntValidtor( int min, int max, QObject *parent) this->max = max; } //--------------------------------------------------------------------------- +void fceuDecIntValidtor::setMinMax( int min, int max) +{ + this->min = min; + this->max = max; +} +//--------------------------------------------------------------------------- QValidator::State fceuDecIntValidtor::validate(QString &input, int &pos) const { int i, v; diff --git a/src/drivers/Qt/ConsoleUtilities.h b/src/drivers/Qt/ConsoleUtilities.h index b6720f32..2a99ade9 100644 --- a/src/drivers/Qt/ConsoleUtilities.h +++ b/src/drivers/Qt/ConsoleUtilities.h @@ -1,4 +1,7 @@ // ConsoleUtilities.h + +#pragma once + #include int getDirFromFile( const char *path, char *dir ); @@ -16,6 +19,8 @@ class fceuDecIntValidtor : public QValidator fceuDecIntValidtor( int min, int max, QObject *parent); QValidator::State validate(QString &input, int &pos) const; + + void setMinMax( int min, int max ); private: int min; int max; diff --git a/src/drivers/Qt/ConsoleWindow.cpp b/src/drivers/Qt/ConsoleWindow.cpp index f34661a1..890d656e 100644 --- a/src/drivers/Qt/ConsoleWindow.cpp +++ b/src/drivers/Qt/ConsoleWindow.cpp @@ -24,6 +24,7 @@ #include "Qt/HotKeyConf.h" #include "Qt/PaletteConf.h" #include "Qt/GuiConf.h" +#include "Qt/MoviePlay.h" #include "Qt/MovieOptions.h" #include "Qt/LuaControl.h" #include "Qt/CheatsConf.h" @@ -660,10 +661,10 @@ void consoleWin_t::createMainMenu(void) // Movie movieMenu = menuBar()->addMenu(tr("Movie")); - // Movie -> Open - openMovAct = new QAction(tr("Open"), this); + // Movie -> Play + openMovAct = new QAction(tr("Play"), this); openMovAct->setShortcut( QKeySequence(tr("Shift+F7"))); - openMovAct->setStatusTip(tr("Open Movie File")); + openMovAct->setStatusTip(tr("Play Movie File")); connect(openMovAct, SIGNAL(triggered()), this, SLOT(openMovie(void)) ); movieMenu->addAction(openMovAct); @@ -1606,77 +1607,11 @@ void consoleWin_t::emuSetFrameAdvDelay(void) void consoleWin_t::openMovie(void) { - int ret, useNativeFileDialogVal; - QString filename; - std::string last; - char dir[512]; - char replayReadOnlySetting; - QFileDialog dialog(this, tr("Open FM2 Movie") ); + MoviePlayDialog_t *win; - dialog.setFileMode(QFileDialog::ExistingFile); + win = new MoviePlayDialog_t(this); - dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)")); - - dialog.setViewMode(QFileDialog::List); - dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden ); - dialog.setLabelText( QFileDialog::Accept, tr("Open") ); - - g_config->getOption ("SDL.LastOpenMovie", &last ); - - getDirFromFile( last.c_str(), dir ); - - dialog.setDirectory( tr(dir) ); - - // Check config option to use native file dialog or not - g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal); - - dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal); - - dialog.show(); - ret = dialog.exec(); - - if ( ret ) - { - QStringList fileList; - fileList = dialog.selectedFiles(); - - if ( fileList.size() > 0 ) - { - filename = fileList[0]; - } - } - - if ( filename.isNull() ) - { - return; - } - qDebug() << "selected file path : " << filename.toUtf8(); - - int pauseframe; - g_config->getOption ("SDL.PauseFrame", &pauseframe); - g_config->setOption ("SDL.PauseFrame", 0); - - FCEUI_printf ("Playing back movie located at %s\n", filename.toStdString().c_str() ); - - if (suggestReadOnlyReplay) - { - replayReadOnlySetting = true; - } - else - { - replayReadOnlySetting = FCEUI_GetMovieToggleReadOnly(); - } - - fceuWrapperLock(); - if (FCEUI_LoadMovie( filename.toStdString().c_str(), - replayReadOnlySetting, pauseframe ? pauseframe : false) == false) - { - printf("Error: Could not open movie file: %s \n", filename.toStdString().c_str() ); - } - g_config->setOption ("SDL.LastOpenMovie", filename.toStdString().c_str() ); - fceuWrapperUnLock(); - - return; + win->show(); } void consoleWin_t::stopMovie(void) diff --git a/src/drivers/Qt/MoviePlay.cpp b/src/drivers/Qt/MoviePlay.cpp new file mode 100644 index 00000000..97cf10a8 --- /dev/null +++ b/src/drivers/Qt/MoviePlay.cpp @@ -0,0 +1,559 @@ +// MoviePlay.cpp +// +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "../../fceu.h" +#include "../../movie.h" + +#include "Qt/main.h" +#include "Qt/dface.h" +#include "Qt/input.h" +#include "Qt/config.h" +#include "Qt/keyscan.h" +#include "Qt/fceuWrapper.h" +#include "Qt/ConsoleUtilities.h" +#include "Qt/MoviePlay.h" + +//---------------------------------------------------------------------------- +MoviePlayDialog_t::MoviePlayDialog_t(QWidget *parent) + : QDialog( parent ) +{ + QVBoxLayout *mainLayout, *vbox; + QHBoxLayout *hbox; + QGroupBox *frame; + QGridLayout *grid; + QLabel *lbl; + QPushButton *okButton, *cancelButton; + bool replayReadOnlySetting; + + setWindowTitle("Movie Play"); + + mainLayout = new QVBoxLayout(); + hbox = new QHBoxLayout(); + + lbl = new QLabel( tr("File:") ); + movSelBox = new QComboBox(); + movBrowseBtn = new QPushButton( tr("Browse") ); + + hbox->addWidget( lbl, 1 ); + hbox->addWidget( movSelBox, 100 ); + hbox->addWidget( movBrowseBtn, 1 ); + + mainLayout->addLayout( hbox ); + + frame = new QGroupBox( tr("Parameters:") ); + vbox = new QVBoxLayout(); + hbox = new QHBoxLayout(); + + frame->setLayout( vbox ); + + openReadOnly = new QCheckBox( tr("Open Read-Only") ); + pauseAtFrame = new QCheckBox( tr("Pause Movie At Frame") ); + + validator = new fceuDecIntValidtor( 0, 100000000, this ); + + pauseAtFrameEntry = new QLineEdit(); + + pauseAtFrameEntry->setValidator( validator ); + + vbox->addWidget( openReadOnly ); + vbox->addLayout( hbox ); + hbox->addWidget( pauseAtFrame ); + hbox->addWidget( pauseAtFrameEntry ); + + mainLayout->addWidget( frame ); + + grid = new QGridLayout(); + grid->setColumnStretch( 0, 1 ); + grid->setColumnStretch( 1, 10 ); + + mainLayout->addLayout( grid ); + + movLenLbl = new QLabel(); + movFramesLbl = new QLabel(); + recCountLbl = new QLabel(); + recFromLbl = new QLabel(); + romUsedLbl = new QLabel(); + romCsumLbl = new QLabel(); + curCsumLbl = new QLabel(); + emuUsedLbl = new QLabel(); + palUsedLbl = new QLabel(); + newppuUsedLbl = new QLabel(); + + grid->addWidget( new QLabel( tr("Length:") ) , 0, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("Frames:") ) , 1, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("Record Count:") ) , 2, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("Recorded From:") ) , 3, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("ROM Used:") ) , 4, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("ROM Checksum:") ) , 5, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("Current ROM Sum:") ) , 6, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("Emulator Used:") ) , 7, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("PAL:") ) , 8, 0, Qt::AlignRight ); + grid->addWidget( new QLabel( tr("New PPU:") ) , 9, 0, Qt::AlignRight ); + + grid->addWidget( movLenLbl , 0, 1, Qt::AlignLeft ); + grid->addWidget( movFramesLbl , 1, 1, Qt::AlignLeft ); + grid->addWidget( recCountLbl , 2, 1, Qt::AlignLeft ); + grid->addWidget( recFromLbl , 3, 1, Qt::AlignLeft ); + grid->addWidget( romUsedLbl , 4, 1, Qt::AlignLeft ); + grid->addWidget( romCsumLbl , 5, 1, Qt::AlignLeft ); + grid->addWidget( curCsumLbl , 6, 1, Qt::AlignLeft ); + grid->addWidget( emuUsedLbl , 7, 1, Qt::AlignLeft ); + grid->addWidget( palUsedLbl , 8, 1, Qt::AlignLeft ); + grid->addWidget( newppuUsedLbl , 9, 1, Qt::AlignLeft ); + + hbox = new QHBoxLayout(); + okButton = new QPushButton( tr("Play") ); + cancelButton = new QPushButton( tr("Cancel") ); + hbox->addWidget( cancelButton ); + hbox->addWidget( okButton ); + okButton->setDefault(true); + mainLayout->addLayout( hbox ); + + setLayout( mainLayout ); + + connect( cancelButton , SIGNAL(clicked(void)), this, SLOT(closeWindow(void)) ); + connect( okButton , SIGNAL(clicked(void)), this, SLOT(playMovie(void)) ); + + connect( movBrowseBtn , SIGNAL(clicked(void)) , this, SLOT(openMovie(void)) ); + connect( movSelBox , SIGNAL(activated(int)), this, SLOT(movieSelect(int)) ); + + connect( pauseAtFrame , SIGNAL(stateChanged(int)), this, SLOT(pauseAtFrameChange(int)) ); + + if (suggestReadOnlyReplay) + { + replayReadOnlySetting = true; + } + else + { + replayReadOnlySetting = FCEUI_GetMovieToggleReadOnly(); + } + openReadOnly->setChecked( replayReadOnlySetting ); + + pauseAtFrameEntry->setEnabled( pauseAtFrame->isChecked() ); + + doScan(); + + updateMovieText(); +} +//---------------------------------------------------------------------------- +MoviePlayDialog_t::~MoviePlayDialog_t(void) +{ + printf("Destroy Movie Play Window\n"); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::closeEvent(QCloseEvent *event) +{ + printf("Movie Play Close Window Event\n"); + done(0); + deleteLater(); + event->accept(); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::closeWindow(void) +{ + //printf("Close Window\n"); + done(0); + deleteLater(); +} +//---------------------------------------------------------------------------- +//void MoviePlayDialog_t::readOnlyReplayChanged( int state ) +//{ +// suggestReadOnlyReplay = (state != Qt::Unchecked); +//} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::movieSelect(int index) +{ + updateMovieText(); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::pauseAtFrameChange(int state) +{ + pauseAtFrameEntry->setEnabled( state != Qt::Unchecked ); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::clearMovieText(void) +{ + movLenLbl->clear(); + movFramesLbl->clear(); + recCountLbl->clear(); + recFromLbl->clear(); + romUsedLbl->clear(); + romCsumLbl->clear(); + curCsumLbl->clear(); + emuUsedLbl->clear(); + palUsedLbl->clear(); + newppuUsedLbl->clear(); + pauseAtFrameEntry->clear(); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::updateMovieText(void) +{ + int idx; + std::string path; + FCEUFILE* fp; + MOVIE_INFO info; + bool scanok; + char stmp[256]; + + if ( movSelBox->count() == 0 ) + { + return; + } + idx = movSelBox->currentIndex(); + + path = movSelBox->itemText(idx).toStdString(); + + fp = FCEU_fopen( path.c_str(),0,"rb",0); + + if ( fp == NULL ) + { + sprintf( stmp, "Error: Failed to open file '%s'", path.c_str() ); + showErrorMsgWindow( stmp ); + clearMovieText(); + return; + } + scanok = FCEUI_MovieGetInfo(fp, info, false); + + if ( scanok ) + { + double div; + + validator->setMinMax( 0, info.num_frames ); + + sprintf(stmp, "%u", (unsigned)info.num_frames); + + movFramesLbl->setText( tr(stmp) ); + pauseAtFrameEntry->setText( tr(stmp) ); + + div = (FCEUI_GetCurrentVidSystem(0,0)) ? 50.006977968268290849 : 60.098813897440515532; // PAL timing + double tempCount = (info.num_frames / div) + 0.005; // +0.005s for rounding + int num_seconds = (int)tempCount; + int fraction = (int)((tempCount - num_seconds) * 100); + int seconds = num_seconds % 60; + int minutes = (num_seconds / 60) % 60; + int hours = (num_seconds / 60 / 60) % 60; + sprintf(stmp, "%02d:%02d:%02d.%02d", hours, minutes, seconds, fraction); + + movLenLbl->setText( tr(stmp) ); + + sprintf(stmp, "%u", (unsigned)info.rerecord_count); + + recCountLbl->setText( tr(stmp) ); + + recFromLbl->setText( tr(info.poweron ? "Power-On" : (info.reset?"Soft-Reset":"Savestate") ) ); + + romUsedLbl->setText( tr(info.name_of_rom_used.c_str()) ); + + romCsumLbl->setText( tr(md5_asciistr(info.md5_of_rom_used)) ); + + if ( GameInfo ) + { + curCsumLbl->setText( tr(md5_asciistr(GameInfo->MD5)) ); + } + else + { + curCsumLbl->clear(); + } + + if (info.emu_version_used < 20000 ) + { + sprintf( stmp, "FCEU %u.%02u.%02d%s", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100, info.emu_version_used < 9813 ? " (blip)" : ""); + } + else + { + sprintf( stmp, "FCEUX %u.%02u.%02d", info.emu_version_used/10000, (info.emu_version_used/100)%100, (info.emu_version_used)%100); + } + emuUsedLbl->setText( tr(stmp) ); + + palUsedLbl->setText( tr(info.pal ? "On" : "Off") ); + + newppuUsedLbl->setText( tr(info.ppuflag ? "On" : "Off") ); + + if ( GameInfo ) + { + strcpy( stmp, md5_asciistr(GameInfo->MD5) ); + + if ( strcmp( stmp, md5_asciistr(info.md5_of_rom_used) ) != 0 ) + { + sprintf( stmp, "Warning: Selected movie file '%s' may not have been created using the currently loaded ROM.", path.c_str() ); + showWarningMsgWindow( stmp ); + } + } + } + else + { + sprintf( stmp, "Error: Selected file '%s' does not have a recognized movie format.", path.c_str() ); + showErrorMsgWindow( stmp ); + clearMovieText(); + } + delete fp; + + return; +} +//---------------------------------------------------------------------------- +int MoviePlayDialog_t::addFileToList( const char *file, bool setActive ) +{ + int n=0; + + for (int i=0; icount(); i++) + { + if ( strcmp( file, movSelBox->itemText(i).toStdString().c_str() ) == 0 ) + { + if ( setActive ) + { + movSelBox->setCurrentIndex(i); + } + return -1; + } + } + + n = movSelBox->count(); + + movSelBox->addItem( tr(file), n ); + + if ( setActive ) + { + movSelBox->setCurrentIndex(n); + } + + return 0; +} +//---------------------------------------------------------------------------- +bool MoviePlayDialog_t::checkMD5Sum( const char *path, const char *md5 ) +{ + FCEUFILE* fp; + MOVIE_INFO info; + bool scanok, md5Match = false; + + fp = FCEU_fopen( path,0,"rb",0); + + if ( fp == NULL ) + { + return md5Match; + } + scanok = FCEUI_MovieGetInfo(fp, info, true); + + if ( scanok ) + { + if ( strcmp( md5, md5_asciistr(info.md5_of_rom_used) ) == 0 ) + { + md5Match = true; + } + } + delete fp; + + return md5Match; +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::scanDirectory( const char *dirPath, const char *md5 ) +{ + QDir dir; + QFileInfoList list; + std::string path; + const QStringList filters( { "*.fm2" } ); + + path.assign( dirPath ); + + dir.setPath( QString::fromStdString(path) ); + + list = dir.entryInfoList( filters, QDir::Files ); + + for (int i = 0; i < list.size(); ++i) + { + QFileInfo fileInfo = list.at(i); + + path = std::string(dirPath) + fileInfo.fileName().toStdString(); + + //printf("File: '%s'\n", path.c_str() ); + + if ( checkMD5Sum( path.c_str(), md5 ) ) + { + addFileToList( path.c_str() ); + } + } + +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::doScan(void) +{ + std::string path, last; + const char *romFile; + const char *baseDir = FCEUI_GetBaseDirectory(); + char md5[256]; + char dir[512], base[256]; + + md5[0] = 0; + + if ( GameInfo ) + { + strcpy( md5, md5_asciistr(GameInfo->MD5) ); + } + + path = std::string(baseDir) + "/movies/"; + + scanDirectory( path.c_str(), md5 ); + + romFile = getRomFile(); + + if ( romFile != NULL ) + { + parseFilepath( romFile, dir, base ); + + path = std::string(dir); + + scanDirectory( path.c_str(), md5 ); + } + + g_config->getOption ("SDL.LastOpenMovie", &last ); + + getDirFromFile( last.c_str(), dir ); + + scanDirectory( dir, md5 ); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::playMovie(void) +{ + int idx, pauseframe = 0; + bool replayReadOnlySetting, movieLoadError = false; + + if ( movSelBox->count() == 0 ) + { + return; + } + std::string path; + + idx = movSelBox->currentIndex(); + + path = movSelBox->itemText(idx).toStdString(); + + replayReadOnlySetting = openReadOnly->isChecked(); + + if ( pauseAtFrame->isChecked() ) + { + pauseframe = strtol( pauseAtFrameEntry->text().toStdString().c_str(), NULL, 0 ); + } + + fceuWrapperLock(); + if (FCEUI_LoadMovie( path.c_str(), + replayReadOnlySetting, pauseframe ? pauseframe : false) == false) + { + movieLoadError = true; + } + fceuWrapperUnLock(); + + if ( movieLoadError ) + { + char stmp[256]; + sprintf( stmp, "Error: Could not load movie file: %s \n", path.c_str() ); + showErrorMsgWindow( stmp ); + } + else + { + closeWindow(); + } +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::openMovie(void) +{ + int ret, useNativeFileDialogVal; + QString filename; + std::string last; + char dir[512]; + char md5Match = 0; + QFileDialog dialog(this, tr("Open FM2 Movie") ); + + dialog.setFileMode(QFileDialog::ExistingFile); + + dialog.setNameFilter(tr("FM2 Movies (*.fm2) ;; All files (*)")); + + dialog.setViewMode(QFileDialog::List); + dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden ); + dialog.setLabelText( QFileDialog::Accept, tr("Open") ); + + g_config->getOption ("SDL.LastOpenMovie", &last ); + + getDirFromFile( last.c_str(), dir ); + + dialog.setDirectory( tr(dir) ); + + // Check config option to use native file dialog or not + g_config->getOption ("SDL.UseNativeFileDialog", &useNativeFileDialogVal); + + dialog.setOption(QFileDialog::DontUseNativeDialog, !useNativeFileDialogVal); + + dialog.show(); + ret = dialog.exec(); + + if ( ret ) + { + QStringList fileList; + fileList = dialog.selectedFiles(); + + if ( fileList.size() > 0 ) + { + filename = fileList[0]; + } + } + + if ( filename.isNull() ) + { + return; + } + qDebug() << "selected file path : " << filename.toUtf8(); + + if ( GameInfo ) + { + char md5[256]; + + strcpy( md5, md5_asciistr(GameInfo->MD5) ); + + if ( checkMD5Sum( filename.toStdString().c_str(), md5 ) ) + { + md5Match = 1; + } + + if ( !md5Match ) + { + printf("Warning MD5 Mismatch\n"); + } + } + + addFileToList( filename.toStdString().c_str(), true ); + + updateMovieText(); + + g_config->setOption ("SDL.LastOpenMovie", filename.toStdString().c_str() ); + + return; +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::showErrorMsgWindow(const char *str) +{ + QMessageBox msgBox(this); + + msgBox.setIcon( QMessageBox::Critical ); + msgBox.setText( tr(str) ); + msgBox.show(); + msgBox.exec(); +} +//---------------------------------------------------------------------------- +void MoviePlayDialog_t::showWarningMsgWindow(const char *str) +{ + QMessageBox msgBox(this); + + msgBox.setIcon( QMessageBox::Warning ); + msgBox.setText( tr(str) ); + msgBox.show(); + msgBox.exec(); +} +//---------------------------------------------------------------------------- diff --git a/src/drivers/Qt/MoviePlay.h b/src/drivers/Qt/MoviePlay.h new file mode 100644 index 00000000..710e307e --- /dev/null +++ b/src/drivers/Qt/MoviePlay.h @@ -0,0 +1,69 @@ +// MoviePlay.h +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Qt/main.h" +#include "Qt/ConsoleUtilities.h" + +class MoviePlayDialog_t : public QDialog +{ + Q_OBJECT + + public: + MoviePlayDialog_t(QWidget *parent = 0); + ~MoviePlayDialog_t(void); + + protected: + void closeEvent(QCloseEvent *event); + + QComboBox *movSelBox; + QPushButton *movBrowseBtn; + QCheckBox *openReadOnly; + QCheckBox *pauseAtFrame; + QLineEdit *pauseAtFrameEntry; + + QLabel *movLenLbl; + QLabel *movFramesLbl; + QLabel *recCountLbl; + QLabel *recFromLbl; + QLabel *romUsedLbl; + QLabel *romCsumLbl; + QLabel *curCsumLbl; + QLabel *emuUsedLbl; + QLabel *palUsedLbl; + QLabel *newppuUsedLbl; + + fceuDecIntValidtor *validator; + + private: + void doScan(void); + void clearMovieText(void); + void updateMovieText(void); + int addFileToList( const char *file, bool setActive = false ); + bool checkMD5Sum( const char *path, const char *md5 ); + void scanDirectory( const char *dirPath, const char *md5 ); + void showErrorMsgWindow(const char *str); + void showWarningMsgWindow(const char *str); + + public slots: + void closeWindow(void); + private slots: + void openMovie(void); + void playMovie(void); + void movieSelect(int index); + void pauseAtFrameChange(int state); + +}; diff --git a/src/drivers/Qt/RamSearch.cpp b/src/drivers/Qt/RamSearch.cpp index a0263a1d..ed0fc097 100644 --- a/src/drivers/Qt/RamSearch.cpp +++ b/src/drivers/Qt/RamSearch.cpp @@ -1467,12 +1467,33 @@ QRamSearchView::QRamSearchView(QWidget *parent) : QWidget(parent) { QPalette pal; - QColor fg(0,0,0), bg(255,255,255); + QColor c, fg(0,0,0), bg(255,255,255); + bool useDarkTheme = false; pal = this->palette(); - pal.setColor(QPalette::Base , bg ); - pal.setColor(QPalette::Background, bg ); - pal.setColor(QPalette::WindowText, fg ); + + // Figure out if we are using a light or dark theme by checking the + // default window text grayscale color. If more white, then we will + // use white text on black background, else we do the opposite. + c = pal.color(QPalette::WindowText); + + if ( qGray( c.red(), c.green(), c.blue() ) > 128 ) + { + useDarkTheme = true; + } + + if ( useDarkTheme ) + { + pal.setColor(QPalette::Base , fg ); + pal.setColor(QPalette::Background, fg ); + pal.setColor(QPalette::WindowText, bg ); + } + else + { + pal.setColor(QPalette::Base , bg ); + pal.setColor(QPalette::Background, bg ); + pal.setColor(QPalette::WindowText, fg ); + } this->setPalette(pal); font.setFamily("Courier New"); diff --git a/src/drivers/Qt/TraceLogger.cpp b/src/drivers/Qt/TraceLogger.cpp index f6303e75..35cfde01 100644 --- a/src/drivers/Qt/TraceLogger.cpp +++ b/src/drivers/Qt/TraceLogger.cpp @@ -1056,15 +1056,37 @@ QTraceLogView::QTraceLogView(QWidget *parent) { QPalette pal; QColor fg("black"), bg("white"); + QColor c; + bool useDarkTheme = false; font.setFamily("Courier New"); font.setStyle( QFont::StyleNormal ); font.setStyleHint( QFont::Monospace ); pal = this->palette(); - pal.setColor(QPalette::Base , bg ); - pal.setColor(QPalette::Background, bg ); - pal.setColor(QPalette::WindowText, fg ); + + // Figure out if we are using a light or dark theme by checking the + // default window text grayscale color. If more white, then we will + // use white text on black background, else we do the opposite. + c = pal.color(QPalette::WindowText); + + if ( qGray( c.red(), c.green(), c.blue() ) > 128 ) + { + useDarkTheme = true; + } + + if ( useDarkTheme ) + { + pal.setColor(QPalette::Base , fg ); + pal.setColor(QPalette::Background, fg ); + pal.setColor(QPalette::WindowText, bg ); + } + else + { + pal.setColor(QPalette::Base , bg ); + pal.setColor(QPalette::Background, bg ); + pal.setColor(QPalette::WindowText, fg ); + } this->setPalette(pal); diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index f0a37bf5..0ee1a16b 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "Qt/main.h" #include "Qt/throttle.h" #include "Qt/config.h" @@ -439,6 +440,7 @@ static const char *DriverUsage = static void ShowUsage(const char *prog) { + int i,j; printf("\nUsage is as follows:\n%s filename\n\n",prog); puts(DriverUsage); #ifdef _S9XLUA_H @@ -448,6 +450,25 @@ static void ShowUsage(const char *prog) puts ("--videolog c Calls mencoder to grab the video and audio streams to\n encode them. Check the documentation for more on this."); puts ("--mute {0|1} Mutes FCEUX while still passing the audio stream to\n mencoder during avi creation."); #endif + puts ("--style=KEY Use Qt GUI Style based on supplied key. Available system style keys are:\n"); + + QStringList styleList = QStyleFactory::keys(); + + j=0; + for (i=0; i= 4 ) + { + printf("\n"); j=0; + } + } + printf("\n\n"); + printf(" Custom Qt stylesheets (.qss files) may be used by setting an\n"); + printf(" environment variable named FCEUX_QT_STYLESHEET equal to the \n"); + printf(" full (absolute) path to the qss file.\n"); + puts(""); printf("Compiled with SDL version %d.%d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL ); SDL_version v;