diff --git a/src/common/EventHandlerSDL2.cxx b/src/common/EventHandlerSDL2.cxx index 0f2c51894..355af746a 100644 --- a/src/common/EventHandlerSDL2.cxx +++ b/src/common/EventHandlerSDL2.cxx @@ -136,7 +136,7 @@ void EventHandlerSDL2::pollEvent() handleEvent(Event::Quit, 1); break; // SDL_QUIT -#if 0 // FIXME +#if 0 //FIXSDL case SDL_ACTIVEEVENT: if((event.active.state & SDL_APPACTIVE) && (event.active.gain == 0)) if(myState == S_EMULATE) enterMenuMode(S_MENU); @@ -159,7 +159,7 @@ EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx) stick = SDL_JoystickOpen(idx); if(stick) { - initialize(SDL_JoystickName(idx), SDL_JoystickNumAxes(stick), + initialize(SDL_JoystickName(stick), SDL_JoystickNumAxes(stick), SDL_JoystickNumButtons(stick), SDL_JoystickNumHats(stick)); } } diff --git a/src/common/FBSurfaceTIA.cxx b/src/common/FBSurfaceTIA.cxx index 26fd0cd10..1d4f1f38f 100644 --- a/src/common/FBSurfaceTIA.cxx +++ b/src/common/FBSurfaceTIA.cxx @@ -19,10 +19,8 @@ #include -#include "Font.hxx" -#include "FrameBufferSDL2.hxx" -#include "TIA.hxx" #include "NTSCFilter.hxx" +#include "TIA.hxx" #include "FBSurfaceTIA.hxx" @@ -33,8 +31,7 @@ FBSurfaceTIA::FBSurfaceTIA(FrameBufferSDL2& buffer) myTexture(NULL), myScanlines(NULL), myScanlinesEnabled(false), - myScanlineIntensityI(50), - myScanlineIntensityF(0.5) + myScanlineIntensity(50) { // Texture width is set to contain all possible sizes for a TIA image, // including Blargg filtering @@ -47,12 +44,20 @@ FBSurfaceTIA::FBSurfaceTIA(FrameBufferSDL2& buffer) mySurface = SDL_CreateRGBSurface(0, width, height, pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask); - mySrc.x = mySrc.y = myDst.x = myDst.y = 0; - mySrc.w = myDst.w = width; - mySrc.h = myDst.h = height; + mySrcR.x = mySrcR.y = myDstR.x = myDstR.y = myScanR.x = myScanR.y = 0; + mySrcR.w = myDstR.w = width; + mySrcR.h = myDstR.h = height; + myScanR.w = 1; myScanR.h = 0; myPitch = mySurface->pitch / pf.BytesPerPixel; + // Generate scanline data + for(int i = 0; i < mySurface->h; i+=2) + { + ourScanData[i] = 0x00000000; + ourScanData[i+1] = 0xff000000; + } + // To generate textures reload(); } @@ -69,15 +74,15 @@ FBSurfaceTIA::~FBSurfaceTIA() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceTIA::getPos(uInt32& x, uInt32& y) const { - x = mySrc.x; - y = mySrc.y; + x = mySrcR.x; + y = mySrcR.y; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceTIA::translateCoords(Int32& x, Int32& y) const { - x = mySrc.x; - y = mySrc.y; + x = mySrcR.x; + y = mySrcR.y; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -145,12 +150,12 @@ void FBSurfaceTIA::update() } // Draw TIA image - SDL_UpdateTexture(myTexture, &mySrc, mySurface->pixels, mySurface->pitch); - SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrc, &myDst); + SDL_UpdateTexture(myTexture, &mySrcR, mySurface->pixels, mySurface->pitch); + SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrcR, &myDstR); // Draw overlaying scanlines if(myScanlinesEnabled) - SDL_RenderCopy(myFB.myRenderer, myScanlines, NULL, &myDst); + SDL_RenderCopy(myFB.myRenderer, myScanlines, &myScanR, &myDstR); // Let postFrameUpdate() know that a change has been made myFB.myDirtyFlag = true; @@ -188,17 +193,16 @@ void FBSurfaceTIA::reload() // Re-create scanline texture (contents don't change) myScanlines = SDL_CreateTexture(myFB.myRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, - 1, 2); + 1, mySurface->h); SDL_SetTextureBlendMode(myScanlines, SDL_BLENDMODE_BLEND); - SDL_SetTextureAlphaMod(myScanlines, myScanlineIntensityF*255); - SDL_UpdateTexture(myScanlines, NULL, ourScanData, 1); + SDL_SetTextureAlphaMod(myScanlines, myScanlineIntensity*2.55); + SDL_UpdateTexture(myScanlines, &myScanR, ourScanData, 4); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void FBSurfaceTIA::setScanIntensity(uInt32 intensity) { - myScanlineIntensityI = intensity; - myScanlineIntensityF = intensity / 100.0; + myScanlineIntensity = intensity; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -231,9 +235,20 @@ void FBSurfaceTIA::setScanInterpolation(bool enable) void FBSurfaceTIA::updateCoords(uInt32 baseH, uInt32 imgX, uInt32 imgY, uInt32 imgW, uInt32 imgH) { - mySrc.h = baseH; - myDst.w = imgW; - myDst.h = imgH; + mySrcR.h = baseH; + myDstR.w = imgW; + myDstR.h = imgH; + + // Scanline repeating is sensitive to non-integral vertical resolution, + // so rounding is performed to eliminate it + // This won't be 100% accurate, but non-integral scaling isn't 100% + // accurate anyway + +float x = float(imgH) / floor(((float)imgH / baseH) + 0.5); +cerr << "myScanR.h = " << x << endl; + + myScanR.w = 1; + myScanR.h = x; updateCoords(); } @@ -242,7 +257,7 @@ void FBSurfaceTIA::updateCoords(uInt32 baseH, void FBSurfaceTIA::updateCoords() { // For a TIA surface, only the width can possibly change - mySrc.w = myFB.ntscEnabled() ? ATARI_NTSC_OUT_WIDTH(160) : 160; + mySrcR.w = myFB.ntscEnabled() ? ATARI_NTSC_OUT_WIDTH(160) : 160; #if 0 // Normal TIA rendering and TV effects use different widths @@ -326,6 +341,3 @@ void FBSurfaceTIA::setTIAPalette(const uInt32* palette) { myFB.myNTSCFilter.setTIAPalette(myFB, palette); } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -uInt32 const FBSurfaceTIA::ourScanData[2] = { 0x00000000, 0xff000000 }; diff --git a/src/common/FBSurfaceTIA.hxx b/src/common/FBSurfaceTIA.hxx index 709eb25a3..616c64515 100644 --- a/src/common/FBSurfaceTIA.hxx +++ b/src/common/FBSurfaceTIA.hxx @@ -43,8 +43,8 @@ class FBSurfaceTIA : public FBSurface // only the methods absolutely necessary for dealing with drawing // a TIA image void getPos(uInt32& x, uInt32& y) const; - uInt32 getWidth() const { return mySrc.w; } - uInt32 getHeight() const { return mySrc.h; } + uInt32 getWidth() const { return mySrcR.w; } + uInt32 getHeight() const { return mySrcR.h; } void translateCoords(Int32& x, Int32& y) const; void update(); void invalidate(); @@ -68,14 +68,13 @@ class FBSurfaceTIA : public FBSurface SDL_Surface* mySurface; SDL_Texture* myTexture; SDL_Texture* myScanlines; - SDL_Rect mySrc, myDst; + SDL_Rect mySrcR, myDstR, myScanR; uInt32 myPitch; bool myScanlinesEnabled; - uInt32 myScanlineIntensityI; - float myScanlineIntensityF; + uInt32 myScanlineIntensity; - static uInt32 const ourScanData[2]; + uInt32 ourScanData[320]; }; #endif diff --git a/src/common/FrameBufferSDL2.cxx b/src/common/FrameBufferSDL2.cxx index ae2490e3a..59906ca43 100644 --- a/src/common/FrameBufferSDL2.cxx +++ b/src/common/FrameBufferSDL2.cxx @@ -88,74 +88,10 @@ FrameBufferSDL2::~FrameBufferSDL2() bool FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, ResolutionList& res) { // First get the maximum windowed desktop resolution - // Check the 'maxres' setting, which is an undocumented developer feature - // that specifies the desktop size - // Normally, this wouldn't be set, and we ask SDL directly - const GUI::Size& s = myOSystem->settings().getSize("maxres"); - if(s.w <= 0 || s.h <= 0) - { - SDL_DisplayMode desktop; - SDL_GetDesktopDisplayMode(0, &desktop); - w = desktop.w; - h = desktop.h; - } - -#if 0 - // Various parts of the codebase assume a minimum screen size of 320x240 - if(!(myDesktopWidth >= 320 && myDesktopHeight >= 240)) - { - logMessage("ERROR: queryVideoHardware failed, " - "window 320x240 or larger required", 0); - return false; - } - - // Then get the valid fullscreen modes - // If there are any errors, just use the desktop resolution - ostringstream buf; - SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN); - if((modes == (SDL_Rect**)0) || (modes == (SDL_Rect**)-1)) - { - Resolution r; - r.width = myDesktopWidth; - r.height = myDesktopHeight; - buf << r.width << "x" << r.height; - r.name = buf.str(); - myResolutions.push_back(r); - } - else - { - // All modes must fit between the lower and upper limits of the desktop - // For 'small' desktop, this means larger than 320x240 - // For 'large'/normal desktop, exclude all those less than 640x480 - bool largeDesktop = myDesktopWidth >= 640 && myDesktopHeight >= 480; - uInt32 lowerWidth = largeDesktop ? 640 : 320, - lowerHeight = largeDesktop ? 480 : 240; - for(uInt32 i = 0; modes[i]; ++i) - { - if(modes[i]->w >= lowerWidth && modes[i]->w <= myDesktopWidth && - modes[i]->h >= lowerHeight && modes[i]->h <= myDesktopHeight) - { - Resolution r; - r.width = modes[i]->w; - r.height = modes[i]->h; - buf.str(""); - buf << r.width << "x" << r.height; - r.name = buf.str(); - myResolutions.insert_at(0, r); // insert in opposite (of descending) order - } - } - // If no modes were valid, use the desktop dimensions - if(myResolutions.size() == 0) - { - Resolution r; - r.width = myDesktopWidth; - r.height = myDesktopHeight; - buf << r.width << "x" << r.height; - r.name = buf.str(); - myResolutions.push_back(r); - } - } -#endif + SDL_DisplayMode desktop; + SDL_GetDesktopDisplayMode(0, &desktop); + w = desktop.w; + h = desktop.h; return true; } @@ -491,7 +427,7 @@ void FrameBufferSDL2::enableNTSC(bool enable) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 FrameBufferSDL2::enableScanlines(int relative, int absolute) { - int intensity = myTiaSurface->myScanlineIntensityI; + int intensity = myTiaSurface->myScanlineIntensity; if(myTiaSurface) { if(relative == 0) intensity = absolute; @@ -559,7 +495,7 @@ string FrameBufferSDL2::effectsInfo() const break; case kBlarggNormal: buf << myNTSCFilter.getPreset() << ", scanlines=" - << myTiaSurface->myScanlineIntensityI << "/" + << myTiaSurface->myScanlineIntensity << "/" #if 0 << (myTiaSurface->myTexFilter[1] == GL_LINEAR ? "inter" : "nointer"); #endif @@ -567,7 +503,7 @@ string FrameBufferSDL2::effectsInfo() const break; case kBlarggPhosphor: buf << myNTSCFilter.getPreset() << ", phosphor, scanlines=" - << myTiaSurface->myScanlineIntensityI << "/" + << myTiaSurface->myScanlineIntensity << "/" #if 0 << (myTiaSurface->myTexFilter[1] == GL_LINEAR ? "inter" : "nointer"); #endif diff --git a/src/emucore/FrameBuffer.cxx b/src/emucore/FrameBuffer.cxx index 576fe7b2d..6d21663fe 100644 --- a/src/emucore/FrameBuffer.cxx +++ b/src/emucore/FrameBuffer.cxx @@ -82,12 +82,21 @@ bool FrameBuffer::initialize() if(!queryHardware(myDesktopWidth, myDesktopHeight, myResolutions)) return false; + // Check the 'maxres' setting, which is an undocumented developer feature + // that specifies the desktop size (not normally set) + const GUI::Size& s = myOSystem->settings().getSize("maxres"); + if(s.w > 0 && s.h > 0) + { + myDesktopWidth = s.w; + myDesktopHeight = s.h; + } + // Various parts of the codebase assume a minimum screen size of 320x240 myDesktopWidth = BSPF_max(myDesktopWidth, 320u); myDesktopHeight = BSPF_max(myDesktopHeight, 240u); if(!(myDesktopWidth >= 320 && myDesktopHeight >= 240)) { - myOSystem->logMessage("ERROR: queryVideoHardware failed, " + myOSystem->logMessage("ERROR: video init failed, " "window 320x240 or larger required", 0); return false; }