Successful display of video in QT gui.
This commit is contained in:
parent
be4c650238
commit
0352483a19
|
@ -1,6 +1,7 @@
|
|||
// GameApp.cpp
|
||||
//
|
||||
#include "GameApp.h"
|
||||
#include "fceuWrapper.h"
|
||||
|
||||
gameWin_t::gameWin_t(QWidget *parent)
|
||||
: QMainWindow( parent )
|
||||
|
@ -81,7 +82,9 @@ void gameWin_t::runGameFrame(void)
|
|||
|
||||
t = (double)ts.tv_sec + (double)(ts.tv_nsec * 1.0e-9);
|
||||
//printf("Run Frame %f\n", t);
|
||||
//
|
||||
|
||||
fceuWrapperUpdate();
|
||||
|
||||
viewport->repaint();
|
||||
|
||||
return;
|
||||
|
|
|
@ -1,13 +1,39 @@
|
|||
// GameViewer.cpp
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "gl_win.h"
|
||||
#include "GameViewer.h"
|
||||
|
||||
extern unsigned int gui_draw_area_width;
|
||||
extern unsigned int gui_draw_area_height;
|
||||
|
||||
gameView_t::gameView_t(QWidget *parent)
|
||||
: QOpenGLWidget( parent )
|
||||
{
|
||||
view_width = 0;
|
||||
view_height = 0;
|
||||
gltexture = 0;
|
||||
|
||||
QSurfaceFormat fmt = QSurfaceFormat::defaultFormat();
|
||||
|
||||
fmt.setRedBufferSize(8);
|
||||
fmt.setGreenBufferSize(8);
|
||||
fmt.setBlueBufferSize(8);
|
||||
fmt.setAlphaBufferSize(8);
|
||||
fmt.setDepthBufferSize( 24 );
|
||||
setTextureFormat(GL_RGBA8);
|
||||
|
||||
printf("R: %i \n", fmt.redBufferSize() );
|
||||
printf("G: %i \n", fmt.greenBufferSize() );
|
||||
printf("B: %i \n", fmt.blueBufferSize() );
|
||||
printf("A: %i \n", fmt.alphaBufferSize() );
|
||||
printf("SW: %i \n", fmt.swapBehavior() );
|
||||
|
||||
setFormat( fmt );
|
||||
}
|
||||
|
||||
gameView_t::~gameView_t(void)
|
||||
|
@ -17,18 +43,45 @@ gameView_t::~gameView_t(void)
|
|||
makeCurrent();
|
||||
|
||||
// Free GL texture
|
||||
if (gltexture)
|
||||
{
|
||||
printf("Destroying GLX Texture\n");
|
||||
glDeleteTextures(1, &gltexture);
|
||||
gltexture=0;
|
||||
}
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void gameView_t::initializeGL(void)
|
||||
{
|
||||
int ipolate = 0;
|
||||
|
||||
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");
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if ( gltexture )
|
||||
{
|
||||
printf("GL Texture already exists\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
glGenTextures(1, &gltexture);
|
||||
}
|
||||
printf("Linear Interpolation on GL Texture: %s \n", ipolate ? "Enabled" : "Disabled");
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,ipolate?GL_LINEAR:GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
|
||||
}
|
||||
|
||||
void gameView_t::resizeGL(int w, int h)
|
||||
|
@ -36,29 +89,108 @@ void gameView_t::resizeGL(int w, int h)
|
|||
printf("GL Resize: %i x %i \n", w, h );
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
view_width = w;
|
||||
view_height = h;
|
||||
|
||||
gui_draw_area_width = w;
|
||||
gui_draw_area_height = h;
|
||||
}
|
||||
|
||||
void gameView_t::paintGL(void)
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
int l=0, r=gl_shm->ncol;
|
||||
int t=0, b=gl_shm->nrow;
|
||||
|
||||
angle += (2.0 * 3.14 * 0.01);
|
||||
float xscale = (float)view_width / (float)gl_shm->ncol;
|
||||
float yscale = (float)view_height / (float)gl_shm->nrow;
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (xscale < yscale )
|
||||
{
|
||||
yscale = xscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
xscale = yscale;
|
||||
}
|
||||
int rw=(int)((r-l)*xscale);
|
||||
int rh=(int)((b-t)*yscale);
|
||||
int sx=(view_width-rw)/2;
|
||||
int sy=(view_height-rh)/2;
|
||||
|
||||
x1 = cos( angle );
|
||||
y1 = sin( angle );
|
||||
glViewport(sx, sy, rw, rh);
|
||||
//glViewport( 0, 0, screen_width, screen_height);
|
||||
|
||||
x2 = -x1;
|
||||
y2 = -y1;
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
|
||||
|
||||
glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
glLineWidth(5.0);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor( 0.0, 0.0f, 0.0f, 0.0f); // Background color to black.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
//glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
glBindTexture(GL_TEXTURE_2D, gltexture);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex2f( x1, y1 );
|
||||
glVertex2f( x2, y2 );
|
||||
//print_pixbuf();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, gl_shm->pixbuf );
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(1.0f*l/256, 1.0f*b/256); // Bottom left of picture.
|
||||
glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
|
||||
glTexCoord2f(1.0f*r/256, 1.0f*b/256);// Bottom right of picture.
|
||||
glVertex2f( 1.0f, -1.0f); // Bottom right of target.
|
||||
|
||||
glTexCoord2f(1.0f*r/256, 1.0f*t/256); // Top right of our picture.
|
||||
glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
|
||||
glTexCoord2f(1.0f*l/256, 1.0f*t/256); // Top left of our picture.
|
||||
glVertex2f(-1.0f, 1.0f); // Top left of target.
|
||||
glEnd();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
//glColor4f( 1.0, 1.0, 1.0, 1.0 );
|
||||
//glLineWidth(5.0);
|
||||
//glBegin(GL_LINES);
|
||||
//glVertex2f(-1.0f, -1.0f); // Bottom left of target.
|
||||
//glVertex2f( 1.0f, 1.0f); // Top right of target.
|
||||
//glEnd();
|
||||
|
||||
context()->swapBuffers( context()->surface() );
|
||||
//if ( double_buffer_ena )
|
||||
//{
|
||||
// glXSwapBuffers( dpy, win );
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// glFlush();
|
||||
//}
|
||||
glFlush();
|
||||
|
||||
//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");
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ class gameView_t : public QOpenGLWidget, protected QOpenGLFunctions
|
|||
void resizeGL(int w, int h);
|
||||
void paintGL(void);
|
||||
|
||||
int view_width;
|
||||
int view_height;
|
||||
GLuint gltexture;
|
||||
|
||||
private slots:
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "throttle.h"
|
||||
|
@ -9,7 +10,9 @@
|
|||
#include "dface.h"
|
||||
#include "fceuWrapper.h"
|
||||
#include "input.h"
|
||||
#include "sdl.h"
|
||||
#include "sdl-video.h"
|
||||
#include "gl_win.h"
|
||||
#include "unix-netplay.h"
|
||||
|
||||
#include "../common/cheat.h"
|
||||
|
@ -50,7 +53,10 @@ Config *g_config = NULL;
|
|||
|
||||
static int inited = 0;
|
||||
static int noconfig=0;
|
||||
static int frameskip=0;
|
||||
static int periodic_saves = 0;
|
||||
|
||||
extern double g_fpsScale;
|
||||
//*****************************************************************
|
||||
// Define Global Functions to be shared with FCEU Core
|
||||
//*****************************************************************
|
||||
|
@ -270,6 +276,505 @@ CloseGame(void)
|
|||
return(1);
|
||||
}
|
||||
|
||||
int fceuWrapperInit( int argc, char *argv[] )
|
||||
{
|
||||
int error;
|
||||
|
||||
FCEUD_Message("Starting " FCEU_NAME_AND_VERSION "...\n");
|
||||
|
||||
// Initialize the configuration system
|
||||
g_config = InitConfig();
|
||||
|
||||
if ( !g_config )
|
||||
{
|
||||
printf("Error: Could not initialize configuration system\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// initialize the infrastructure
|
||||
error = FCEUI_Initialize();
|
||||
|
||||
if (error != 1)
|
||||
{
|
||||
printf("Error: Initializing FCEUI\n");
|
||||
//ShowUsage(argv[0]);
|
||||
//SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int romIndex = g_config->parse(argc, argv);
|
||||
|
||||
// This is here so that a default fceux.cfg will be created on first
|
||||
// run, even without a valid ROM to play.
|
||||
// Unless, of course, there's actually --no-config given
|
||||
// mbg 8/23/2008 - this is also here so that the inputcfg routines can have
|
||||
// a chance to dump the new inputcfg to the fceux.cfg in case you didnt
|
||||
// specify a rom filename
|
||||
g_config->getOption("SDL.NoConfig", &noconfig);
|
||||
|
||||
if (!noconfig)
|
||||
{
|
||||
g_config->save();
|
||||
}
|
||||
|
||||
std::string s;
|
||||
|
||||
g_config->getOption("SDL.InputCfg", &s);
|
||||
|
||||
if (s.size() != 0)
|
||||
{
|
||||
InitVideo(GameInfo);
|
||||
InputCfg(s);
|
||||
}
|
||||
|
||||
// update the input devices
|
||||
UpdateInput(g_config);
|
||||
|
||||
// check for a .fcm file to convert to .fm2
|
||||
g_config->getOption ("SDL.FCMConvert", &s);
|
||||
g_config->setOption ("SDL.FCMConvert", "");
|
||||
if (!s.empty())
|
||||
{
|
||||
int okcount = 0;
|
||||
std::string infname = s.c_str();
|
||||
// produce output filename
|
||||
std::string outname;
|
||||
size_t dot = infname.find_last_of (".");
|
||||
if (dot == std::string::npos)
|
||||
outname = infname + ".fm2";
|
||||
else
|
||||
outname = infname.substr(0,dot) + ".fm2";
|
||||
|
||||
MovieData md;
|
||||
EFCM_CONVERTRESULT result = convert_fcm (md, infname);
|
||||
|
||||
if (result == FCM_CONVERTRESULT_SUCCESS) {
|
||||
okcount++;
|
||||
// *outf = new EMUFILE;
|
||||
EMUFILE_FILE* outf = FCEUD_UTF8_fstream (outname, "wb");
|
||||
md.dump (outf,false);
|
||||
delete outf;
|
||||
FCEUD_Message ("Your file has been converted to FM2.\n");
|
||||
}
|
||||
else {
|
||||
FCEUD_Message ("Something went wrong while converting your file...\n");
|
||||
}
|
||||
|
||||
DriverKill();
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
// If x/y res set to 0, store current display res in SDL.LastX/YRes
|
||||
int yres, xres;
|
||||
g_config->getOption("SDL.XResolution", &xres);
|
||||
g_config->getOption("SDL.YResolution", &yres);
|
||||
|
||||
int autoResume;
|
||||
g_config->getOption("SDL.AutoResume", &autoResume);
|
||||
if(autoResume)
|
||||
{
|
||||
AutoResumePlay = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AutoResumePlay = false;
|
||||
}
|
||||
|
||||
// check to see if recording HUD to AVI is enabled
|
||||
int rh;
|
||||
g_config->getOption("SDL.RecordHUD", &rh);
|
||||
if( rh == 0)
|
||||
FCEUI_SetAviEnableHUDrecording(true);
|
||||
else
|
||||
FCEUI_SetAviEnableHUDrecording(false);
|
||||
|
||||
// check to see if movie messages are disabled
|
||||
int mm;
|
||||
g_config->getOption("SDL.MovieMsg", &mm);
|
||||
if( mm == 0)
|
||||
FCEUI_SetAviDisableMovieMessages(true);
|
||||
else
|
||||
FCEUI_SetAviDisableMovieMessages(false);
|
||||
|
||||
// check for a .fm2 file to rip the subtitles
|
||||
g_config->getOption("SDL.RipSubs", &s);
|
||||
g_config->setOption("SDL.RipSubs", "");
|
||||
if (!s.empty())
|
||||
{
|
||||
MovieData md;
|
||||
std::string infname;
|
||||
infname = s.c_str();
|
||||
FCEUFILE *fp = FCEU_fopen(s.c_str(), 0, "rb", 0);
|
||||
|
||||
// load the movie and and subtitles
|
||||
extern bool LoadFM2(MovieData&, EMUFILE*, int, bool);
|
||||
LoadFM2(md, fp->stream, INT_MAX, false);
|
||||
LoadSubtitles(md); // fill subtitleFrames and subtitleMessages
|
||||
delete fp;
|
||||
|
||||
// produce .srt file's name and open it for writing
|
||||
std::string outname;
|
||||
size_t dot = infname.find_last_of (".");
|
||||
if (dot == std::string::npos)
|
||||
outname = infname + ".srt";
|
||||
else
|
||||
outname = infname.substr(0,dot) + ".srt";
|
||||
FILE *srtfile;
|
||||
srtfile = fopen(outname.c_str(), "w");
|
||||
|
||||
if (srtfile != NULL)
|
||||
{
|
||||
extern std::vector<int> subtitleFrames;
|
||||
extern std::vector<std::string> subtitleMessages;
|
||||
float fps = (md.palFlag == 0 ? 60.0988 : 50.0069); // NTSC vs PAL
|
||||
float subduration = 3; // seconds for the subtitles to be displayed
|
||||
for (int i = 0; i < subtitleFrames.size(); i++)
|
||||
{
|
||||
fprintf(srtfile, "%i\n", i+1); // starts with 1, not 0
|
||||
double seconds, ms, endseconds, endms;
|
||||
seconds = subtitleFrames[i]/fps;
|
||||
if (i+1 < subtitleFrames.size()) // there's another subtitle coming after this one
|
||||
{
|
||||
if (subtitleFrames[i+1]-subtitleFrames[i] < subduration*fps) // avoid two subtitles at the same time
|
||||
{
|
||||
endseconds = (subtitleFrames[i+1]-1)/fps; // frame x: subtitle1; frame x+1 subtitle2
|
||||
} else {
|
||||
endseconds = seconds+subduration;
|
||||
}
|
||||
} else {
|
||||
endseconds = seconds+subduration;
|
||||
}
|
||||
ms = modf(seconds, &seconds);
|
||||
endms = modf(endseconds, &endseconds);
|
||||
// this is just beyond ugly, don't show it to your kids
|
||||
fprintf(srtfile,
|
||||
"%02.0f:%02d:%02d,%03d --> %02.0f:%02d:%02d,%03d\n", // hh:mm:ss,ms --> hh:mm:ss,ms
|
||||
floor(seconds/3600), (int)floor(seconds/60 ) % 60, (int)floor(seconds) % 60, (int)(ms*1000),
|
||||
floor(endseconds/3600), (int)floor(endseconds/60) % 60, (int)floor(endseconds) % 60, (int)(endms*1000));
|
||||
fprintf(srtfile, "%s\n\n", subtitleMessages[i].c_str()); // new line for every subtitle
|
||||
}
|
||||
fclose(srtfile);
|
||||
printf("%d subtitles have been ripped.\n", (int)subtitleFrames.size());
|
||||
} else {
|
||||
FCEUD_Message("Couldn't create output srt file...\n");
|
||||
}
|
||||
|
||||
DriverKill();
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
gl_shm = open_video_shm();
|
||||
|
||||
if ( gl_shm == NULL )
|
||||
{
|
||||
printf("Error: Failed to open video Shared memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// update the emu core
|
||||
UpdateEMUCore(g_config);
|
||||
|
||||
#ifdef CREATE_AVI
|
||||
g_config->getOption("SDL.VideoLog", &s);
|
||||
g_config->setOption("SDL.VideoLog", "");
|
||||
if(!s.empty())
|
||||
{
|
||||
NESVideoSetVideoCmd(s.c_str());
|
||||
LoggingEnabled = 1;
|
||||
g_config->getOption("SDL.MuteCapture", &mutecapture);
|
||||
} else {
|
||||
mutecapture = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
int id;
|
||||
g_config->getOption("SDL.InputDisplay", &id);
|
||||
extern int input_display;
|
||||
input_display = id;
|
||||
// not exactly an id as an true/false switch; still better than creating another int for that
|
||||
g_config->getOption("SDL.SubtitleDisplay", &id);
|
||||
extern int movieSubtitles;
|
||||
movieSubtitles = id;
|
||||
}
|
||||
|
||||
// load the hotkeys from the config life
|
||||
setHotKeys();
|
||||
|
||||
if (romIndex >= 0)
|
||||
{
|
||||
// load the specified game
|
||||
error = LoadGame(argv[romIndex]);
|
||||
if (error != 1)
|
||||
{
|
||||
DriverKill();
|
||||
SDL_Quit();
|
||||
return -1;
|
||||
}
|
||||
g_config->setOption("SDL.LastOpenFile", argv[romIndex]);
|
||||
g_config->save();
|
||||
}
|
||||
|
||||
// movie playback
|
||||
g_config->getOption("SDL.Movie", &s);
|
||||
g_config->setOption("SDL.Movie", "");
|
||||
if (s != "")
|
||||
{
|
||||
if(s.find(".fm2") != std::string::npos || s.find(".fm3") != std::string::npos)
|
||||
{
|
||||
static int pauseframe;
|
||||
g_config->getOption("SDL.PauseFrame", &pauseframe);
|
||||
g_config->setOption("SDL.PauseFrame", 0);
|
||||
FCEUI_printf("Playing back movie located at %s\n", s.c_str());
|
||||
FCEUI_LoadMovie(s.c_str(), false, pauseframe ? pauseframe : false);
|
||||
}
|
||||
else
|
||||
{
|
||||
FCEUI_printf("Sorry, I don't know how to play back %s\n", s.c_str());
|
||||
}
|
||||
g_config->getOption("SDL.MovieLength",&KillFCEUXonFrame);
|
||||
printf("KillFCEUXonFrame %d\n",KillFCEUXonFrame);
|
||||
}
|
||||
|
||||
int save_state;
|
||||
g_config->getOption("SDL.PeriodicSaves", &periodic_saves);
|
||||
g_config->getOption("SDL.AutoSaveState", &save_state);
|
||||
if(periodic_saves && save_state < 10 && save_state >= 0){
|
||||
FCEUI_SelectState(save_state, 0);
|
||||
} else {
|
||||
periodic_saves = 0;
|
||||
}
|
||||
|
||||
#ifdef _S9XLUA_H
|
||||
// load lua script if option passed
|
||||
g_config->getOption("SDL.LuaScript", &s);
|
||||
g_config->setOption("SDL.LuaScript", "");
|
||||
if (s != "")
|
||||
{
|
||||
#ifdef __linux
|
||||
// Resolve absolute path to file
|
||||
char fullpath[2048];
|
||||
if ( realpath( s.c_str(), fullpath ) != NULL )
|
||||
{
|
||||
//printf("Fullpath: '%s'\n", fullpath );
|
||||
s.assign( fullpath );
|
||||
}
|
||||
#endif
|
||||
FCEU_LoadLuaCode(s.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
int id;
|
||||
g_config->getOption("SDL.NewPPU", &id);
|
||||
if (id)
|
||||
newppu = 1;
|
||||
}
|
||||
|
||||
g_config->getOption("SDL.Frameskip", &frameskip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fceuWrapperClose( void )
|
||||
{
|
||||
CloseGame();
|
||||
|
||||
// exit the infrastructure
|
||||
FCEUI_Kill();
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the video, audio, and input subsystems with the provided
|
||||
* video (XBuf) and audio (Buffer) information.
|
||||
*/
|
||||
void
|
||||
FCEUD_Update(uint8 *XBuf,
|
||||
int32 *Buffer,
|
||||
int Count)
|
||||
{
|
||||
int blitDone = 0;
|
||||
extern int FCEUDnetplay;
|
||||
|
||||
#ifdef CREATE_AVI
|
||||
if(LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE))
|
||||
{
|
||||
if(LoggingEnabled == 2)
|
||||
{
|
||||
int16* MonoBuf = new int16[Count];
|
||||
int n;
|
||||
for(n=0; n<Count; ++n)
|
||||
MonoBuf[n] = Buffer[n] & 0xFFFF;
|
||||
NESVideoLoggingAudio
|
||||
(
|
||||
MonoBuf,
|
||||
FSettings.SndRate, 16, 1,
|
||||
Count
|
||||
);
|
||||
delete [] MonoBuf;
|
||||
}
|
||||
Count /= 2;
|
||||
if(inited & 1)
|
||||
{
|
||||
if(Count > GetWriteSound()) Count = GetWriteSound();
|
||||
if (!mutecapture)
|
||||
if(Count > 0 && Buffer) WriteSound(Buffer,Count);
|
||||
}
|
||||
if(inited & 2)
|
||||
FCEUD_UpdateInput();
|
||||
if(XBuf && (inited & 4)) BlitScreen(XBuf);
|
||||
|
||||
//SpeedThrottle();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ocount = Count;
|
||||
// apply frame scaling to Count
|
||||
Count = (int)(Count / g_fpsScale);
|
||||
if (Count)
|
||||
{
|
||||
int32 can=GetWriteSound();
|
||||
static int uflow=0;
|
||||
int32 tmpcan;
|
||||
|
||||
// don't underflow when scaling fps
|
||||
if(can >= GetMaxSound() && g_fpsScale==1.0) uflow=1; /* Go into massive underflow mode. */
|
||||
|
||||
if(can > Count) can=Count;
|
||||
else uflow=0;
|
||||
|
||||
#ifdef CREATE_AVI
|
||||
if (!mutecapture)
|
||||
#endif
|
||||
WriteSound(Buffer,can);
|
||||
|
||||
//if(uflow) puts("Underflow");
|
||||
tmpcan = GetWriteSound();
|
||||
// don't underflow when scaling fps
|
||||
if (g_fpsScale>1.0 || ((tmpcan < Count*0.90) && !uflow))
|
||||
{
|
||||
if (XBuf && (inited&4) && !(NoWaiting & 2))
|
||||
{
|
||||
BlitScreen(XBuf); blitDone = 1;
|
||||
}
|
||||
Buffer+=can;
|
||||
Count-=can;
|
||||
if(Count)
|
||||
{
|
||||
if(NoWaiting)
|
||||
{
|
||||
can=GetWriteSound();
|
||||
if(Count>can) Count=can;
|
||||
#ifdef CREATE_AVI
|
||||
if (!mutecapture)
|
||||
#endif
|
||||
WriteSound(Buffer,Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
while(Count>0)
|
||||
{
|
||||
#ifdef CREATE_AVI
|
||||
if (!mutecapture)
|
||||
#endif
|
||||
WriteSound(Buffer,(Count<ocount) ? Count : ocount);
|
||||
Count -= ocount;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //else puts("Skipped");
|
||||
else if (!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8)))
|
||||
{
|
||||
if (Count > tmpcan) Count=tmpcan;
|
||||
while(tmpcan > 0)
|
||||
{
|
||||
// printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
|
||||
#ifdef CREATE_AVI
|
||||
if (!mutecapture)
|
||||
#endif
|
||||
WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
|
||||
tmpcan -= Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
|
||||
{
|
||||
while (SpeedThrottle())
|
||||
{
|
||||
FCEUD_UpdateInput();
|
||||
}
|
||||
}
|
||||
if (XBuf && (inited&4))
|
||||
{
|
||||
BlitScreen(XBuf); blitDone = 1;
|
||||
}
|
||||
}
|
||||
if ( !blitDone )
|
||||
{
|
||||
if (XBuf && (inited&4))
|
||||
{
|
||||
BlitScreen(XBuf); blitDone = 1;
|
||||
}
|
||||
}
|
||||
FCEUD_UpdateInput();
|
||||
//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
|
||||
// SpeedThrottle();
|
||||
//if(XBuf && (inited&4))
|
||||
//{
|
||||
// BlitScreen(XBuf);
|
||||
//}
|
||||
//if(Count)
|
||||
// WriteSound(Buffer,Count,NoWaiting);
|
||||
//FCEUD_UpdateInput();
|
||||
}
|
||||
|
||||
static void DoFun(int frameskip, int periodic_saves)
|
||||
{
|
||||
uint8 *gfx;
|
||||
int32 *sound;
|
||||
int32 ssize;
|
||||
static int fskipc = 0;
|
||||
static int opause = 0;
|
||||
|
||||
//TODO peroidic saves, working on it right now
|
||||
if (periodic_saves && FCEUD_GetTime() % PERIODIC_SAVE_INTERVAL < 30){
|
||||
FCEUI_SaveState(NULL, false);
|
||||
}
|
||||
#ifdef FRAMESKIP
|
||||
fskipc = (fskipc + 1) % (frameskip + 1);
|
||||
#endif
|
||||
|
||||
if (NoWaiting)
|
||||
{
|
||||
gfx = 0;
|
||||
}
|
||||
FCEUI_Emulate(&gfx, &sound, &ssize, fskipc);
|
||||
FCEUD_Update(gfx, sound, ssize);
|
||||
|
||||
if(opause!=FCEUI_EmulationPaused())
|
||||
{
|
||||
opause=FCEUI_EmulationPaused();
|
||||
SilenceSound(opause);
|
||||
}
|
||||
}
|
||||
|
||||
int fceuWrapperUpdate( void )
|
||||
{
|
||||
if (GameInfo)
|
||||
{
|
||||
DoFun(frameskip, periodic_saves);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// dummy functions
|
||||
|
||||
#define DUMMY(__f) \
|
||||
|
|
|
@ -21,3 +21,8 @@ extern Config *g_config;
|
|||
|
||||
int LoadGame(const char *path);
|
||||
int CloseGame(void);
|
||||
|
||||
int fceuWrapperInit( int argc, char *argv[] );
|
||||
int fceuWrapperClose( void );
|
||||
int fceuWrapperUpdate( void );
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
#include <QApplication>
|
||||
|
||||
#include "GameApp.h"
|
||||
#include "fceuWrapper.h"
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
gameWin_t win;
|
||||
|
||||
win.resize( 200, 200 );
|
||||
fceuWrapperInit( argc, argv );
|
||||
|
||||
win.resize( 512, 512 );
|
||||
win.show();
|
||||
|
||||
return app.exec();
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define LSB_FIRST
|
||||
#endif
|
||||
|
||||
// GLOBALS
|
||||
extern Config *g_config;
|
||||
|
||||
|
@ -322,6 +326,21 @@ void LockConsole(){}
|
|||
///Currently unimplemented.
|
||||
void UnlockConsole(){}
|
||||
|
||||
static int testPattern = 0;
|
||||
|
||||
static void WriteTestPattern(void)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
k=0;
|
||||
for (i=0; i<GL_NES_WIDTH; i++)
|
||||
{
|
||||
for (j=0; j<GL_NES_HEIGHT; j++)
|
||||
{
|
||||
gl_shm->pixbuf[k] = 0xffffffff; k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Pushes the given buffer of bits to the screen.
|
||||
*/
|
||||
|
@ -352,7 +371,14 @@ BlitScreen(uint8 *XBuf)
|
|||
|
||||
if ( dest == NULL ) return;
|
||||
|
||||
if ( testPattern )
|
||||
{
|
||||
WriteTestPattern();
|
||||
}
|
||||
else
|
||||
{
|
||||
Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1);
|
||||
}
|
||||
|
||||
//guiPixelBufferReDraw();
|
||||
|
||||
|
|
|
@ -43,7 +43,9 @@ unix {
|
|||
QMAKE_CXXFLAGS += -D_S9XLUA_H
|
||||
}
|
||||
|
||||
QMAKE_CXXFLAGS += -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs
|
||||
QMAKE_CXXFLAGS -= -O2
|
||||
QMAKE_CXXFLAGS += -O0 -g3 -Wall -Wno-write-strings -Wno-sign-compare -Wno-parentheses -Wno-unused-local-typedefs
|
||||
QMAKE_CXXFLAGS_RELEASE -= -O2
|
||||
}
|
||||
|
||||
# Input
|
||||
|
|
Loading…
Reference in New Issue