Added movie record input dialog to Qt GUI.

This commit is contained in:
mjbudd77 2021-08-05 22:35:29 -04:00
parent f3af816eda
commit 455df4caae
7 changed files with 447 additions and 95 deletions

View File

@ -461,6 +461,7 @@ set(SRC_DRIVERS_SDL
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/ColorMenu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/GuiConf.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MoviePlay.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/Qt/MovieRecord.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

View File

@ -71,6 +71,7 @@
#include "Qt/GuiConf.h"
#include "Qt/AviRecord.h"
#include "Qt/MoviePlay.h"
#include "Qt/MovieRecord.h"
#include "Qt/MovieOptions.h"
#include "Qt/TimingConf.h"
#include "Qt/FrameTimingStats.h"
@ -1636,19 +1637,11 @@ void consoleWin_t::createMainMenu(void)
recMovAct->setIcon( QIcon(":icons/media-record.png") );
connect(recMovAct, SIGNAL(triggered()), this, SLOT(recordMovie(void)) );
Hotkeys[ HK_RECORD_MOVIE_TO ].setAction( recMovAct );
connect( Hotkeys[ HK_RECORD_MOVIE_TO ].getShortcut(), SIGNAL(activated()), this, SLOT(recordMovie(void)) );
movieMenu->addAction(recMovAct);
// Movie -> Record As
recAsMovAct = new QAction(tr("Record &As"), this);
//recAsMovAct->setShortcut( QKeySequence(tr("Shift+F5")));
recAsMovAct->setStatusTip(tr("Record Movie"));
connect(recAsMovAct, SIGNAL(triggered()), this, SLOT(recordMovieAs(void)) );
Hotkeys[ HK_RECORD_MOVIE_TO ].setAction( recAsMovAct );
connect( Hotkeys[ HK_RECORD_MOVIE_TO ].getShortcut(), SIGNAL(activated()), this, SLOT(recordMovieAs(void)) );
movieMenu->addAction(recAsMovAct);
movieMenu->addSeparator();
// Movie -> Avi Recording
@ -3450,74 +3443,10 @@ void consoleWin_t::recordMovie(void)
fceuWrapperLock();
if (fceuWrapperGameLoaded())
{
std::string name = FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0);
FCEUI_printf ("Recording movie to %s\n", name.c_str ());
FCEUI_SaveMovie (name.c_str (), MOVIE_FLAG_NONE, L"");
MovieRecordDialog_t dialog(this);
dialog.exec();
}
fceuWrapperUnLock();
return;
}
void consoleWin_t::recordMovieAs(void)
{
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
QFileDialog dialog(this, tr("Save FM2 Movie for Recording") );
dialog.setFileMode(QFileDialog::AnyFile);
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("Save") );
dialog.setDefaultSuffix( tr(".fm2") );
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);
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 ("Recording movie to %s\n", filename.toStdString().c_str() );
fceuWrapperLock();
std::string s = GetUserText ("Author name");
std::wstring author (s.begin (), s.end ());
FCEUI_SaveMovie ( filename.toStdString().c_str(), MOVIE_FLAG_NONE, author);
fceuWrapperUnLock();
return;
}
@ -4042,7 +3971,6 @@ void consoleWin_t::updatePeriodic(void)
saveStateAct->setEnabled( FCEU_IsValidUI( FCEUI_SAVESTATE ) );
openMovAct->setEnabled( FCEU_IsValidUI( FCEUI_PLAYMOVIE ) );
recMovAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) );
recAsMovAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) );
recAviAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEU_IsValidUI( FCEUI_STOPAVI ) );
recAsAviAct->setEnabled( FCEU_IsValidUI( FCEUI_RECORDMOVIE ) && !FCEU_IsValidUI( FCEUI_STOPAVI ) );
stopAviAct->setEnabled( FCEU_IsValidUI( FCEUI_STOPAVI ) );

View File

@ -233,7 +233,6 @@ class consoleWin_t : public QMainWindow
QAction *playMovBeginAct;
QAction *stopMovAct;
QAction *recMovAct;
QAction *recAsMovAct;
QAction *region[3];
QAction *ramInit[4];
QAction *recAviAct;
@ -294,6 +293,7 @@ class consoleWin_t : public QMainWindow
void openGamePadConfWin(void);
void toggleFullscreen(void);
void toggleMenuVis(void);
void recordMovie(void);
private slots:
void closeApp(void);
void openROMFile(void);
@ -371,8 +371,6 @@ class consoleWin_t : public QMainWindow
void openRamSearch(void);
void openMovie(void);
void stopMovie(void);
void recordMovie(void);
void recordMovieAs(void);
void playMovieFromBeginning(void);
void setCustomAutoFire(void);
void incrSoundVolume(void);

View File

@ -0,0 +1,369 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2020 mjbudd77
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
// MovieRecord.cpp
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <QHeaderView>
#include <QCloseEvent>
#include <QFileDialog>
#include <QMessageBox>
#include <QGridLayout>
#include <QSettings>
#include <QFile>
#include <QDir>
#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/MovieRecord.h"
//----------------------------------------------------------------------------
MovieRecordDialog_t::MovieRecordDialog_t(QWidget *parent)
: QDialog(parent)
{
QVBoxLayout *mainLayout;
QHBoxLayout *hbox;
QGridLayout *grid;
QSettings settings;
std::string name;
setWindowTitle( tr("Record Input Movie") );
mainLayout = new QVBoxLayout();
grid = new QGridLayout();
hbox = new QHBoxLayout();
setLayout( mainLayout );
mainLayout->addLayout( grid );
mainLayout->addLayout( hbox );
dirEdit = new QLineEdit();
fileEdit = new QLineEdit();
authorEdit = new QLineEdit();
fileBrowse = new QPushButton( tr("...") );
stateSel = new QComboBox();
okButton = new QPushButton( tr("OK") );
cancelButton = new QPushButton( tr("Cancel") );
okButton->setIcon(style()->standardIcon(QStyle::SP_DialogApplyButton));
cancelButton->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton));
fileBrowse->setIcon(style()->standardIcon(QStyle::SP_FileDialogStart) );
stateSel->addItem( tr("Start") , 0 );
stateSel->addItem( tr("Now") , 1 );
stateSel->addItem( tr("Save RAM") , 2 );
stateSel->addItem( tr("Browse..."), 3 );
grid->addWidget( new QLabel( tr("Path:") ), 0, 0 );
grid->addWidget( dirEdit , 0, 1 );
grid->addWidget( new QLabel( tr("File:") ), 1, 0 );
grid->addWidget( fileEdit , 1, 1 );
grid->addWidget( fileBrowse, 1, 2 );
grid->addWidget( new QLabel( tr("Record:") ), 2, 0 );
grid->addWidget( stateSel , 2, 1 );
grid->addWidget( new QLabel( tr("Author:") ), 3, 0 );
grid->addWidget( authorEdit , 3, 1 );
hbox->addWidget( cancelButton, 1 );
hbox->addStretch(10);
hbox->addWidget( okButton, 1 );
dirEdit->setReadOnly(true);
setFilePath( FCEU_MakeFName (FCEUMKF_MOVIE, 0, 0) );
connect( fileBrowse, SIGNAL(clicked(void)), this, SLOT(browseFiles(void)) );
connect( okButton, SIGNAL(clicked(void)), this, SLOT(recordMovie(void)) );
connect( cancelButton, SIGNAL(clicked(void)), this, SLOT(reject(void)) );
connect( stateSel, SIGNAL(activated(int)), this, SLOT(stateSelChanged(int)) );
okButton->setDefault(true);
restoreGeometry(settings.value("movieRecordWindow/geometry").toByteArray());
}
//----------------------------------------------------------------------------
MovieRecordDialog_t::~MovieRecordDialog_t(void)
{
QSettings settings;
settings.setValue("movieRecordWindow/geometry", saveGeometry());
//printf("Destroy Movie Play Window\n");
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::closeEvent(QCloseEvent *event)
{
QSettings settings;
settings.setValue("movieRecordWindow/geometry", saveGeometry());
done(0);
deleteLater();
event->accept();
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::closeWindow(void)
{
QSettings settings;
settings.setValue("movieRecordWindow/geometry", saveGeometry());
done(0);
deleteLater();
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::setFilePath( const char *s )
{
setFilePath( tr(s) );
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::setFilePath( std::string s )
{
setFilePath( QString::fromStdString(s) );
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::setFilePath( QString s )
{
QFileInfo fi(s);
dirEdit->setText( fi.absolutePath() );
fileEdit->setText( fi.fileName() );
filepath = s.toStdString();
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::stateSelChanged( int idx )
{
//printf("State:%i\n", idx);
if ( idx >= 3 )
{
setLoadState();
okButton->setEnabled( ic_file.size() > 0 );
}
else
{
okButton->setEnabled( true );
}
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::setLoadState(void)
{
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
const char *base;
QFileDialog dialog(this, tr("Load State From File") );
QList<QUrl> urls;
QDir d;
base = FCEUI_GetBaseDirectory();
urls << QUrl::fromLocalFile( QDir::rootPath() );
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first());
urls << QUrl::fromLocalFile(QStandardPaths::standardLocations(QStandardPaths::DownloadLocation).first());
if ( base )
{
urls << QUrl::fromLocalFile( QDir( base ).absolutePath() );
d.setPath( QString(base) + "/fcs");
if ( d.exists() )
{
urls << QUrl::fromLocalFile( d.absolutePath() );
}
d.setPath( QString(base) + "/sav");
if ( d.exists() )
{
urls << QUrl::fromLocalFile( d.absolutePath() );
}
}
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("FCS & SAV Files (*.sav *.SAV *.fc? *.FC?) ;; All files (*)"));
dialog.setViewMode(QFileDialog::List);
dialog.setFilter( QDir::AllEntries | QDir::AllDirs | QDir::Hidden );
dialog.setLabelText( QFileDialog::Accept, tr("Select") );
g_config->getOption ("SDL.LastLoadStateFrom", &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.setSidebarUrls(urls);
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();
g_config->setOption ("SDL.LastLoadStateFrom", filename.toStdString().c_str() );
ic_file = filename.toStdString();
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::recordMovie(void)
{
bool startRecording = true;
if (fceuWrapperGameLoaded())
{
QString qs;
int recordFrom = stateSel->currentIndex();
EMOVIE_FLAG flags = MOVIE_FLAG_NONE;
if (recordFrom == 0) flags = MOVIE_FLAG_FROM_POWERON;
if (recordFrom == 2) flags = MOVIE_FLAG_FROM_SAVERAM;
if ( recordFrom >= 3 )
{
FCEUI_LoadState(ic_file.c_str());
{
extern int loadStateFailed;
if (loadStateFailed)
{
char str [1024];
sprintf(str, "Failed to load save state \"%s\".\nRecording from current state instead...", ic_file.c_str());
FCEUD_PrintError(str);
}
}
}
qs = QString::fromStdString(filepath);
if ( QFile::exists(qs) )
{
int ret;
ret = QMessageBox::warning( this, tr("Overwrite Warning"),
tr("Pre-existing movie file Will be overwritten.\nReplace file?"), QMessageBox::Yes | QMessageBox::No );
if ( ret == QMessageBox::No )
{
startRecording = false;
}
}
if ( startRecording )
{
std::string s = authorEdit->text().toStdString();
std::wstring author (s.begin (), s.end ());
FCEUI_printf("Recording movie to %s\n", filepath.c_str ());
FCEUI_SaveMovie (filepath.c_str(), flags, author);
done(0);
deleteLater();
}
}
}
//----------------------------------------------------------------------------
void MovieRecordDialog_t::browseFiles(void)
{
int ret, useNativeFileDialogVal;
QString filename;
std::string last;
char dir[512];
QFileDialog dialog(this, tr("Save FM2 Movie for Recording") );
dialog.setFileMode(QFileDialog::AnyFile);
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("Save To") );
dialog.setDefaultSuffix( tr(".fm2") );
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);
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 ("Recording movie to %s\n", filename.toStdString().c_str() );
setFilePath( filename );
return;
}
//----------------------------------------------------------------------------

View File

@ -0,0 +1,54 @@
// MovieRecord.h
//
#pragma once
#include <QWidget>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QComboBox>
#include <QCheckBox>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include <QFrame>
#include <QGroupBox>
#include "Qt/main.h"
#include "Qt/ConsoleUtilities.h"
class MovieRecordDialog_t : public QDialog
{
Q_OBJECT
public:
MovieRecordDialog_t(QWidget *parent = 0);
~MovieRecordDialog_t(void);
protected:
void closeEvent(QCloseEvent *event);
QLineEdit *dirEdit;
QLineEdit *fileEdit;
QLineEdit *authorEdit;
QPushButton *fileBrowse;
QPushButton *okButton;
QPushButton *cancelButton;
QComboBox *stateSel;
std::string filepath;
std::string ic_file;
private:
void setFilePath( QString s );
void setFilePath( std::string s );
void setFilePath( const char *s );
void setLoadState(void);
public slots:
void closeWindow(void);
private slots:
void browseFiles(void);
void recordMovie(void);
void stateSelChanged(int idx);
};

View File

@ -19,6 +19,7 @@
*/
#include <QFileDialog>
#include <QInputDialog>
#include <QApplication>
#include "Qt/main.h"
@ -644,25 +645,27 @@ static std::string GetFilename(const char *title, int mode, const char *filter)
return fname;
}
/**
* This function opens a text entry dialog and returns the user's input
*/
std::string GetUserText(const char *title)
{
return "";
}
/**
* Lets the user start a new .fm2 movie file
**/
void FCEUD_MovieRecordTo(void)
{
std::string fname = GetFilename("Save FM2 movie for recording", 2, "FM2 movies|*.fm2");
if (!fname.size())
return; // no filename selected, quit the whole thing
std::wstring author = mbstowcs(GetUserText("Author Name")); // the author can be empty, so no need to check here
//bool ok = false;
//std::string fname = GetFilename("Save FM2 movie for recording", 2, "FM2 movies|*.fm2");
//if (!fname.size())
//{
// return; // no filename selected, quit the whole thing
//}
//std::string s = QInputDialog::getText( consoleWindow, QObject::tr("Movie Recording"),
// QObject::tr("Enter Author Name"), QLineEdit::Normal, QObject::tr(""), &ok ).toStdString();
FCEUI_SaveMovie(fname.c_str(), MOVIE_FLAG_FROM_POWERON, author);
//std::wstring author (s.begin (), s.end ());
//FCEUI_SaveMovie(fname.c_str(), MOVIE_FLAG_FROM_POWERON, author);
if ( consoleWindow )
{
consoleWindow->recordMovie();
}
}
/**

View File

@ -140,7 +140,6 @@ void FCEUD_UpdateInput(void);
void UpdateInput(Config *config);
std::string GetUserText(const char* title);
const char* ButtonName(const ButtConfig* bc);
int getInputSelection( int port, int *cur, int *usr );