From 0352483a19b63eac78db0525f695a01b4bfaa041 Mon Sep 17 00:00:00 2001 From: Matthew Budd Date: Tue, 23 Jun 2020 22:51:10 -0400 Subject: [PATCH] Successful display of video in QT gui. --- src/drivers/Qt/GameApp.cpp | 5 +- src/drivers/Qt/GameViewer.cpp | 158 ++++++++++- src/drivers/Qt/GameViewer.h | 4 + src/drivers/Qt/fceuWrapper.cpp | 505 +++++++++++++++++++++++++++++++++ src/drivers/Qt/fceuWrapper.h | 5 + src/drivers/Qt/main.cpp | 5 +- src/drivers/Qt/sdl-video.cpp | 28 +- src/fceux.pro | 4 +- 8 files changed, 697 insertions(+), 17 deletions(-) diff --git a/src/drivers/Qt/GameApp.cpp b/src/drivers/Qt/GameApp.cpp index de15835f..8602a26d 100644 --- a/src/drivers/Qt/GameApp.cpp +++ b/src/drivers/Qt/GameApp.cpp @@ -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; diff --git a/src/drivers/Qt/GameViewer.cpp b/src/drivers/Qt/GameViewer.cpp index ef32e331..718cd743 100644 --- a/src/drivers/Qt/GameViewer.cpp +++ b/src/drivers/Qt/GameViewer.cpp @@ -1,13 +1,39 @@ // GameViewer.cpp // +#include +#include +#include #include +#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); - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + float xscale = (float)view_width / (float)gl_shm->ncol; + float yscale = (float)view_height / (float)gl_shm->nrow; - x1 = cos( angle ); - y1 = sin( angle ); + 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; - x2 = -x1; - y2 = -y1; + glViewport(sx, sy, rw, rh); + //glViewport( 0, 0, screen_width, screen_height); - glColor4f( 1.0, 1.0, 1.0, 1.0 ); - glLineWidth(5.0); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - glBegin(GL_LINES); - glVertex2f( x1, y1 ); - glVertex2f( x2, y2 ); + 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); + + //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"); } diff --git a/src/drivers/Qt/GameViewer.h b/src/drivers/Qt/GameViewer.h index 655eb9de..edc0524a 100644 --- a/src/drivers/Qt/GameViewer.h +++ b/src/drivers/Qt/GameViewer.h @@ -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: }; diff --git a/src/drivers/Qt/fceuWrapper.cpp b/src/drivers/Qt/fceuWrapper.cpp index 61d7812b..c8402f7c 100644 --- a/src/drivers/Qt/fceuWrapper.cpp +++ b/src/drivers/Qt/fceuWrapper.cpp @@ -2,6 +2,7 @@ // #include #include +#include #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 subtitleFrames; + extern std::vector 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 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= (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) \ diff --git a/src/drivers/Qt/fceuWrapper.h b/src/drivers/Qt/fceuWrapper.h index 0c279144..804e8bb8 100644 --- a/src/drivers/Qt/fceuWrapper.h +++ b/src/drivers/Qt/fceuWrapper.h @@ -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 ); + diff --git a/src/drivers/Qt/main.cpp b/src/drivers/Qt/main.cpp index 14864529..807ae5d8 100644 --- a/src/drivers/Qt/main.cpp +++ b/src/drivers/Qt/main.cpp @@ -1,13 +1,16 @@ #include #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(); diff --git a/src/drivers/Qt/sdl-video.cpp b/src/drivers/Qt/sdl-video.cpp index 98f59009..4e70a08c 100644 --- a/src/drivers/Qt/sdl-video.cpp +++ b/src/drivers/Qt/sdl-video.cpp @@ -45,6 +45,10 @@ #include #include +#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; ipixbuf[k] = 0xffffffff; k++; + } + } +} /** * Pushes the given buffer of bits to the screen. */ @@ -352,7 +371,14 @@ BlitScreen(uint8 *XBuf) if ( dest == NULL ) return; - Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); + if ( testPattern ) + { + WriteTestPattern(); + } + else + { + Blit8ToHigh(XBuf + NOFFSET, dest, NWIDTH, s_tlines, pitch, 1, 1); + } //guiPixelBufferReDraw(); diff --git a/src/fceux.pro b/src/fceux.pro index 24cf00c0..04dbcd67 100644 --- a/src/fceux.pro +++ b/src/fceux.pro @@ -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