Starting new QT gui.

This commit is contained in:
Matthew Budd 2020-06-23 20:40:43 -04:00
parent fb9ee25800
commit be4c650238
27 changed files with 5570 additions and 0 deletions

View File

@ -0,0 +1,22 @@
QMAKE_CXX.INCDIRS = \
/usr/include/c++/8 \
/usr/include/c++/8/x86_64-redhat-linux \
/usr/include/c++/8/backward \
/usr/lib/gcc/x86_64-redhat-linux/8/include \
/usr/local/include \
/usr/include
QMAKE_CXX.LIBDIRS = \
/usr/lib/gcc/x86_64-redhat-linux/8 \
/usr/lib64 \
/lib64 \
/usr/lib \
/lib
QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 8
QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 3
QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 1
QMAKE_CXX.COMPILER_MACROS = \
QT_COMPILER_STDCXX \
QMAKE_GCC_MAJOR_VERSION \
QMAKE_GCC_MINOR_VERSION \
QMAKE_GCC_PATCH_VERSION

View File

@ -0,0 +1,88 @@
// GameApp.cpp
//
#include "GameApp.h"
gameWin_t::gameWin_t(QWidget *parent)
: QMainWindow( parent )
{
QWidget *widget = new QWidget( this );
setCentralWidget(widget);
QVBoxLayout *layout = new QVBoxLayout;
layout->setMargin(5);
createMainMenu();
viewport = new gameView_t();
//viewport.resize( 200, 200 );
layout->addWidget(viewport);
widget->setLayout(layout);
gameTimer = new QTimer( this );
connect( gameTimer, &QTimer::timeout, this, &gameWin_t::runGameFrame );
gameTimer->setTimerType( Qt::PreciseTimer );
gameTimer->start( 10 );
}
gameWin_t::~gameWin_t(void)
{
delete viewport;
}
void gameWin_t::createMainMenu(void)
{
menuBar()->setNativeMenuBar(false);
fileMenu = menuBar()->addMenu(tr("&File"));
openAct = new QAction(tr("&Open"), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an Existing File"));
connect(openAct, SIGNAL(triggered()), this, SLOT(openFile(void)) );
fileMenu->addAction(openAct);
quitAct = new QAction(tr("&Quit"), this);
quitAct->setStatusTip(tr("Quit the Application"));
connect(quitAct, SIGNAL(triggered()), qApp, SLOT(quit()));
fileMenu->addAction(quitAct);
helpMenu = menuBar()->addMenu(tr("&Help"));
aboutAct = new QAction(tr("&About"), this);
aboutAct->setStatusTip(tr("About Qplot"));
connect(aboutAct, SIGNAL(triggered()), this, SLOT(aboutQPlot(void)) );
helpMenu->addAction(aboutAct);
};
void gameWin_t::openFile(void)
{
printf("Open File\n");
return;
}
void gameWin_t::aboutQPlot(void)
{
printf("About QPlot\n");
return;
}
void gameWin_t::runGameFrame(void)
{
struct timespec ts;
double t;
clock_gettime( CLOCK_REALTIME, &ts );
t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9);
//printf("Run Frame %f\n", t);
//
viewport->repaint();
return;
}

50
src/drivers/Qt/GameApp.h Normal file
View File

@ -0,0 +1,50 @@
//
#ifndef __GameAppH__
#define __GameAppH__
#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QPushButton>
#include <QMenu>
#include <QMenuBar>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTimer>
#include "GameViewer.h"
class gameWin_t : public QMainWindow
{
Q_OBJECT
public:
gameWin_t(QWidget *parent = 0);
~gameWin_t(void);
gameView_t *viewport;
//QPushButton hello( "Hello world!", 0 );
//
QMenu *fileMenu;
QMenu *helpMenu;
QAction *openAct;
QAction *quitAct;
QAction *aboutAct;
QTimer *gameTimer;
private:
void createMainMenu(void);
private slots:
void openFile(void);
void aboutQPlot(void);
void runGameFrame(void);
};
#endif

View File

@ -0,0 +1,64 @@
// GameViewer.cpp
//
#include <math.h>
#include "GameViewer.h"
gameView_t::gameView_t(QWidget *parent)
: QOpenGLWidget( parent )
{
}
gameView_t::~gameView_t(void)
{
// Make sure the context is current and then explicitly
// destroy all underlying OpenGL resources.
makeCurrent();
// Free GL texture
doneCurrent();
}
void gameView_t::initializeGL(void)
{
initializeOpenGLFunctions();
// Set up the rendering context, load shaders and other resources, etc.:
//QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
printf("GL Init!\n");
}
void gameView_t::resizeGL(int w, int h)
{
printf("GL Resize: %i x %i \n", w, h );
glViewport(0, 0, w, h);
}
void gameView_t::paintGL(void)
{
float x1, y1, x2, y2;
angle += (2.0 * 3.14 * 0.01);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
x1 = cos( angle );
y1 = sin( angle );
x2 = -x1;
y2 = -y1;
glColor4f( 1.0, 1.0, 1.0, 1.0 );
glLineWidth(5.0);
glBegin(GL_LINES);
glVertex2f( x1, y1 );
glVertex2f( x2, y2 );
glEnd();
//printf("Paint GL!\n");
}

View File

@ -0,0 +1,26 @@
// GameViewer.h
//
#pragma once
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
class gameView_t : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
gameView_t(QWidget *parent = 0);
~gameView_t(void);
float angle;
protected:
void initializeGL(void);
void resizeGL(int w, int h);
void paintGL(void);
private slots:
};

485
src/drivers/Qt/config.cpp Normal file
View File

@ -0,0 +1,485 @@
#include "main.h"
#include "throttle.h"
#include "config.h"
#include "../common/cheat.h"
#include "input.h"
#include "dface.h"
#include "sdl.h"
#include "sdl-video.h"
#include "unix-netplay.h"
#ifdef WIN32
#include <windows.h>
#endif
#include <unistd.h>
#include <csignal>
#include <cstring>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
static const char* HotkeyStrings[HK_MAX] = {
"CheatMenu",
"BindState",
"LoadLua",
"ToggleBG",
"SaveState",
"FDSSelect",
"LoadState",
"FDSEject",
"VSInsertCoin",
"VSToggleDip",
"MovieToggleFrameDisplay",
"SubtitleDisplay",
"Reset",
"Screenshot",
"Pause",
"DecreaseSpeed",
"IncreaseSpeed",
"FrameAdvance",
"Turbo",
"ToggleInputDisplay",
"ToggleMovieRW",
"MuteCapture",
"Quit",
"FrameAdvanceLagSkip",
"LagCounterDisplay",
"SelectState0", "SelectState1", "SelectState2", "SelectState3",
"SelectState4", "SelectState5", "SelectState6", "SelectState7",
"SelectState8", "SelectState9", "SelectStateNext", "SelectStatePrev",
"VolumeDown", "VolumeUp" };
const char *getHotkeyString( int i )
{
if ( (i>=0) && (i<HK_MAX) )
{
return HotkeyStrings[i];
}
return NULL;
}
/**
* Read a custom pallete from a file and load it into the core.
*/
int
LoadCPalette(const std::string &file)
{
uint8 tmpp[192];
FILE *fp;
if(!(fp = FCEUD_UTF8fopen(file.c_str(), "rb"))) {
char errorMsg[256];
strcpy(errorMsg, "Error loading custom palette from file: ");
strcat(errorMsg, file.c_str());
FCEUD_PrintError(errorMsg);
return 0;
}
size_t result = fread(tmpp, 1, 192, fp);
if(result != 192) {
char errorMsg[256];
strcpy(errorMsg, "Error loading custom palette from file: ");
strcat(errorMsg, file.c_str());
FCEUD_PrintError(errorMsg);
return 0;
}
FCEUI_SetUserPalette(tmpp, result/3);
fclose(fp);
return 1;
}
/**
* Creates the subdirectories used for saving snapshots, movies, game
* saves, etc. Hopefully obsolete with new configuration system.
*/
static void
CreateDirs(const std::string &dir)
{
const char *subs[8]={"fcs","snaps","gameinfo","sav","cheats","movies","cfg.d"};
std::string subdir;
int x;
#if defined(WIN32) || defined(NEED_MINGW_HACKS)
mkdir(dir.c_str());
chmod(dir.c_str(), 755);
for(x = 0; x < 6; x++) {
subdir = dir + PSS + subs[x];
mkdir(subdir.c_str());
}
#else
mkdir(dir.c_str(), S_IRWXU);
for(x = 0; x < 6; x++) {
subdir = dir + PSS + subs[x];
mkdir(subdir.c_str(), S_IRWXU);
}
#endif
}
/**
* Attempts to locate FCEU's application directory. This will
* hopefully become obsolete once the new configuration system is in
* place.
*/
static void
GetBaseDirectory(std::string &dir)
{
char *home = getenv("HOME");
if(home) {
dir = std::string(home) + "/.fceux";
} else {
#ifdef WIN32
home = new char[MAX_PATH + 1];
GetModuleFileName(NULL, home, MAX_PATH + 1);
char *lastBS = strrchr(home,'\\');
if(lastBS) {
*lastBS = 0;
}
dir = std::string(home);
delete[] home;
#else
dir = "";
#endif
}
}
// returns a config structure with default options
// also creates config base directory (ie: /home/user/.fceux as well as subdirs
Config *
InitConfig()
{
std::string dir, prefix;
Config *config;
GetBaseDirectory(dir);
FCEUI_SetBaseDirectory(dir.c_str());
CreateDirs(dir);
config = new Config(dir);
// sound options
config->addOption('s', "sound", "SDL.Sound", 1);
config->addOption("volume", "SDL.Sound.Volume", 150);
config->addOption("trianglevol", "SDL.Sound.TriangleVolume", 256);
config->addOption("square1vol", "SDL.Sound.Square1Volume", 256);
config->addOption("square2vol", "SDL.Sound.Square2Volume", 256);
config->addOption("noisevol", "SDL.Sound.NoiseVolume", 256);
config->addOption("pcmvol", "SDL.Sound.PCMVolume", 256);
config->addOption("soundrate", "SDL.Sound.Rate", 44100);
config->addOption("soundq", "SDL.Sound.Quality", 1);
config->addOption("soundrecord", "SDL.Sound.RecordFile", "");
config->addOption("soundbufsize", "SDL.Sound.BufSize", 128);
config->addOption("lowpass", "SDL.Sound.LowPass", 0);
config->addOption('g', "gamegenie", "SDL.GameGenie", 0);
config->addOption("pal", "SDL.PAL", 0);
config->addOption("frameskip", "SDL.Frameskip", 0);
config->addOption("clipsides", "SDL.ClipSides", 0);
config->addOption("nospritelim", "SDL.DisableSpriteLimit", 1);
config->addOption("swapduty", "SDL.SwapDuty", 0);
// color control
config->addOption('p', "palette", "SDL.Palette", "");
config->addOption("tint", "SDL.Tint", 56);
config->addOption("hue", "SDL.Hue", 72);
config->addOption("ntsccolor", "SDL.NTSCpalette", 0);
// scanline settings
config->addOption("slstart", "SDL.ScanLineStart", 0);
config->addOption("slend", "SDL.ScanLineEnd", 239);
// video controls
config->addOption('f', "fullscreen", "SDL.Fullscreen", 0);
// set x/y res to 0 for automatic fullscreen resolution detection (no change)
config->addOption('x', "xres", "SDL.XResolution", 0);
config->addOption('y', "yres", "SDL.YResolution", 0);
config->addOption("SDL.LastXRes", 0);
config->addOption("SDL.LastYRes", 0);
config->addOption('b', "bpp", "SDL.BitsPerPixel", 32);
config->addOption("doublebuf", "SDL.DoubleBuffering", 1);
config->addOption("autoscale", "SDL.AutoScale", 1);
config->addOption("keepratio", "SDL.KeepRatio", 1);
config->addOption("xscale", "SDL.XScale", 1.0);
config->addOption("yscale", "SDL.YScale", 1.0);
config->addOption("xstretch", "SDL.XStretch", 0);
config->addOption("ystretch", "SDL.YStretch", 0);
config->addOption("noframe", "SDL.NoFrame", 0);
config->addOption("special", "SDL.SpecialFilter", 0);
config->addOption("showfps", "SDL.ShowFPS", 0);
config->addOption("togglemenu", "SDL.ToggleMenu", 0);
// OpenGL options
config->addOption("opengl", "SDL.OpenGL", 1);
config->addOption("openglip", "SDL.OpenGLip", 1);
config->addOption("SDL.SpecialFilter", 0);
config->addOption("SDL.SpecialFX", 0);
config->addOption("SDL.Vsync", 1);
// network play options - netplay is broken
config->addOption("server", "SDL.NetworkIsServer", 0);
config->addOption('n', "net", "SDL.NetworkIP", "");
config->addOption('u', "user", "SDL.NetworkUsername", "");
config->addOption('w', "pass", "SDL.NetworkPassword", "");
config->addOption('k', "netkey", "SDL.NetworkGameKey", "");
config->addOption("port", "SDL.NetworkPort", 4046);
config->addOption("players", "SDL.NetworkPlayers", 1);
// input configuration options
config->addOption("input1", "SDL.Input.0", "GamePad.0");
config->addOption("input2", "SDL.Input.1", "GamePad.1");
config->addOption("input3", "SDL.Input.2", "Gamepad.2");
config->addOption("input4", "SDL.Input.3", "Gamepad.3");
// allow for input configuration
config->addOption('i', "inputcfg", "SDL.InputCfg", InputCfg);
// display input
config->addOption("inputdisplay", "SDL.InputDisplay", 0);
// enable / disable opposite directionals (left + right or up + down simultaneously)
config->addOption("opposite-directionals", "SDL.Input.EnableOppositeDirectionals", 1);
// pause movie playback at frame x
config->addOption("pauseframe", "SDL.PauseFrame", 0);
config->addOption("recordhud", "SDL.RecordHUD", 1);
config->addOption("moviemsg", "SDL.MovieMsg", 1);
// overwrite the config file?
config->addOption("no-config", "SDL.NoConfig", 0);
config->addOption("autoresume", "SDL.AutoResume", 0);
// video playback
config->addOption("playmov", "SDL.Movie", "");
config->addOption("subtitles", "SDL.SubtitleDisplay", 1);
config->addOption("movielength", "SDL.MovieLength", 0);
config->addOption("fourscore", "SDL.FourScore", 0);
config->addOption("nofscursor", "SDL.NoFullscreenCursor", 1);
#ifdef _S9XLUA_H
// load lua script
config->addOption("loadlua", "SDL.LuaScript", "");
#endif
#ifdef CREATE_AVI
config->addOption("videolog", "SDL.VideoLog", "");
config->addOption("mute", "SDL.MuteCapture", 0);
#endif
// auto load/save on gameload/close
config->addOption("loadstate", "SDL.AutoLoadState", INVALID_STATE);
config->addOption("savestate", "SDL.AutoSaveState", INVALID_STATE);
//TODO implement this
config->addOption("periodicsaves", "SDL.PeriodicSaves", 0);
#ifdef _GTK
char* home_dir = getenv("HOME");
// prefixed with _ because they are internal (not cli options)
config->addOption("_lastopenfile", "SDL.LastOpenFile", home_dir);
config->addOption("_laststatefrom", "SDL.LastLoadStateFrom", home_dir);
config->addOption("_lastopennsf", "SDL.LastOpenNSF", home_dir);
config->addOption("_lastsavestateas", "SDL.LastSaveStateAs", home_dir);
config->addOption("_lastloadlua", "SDL.LastLoadLua", "");
#endif
// fcm -> fm2 conversion
config->addOption("fcmconvert", "SDL.FCMConvert", "");
// fm2 -> srt conversion
config->addOption("ripsubs", "SDL.RipSubs", "");
// enable new PPU core
config->addOption("newppu", "SDL.NewPPU", 0);
// quit when a+b+select+start is pressed
config->addOption("4buttonexit", "SDL.ABStartSelectExit", 0);
// GamePad 0 - 3
for(unsigned int i = 0; i < GAMEPAD_NUM_DEVICES; i++)
{
char buf[64];
snprintf(buf, sizeof(buf)-1, "SDL.Input.GamePad.%u.", i);
prefix = buf;
config->addOption(prefix + "DeviceType", DefaultGamePadDevice[i]);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < GAMEPAD_NUM_BUTTONS; j++) {
config->addOption(prefix + GamePadNames[j], DefaultGamePad[i][j]);
}
}
// PowerPad 0 - 1
for(unsigned int i = 0; i < POWERPAD_NUM_DEVICES; i++) {
char buf[64];
snprintf(buf, sizeof(buf)-1, "SDL.Input.PowerPad.%u.", i);
prefix = buf;
config->addOption(prefix + "DeviceType", DefaultPowerPadDevice[i]);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < POWERPAD_NUM_BUTTONS; j++) {
config->addOption(prefix +PowerPadNames[j], DefaultPowerPad[i][j]);
}
}
// QuizKing
prefix = "SDL.Input.QuizKing.";
config->addOption(prefix + "DeviceType", DefaultQuizKingDevice);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < QUIZKING_NUM_BUTTONS; j++) {
config->addOption(prefix + QuizKingNames[j], DefaultQuizKing[j]);
}
// HyperShot
prefix = "SDL.Input.HyperShot.";
config->addOption(prefix + "DeviceType", DefaultHyperShotDevice);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < HYPERSHOT_NUM_BUTTONS; j++) {
config->addOption(prefix + HyperShotNames[j], DefaultHyperShot[j]);
}
// Mahjong
prefix = "SDL.Input.Mahjong.";
config->addOption(prefix + "DeviceType", DefaultMahjongDevice);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < MAHJONG_NUM_BUTTONS; j++) {
config->addOption(prefix + MahjongNames[j], DefaultMahjong[j]);
}
// TopRider
prefix = "SDL.Input.TopRider.";
config->addOption(prefix + "DeviceType", DefaultTopRiderDevice);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < TOPRIDER_NUM_BUTTONS; j++) {
config->addOption(prefix + TopRiderNames[j], DefaultTopRider[j]);
}
// FTrainer
prefix = "SDL.Input.FTrainer.";
config->addOption(prefix + "DeviceType", DefaultFTrainerDevice);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < FTRAINER_NUM_BUTTONS; j++) {
config->addOption(prefix + FTrainerNames[j], DefaultFTrainer[j]);
}
// FamilyKeyBoard
prefix = "SDL.Input.FamilyKeyBoard.";
config->addOption(prefix + "DeviceType", DefaultFamilyKeyBoardDevice);
config->addOption(prefix + "DeviceNum", 0);
for(unsigned int j = 0; j < FAMILYKEYBOARD_NUM_BUTTONS; j++) {
config->addOption(prefix + FamilyKeyBoardNames[j],
DefaultFamilyKeyBoard[j]);
}
// for FAMICOM microphone in pad 2 pad 1 didn't have it
// Takeshi no Chousenjou uses it for example.
prefix = "SDL.Input.FamicomPad2.";
config->addOption("rp2mic", prefix + "EnableMic", 0);
// TODO: use a better data structure to store the hotkeys or something
// improve this code overall in the future to make it
// easier to maintain
const int Hotkeys[HK_MAX] = {
SDLK_F1, // cheat menu
SDLK_F2, // bind state
SDLK_F3, // load lua
SDLK_F4, // toggleBG
SDLK_F5, // save state
SDLK_F6, // fds select
SDLK_F7, // load state
SDLK_F8, // fds eject
SDLK_F6, // VS insert coin
SDLK_F8, // VS toggle dipswitch
SDLK_PERIOD, // toggle frame display
SDLK_F10, // toggle subtitle
SDLK_F11, // reset
SDLK_F12, // screenshot
SDLK_PAUSE, // pause
SDLK_MINUS, // speed++
SDLK_EQUALS, // speed--
SDLK_BACKSLASH, //frame advnace
SDLK_TAB, // turbo
SDLK_COMMA, // toggle input display
SDLK_q, // toggle movie RW
SDLK_QUOTE, // toggle mute capture
0, // quit // edit 10/11/11 - don't map to escape, it causes ugly things to happen to sdl. can be manually appended to config
SDLK_DELETE, // frame advance lag skip
SDLK_SLASH, // lag counter display
SDLK_0, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5,
SDLK_6, SDLK_7, SDLK_8, SDLK_9,
SDLK_PAGEUP, // select state next
SDLK_PAGEDOWN}; // select state prev
prefix = "SDL.Hotkeys.";
for(int i=0; i < HK_MAX; i++)
config->addOption(prefix + HotkeyStrings[i], Hotkeys[i]);
// All mouse devices
config->addOption("SDL.OekaKids.0.DeviceType", "Mouse");
config->addOption("SDL.OekaKids.0.DeviceNum", 0);
config->addOption("SDL.Arkanoid.0.DeviceType", "Mouse");
config->addOption("SDL.Arkanoid.0.DeviceNum", 0);
config->addOption("SDL.Shadow.0.DeviceType", "Mouse");
config->addOption("SDL.Shadow.0.DeviceNum", 0);
config->addOption("SDL.Zapper.0.DeviceType", "Mouse");
config->addOption("SDL.Zapper.0.DeviceNum", 0);
return config;
}
void
UpdateEMUCore(Config *config)
{
int ntsccol, ntsctint, ntschue, flag, region, start, end;
std::string cpalette;
config->getOption("SDL.NTSCpalette", &ntsccol);
config->getOption("SDL.Tint", &ntsctint);
config->getOption("SDL.Hue", &ntschue);
FCEUI_SetNTSCTH(ntsccol, ntsctint, ntschue);
config->getOption("SDL.Palette", &cpalette);
if(cpalette.size()) {
LoadCPalette(cpalette);
}
config->getOption("SDL.PAL", &region);
FCEUI_SetRegion(region);
config->getOption("SDL.GameGenie", &flag);
FCEUI_SetGameGenie(flag ? 1 : 0);
config->getOption("SDL.Sound.LowPass", &flag);
FCEUI_SetLowPass(flag ? 1 : 0);
config->getOption("SDL.DisableSpriteLimit", &flag);
FCEUI_DisableSpriteLimitation(flag ? 1 : 0);
config->getOption("SDL.ScanLineStart", &start);
config->getOption("SDL.ScanLineEnd", &end);
#if DOING_SCANLINE_CHECKS
for(int i = 0; i < 2; x++) {
if(srendlinev[x]<0 || srendlinev[x]>239) srendlinev[x]=0;
if(erendlinev[x]<srendlinev[x] || erendlinev[x]>239) erendlinev[x]=239;
}
#endif
FCEUI_SetRenderedLines(start + 8, end - 8, start, end);
}

28
src/drivers/Qt/config.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef CONFIG_H_HF128
#define CONFIG_H_HF128
#include "../common/configSys.h"
Config *InitConfig(void);
void UpdateEMUCore(Config *);
int LoadCPalette(const std::string &file);
// hotkey definitions
// TODO: encapsulate this in an improved data structure
enum HOTKEY { HK_CHEAT_MENU=0, HK_BIND_STATE, HK_LOAD_LUA, HK_TOGGLE_BG,
HK_SAVE_STATE, HK_FDS_SELECT, HK_LOAD_STATE, HK_FDS_EJECT ,
HK_VS_INSERT_COIN, HK_VS_TOGGLE_DIPSWITCH,
HK_TOGGLE_FRAME_DISPLAY, HK_TOGGLE_SUBTITLE, HK_RESET, HK_SCREENSHOT,
HK_PAUSE, HK_DECREASE_SPEED, HK_INCREASE_SPEED, HK_FRAME_ADVANCE, HK_TURBO,
HK_TOGGLE_INPUT_DISPLAY, HK_MOVIE_TOGGLE_RW, HK_MUTE_CAPTURE, HK_QUIT,
HK_FA_LAG_SKIP, HK_LAG_COUNTER_DISPLAY,
HK_SELECT_STATE_0, HK_SELECT_STATE_1, HK_SELECT_STATE_2, HK_SELECT_STATE_3,
HK_SELECT_STATE_4, HK_SELECT_STATE_5, HK_SELECT_STATE_6, HK_SELECT_STATE_7,
HK_SELECT_STATE_8, HK_SELECT_STATE_9,
HK_SELECT_STATE_NEXT, HK_SELECT_STATE_PREV, HK_VOLUME_DOWN, HK_VOLUME_UP,
HK_MAX};
const char *getHotkeyString( int i );
#endif

37
src/drivers/Qt/dface.h Normal file
View File

@ -0,0 +1,37 @@
#include "../common/args.h"
#include "../common/config.h"
#include "input.h"
extern CFGSTRUCT DriverConfig[];
extern ARGPSTRUCT DriverArgs[];
void DoDriverArgs(void);
int InitSound();
void WriteSound(int32 *Buffer, int Count);
int KillSound(void);
uint32 GetMaxSound(void);
uint32 GetWriteSound(void);
void SilenceSound(int s); /* DOS and SDL */
int InitJoysticks(void);
int KillJoysticks(void);
uint32 *GetJSOr(void);
int InitVideo(FCEUGI *gi);
int KillVideo(void);
void BlitScreen(uint8 *XBuf);
void LockConsole(void);
void UnlockConsole(void);
void ToggleFS(); /* SDL */
int LoadGame(const char *path);
//int CloseGame(void);
void Giggles(int);
void DoFun(void);
int FCEUD_NetworkConnect(void);

View File

@ -0,0 +1,300 @@
// fceuWrapper.cpp
//
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "throttle.h"
#include "config.h"
#include "dface.h"
#include "fceuWrapper.h"
#include "input.h"
#include "sdl-video.h"
#include "unix-netplay.h"
#include "../common/cheat.h"
#include "../../fceu.h"
#include "../../movie.h"
#include "../../version.h"
#ifdef _S9XLUA_H
#include "../../fceulua.h"
#endif
#include "../common/configSys.h"
#include "../../oldmovie.h"
#include "../../types.h"
#ifdef CREATE_AVI
#include "../videolog/nesvideos-piece.h"
#endif
//*****************************************************************
// Define Global Variables to be shared with FCEU Core
//*****************************************************************
int dendy = 0;
int eoptions=0;
int isloaded=0;
int pal_emulation=0;
int gametype = 0;
int closeFinishedMovie = 0;
int KillFCEUXonFrame = 0;
bool swapDuty = 0;
bool turbo = false;
unsigned int gui_draw_area_width = 256;
unsigned int gui_draw_area_height = 256;
// global configuration object
Config *g_config = NULL;
static int inited = 0;
static int noconfig=0;
//*****************************************************************
// Define Global Functions to be shared with FCEU Core
//*****************************************************************
//
/**
* Prints a textual message without adding a newline at the end.
*
* @param text The text of the message.
*
* TODO: This function should have a better name.
**/
void FCEUD_Message(const char *text)
{
fputs(text, stdout);
}
/**
* Shows an error message in a message box.
* (For now: prints to stderr.)
*
* If running in GTK mode, display a dialog message box of the error.
*
* @param errormsg Text of the error message.
**/
void FCEUD_PrintError(const char *errormsg)
{
fprintf(stderr, "%s\n", errormsg);
}
/**
* Opens a file, C++ style, to be read a byte at a time.
*/
FILE *FCEUD_UTF8fopen(const char *fn, const char *mode)
{
return(fopen(fn,mode));
}
/**
* Opens a file to be read a byte at a time.
*/
EMUFILE_FILE* FCEUD_UTF8_fstream(const char *fn, const char *m)
{
std::ios_base::openmode mode = std::ios_base::binary;
if(!strcmp(m,"r") || !strcmp(m,"rb"))
mode |= std::ios_base::in;
else if(!strcmp(m,"w") || !strcmp(m,"wb"))
mode |= std::ios_base::out | std::ios_base::trunc;
else if(!strcmp(m,"a") || !strcmp(m,"ab"))
mode |= std::ios_base::out | std::ios_base::app;
else if(!strcmp(m,"r+") || !strcmp(m,"r+b"))
mode |= std::ios_base::in | std::ios_base::out;
else if(!strcmp(m,"w+") || !strcmp(m,"w+b"))
mode |= std::ios_base::in | std::ios_base::out | std::ios_base::trunc;
else if(!strcmp(m,"a+") || !strcmp(m,"a+b"))
mode |= std::ios_base::in | std::ios_base::out | std::ios_base::app;
return new EMUFILE_FILE(fn, m);
//return new std::fstream(fn,mode);
}
static const char *s_linuxCompilerString = "g++ " __VERSION__;
/**
* Returns the compiler string.
*/
const char *FCEUD_GetCompilerString(void)
{
return s_linuxCompilerString;
}
/**
* Get the time in ticks.
*/
uint64
FCEUD_GetTime(void)
{
return SDL_GetTicks();
}
/**
* Get the tick frequency in Hz.
*/
uint64
FCEUD_GetTimeFreq(void)
{
// SDL_GetTicks() is in milliseconds
return 1000;
}
void FCEUD_DebugBreakpoint( int addr )
{
// TODO
}
/**
* Initialize all of the subsystem drivers: video, audio, and joystick.
*/
static int
DriverInitialize(FCEUGI *gi)
{
if(InitVideo(gi) < 0) return 0;
inited|=4;
if(InitSound())
inited|=1;
if(InitJoysticks())
inited|=2;
int fourscore=0;
g_config->getOption("SDL.FourScore", &fourscore);
eoptions &= ~EO_FOURSCORE;
if(fourscore)
eoptions |= EO_FOURSCORE;
InitInputInterface();
return 1;
}
/**
* Shut down all of the subsystem drivers: video, audio, and joystick.
*/
static void
DriverKill()
{
if (!noconfig)
g_config->save();
if(inited&2)
KillJoysticks();
if(inited&4)
KillVideo();
if(inited&1)
KillSound();
inited=0;
}
/**
* Loads a game, given a full path/filename. The driver code must be
* initialized after the game is loaded, because the emulator code
* provides data necessary for the driver code(number of scanlines to
* render, what virtual input devices to use, etc.).
*/
int LoadGame(const char *path)
{
if (isloaded){
CloseGame();
}
if(!FCEUI_LoadGame(path, 1)) {
return 0;
}
int state_to_load;
g_config->getOption("SDL.AutoLoadState", &state_to_load);
if (state_to_load >= 0 && state_to_load < 10){
FCEUI_SelectState(state_to_load, 0);
FCEUI_LoadState(NULL, false);
}
ParseGIInput(GameInfo);
RefreshThrottleFPS();
if(!DriverInitialize(GameInfo)) {
return(0);
}
// set pal/ntsc
int id;
g_config->getOption("SDL.PAL", &id);
FCEUI_SetRegion(id);
g_config->getOption("SDL.SwapDuty", &id);
swapDuty = id;
std::string filename;
g_config->getOption("SDL.Sound.RecordFile", &filename);
if(filename.size()) {
if(!FCEUI_BeginWaveRecord(filename.c_str())) {
g_config->setOption("SDL.Sound.RecordFile", "");
}
}
isloaded = 1;
FCEUD_NetworkConnect();
return 1;
}
/**
* Closes a game. Frees memory, and deinitializes the drivers.
*/
int
CloseGame(void)
{
std::string filename;
if(!isloaded) {
return(0);
}
int state_to_save;
g_config->getOption("SDL.AutoSaveState", &state_to_save);
if (state_to_save < 10 && state_to_save >= 0){
FCEUI_SelectState(state_to_save, 0);
FCEUI_SaveState(NULL, false);
}
FCEUI_CloseGame();
DriverKill();
isloaded = 0;
GameInfo = 0;
g_config->getOption("SDL.Sound.RecordFile", &filename);
if(filename.size()) {
FCEUI_EndWaveRecord();
}
InputUserActiveFix();
return(1);
}
// dummy functions
#define DUMMY(__f) \
void __f(void) {\
printf("%s\n", #__f);\
FCEU_DispMessage("Not implemented.",0);\
}
DUMMY(FCEUD_HideMenuToggle)
DUMMY(FCEUD_MovieReplayFrom)
DUMMY(FCEUD_ToggleStatusIcon)
DUMMY(FCEUD_AviRecordTo)
DUMMY(FCEUD_AviStop)
void FCEUI_AviVideoUpdate(const unsigned char* buffer) { }
int FCEUD_ShowStatusIcon(void) {return 0;}
bool FCEUI_AviIsRecording(void) {return false;}
void FCEUI_UseInputPreset(int preset) { }
bool FCEUD_PauseAfterPlayback() { return false; }
void FCEUD_TurboOn (void) { /* TODO */ };
void FCEUD_TurboOff (void) { /* TODO */ };
void FCEUD_TurboToggle(void) { /* TODO */ };
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex) { return 0; }
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename) { return 0; }
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string &fname, int innerIndex, int* userCancel) { return 0; }
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int* userCancel) { return 0; }
ArchiveScanRecord FCEUD_ScanArchive(std::string fname) { return ArchiveScanRecord(); }

View File

@ -0,0 +1,23 @@
// fceuWrapper.h
//
#include "config.h"
//*****************************************************************
// Define Global Variables to be shared with FCEU Core
//*****************************************************************
extern int dendy;
extern int eoptions;
extern int isLoaded;
extern int pal_emulation;
extern int gametype;
extern int closeFinishedMovie;
extern bool turbo;
extern bool swapDuty;
extern unsigned int gui_draw_area_width;
extern unsigned int gui_draw_area_height;
// global configuration object
extern Config *g_config;
int LoadGame(const char *path);
int CloseGame(void);

54
src/drivers/Qt/gl_win.cpp Normal file
View File

@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "gl_win.h"
gl_win_shm_t *gl_shm = NULL;
//************************************************************************
gl_win_shm_t *open_video_shm(void)
{
int shmId;
gl_win_shm_t *vaddr;
struct shmid_ds ds;
shmId = shmget( IPC_PRIVATE, sizeof(struct gl_win_shm_t), IPC_CREAT | S_IRWXU | S_IRWXG );
if ( shmId == -1 )
{
perror("Error: GL shmget Failed:");
return NULL;
}
printf("Created ShmID: %i \n", shmId );
vaddr = (gl_win_shm_t*)shmat( shmId, NULL, 0);
if ( vaddr == (gl_win_shm_t*)-1 )
{
perror("Error: GLX shmat Failed:");
return NULL;
}
memset( vaddr, 0, sizeof(struct gl_win_shm_t));
if ( shmctl( shmId, IPC_RMID, &ds ) != 0 )
{
perror("Error: GLX shmctl IPC_RMID Failed:");
}
//sem_init( &vaddr->sem, 1, 1 );
vaddr->ncol = 256;
vaddr->nrow = 256;
vaddr->pitch = 256 * 4;
return vaddr;
}
//************************************************************************

68
src/drivers/Qt/gl_win.h Normal file
View File

@ -0,0 +1,68 @@
// glxwin.cpp
//
#ifndef __GLXWIN_H__
#define __GLXWIN_H__
#include <stdint.h>
#define GL_WIN_PIXEL_LINEAR_FILTER 0x0001
#define GL_WIN_DOUBLE_BUFFER 0x0002
#define GL_NES_WIDTH 256
#define GL_NES_HEIGHT 256
struct gl_win_shm_t
{
int pid;
int run;
uint32_t render_count;
uint32_t blit_count;
int ncol;
int nrow;
int pitch;
// Pass Key Events back to QT Gui
struct
{
int head;
int tail;
struct {
int type;
int keycode;
int state;
} data[64];
} keyEventBuf;
// Gui Command Event Queue
struct
{
int head;
int tail;
struct {
int id;
union {
int i32[4];
float f32[4];
} param;
} cmd[64];
} guiEvent;
uint32_t pixbuf[65536]; // 256 x 256
void clear_pixbuf(void)
{
memset( pixbuf, 0, sizeof(pixbuf) );
}
};
extern gl_win_shm_t *gl_shm;
gl_win_shm_t *open_video_shm(void);
#endif

2355
src/drivers/Qt/input.cpp Normal file

File diff suppressed because it is too large Load Diff

62
src/drivers/Qt/input.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef _aosdfjk02fmasf
#define _aosdfjk02fmasf
#include "../common/configSys.h"
#define MAXBUTTCONFIG 4
typedef struct {
uint8 ButtType[MAXBUTTCONFIG];
uint8 DeviceNum[MAXBUTTCONFIG];
//uint16 ButtonNum[MAXBUTTCONFIG];
int ButtonNum[MAXBUTTCONFIG];
uint32 NumC;
//uint64 DeviceID[MAXBUTTCONFIG]; /* TODO */
} ButtConfig;
extern int NoWaiting;
extern CFGSTRUCT InputConfig[];
extern ARGPSTRUCT InputArgs[];
extern int Hotkeys[];
void ParseGIInput(FCEUGI *GI);
void setHotKeys();
int getKeyState( int k );
int ButtonConfigBegin();
void ButtonConfigEnd();
void ConfigButton(char *text, ButtConfig *bc);
int DWaitButton(const uint8 *text, ButtConfig *bc, int wb, int *buttonConfigStatus = NULL);
#define BUTTC_KEYBOARD 0x00
#define BUTTC_JOYSTICK 0x01
#define BUTTC_MOUSE 0x02
#define FCFGD_GAMEPAD 1
#define FCFGD_POWERPAD 2
#define FCFGD_HYPERSHOT 3
#define FCFGD_QUIZKING 4
#define SDL_FCEU_HOTKEY_EVENT SDL_USEREVENT
void InitInputInterface(void);
void InputUserActiveFix(void);
extern bool replaceP2StartWithMicrophone;
extern ButtConfig GamePadConfig[4][10];
//extern ButtConfig powerpadsc[2][12];
//extern ButtConfig QuizKingButtons[6];
//extern ButtConfig FTrainerButtons[12];
void IncreaseEmulationSpeed(void);
void DecreaseEmulationSpeed(void);
int DTestButtonJoy(ButtConfig *bc);
void FCEUD_UpdateInput(void);
void UpdateInput(Config *config);
void InputCfg(const std::string &);
std::string GetUserText(const char* title);
const char* ButtonName(const ButtConfig* bc, int which);
#endif

44
src/drivers/Qt/keyscan.h Normal file
View File

@ -0,0 +1,44 @@
#define SDLK_A SDLK_a
#define SDLK_B SDLK_b
#define SDLK_C SDLK_c
#define SDLK_D SDLK_d
#define SDLK_E SDLK_e
#define SDLK_F SDLK_f
#define SDLK_G SDLK_g
#define SDLK_H SDLK_h
#define SDLK_I SDLK_i
#define SDLK_J SDLK_j
#define SDLK_K SDLK_k
#define SDLK_L SDLK_l
#define SDLK_M SDLK_m
#define SDLK_N SDLK_n
#define SDLK_O SDLK_o
#define SDLK_P SDLK_p
#define SDLK_Q SDLK_q
#define SDLK_R SDLK_r
#define SDLK_S SDLK_s
#define SDLK_T SDLK_t
#define SDLK_U SDLK_u
#define SDLK_V SDLK_v
#define SDLK_W SDLK_w
#define SDLK_X SDLK_x
#define SDLK_Y SDLK_y
#define SDLK_Z SDLK_z
#define SDLK_LEFTCONTROL SDLK_LCTRL
#define SDLK_RIGHTCONTROL SDLK_RCTRL
#define SDLK_LEFTALT SDLK_LALT
#define SDLK_RIGHTALT SDLK_RALT
#define SDLK_LEFTSHIFT SDLK_LSHIFT
#define SDLK_RIGHTSHIFT SDLK_RSHIFT
#define SDLK_CURSORDOWN SDLK_DOWN
#define SDLK_CURSORUP SDLK_UP
#define SDLK_CURSORLEFT SDLK_LEFT
#define SDLK_CURSORRIGHT SDLK_RIGHT
#define SDLK_ENTER SDLK_RETURN
#define SDLK_EQUAL SDLK_EQUALS
#define SDLK_APOSTROPHE SDLK_QUOTE
#define SDLK_BRACKET_LEFT SDLK_LEFTBRACKET
#define SDLK_BRACKET_RIGHT SDLK_RIGHTBRACKET
#define SDLK_SCROLLLOCK SDLK_SCROLLOCK /* I guess the SDL people don't like lots of Ls... */
#define SDLK_GRAVE SDLK_BACKQUOTE
#define MKK(k) SDLK_##k

15
src/drivers/Qt/main.cpp Normal file
View File

@ -0,0 +1,15 @@
#include <QApplication>
#include "GameApp.h"
int main( int argc, char *argv[] )
{
QApplication app(argc, argv);
gameWin_t win;
win.resize( 200, 200 );
win.show();
return app.exec();
}

100
src/drivers/Qt/main.h Normal file
View File

@ -0,0 +1,100 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* 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
*/
#ifndef __FCEU_SDL_MAIN_H
#define __FCEU_SDL_MAIN_H
#include "../../driver.h"
#include "../common/config.h"
#include "../common/args.h"
extern int eoptions;
#define EO_NO8LIM 1
#define EO_SUBASE 2
#define EO_CLIPSIDES 8
#define EO_SNAPNAME 16
#define EO_FOURSCORE 32
#define EO_NOTHROTTLE 64
#define EO_GAMEGENIE 128
#define EO_PAL 256
#define EO_LOWPASS 512
#define EO_AUTOHIDE 1024
extern int _sound;
extern long soundrate;
extern long soundbufsize;
extern int pal_emulation;
int CLImain(int argc, char *argv[]);
// Device management defaults
#define NUM_INPUT_DEVICES 3
// GamePad defaults
#define GAMEPAD_NUM_DEVICES 4
#define GAMEPAD_NUM_BUTTONS 10
extern const char *GamePadNames[GAMEPAD_NUM_BUTTONS];
extern const char *DefaultGamePadDevice[GAMEPAD_NUM_DEVICES];
extern const int DefaultGamePad[GAMEPAD_NUM_DEVICES][GAMEPAD_NUM_BUTTONS];
// PowerPad defaults
#define POWERPAD_NUM_DEVICES 2
#define POWERPAD_NUM_BUTTONS 12
extern const char *PowerPadNames[POWERPAD_NUM_BUTTONS];
extern const char *DefaultPowerPadDevice[POWERPAD_NUM_DEVICES];
extern const int DefaultPowerPad[POWERPAD_NUM_DEVICES][POWERPAD_NUM_BUTTONS];
// QuizKing defaults
#define QUIZKING_NUM_BUTTONS 6
extern const char *QuizKingNames[QUIZKING_NUM_BUTTONS];
extern const char *DefaultQuizKingDevice;
extern const int DefaultQuizKing[QUIZKING_NUM_BUTTONS];
// HyperShot defaults
#define HYPERSHOT_NUM_BUTTONS 4
extern const char *HyperShotNames[HYPERSHOT_NUM_BUTTONS];
extern const char *DefaultHyperShotDevice;
extern const int DefaultHyperShot[HYPERSHOT_NUM_BUTTONS];
// Mahjong defaults
#define MAHJONG_NUM_BUTTONS 21
extern const char *MahjongNames[MAHJONG_NUM_BUTTONS];
extern const char *DefaultMahjongDevice;
extern const int DefaultMahjong[MAHJONG_NUM_BUTTONS];
// TopRider defaults
#define TOPRIDER_NUM_BUTTONS 8
extern const char *TopRiderNames[TOPRIDER_NUM_BUTTONS];
extern const char *DefaultTopRiderDevice;
extern const int DefaultTopRider[TOPRIDER_NUM_BUTTONS];
// FTrainer defaults
#define FTRAINER_NUM_BUTTONS 12
extern const char *FTrainerNames[FTRAINER_NUM_BUTTONS];
extern const char *DefaultFTrainerDevice;
extern const int DefaultFTrainer[FTRAINER_NUM_BUTTONS];
// FamilyKeyBoard defaults
#define FAMILYKEYBOARD_NUM_BUTTONS 0x48
extern const char *FamilyKeyBoardNames[FAMILYKEYBOARD_NUM_BUTTONS];
extern const char *DefaultFamilyKeyBoardDevice;
extern const int DefaultFamilyKeyBoard[FAMILYKEYBOARD_NUM_BUTTONS];
#endif

View File

@ -0,0 +1,123 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
* Copyright (C) 2002 Paul Kuliniewicz
*
* 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
*/
/// \file
/// \brief Handles joystick input using the SDL.
#include "sdl.h"
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <cerrno>
#define MAX_JOYSTICKS 32
static SDL_Joystick *s_Joysticks[MAX_JOYSTICKS] = {NULL};
static int s_jinited = 0;
/**
* Tests if the given button is active on the joystick.
*/
int
DTestButtonJoy(ButtConfig *bc)
{
int x;
for(x = 0; x < bc->NumC; x++)
{
if(bc->ButtonNum[x] & 0x2000)
{
/* Hat "button" */
if(SDL_JoystickGetHat(s_Joysticks[bc->DeviceNum[x]],
((bc->ButtonNum[x] >> 8) & 0x1F)) &
(bc->ButtonNum[x]&0xFF))
return 1;
}
else if(bc->ButtonNum[x] & 0x8000)
{
/* Axis "button" */
int pos;
pos = SDL_JoystickGetAxis(s_Joysticks[bc->DeviceNum[x]],
bc->ButtonNum[x] & 16383);
if ((bc->ButtonNum[x] & 0x4000) && pos <= -16383) {
return 1;
} else if (!(bc->ButtonNum[x] & 0x4000) && pos >= 16363) {
return 1;
}
}
else if(SDL_JoystickGetButton(s_Joysticks[bc->DeviceNum[x]],
bc->ButtonNum[x]))
return 1;
}
return 0;
}
/**
* Shutdown the SDL joystick subsystem.
*/
int
KillJoysticks()
{
int n; /* joystick index */
if(!s_jinited) {
return -1;
}
for(n = 0; n < MAX_JOYSTICKS; n++) {
if (s_Joysticks[n] != 0) {
SDL_JoystickClose(s_Joysticks[n]);
}
s_Joysticks[n]=0;
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
return 0;
}
/**
* Initialize the SDL joystick subsystem.
*/
int
InitJoysticks()
{
int n; /* joystick index */
int total;
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
total = SDL_NumJoysticks();
if(total>MAX_JOYSTICKS) {
total = MAX_JOYSTICKS;
}
for(n = 0; n < total; n++) {
/* Open the joystick under SDL. */
s_Joysticks[n] = SDL_JoystickOpen(n);
//printf("Could not open joystick %d: %s.\n",
//joy[n] - 1, SDL_GetError());
continue;
}
s_jinited = 1;
return 1;
}

View File

@ -0,0 +1,280 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* 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
*/
/// \file
/// \brief Handles sound emulation using the SDL.
#include "sdl.h"
#include "../common/configSys.h"
#include "../../utils/memory.h"
#include <cstdio>
#include <cstring>
#include <cstdlib>
extern Config *g_config;
static volatile int *s_Buffer = 0;
static unsigned int s_BufferSize;
static unsigned int s_BufferRead;
static unsigned int s_BufferWrite;
static volatile unsigned int s_BufferIn;
static int s_mute = 0;
/**
* Callback from the SDL to get and play audio data.
*/
static void
fillaudio(void *udata,
uint8 *stream,
int len)
{
int16 *tmps = (int16*)stream;
len >>= 1;
while(len) {
int16 sample = 0;
if(s_BufferIn) {
sample = s_Buffer[s_BufferRead];
s_BufferRead = (s_BufferRead + 1) % s_BufferSize;
s_BufferIn--;
} else {
sample = 0;
}
*tmps = sample;
tmps++;
len--;
}
}
/**
* Initialize the audio subsystem.
*/
int
InitSound()
{
int sound, soundrate, soundbufsize, soundvolume, soundtrianglevolume, soundsquare1volume, soundsquare2volume, soundnoisevolume, soundpcmvolume, soundq;
SDL_AudioSpec spec;
const char *driverName;
g_config->getOption("SDL.Sound", &sound);
if (!sound)
{
return 0;
}
memset(&spec, 0, sizeof(spec));
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
puts(SDL_GetError());
KillSound();
return 0;
}
// load configuration variables
g_config->getOption("SDL.Sound.Rate", &soundrate);
g_config->getOption("SDL.Sound.BufSize", &soundbufsize);
g_config->getOption("SDL.Sound.Volume", &soundvolume);
g_config->getOption("SDL.Sound.Quality", &soundq);
g_config->getOption("SDL.Sound.TriangleVolume", &soundtrianglevolume);
g_config->getOption("SDL.Sound.Square1Volume", &soundsquare1volume);
g_config->getOption("SDL.Sound.Square2Volume", &soundsquare2volume);
g_config->getOption("SDL.Sound.NoiseVolume", &soundnoisevolume);
g_config->getOption("SDL.Sound.PCMVolume", &soundpcmvolume);
spec.freq = soundrate;
spec.format = AUDIO_S16SYS;
spec.channels = 1;
spec.samples = 512;
spec.callback = fillaudio;
spec.userdata = 0;
s_BufferSize = soundbufsize * soundrate / 1000;
// For safety, set a bare minimum:
if (s_BufferSize < spec.samples * 2)
{
s_BufferSize = spec.samples * 2;
}
s_Buffer = (int *)FCEU_dmalloc(sizeof(int) * s_BufferSize);
if (!s_Buffer)
{
return 0;
}
s_BufferRead = s_BufferWrite = s_BufferIn = 0;
if (SDL_OpenAudio(&spec, 0) < 0)
{
puts(SDL_GetError());
KillSound();
return 0;
}
SDL_PauseAudio(0);
driverName = SDL_GetCurrentAudioDriver();
if ( driverName )
{
fprintf(stderr, "Loading SDL sound with %s driver...\n", driverName);
}
FCEUI_SetSoundVolume(soundvolume);
FCEUI_SetSoundQuality(soundq);
FCEUI_Sound(soundrate);
FCEUI_SetTriangleVolume(soundtrianglevolume);
FCEUI_SetSquare1Volume(soundsquare1volume);
FCEUI_SetSquare2Volume(soundsquare2volume);
FCEUI_SetNoiseVolume(soundnoisevolume);
FCEUI_SetPCMVolume(soundpcmvolume);
return 1;
}
/**
* Returns the size of the audio buffer.
*/
uint32
GetMaxSound(void)
{
return(s_BufferSize);
}
/**
* Returns the amount of free space in the audio buffer.
*/
uint32
GetWriteSound(void)
{
return(s_BufferSize - s_BufferIn);
}
/**
* Send a sound clip to the audio subsystem.
*/
void
WriteSound(int32 *buf,
int Count)
{
extern int EmulationPaused;
if (EmulationPaused == 0)
while(Count)
{
while(s_BufferIn == s_BufferSize)
{
SDL_Delay(1);
}
s_Buffer[s_BufferWrite] = *buf;
Count--;
s_BufferWrite = (s_BufferWrite + 1) % s_BufferSize;
SDL_LockAudio();
s_BufferIn++;
SDL_UnlockAudio();
buf++;
}
}
/**
* Pause (1) or unpause (0) the audio output.
*/
void
SilenceSound(int n)
{
SDL_PauseAudio(n);
}
/**
* Shut down the audio subsystem.
*/
int
KillSound(void)
{
FCEUI_Sound(0);
SDL_CloseAudio();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
if(s_Buffer) {
free((void *)s_Buffer);
s_Buffer = 0;
}
return 0;
}
/**
* Adjust the volume either down (-1), up (1), or to the default (0).
* Unmutes if mute was active before.
*/
void
FCEUD_SoundVolumeAdjust(int n)
{
int soundvolume;
g_config->getOption("SDL.Sound.Volume", &soundvolume);
switch(n) {
case -1:
soundvolume -= 10;
if(soundvolume < 0) {
soundvolume = 0;
}
break;
case 0:
soundvolume = 100;
break;
case 1:
soundvolume += 10;
if(soundvolume > 150) {
soundvolume = 150;
}
break;
}
s_mute = 0;
FCEUI_SetSoundVolume(soundvolume);
g_config->setOption("SDL.Sound.Volume", soundvolume);
FCEU_DispMessage("Sound volume %d.",0, soundvolume);
}
/**
* Toggles the sound on or off.
*/
void
FCEUD_SoundToggle(void)
{
if(s_mute) {
int soundvolume;
g_config->getOption("SDL.SoundVolume", &soundvolume);
s_mute = 0;
FCEUI_SetSoundVolume(soundvolume);
FCEU_DispMessage("Sound mute off.",0);
} else {
s_mute = 1;
FCEUI_SetSoundVolume(0);
FCEU_DispMessage("Sound mute on.",0);
}
}

View File

@ -0,0 +1,154 @@
/// \file
/// \brief Handles emulation speed throttling using the SDL timing functions.
#include "sdl.h"
#include "throttle.h"
static const double Slowest = 0.015625; // 1/64x speed (around 1 fps on NTSC)
static const double Fastest = 32; // 32x speed (around 1920 fps on NTSC)
static const double Normal = 1.0; // 1x speed (around 60 fps on NTSC)
static uint64 Lasttime, Nexttime;
static long double desired_frametime;
static int InFrame;
double g_fpsScale = Normal; // used by sdl.cpp
bool MaxSpeed = false;
/* LOGMUL = exp(log(2) / 3)
*
* This gives us a value such that if we do x*=LOGMUL three times,
* then after that, x is twice the value it was before.
*
* This gives us three speed steps per order of magnitude.
*
*/
#define LOGMUL 1.259921049894873
/**
* Refreshes the FPS throttling variables.
*/
void
RefreshThrottleFPS()
{
uint64 fps = FCEUI_GetDesiredFPS(); // Do >> 24 to get in Hz
desired_frametime = 16777216.0l / (fps * g_fpsScale);
Lasttime=0;
Nexttime=0;
InFrame=0;
}
/**
* Perform FPS speed throttling by delaying until the next time slot.
*/
int
SpeedThrottle()
{
if(g_fpsScale >= 32)
{
return 0; /* Done waiting */
}
uint64 time_left;
uint64 cur_time;
if(!Lasttime)
Lasttime = SDL_GetTicks();
if(!InFrame)
{
InFrame = 1;
Nexttime = Lasttime + desired_frametime * 1000;
}
cur_time = SDL_GetTicks();
if(cur_time >= Nexttime)
time_left = 0;
else
time_left = Nexttime - cur_time;
if(time_left > 50)
{
time_left = 50;
/* In order to keep input responsive, don't wait too long at once */
/* 50 ms wait gives us a 20 Hz responsetime which is nice. */
}
else
InFrame = 0;
//fprintf(stderr, "attempting to sleep %Ld ms, frame complete=%s\n",
// time_left, InFrame?"no":"yes");
if ( time_left > 0 )
{
SDL_Delay(time_left);
}
if(!InFrame)
{
Lasttime = SDL_GetTicks();
return 0; /* Done waiting */
}
return 1; /* Must still wait some more */
}
/**
* Set the emulation speed throttling to the next entry in the speed table.
*/
void IncreaseEmulationSpeed(void)
{
g_fpsScale *= LOGMUL;
if(g_fpsScale > Fastest) g_fpsScale = Fastest;
RefreshThrottleFPS();
FCEU_DispMessage("Emulation speed %.1f%%",0, g_fpsScale*100.0);
}
/**
* Set the emulation speed throttling to the previous entry in the speed table.
*/
void DecreaseEmulationSpeed(void)
{
g_fpsScale /= LOGMUL;
if(g_fpsScale < Slowest)
g_fpsScale = Slowest;
RefreshThrottleFPS();
FCEU_DispMessage("Emulation speed %.1f%%",0, g_fpsScale*100.0);
}
/**
* Set the emulation speed throttling to a specific value.
*/
void
FCEUD_SetEmulationSpeed(int cmd)
{
MaxSpeed = false;
switch(cmd) {
case EMUSPEED_SLOWEST:
g_fpsScale = Slowest;
break;
case EMUSPEED_SLOWER:
DecreaseEmulationSpeed();
break;
case EMUSPEED_NORMAL:
g_fpsScale = Normal;
break;
case EMUSPEED_FASTER:
IncreaseEmulationSpeed();
break;
case EMUSPEED_FASTEST:
g_fpsScale = Fastest;
MaxSpeed = true;
break;
default:
return;
}
RefreshThrottleFPS();
FCEU_DispMessage("Emulation speed %.1f%%",0, g_fpsScale*100.0);
}

View File

@ -0,0 +1,464 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* 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
*/
/// \file
/// \brief Handles the graphical game display for the SDL implementation.
#include "sdl.h"
#include "gl_win.h"
#include "../common/vidblit.h"
#include "../../fceu.h"
#include "../../version.h"
#include "../../video.h"
#include "../../utils/memory.h"
//#include "sdl-icon.h"
#include "dface.h"
#include "../common/configSys.h"
#include "sdl-video.h"
#include "fceuWrapper.h"
#ifdef CREATE_AVI
#include "../videolog/nesvideos-piece.h"
#endif
#include <cstdio>
#include <cstring>
#include <cstdlib>
// GLOBALS
extern Config *g_config;
// STATIC GLOBALS
static int s_curbpp = 0;
static int s_srendline, s_erendline;
static int s_tlines;
static int s_inited = 0;
//#ifdef OPENGL
//static int s_useOpenGL = 0;
//#endif
static double s_exs = 1.0, s_eys = 1.0;
static int s_eefx = 0;
static int s_clipSides = 0;
static int s_fullscreen = 0;
static int noframe = 0;
static int initBlitToHighDone = 0;
#define NWIDTH (256 - (s_clipSides ? 16 : 0))
#define NOFFSET (s_clipSides ? 8 : 0)
static int s_paletterefresh = 1;
extern bool MaxSpeed;
/**
* Attempts to destroy the graphical video display. Returns 0 on
* success, -1 on failure.
*/
//draw input aids if we are fullscreen
bool FCEUD_ShouldDrawInputAids()
{
return s_fullscreen!=0;
}
int
KillVideo()
{
//printf("Killing Video\n");
if ( gl_shm != NULL )
{
gl_shm->clear_pixbuf();
}
//destroy_gui_video();
// return failure if the video system was not initialized
if (s_inited == 0)
return -1;
// if the rest of the system has been initialized, shut it down
// // shut down the system that converts from 8 to 16/32 bpp
// if (s_curbpp > 8)
// {
// KillBlitToHigh();
// }
// SDL Video system is not used.
// shut down the SDL video sub-system
//SDL_QuitSubSystem(SDL_INIT_VIDEO);
s_inited = 0;
return 0;
}
// this variable contains information about the special scaling filters
static int s_sponge = 0;
/**
* These functions determine an appropriate scale factor for fullscreen/
*/
inline double GetXScale(int xres)
{
return ((double)xres) / NWIDTH;
}
inline double GetYScale(int yres)
{
return ((double)yres) / s_tlines;
}
void FCEUD_VideoChanged()
{
int buf;
g_config->getOption("SDL.PAL", &buf);
if(buf == 1)
PAL = 1;
else
PAL = 0; // NTSC and Dendy
}
int InitVideo(FCEUGI *gi)
{
int doublebuf, xstretch, ystretch, xres, yres, show_fps;
FCEUI_printf("Initializing video...");
// load the relevant configuration variables
g_config->getOption("SDL.Fullscreen", &s_fullscreen);
g_config->getOption("SDL.DoubleBuffering", &doublebuf);
//#ifdef OPENGL
// g_config->getOption("SDL.OpenGL", &s_useOpenGL);
//#endif
//g_config->getOption("SDL.SpecialFilter", &s_sponge);
g_config->getOption("SDL.XStretch", &xstretch);
g_config->getOption("SDL.YStretch", &ystretch);
//g_config->getOption("SDL.LastXRes", &xres);
//g_config->getOption("SDL.LastYRes", &yres);
g_config->getOption("SDL.ClipSides", &s_clipSides);
g_config->getOption("SDL.NoFrame", &noframe);
g_config->getOption("SDL.ShowFPS", &show_fps);
//g_config->getOption("SDL.XScale", &s_exs);
//g_config->getOption("SDL.YScale", &s_eys);
uint32_t rmask, gmask, bmask;
s_sponge = 0;
s_exs = 1.0;
s_eys = 1.0;
xres = gui_draw_area_width;
yres = gui_draw_area_height;
// check the starting, ending, and total scan lines
FCEUI_GetCurrentVidSystem(&s_srendline, &s_erendline);
s_tlines = s_erendline - s_srendline + 1;
//init_gui_video( s_useOpenGL );
s_inited = 1;
// check to see if we are showing FPS
FCEUI_SetShowFPS(show_fps);
#ifdef LSB_FIRST
rmask = 0x000000FF;
gmask = 0x0000FF00;
bmask = 0x00FF0000;
#else
rmask = 0x00FF0000;
gmask = 0x0000FF00;
bmask = 0x000000FF;
#endif
s_curbpp = 32; // Bits per pixel is always 32
FCEU_printf(" Video Mode: %d x %d x %d bpp %s\n",
xres, yres, s_curbpp,
s_fullscreen ? "full screen" : "");
if (s_curbpp != 8 && s_curbpp != 16 && s_curbpp != 24 && s_curbpp != 32)
{
FCEU_printf(" Sorry, %dbpp modes are not supported by FCE Ultra. Supported bit depths are 8bpp, 16bpp, and 32bpp.\n", s_curbpp);
KillVideo();
return -1;
}
#ifdef OPENGL
if(s_exs <= 0.01) {
FCEUD_PrintError("xscale out of bounds.");
KillVideo();
return -1;
}
if(s_eys <= 0.01) {
FCEUD_PrintError("yscale out of bounds.");
KillVideo();
return -1;
}
//if(s_sponge && s_useOpenGL) {
// FCEUD_PrintError("scalers not compatible with openGL mode.");
// KillVideo();
// return -1;
//}
#endif
if ( !initBlitToHighDone )
{
InitBlitToHigh(s_curbpp >> 3,
rmask,
gmask,
bmask,
s_eefx, s_sponge, 0);
initBlitToHighDone = 1;
}
return 0;
}
/**
* Toggles the full-screen display.
*/
void ToggleFS(void)
{
// pause while we we are making the switch
bool paused = FCEUI_EmulationPaused();
if(!paused)
FCEUI_ToggleEmulationPause();
int error, fullscreen = s_fullscreen;
// shut down the current video system
KillVideo();
// flip the fullscreen flag
g_config->setOption("SDL.Fullscreen", !fullscreen);
#ifdef _GTK
if(noGui == 0)
{
if(!fullscreen)
showGui(0);
else
showGui(1);
}
#endif
// try to initialize the video
error = InitVideo(GameInfo);
if(error) {
// if we fail, just continue with what worked before
g_config->setOption("SDL.Fullscreen", fullscreen);
InitVideo(GameInfo);
}
// if we paused to make the switch; unpause
if(!paused)
FCEUI_ToggleEmulationPause();
}
static SDL_Color s_psdl[256];
/**
* Sets the color for a particular index in the palette.
*/
void
FCEUD_SetPalette(uint8 index,
uint8 r,
uint8 g,
uint8 b)
{
s_psdl[index].r = r;
s_psdl[index].g = g;
s_psdl[index].b = b;
s_paletterefresh = 1;
}
/**
* Gets the color for a particular index in the palette.
*/
void
FCEUD_GetPalette(uint8 index,
uint8 *r,
uint8 *g,
uint8 *b)
{
*r = s_psdl[index].r;
*g = s_psdl[index].g;
*b = s_psdl[index].b;
}
/**
* Pushes the palette structure into the underlying video subsystem.
*/
static void RedoPalette()
{
if (s_curbpp > 8)
{
SetPaletteBlitToHigh((uint8*)s_psdl);
}
}
// XXX soules - console lock/unlock unimplemented?
///Currently unimplemented.
void LockConsole(){}
///Currently unimplemented.
void UnlockConsole(){}
/**
* Pushes the given buffer of bits to the screen.
*/
void
BlitScreen(uint8 *XBuf)
{
uint8 *dest;
int w, h, pitch;
// refresh the palette if required
if (s_paletterefresh)
{
RedoPalette();
s_paletterefresh = 0;
}
// XXX soules - not entirely sure why this is being done yet
XBuf += s_srendline * 256;
dest = (uint8*)gl_shm->pixbuf;
w = GL_NES_WIDTH;
h = GL_NES_HEIGHT;
pitch = w*4;
gl_shm->ncol = NWIDTH;
gl_shm->nrow = s_tlines;
gl_shm->pitch = pitch;
if ( dest == NULL ) return;
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1);
//guiPixelBufferReDraw();
#ifdef CREATE_AVI
{ int fps = FCEUI_GetDesiredFPS();
static unsigned char* result = NULL;
static unsigned resultsize = 0;
int width = NWIDTH, height = s_tlines;
if(!result || resultsize != width*height*3*2)
{
if(result) free(result);
result = (unsigned char*) FCEU_dmalloc(resultsize = width*height*3*2);
}
switch(s_curbpp)
{
#if 0
case 24: case 32: case 15: case 16:
/* Convert to I420 if possible, because our I420 conversion is optimized
* and it'll produce less network traffic, hence faster throughput than
* anything else. And H.264 eats only I420, so it'd be converted sooner
* or later anyway if we didn't do it. Win-win situation.
*/
switch(s_curbpp)
{
case 32: Convert32To_I420Frame(s_screen->pixels, &result[0], width*height, width); break;
case 24: Convert24To_I420Frame(s_screen->pixels, &result[0], width*height, width); break;
case 15: Convert15To_I420Frame(s_screen->pixels, &result[0], width*height, width); break;
case 16: Convert16To_I420Frame(s_screen->pixels, &result[0], width*height, width); break;
}
NESVideoLoggingVideo(&result[0], width,height, fps, 12);
break;
#endif
default:
NESVideoLoggingVideo( dest, width,height, fps, s_curbpp);
}
}
#endif // CREATE_AVI
#if REALTIME_LOGGING
{
static struct timeval last_time;
static int first_time=1;
extern long soundrate;
struct timeval cur_time;
gettimeofday(&cur_time, NULL);
double timediff =
(cur_time.tv_sec *1e6 + cur_time.tv_usec
- (last_time.tv_sec *1e6 + last_time.tv_usec)) / 1e6;
int nframes = timediff * 60 - 1;
if(first_time)
first_time = 0;
else while(nframes > 0)
{
static const unsigned char Buf[800*4] = {0};
NESVideoLoggingVideo(screen->pixels, 256,tlines, FCEUI_GetDesiredFPS(), s_curbpp);
NESVideoLoggingAudio(Buf, soundrate,16,1, soundrate/60.0);
--nframes;
}
memcpy(&last_time, &cur_time, sizeof(last_time));
}
#endif // REALTIME_LOGGING
}
/**
* Converts an x-y coordinate in the window manager into an x-y
* coordinate on FCEU's screen.
*/
uint32
PtoV(uint16 x,
uint16 y)
{
y = (uint16)((double)y / s_eys);
x = (uint16)((double)x / s_exs);
if(s_clipSides) {
x += 8;
}
y += s_srendline;
return (x | (y << 16));
}
bool enableHUDrecording = false;
bool FCEUI_AviEnableHUDrecording()
{
if (enableHUDrecording)
return true;
return false;
}
void FCEUI_SetAviEnableHUDrecording(bool enable)
{
enableHUDrecording = enable;
}
bool disableMovieMessages = false;
bool FCEUI_AviDisableMovieMessages()
{
if (disableMovieMessages)
return true;
return false;
}
void FCEUI_SetAviDisableMovieMessages(bool disable)
{
disableMovieMessages = disable;
}

View File

@ -0,0 +1,17 @@
#ifndef __FCEU_SDL_VIDEO_H
#define __FCEU_SDL_VIDEO_H
#ifdef _SDL2
#include <SDL2/SDL.h>
#else
#include <SDL.h>
#endif
uint32 PtoV(uint16 x, uint16 y);
bool FCEUD_ShouldDrawInputAids();
bool FCEUI_AviDisableMovieMessages();
bool FCEUI_AviEnableHUDrecording();
void FCEUI_SetAviEnableHUDrecording(bool enable);
bool FCEUI_AviDisableMovieMessages();
void FCEUI_SetAviDisableMovieMessages(bool disable);
#endif

32
src/drivers/Qt/sdl.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef __FCEU_SDL_H
#define __FCEU_SDL_H
#if _SDL2
#include <SDL2/SDL.h>
#else
#include <SDL.h>
#endif
#include "main.h"
#include "dface.h"
#include "input.h"
// I'm using this as a #define so the compiler can optimize the
// modulo operation
#define PERIODIC_SAVE_INTERVAL 5000 // milliseconds
const int INVALID_STATE = 99;
extern int noGui;
extern int isloaded;
extern int dendy;
extern int pal_emulation;
extern bool swapDuty;
int LoadGame(const char *path);
int CloseGame(void);
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
uint64 FCEUD_GetTime();
#endif

View File

@ -0,0 +1,2 @@
void RefreshThrottleFPS();
int SpeedThrottle(void);

View File

@ -0,0 +1,366 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2002 Xodnizel
*
* 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
*/
//todo - ensure that #ifdef WIN32 makes sense
//consider changing this to use sdl net stuff?
//#include "main.h"
//#include "input.h"
//#include "dface.h"
#include "unix-netplay.h"
#include "../../fceu.h"
#include "../../driver.h"
#include "../../utils/md5.h"
#include "../../utils/memory.h"
#include <string>
#include "../common/configSys.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cerrno>
#include <fcntl.h>
#ifdef WIN32
#include <winsock.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
extern Config *g_config;
#ifndef socklen_t
#define socklen_t int
#endif
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
int FCEUDnetplay=0;
static int s_Socket = -1;
static void
en32(uint8 *buf,
uint32 morp)
{
buf[0] = morp;
buf[1] = morp >> 8;
buf[2] = morp >> 16;
buf[3] = morp >> 24;
}
/*
static uint32 de32(uint8 *morp)
{
return(morp[0]|(morp[1]<<8)|(morp[2]<<16)|(morp[3]<<24));
}
*/
int
FCEUD_NetworkConnect(void)
{
struct sockaddr_in sockin;
struct hostent *phostentb;
unsigned long hadr;
int TSocket, tcpopt, error;
int netdivisor;
// get any required configuration variables
int port, localPlayers;
std::string server, username, password, key;
g_config->getOption("SDL.NetworkIP", &server);
g_config->getOption("SDL.NetworkUsername", &username);
g_config->getOption("SDL.NetworkPassword", &password);
g_config->getOption("SDL.NetworkGameKey", &key);
g_config->getOption("SDL.NetworkPort", &port);
g_config->getOption("SDL.NetworkPlayers", &localPlayers);
g_config->setOption("SDL.NetworkIP", "");
g_config->setOption("SDL.NetworkPassword", "");
g_config->setOption("SDL.NetworkGameKey", "");
// only initialize if remote server is specified
if(!server.size()) {
return 0;
}
TSocket = socket(AF_INET, SOCK_STREAM, 0);
if(TSocket < 0) {
const char* s = "Error creating stream socket.";
puts(s);
FCEU_DispMessage(s,0);
FCEUD_NetworkClose();
return 0;
}
// try to setup TCP_NODELAY to avoid network jitters
tcpopt = 1;
#ifdef BEOS
error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int));
#elif WIN32
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY,
(char*)&tcpopt, sizeof(int));
#else
error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int));
#endif
if(error) {
puts("Nodelay fail");
}
memset(&sockin, 0, sizeof(sockin));
sockin.sin_family = AF_INET;
hadr = inet_addr(server.c_str());
if(hadr != INADDR_NONE) {
sockin.sin_addr.s_addr = hadr;
} else {
puts("*** Looking up host name...");
phostentb = gethostbyname(server.c_str());
if(!phostentb) {
puts("Error getting host network information.");
FCEU_DispMessage("Error getting host info",0);
close(TSocket);
FCEUD_NetworkClose();
return(0);
}
memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length);
}
sockin.sin_port = htons(port);
puts("*** Connecting to remote host...");
error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin));
if(error < 0) {
puts("Error connecting to remote host.");
FCEU_DispMessage("Error connecting to server",0);
close(TSocket);
FCEUD_NetworkClose();
return 0;
}
s_Socket = TSocket;
puts("*** Sending initialization data to server...");
uint8 *sendbuf;
uint8 buf[5];
uint32 sblen;
sblen = 4 + 16 + 16 + 64 + 1 + username.size();
sendbuf = (uint8 *)FCEU_dmalloc(sblen);
memset(sendbuf, 0, sblen);
// XXX soules - should use htons instead of en32() from above!
//uint32 data = htons(sblen - 4);
//memcpy(sendbuf, &data, sizeof(data));
en32(sendbuf, sblen - 4);
if(key.size())
{
struct md5_context md5;
uint8 md5out[16];
md5_starts(&md5);
md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16);
md5_update(&md5, (uint8 *)key.c_str(), key.size());
md5_finish(&md5, md5out);
memcpy(sendbuf + 4, md5out, 16);
} else
{
memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16);
}
if(password.size()) {
struct md5_context md5;
uint8 md5out[16];
md5_starts(&md5);
md5_update(&md5, (uint8 *)password.c_str(), password.size());
md5_finish(&md5, md5out);
memcpy(sendbuf + 4 + 16, md5out, 16);
}
memset(sendbuf + 4 + 16 + 16, 0, 64);
sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers;
if(username.size()) {
memcpy(sendbuf + 4 + 16 + 16 + 64 + 1,
username.c_str(), username.size());
}
#ifdef WIN32
send(s_Socket, (char*)sendbuf, sblen, 0);
#else
send(s_Socket, sendbuf, sblen, 0);
#endif
FCEU_dfree(sendbuf);
#ifdef WIN32
recv(s_Socket, (char*)buf, 1, 0);
#else
recv(s_Socket, buf, 1, MSG_WAITALL);
#endif
netdivisor = buf[0];
puts("*** Connection established.");
FCEU_DispMessage("Connection established.",0);
FCEUDnetplay = 1;
FCEUI_NetplayStart(localPlayers, netdivisor);
return 1;
}
int
FCEUD_SendData(void *data,
uint32 len)
{
int check = 0, error = 0;
#ifndef WIN32
error = ioctl(fileno(stdin), FIONREAD, &check);
#endif
if(!error && check) {
char buf[1024];
char *f;
buf[0] = 0;
if ( fgets(buf, 1024, stdin) )
{
if((f=strrchr(buf,'\n'))) {
*f = 0;
}
}
FCEUI_NetplayText((uint8 *)buf);
}
#ifdef WIN32
send(s_Socket, (char*)data, len ,0);
#else
send(s_Socket, data, len ,0);
#endif
return 1;
}
int
FCEUD_RecvData(void *data,
uint32 len)
{
int size;
//NoWaiting &= ~2;
for(;;)
{
fd_set funfun;
struct timeval popeye;
popeye.tv_sec=0;
popeye.tv_usec=100000;
FD_ZERO(&funfun);
FD_SET(s_Socket, &funfun);
switch(select(s_Socket + 1,&funfun,0,0,&popeye)) {
case 0: continue;
case -1:return 0;
}
if(FD_ISSET(s_Socket,&funfun)) {
#ifdef WIN32
size = recv(s_Socket, (char*)data, len, 0);
#else
size = recv(s_Socket, data, len, MSG_WAITALL);
#endif
if(size == len) {
//unsigned long beefie;
FD_ZERO(&funfun);
FD_SET(s_Socket, &funfun);
popeye.tv_sec = popeye.tv_usec = 0;
if(select(s_Socket + 1, &funfun, 0, 0, &popeye) == 1)
//if(!ioctl(s_Socket,FIONREAD,&beefie))
// if(beefie)
{
//NoWaiting|=2;
}
return 1;
} else {
return 0;
}
}
}
return 0;
}
void
FCEUD_NetworkClose(void)
{
if(s_Socket > 0) {
#ifdef BEOS
closesocket(s_Socket);
#else
close(s_Socket);
#endif
}
s_Socket = -1;
if(FCEUDnetplay) {
FCEUI_NetplayStop();
}
FCEUDnetplay = 0;
}
void
FCEUD_NetplayText(uint8 *text)
{
char *tot = (char *)FCEU_dmalloc(strlen((const char *)text) + 1);
char *tmp;
if (!tot)
return;
strcpy(tot, (const char *)text);
tmp = tot;
while(*tmp) {
if(*tmp < 0x20) {
*tmp = ' ';
}
tmp++;
}
puts(tot);
FCEU_dfree(tot);
}

View File

@ -0,0 +1,6 @@
extern char *netplaynick;
extern char *netplayhost;
extern char *netpassword;
extern char *netgamekey;
extern int tport;
extern int netlocalplayers;

305
src/fceux.pro Normal file
View File

@ -0,0 +1,305 @@
######################################################################
# Automatically generated by qmake (3.1) Sat Jun 20 21:20:47 2020
######################################################################
TEMPLATE = app
TARGET = fceux
INCLUDEPATH += .
# The following define makes your compiler warn you if you use any
# feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
QT += widgets
CONFIG += object_parallel_to_source
unix {
QT_CONFIG -= no-pkg-config
CONFIG += link_pkgconfig
QMAKE_CXXFLAGS += -DPSS_STYLE=1 -DHAVE_ASPRINTF
packagesExist(minizip){
PKGCONFIG += minizip
QMAKE_CXXFLAGS += -D_SYSTEM_MINIZIP
}
packagesExist(zlib){
PKGCONFIG += zlib
}
PKGCONFIG += sdl2
packagesExist(lua-5.1){
PKGCONFIG += lua-5.1
QMAKE_CXXFLAGS += -D_S9XLUA_H
}
QMAKE_CXXFLAGS += -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs
}
# Input
SOURCES += asm.cpp
SOURCES += cart.cpp
SOURCES += cheat.cpp
SOURCES += conddebug.cpp
SOURCES += config.cpp
SOURCES += debug.cpp
SOURCES += drawing.cpp
SOURCES += fceu.cpp
SOURCES += fds.cpp
SOURCES += file.cpp
SOURCES += emufile.cpp
SOURCES += filter.cpp
SOURCES += ines.cpp
SOURCES += input.cpp
SOURCES += movie.cpp
SOURCES += netplay.cpp
SOURCES += nsf.cpp
SOURCES += oldmovie.cpp
SOURCES += palette.cpp
SOURCES += ppu.cpp
SOURCES += sound.cpp
SOURCES += state.cpp
SOURCES += unif.cpp
SOURCES += video.cpp
SOURCES += vsuni.cpp
SOURCES += wave.cpp
SOURCES += x6502.cpp
unix {
packagesExist(lua-5.1){
SOURCES += lua-engine.cpp
}
}
SOURCES += boards/01-222.cpp
SOURCES += boards/09-034a.cpp
SOURCES += boards/103.cpp
SOURCES += boards/106.cpp
SOURCES += boards/108.cpp
SOURCES += boards/112.cpp
SOURCES += boards/116.cpp
SOURCES += boards/117.cpp
SOURCES += boards/120.cpp
SOURCES += boards/121.cpp
SOURCES += boards/12in1.cpp
SOURCES += boards/151.cpp
SOURCES += boards/156.cpp
SOURCES += boards/158B.cpp
SOURCES += boards/15.cpp
SOURCES += boards/164.cpp
SOURCES += boards/168.cpp
SOURCES += boards/170.cpp
SOURCES += boards/175.cpp
SOURCES += boards/176.cpp
SOURCES += boards/177.cpp
SOURCES += boards/178.cpp
SOURCES += boards/183.cpp
SOURCES += boards/185.cpp
SOURCES += boards/186.cpp
SOURCES += boards/187.cpp
SOURCES += boards/189.cpp
SOURCES += boards/18.cpp
SOURCES += boards/190.cpp
SOURCES += boards/193.cpp
SOURCES += boards/199.cpp
SOURCES += boards/206.cpp
SOURCES += boards/208.cpp
SOURCES += boards/222.cpp
SOURCES += boards/225.cpp
SOURCES += boards/228.cpp
SOURCES += boards/230.cpp
SOURCES += boards/232.cpp
SOURCES += boards/234.cpp
SOURCES += boards/235.cpp
SOURCES += boards/244.cpp
SOURCES += boards/246.cpp
SOURCES += boards/252.cpp
SOURCES += boards/253.cpp
SOURCES += boards/28.cpp
SOURCES += boards/32.cpp
SOURCES += boards/33.cpp
SOURCES += boards/34.cpp
SOURCES += boards/36.cpp
SOURCES += boards/3d-block.cpp
SOURCES += boards/40.cpp
SOURCES += boards/411120-c.cpp
SOURCES += boards/41.cpp
SOURCES += boards/42.cpp
SOURCES += boards/43.cpp
SOURCES += boards/46.cpp
SOURCES += boards/50.cpp
SOURCES += boards/51.cpp
SOURCES += boards/57.cpp
SOURCES += boards/603-5052.cpp
SOURCES += boards/62.cpp
SOURCES += boards/65.cpp
SOURCES += boards/67.cpp
SOURCES += boards/68.cpp
SOURCES += boards/69.cpp
SOURCES += boards/71.cpp
SOURCES += boards/72.cpp
SOURCES += boards/77.cpp
SOURCES += boards/79.cpp
SOURCES += boards/80013-B.cpp
SOURCES += boards/80.cpp
SOURCES += boards/8157.cpp
SOURCES += boards/8237.cpp
SOURCES += boards/82.cpp
SOURCES += boards/830118C.cpp
SOURCES += boards/88.cpp
SOURCES += boards/8in1.cpp
SOURCES += boards/90.cpp
SOURCES += boards/91.cpp
SOURCES += boards/96.cpp
SOURCES += boards/99.cpp
SOURCES += boards/a9746.cpp
SOURCES += boards/ac-08.cpp
SOURCES += boards/addrlatch.cpp
SOURCES += boards/ax5705.cpp
SOURCES += boards/bandai.cpp
SOURCES += boards/bb.cpp
SOURCES += boards/bmc13in1jy110.cpp
SOURCES += boards/bmc42in1r.cpp
SOURCES += boards/bmc64in1nr.cpp
SOURCES += boards/bmc70in1.cpp
SOURCES += boards/BMW8544.cpp
SOURCES += boards/bonza.cpp
SOURCES += boards/bs-5.cpp
SOURCES += boards/cheapocabra.cpp
SOURCES += boards/cityfighter.cpp
SOURCES += boards/coolboy.cpp
SOURCES += boards/dance2000.cpp
SOURCES += boards/datalatch.cpp
SOURCES += boards/dream.cpp
SOURCES += boards/__dummy_mapper.cpp
SOURCES += boards/edu2000.cpp
SOURCES += boards/eh8813a.cpp
SOURCES += boards/emu2413.c
SOURCES += boards/et-100.cpp
SOURCES += boards/et-4320.cpp
SOURCES += boards/F-15.cpp
SOURCES += boards/famicombox.cpp
SOURCES += boards/ffe.cpp
SOURCES += boards/fk23c.cpp
SOURCES += boards/fns.cpp
SOURCES += boards/ghostbusters63in1.cpp
SOURCES += boards/gs-2004.cpp
SOURCES += boards/gs-2013.cpp
SOURCES += boards/h2288.cpp
SOURCES += boards/hp10xx_hp20xx.cpp
SOURCES += boards/hp898f.cpp
SOURCES += boards/inlnsf.cpp
SOURCES += boards/karaoke.cpp
SOURCES += boards/kof97.cpp
SOURCES += boards/ks7010.cpp
SOURCES += boards/ks7012.cpp
SOURCES += boards/ks7013.cpp
SOURCES += boards/ks7016.cpp
SOURCES += boards/ks7017.cpp
SOURCES += boards/ks7030.cpp
SOURCES += boards/ks7031.cpp
SOURCES += boards/ks7032.cpp
SOURCES += boards/ks7037.cpp
SOURCES += boards/ks7057.cpp
SOURCES += boards/le05.cpp
SOURCES += boards/lh32.cpp
SOURCES += boards/lh53.cpp
SOURCES += boards/malee.cpp
SOURCES += boards/mihunche.cpp
SOURCES += boards/mmc1.cpp
SOURCES += boards/mmc2and4.cpp
SOURCES += boards/mmc3.cpp
SOURCES += boards/mmc5.cpp
SOURCES += boards/n106.cpp
SOURCES += boards/n625092.cpp
SOURCES += boards/novel.cpp
SOURCES += boards/onebus.cpp
SOURCES += boards/pec-586.cpp
SOURCES += boards/rt-01.cpp
SOURCES += boards/sa-9602b.cpp
SOURCES += boards/sachen.cpp
SOURCES += boards/sb-2000.cpp
SOURCES += boards/sc-127.cpp
SOURCES += boards/sheroes.cpp
SOURCES += boards/sl1632.cpp
SOURCES += boards/subor.cpp
SOURCES += boards/super24.cpp
SOURCES += boards/supervision.cpp
SOURCES += boards/t-227-1.cpp
SOURCES += boards/t-262.cpp
SOURCES += boards/tengen.cpp
SOURCES += boards/tf-1201.cpp
SOURCES += boards/transformer.cpp
SOURCES += boards/unrom512.cpp
SOURCES += boards/vrc1.cpp
SOURCES += boards/vrc2and4.cpp
SOURCES += boards/vrc3.cpp
SOURCES += boards/vrc5.cpp
SOURCES += boards/vrc6.cpp
SOURCES += boards/vrc7.cpp
SOURCES += boards/vrc7p.cpp
SOURCES += boards/yoko.cpp
SOURCES += input/arkanoid.cpp
SOURCES += input/bworld.cpp
SOURCES += input/cursor.cpp
SOURCES += input/fkb.cpp
SOURCES += input/fns.cpp
SOURCES += input/ftrainer.cpp
SOURCES += input/hypershot.cpp
SOURCES += input/mahjong.cpp
SOURCES += input/mouse.cpp
SOURCES += input/oekakids.cpp
SOURCES += input/pec586kb.cpp
SOURCES += input/powerpad.cpp
SOURCES += input/quiz.cpp
SOURCES += input/shadow.cpp
SOURCES += input/snesmouse.cpp
SOURCES += input/suborkb.cpp
SOURCES += input/toprider.cpp
SOURCES += input/virtualboy.cpp
SOURCES += input/zapper.cpp
SOURCES += utils/backward.cpp
SOURCES += utils/ConvertUTF.c
SOURCES += utils/xstring.cpp
SOURCES += utils/crc32.cpp
SOURCES += utils/endian.cpp
SOURCES += utils/general.cpp
SOURCES += utils/guid.cpp
SOURCES += utils/md5.cpp
SOURCES += utils/memory.cpp
SOURCES += drivers/common/args.cpp
SOURCES += drivers/common/cheat.cpp
SOURCES += drivers/common/config.cpp
SOURCES += drivers/common/configSys.cpp
SOURCES += drivers/common/hq2x.cpp
SOURCES += drivers/common/hq3x.cpp
SOURCES += drivers/common/scale2x.cpp
SOURCES += drivers/common/scale3x.cpp
SOURCES += drivers/common/scalebit.cpp
SOURCES += drivers/common/vidblit.cpp
SOURCES += drivers/common/nes_ntsc.c
HEADERS += drivers/Qt/GameApp.h
HEADERS += drivers/Qt/GameViewer.h
SOURCES += drivers/Qt/main.cpp
SOURCES += drivers/Qt/GameApp.cpp
SOURCES += drivers/Qt/GameViewer.cpp
SOURCES += drivers/Qt/fceuWrapper.cpp
SOURCES += drivers/Qt/config.cpp
SOURCES += drivers/Qt/input.cpp
SOURCES += drivers/Qt/gl_win.cpp
SOURCES += drivers/Qt/sdl-sound.cpp
SOURCES += drivers/Qt/sdl-video.cpp
SOURCES += drivers/Qt/sdl-joystick.cpp
SOURCES += drivers/Qt/sdl-throttle.cpp
SOURCES += drivers/Qt/unix-netplay.cpp