mirror of https://github.com/stella-emu/stella.git
OK, SDL2 is in the building! This is the first pass at porting the code
to SDL2. For now, there are many things broken, namely keyboard handling and fullscreen modes. But the launcher does show up, allows to start a game and enter/exit the debugger, etc. The code will only compile on Linux for now, and sometimes maybe not even then. Expect breakage on a regular basis over the next month or so. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2854 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
46733e32c0
commit
a1ea1b0c96
|
@ -6,7 +6,7 @@
|
|||
# * command line options to...
|
||||
# - override the host settings (for cross compiles
|
||||
# - whether to do a debug build (with -g) or an optimized build (-O3 etc.)
|
||||
# * detect whether the chosen backend is available (e.g. call sdl-config)
|
||||
# * detect whether the chosen backend is available (e.g. call sdl2-config)
|
||||
# * ....
|
||||
|
||||
|
||||
|
@ -42,10 +42,9 @@ _zip="zip -q"
|
|||
_cp=cp
|
||||
_windowspath=""
|
||||
_windres=windres
|
||||
_sdlconfig=sdl-config
|
||||
_sdlconfig=sdl2-config
|
||||
_sdlpath="$PATH"
|
||||
_prefix=/usr/local
|
||||
X_LIBS="/usr/X11R6/lib"
|
||||
|
||||
_srcdir=`dirname $0`
|
||||
|
||||
|
@ -124,13 +123,13 @@ add_line_to_config_mk() {
|
|||
|
||||
|
||||
#
|
||||
# Determine sdl-config
|
||||
# Determine sdl2-config
|
||||
#
|
||||
# TODO: small bit of code to test sdl useability
|
||||
find_sdlconfig()
|
||||
{
|
||||
echo_n "Looking for sdl-config... "
|
||||
sdlconfigs="$_sdlconfig:sdl-config:sdl11-config:sdl12-config"
|
||||
echo_n "Looking for sdl2-config... "
|
||||
sdlconfigs="$_sdlconfig"
|
||||
_sdlconfig=
|
||||
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="$SEPARATOR"
|
||||
|
@ -220,10 +219,9 @@ Optional Features:
|
|||
--force-builtin-zlib force use of built-in zlib library [auto]
|
||||
|
||||
Optional Libraries:
|
||||
--with-sdl-prefix=DIR Prefix where the sdl-config script is installed (optional)
|
||||
--with-sdl-prefix=DIR Prefix where the sdl2-config script is installed (optional)
|
||||
--with-libpng-prefix=DIR Prefix where libpng is installed (optional)
|
||||
--with-zlib-prefix=DIR Prefix where zlib is installed (optional)
|
||||
--x-libraries Path to X11 libraries [${X_LIBS}]
|
||||
|
||||
Some influential environment variables:
|
||||
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
|
||||
|
@ -273,10 +271,6 @@ for ac_option in $@; do
|
|||
ZLIB_CFLAGS="-I$_prefix/include"
|
||||
ZLIB_LIBS="-L$_prefix/lib"
|
||||
;;
|
||||
--x-libraries=*)
|
||||
arg=`echo $ac_option | cut -d '=' -f 2`
|
||||
X_LIBS="$arg"
|
||||
;;
|
||||
--host=*)
|
||||
_host=`echo $ac_option | cut -d '=' -f 2`
|
||||
;;
|
||||
|
|
|
@ -62,7 +62,8 @@ void EventHandlerSDL2::pollEvent()
|
|||
{
|
||||
handleKeyEvent((StellaKey)event.key.keysym.sym,
|
||||
(StellaMod)event.key.keysym.mod,
|
||||
event.key.keysym.unicode & 0x7f,
|
||||
//FIXSDL event.key.keysym.unicode & 0x7f,
|
||||
event.key.keysym.scancode,
|
||||
event.key.type == SDL_KEYDOWN);
|
||||
break;
|
||||
}
|
||||
|
@ -88,20 +89,19 @@ void EventHandlerSDL2::pollEvent()
|
|||
handleMouseButtonEvent(pressed ? EVENT_RBUTTONDOWN : EVENT_RBUTTONUP,
|
||||
event.button.x, event.button.y);
|
||||
break;
|
||||
case SDL_BUTTON_WHEELDOWN:
|
||||
if(pressed)
|
||||
handleMouseButtonEvent(EVENT_WHEELDOWN, event.button.x,
|
||||
event.button.y);
|
||||
break;
|
||||
case SDL_BUTTON_WHEELUP:
|
||||
if(pressed)
|
||||
handleMouseButtonEvent(EVENT_WHEELUP, event.button.x,
|
||||
event.button.y);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if(event.wheel.y < 0)
|
||||
handleMouseButtonEvent(EVENT_WHEELDOWN, 0, event.wheel.y);
|
||||
else if(event.wheel.y > 0)
|
||||
handleMouseButtonEvent(EVENT_WHEELUP, 0, event.wheel.y);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
|
@ -151,26 +151,24 @@ void EventHandlerSDL2::pollEvent()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EventHandlerSDL2::JoystickSDL2::JoystickSDL2(int idx)
|
||||
: stick(NULL)
|
||||
{
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
stick = SDL_JoystickOpen(idx);
|
||||
if(stick)
|
||||
{
|
||||
initialize(SDL_JoystickName(idx), SDL_JoystickNumAxes(stick),
|
||||
SDL_JoystickNumButtons(stick), SDL_JoystickNumHats(stick));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
EventHandlerSDL2::JoystickSDL2::~JoystickSDL2()
|
||||
{
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
if(stick)
|
||||
SDL_JoystickClose(stick);
|
||||
stick = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -58,6 +58,7 @@ class EventHandlerSDL2 : public EventHandler
|
|||
private:
|
||||
SDL_Event event;
|
||||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
// A thin wrapper around a basic StellaJoystick, holding the pointer to
|
||||
// the underlying SDL stick.
|
||||
class JoystickSDL2 : public StellaJoystick
|
||||
|
@ -69,6 +70,7 @@ class EventHandlerSDL2 : public EventHandler
|
|||
private:
|
||||
SDL_Joystick* stick;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,35 +29,38 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceTIA::FBSurfaceTIA(FrameBufferSDL2& buffer)
|
||||
: myFB(buffer),
|
||||
myGL(myFB.p_gl),
|
||||
mySurface(NULL),
|
||||
myTexture(NULL),
|
||||
myVBOID(0),
|
||||
myBaseW(0),
|
||||
myBaseH(0),
|
||||
myScanlinesEnabled(false),
|
||||
myScanlineIntensityI(50),
|
||||
myScanlineIntensityF(0.5)
|
||||
myScanlinesEnabled(false)
|
||||
// myScanlineIntensityI(50),
|
||||
// myScanlineIntensityF(0.5)
|
||||
{
|
||||
myTexID[0] = myTexID[1] = 0;
|
||||
|
||||
// Texture width is set to contain all possible sizes for a TIA image,
|
||||
// including Blargg filtering
|
||||
myTexWidth = FrameBufferSDL2::power_of_two(ATARI_NTSC_OUT_WIDTH(160));
|
||||
myTexHeight = FrameBufferSDL2::power_of_two(320);
|
||||
int width = ATARI_NTSC_OUT_WIDTH(160);
|
||||
int height = 320;
|
||||
|
||||
// Create a surface in the same format as the parent GL class
|
||||
const SDL_PixelFormat& pf = myFB.myPixelFormat;
|
||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, myTexWidth, myTexHeight,
|
||||
pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
|
||||
|
||||
myPitch = myTexture->pitch / pf.BytesPerPixel;
|
||||
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;
|
||||
|
||||
myPitch = mySurface->pitch / pf.BytesPerPixel;
|
||||
|
||||
// To generate texture
|
||||
reload();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceTIA::~FBSurfaceTIA()
|
||||
{
|
||||
if(myTexture)
|
||||
SDL_FreeSurface(myTexture);
|
||||
if(mySurface)
|
||||
SDL_FreeSurface(mySurface);
|
||||
|
||||
free();
|
||||
}
|
||||
|
@ -65,29 +68,29 @@ FBSurfaceTIA::~FBSurfaceTIA()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::getPos(uInt32& x, uInt32& y) const
|
||||
{
|
||||
x = myImageX;
|
||||
y = myImageY;
|
||||
x = mySrc.x;
|
||||
y = mySrc.y;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::translateCoords(Int32& x, Int32& y) const
|
||||
{
|
||||
x -= myImageX;
|
||||
y -= myImageY;
|
||||
x = mySrc.x;
|
||||
y = mySrc.y;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::update()
|
||||
{
|
||||
// Copy the mediasource framebuffer to the RGB texture
|
||||
// In OpenGL mode, it's faster to just assume that the screen is dirty
|
||||
// and always do an update
|
||||
// In hardware rendering mode, it's faster to just assume that the screen
|
||||
// is dirty and always do an update
|
||||
|
||||
uInt8* currentFrame = myTIA->currentFrameBuffer();
|
||||
uInt8* previousFrame = myTIA->previousFrameBuffer();
|
||||
uInt32 width = myTIA->width();
|
||||
uInt32 height = myTIA->height();
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels;
|
||||
uInt32* buffer = (uInt32*) mySurface->pixels;
|
||||
|
||||
// TODO - Eventually 'phosphor' won't be a separate mode, and will become
|
||||
// a post-processing filter by blending several frames.
|
||||
|
@ -129,17 +132,25 @@ void FBSurfaceTIA::update()
|
|||
case FrameBufferSDL2::kBlarggNormal:
|
||||
{
|
||||
myFB.myNTSCFilter.blit_single(currentFrame, width, height,
|
||||
buffer, myTexture->pitch);
|
||||
buffer, mySurface->pitch);
|
||||
break;
|
||||
}
|
||||
case FrameBufferSDL2::kBlarggPhosphor:
|
||||
{
|
||||
myFB.myNTSCFilter.blit_double(currentFrame, previousFrame, width, height,
|
||||
buffer, myTexture->pitch);
|
||||
buffer, mySurface->pitch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Rect tmp;
|
||||
tmp.x = tmp.y = 0;
|
||||
tmp.w = 160; tmp.h = 210;
|
||||
SDL_UpdateTexture(myTexture, NULL, mySurface->pixels, mySurface->pitch);
|
||||
SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrc, &myDst);
|
||||
|
||||
|
||||
#if 0
|
||||
myGL.EnableClientState(GL_VERTEX_ARRAY);
|
||||
myGL.EnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
|
@ -150,7 +161,7 @@ void FBSurfaceTIA::update()
|
|||
myGL.PixelStorei(GL_UNPACK_ROW_LENGTH, myPitch);
|
||||
myGL.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myBaseW, myBaseH,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
myTexture->pixels);
|
||||
mySurface->pixels);
|
||||
|
||||
if(myFB.myVBOAvailable)
|
||||
{
|
||||
|
@ -192,6 +203,7 @@ void FBSurfaceTIA::update()
|
|||
|
||||
myGL.DisableClientState(GL_VERTEX_ARRAY);
|
||||
myGL.DisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
#endif
|
||||
|
||||
// Let postFrameUpdate() know that a change has been made
|
||||
myFB.myDirtyFlag = true;
|
||||
|
@ -200,20 +212,27 @@ void FBSurfaceTIA::update()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::invalidate()
|
||||
{
|
||||
SDL_FillRect(myTexture, NULL, 0);
|
||||
SDL_FillRect(mySurface, NULL, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::free()
|
||||
{
|
||||
myGL.DeleteTextures(2, myTexID);
|
||||
if(myFB.myVBOAvailable)
|
||||
myGL.DeleteBuffers(1, &myVBOID);
|
||||
if(myTexture)
|
||||
{
|
||||
SDL_DestroyTexture(myTexture);
|
||||
myTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::reload()
|
||||
{
|
||||
// Re-create texture; the underlying SDL_Surface is fine as-is
|
||||
myTexture = SDL_CreateTexture(myFB.myRenderer,
|
||||
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
|
||||
mySurface->w, mySurface->h);
|
||||
#if 0
|
||||
// This does a 'soft' reset of the surface
|
||||
// It seems that on some system (notably, OSX), creating a new SDL window
|
||||
// destroys the GL context, requiring a reload of all textures
|
||||
|
@ -241,7 +260,7 @@ void FBSurfaceTIA::reload()
|
|||
myGL.PixelStorei(GL_UNPACK_ROW_LENGTH, myPitch);
|
||||
myGL.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, myTexWidth, myTexHeight, 0,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
myTexture->pixels);
|
||||
mySurface->pixels);
|
||||
|
||||
// Scanline texture (@ index 1)
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[1]);
|
||||
|
@ -264,51 +283,72 @@ void FBSurfaceTIA::reload()
|
|||
myGL.BindBuffer(GL_ARRAY_BUFFER, myVBOID);
|
||||
myGL.BufferData(GL_ARRAY_BUFFER, 32*sizeof(GLfloat), myCoord, GL_STATIC_DRAW);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::setScanIntensity(uInt32 intensity)
|
||||
{
|
||||
#if 0
|
||||
myScanlineIntensityI = (GLuint)intensity;
|
||||
myScanlineIntensityF = (GLfloat)intensity / 100;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::setTexInterpolation(bool enable)
|
||||
{
|
||||
#if 0
|
||||
myTexFilter[0] = enable ? GL_LINEAR : GL_NEAREST;
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myTexFilter[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myTexFilter[0]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::setScanInterpolation(bool enable)
|
||||
{
|
||||
#if 0
|
||||
myTexFilter[1] = enable ? GL_LINEAR : GL_NEAREST;
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myTexFilter[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myTexFilter[1]);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::updateCoords(uInt32 baseH,
|
||||
uInt32 imgX, uInt32 imgY, uInt32 imgW, uInt32 imgH)
|
||||
{
|
||||
//cerr << "baseH=" << baseH << ", x=" << imgX << ", y=" << imgY << ", w=" << imgW << ", h=" << imgH << endl;
|
||||
|
||||
mySrc.w = myFB.ntscEnabled() ? ATARI_NTSC_OUT_WIDTH(160) : 160;
|
||||
mySrc.h = baseH;
|
||||
|
||||
myDst.w = imgW;
|
||||
myDst.h = imgH;
|
||||
|
||||
//cerr << "src: x=" << mySrc.x << ", y=" << mySrc.y << ", w=" << mySrc.w << ", h=" << mySrc.h << endl;
|
||||
//cerr << "dst: x=" << myDst.x << ", y=" << myDst.y << ", w=" << myDst.w << ", h=" << myDst.h << endl;
|
||||
|
||||
#if 0
|
||||
myBaseH = baseH;
|
||||
myImageX = imgX; myImageY = imgY;
|
||||
myImageW = imgW; myImageH = imgH;
|
||||
|
||||
updateCoords();
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceTIA::updateCoords()
|
||||
{
|
||||
#if 0
|
||||
// Normal TIA rendering and TV effects use different widths
|
||||
// We use the same buffer, and only pick the width we need
|
||||
myBaseW = myFB.ntscEnabled() ? ATARI_NTSC_OUT_WIDTH(160) : 160;
|
||||
|
@ -382,6 +422,7 @@ void FBSurfaceTIA::updateCoords()
|
|||
myGL.BindBuffer(GL_ARRAY_BUFFER, myVBOID);
|
||||
myGL.BufferData(GL_ARRAY_BUFFER, 32*sizeof(GLfloat), myCoord, GL_STATIC_DRAW);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -25,10 +25,9 @@
|
|||
#include "FrameBufferSDL2.hxx"
|
||||
|
||||
/**
|
||||
A surface suitable for OpenGL rendering mode, but specifically for
|
||||
rendering from a TIA source. It doesn't implement most of the
|
||||
drawing primitives, since it's concerned with TIA images only.
|
||||
This class extends FrameBuffer::FBSurface.
|
||||
A surface suitable for SDL Render2D API and rendering from a TIA source.
|
||||
It doesn't implement most of the drawing primitives, since it's concerned
|
||||
with TIA images only. This class extends FrameBuffer::FBSurface.
|
||||
|
||||
@author Stephen Anthony
|
||||
*/
|
||||
|
@ -44,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 myImageW; }
|
||||
uInt32 getHeight() const { return myImageH; }
|
||||
uInt32 getWidth() const { return mySrc.w; }
|
||||
uInt32 getHeight() const { return mySrc.h; }
|
||||
void translateCoords(Int32& x, Int32& y) const;
|
||||
void update();
|
||||
void invalidate();
|
||||
|
@ -64,23 +63,14 @@ class FBSurfaceTIA : public FBSurface
|
|||
|
||||
private:
|
||||
FrameBufferSDL2& myFB;
|
||||
const FrameBufferSDL2::GLpointers& myGL;
|
||||
const TIA* myTIA;
|
||||
SDL_Surface* myTexture;
|
||||
|
||||
SDL_Surface* mySurface;
|
||||
SDL_Texture* myTexture;
|
||||
SDL_Rect mySrc, myDst;
|
||||
uInt32 myPitch;
|
||||
|
||||
GLuint myTexID[2], myVBOID;
|
||||
GLsizei myTexWidth;
|
||||
GLsizei myTexHeight;
|
||||
GLuint myBaseW, myBaseH;
|
||||
GLuint myImageX, myImageY, myImageW, myImageH;
|
||||
GLfloat myTexCoordW, myTexCoordH;
|
||||
GLfloat myCoord[32];
|
||||
GLint myTexFilter[2];
|
||||
|
||||
bool myScanlinesEnabled;
|
||||
GLuint myScanlineIntensityI;
|
||||
GLfloat myScanlineIntensityF;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,38 +23,31 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceUI::FBSurfaceUI(FrameBufferSDL2& buffer, uInt32 width, uInt32 height)
|
||||
: myFB(buffer),
|
||||
myGL(myFB.p_gl),
|
||||
mySurface(NULL),
|
||||
myTexture(NULL),
|
||||
myTexID(0),
|
||||
myVBOID(0),
|
||||
myImageX(0),
|
||||
myImageY(0),
|
||||
myImageW(width),
|
||||
myImageH(height)
|
||||
mySurfaceIsDirty(true)
|
||||
{
|
||||
// Fill buffer struct with valid data
|
||||
myTexWidth = FrameBufferSDL2::power_of_two(myImageW);
|
||||
myTexHeight = FrameBufferSDL2::power_of_two(myImageH);
|
||||
myTexCoordW = (GLfloat) myImageW / myTexWidth;
|
||||
myTexCoordH = (GLfloat) myImageH / myTexHeight;
|
||||
|
||||
// Create a surface in the same format as the parent GL class
|
||||
const SDL_PixelFormat& pf = myFB.myPixelFormat;
|
||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, myTexWidth, myTexHeight,
|
||||
pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
|
||||
|
||||
myPitch = myTexture->pitch / pf.BytesPerPixel;
|
||||
mySurface = SDL_CreateRGBSurface(0, width, height,
|
||||
pf.BitsPerPixel, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask);
|
||||
|
||||
// Associate the SDL surface with a GL texture object
|
||||
updateCoords();
|
||||
mySrc.x = mySrc.y = myDst.x = myDst.y = 0;
|
||||
mySrc.w = myDst.w = width;
|
||||
mySrc.h = myDst.h = height;
|
||||
|
||||
myPitch = mySurface->pitch / pf.BytesPerPixel;
|
||||
|
||||
// To generate texture
|
||||
reload();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FBSurfaceUI::~FBSurfaceUI()
|
||||
{
|
||||
if(myTexture)
|
||||
SDL_FreeSurface(myTexture);
|
||||
if(mySurface)
|
||||
SDL_FreeSurface(mySurface);
|
||||
|
||||
free();
|
||||
}
|
||||
|
@ -62,7 +55,7 @@ FBSurfaceUI::~FBSurfaceUI()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
|
||||
{
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels + y * myPitch + x;
|
||||
uInt32* buffer = (uInt32*) mySurface->pixels + y * myPitch + x;
|
||||
while(x++ <= x2)
|
||||
*buffer++ = (uInt32) myFB.myDefPalette[color];
|
||||
}
|
||||
|
@ -70,7 +63,7 @@ void FBSurfaceUI::hLine(uInt32 x, uInt32 y, uInt32 x2, uInt32 color)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::vLine(uInt32 x, uInt32 y, uInt32 y2, uInt32 color)
|
||||
{
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels + y * myPitch + x;
|
||||
uInt32* buffer = (uInt32*) mySurface->pixels + y * myPitch + x;
|
||||
while(y++ <= y2)
|
||||
{
|
||||
*buffer = (uInt32) myFB.myDefPalette[color];
|
||||
|
@ -87,7 +80,7 @@ void FBSurfaceUI::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, uInt32 color)
|
|||
tmp.y = y;
|
||||
tmp.w = w;
|
||||
tmp.h = h;
|
||||
SDL_FillRect(myTexture, &tmp, myFB.myDefPalette[color]);
|
||||
SDL_FillRect(mySurface, &tmp, myFB.myDefPalette[color]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -122,7 +115,7 @@ void FBSurfaceUI::drawChar(const GUI::Font& font, uInt8 chr,
|
|||
}
|
||||
|
||||
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels +
|
||||
uInt32* buffer = (uInt32*) mySurface->pixels +
|
||||
(ty + desc.ascent - bby - bbh) * myPitch +
|
||||
tx + bbx;
|
||||
|
||||
|
@ -143,7 +136,7 @@ void FBSurfaceUI::drawChar(const GUI::Font& font, uInt8 chr,
|
|||
void FBSurfaceUI::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
|
||||
uInt32 color, uInt32 h)
|
||||
{
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels + ty * myPitch + tx;
|
||||
uInt32* buffer = (uInt32*) mySurface->pixels + ty * myPitch + tx;
|
||||
|
||||
for(uInt32 y = 0; y < h; ++y)
|
||||
{
|
||||
|
@ -159,7 +152,7 @@ void FBSurfaceUI::drawBitmap(uInt32* bitmap, uInt32 tx, uInt32 ty,
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::drawPixels(uInt32* data, uInt32 tx, uInt32 ty, uInt32 numpixels)
|
||||
{
|
||||
uInt32* buffer = (uInt32*) myTexture->pixels + ty * myPitch + tx;
|
||||
uInt32* buffer = (uInt32*) mySurface->pixels + ty * myPitch + tx;
|
||||
|
||||
for(uInt32 i = 0; i < numpixels; ++i)
|
||||
*buffer++ = (uInt32) data[i];
|
||||
|
@ -170,42 +163,34 @@ void FBSurfaceUI::drawSurface(const FBSurface* surface, uInt32 tx, uInt32 ty)
|
|||
{
|
||||
const FBSurfaceUI* s = (const FBSurfaceUI*) surface;
|
||||
|
||||
SDL_Rect dstrect;
|
||||
dstrect.x = tx;
|
||||
dstrect.y = ty;
|
||||
SDL_Rect srcrect;
|
||||
srcrect.x = 0;
|
||||
srcrect.y = 0;
|
||||
srcrect.w = s->myImageW;
|
||||
srcrect.h = s->myImageH;
|
||||
SDL_Rect dst;
|
||||
dst.x = tx;
|
||||
dst.y = ty;
|
||||
dst.w = s->mySrc.w;
|
||||
dst.h = s->mySrc.h;
|
||||
|
||||
SDL_BlitSurface(s->myTexture, &srcrect, myTexture, &dstrect);
|
||||
SDL_BlitSurface(s->mySurface, &(s->mySrc), mySurface, &dst);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
// OpenGL mode doesn't make use of dirty rectangles
|
||||
// It's faster to just update the entire surface
|
||||
// It's faster to just update the entire (hardware) surface
|
||||
mySurfaceIsDirty = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::getPos(uInt32& x, uInt32& y) const
|
||||
{
|
||||
x = myImageX;
|
||||
y = myImageY;
|
||||
x = myDst.x;
|
||||
y = myDst.y;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::setPos(uInt32 x, uInt32 y)
|
||||
{
|
||||
if(myImageX != x || myImageY != y)
|
||||
{
|
||||
myImageX = x;
|
||||
myImageY = y;
|
||||
updateCoords();
|
||||
}
|
||||
myDst.x = x;
|
||||
myDst.y = y;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -214,12 +199,8 @@ void FBSurfaceUI::setWidth(uInt32 w)
|
|||
// This method can't be used with 'scaled' surface (aka TIA surfaces)
|
||||
// That shouldn't really matter, though, as all the UI stuff isn't scaled,
|
||||
// and it's the only thing that uses it
|
||||
if(myImageW != w)
|
||||
{
|
||||
myImageW = BSPF_min(w, (uInt32)myTexWidth);
|
||||
myTexCoordW = (GLfloat) myImageW / myTexWidth;
|
||||
updateCoords();
|
||||
}
|
||||
mySrc.w = w;
|
||||
myDst.w = w;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -228,19 +209,15 @@ void FBSurfaceUI::setHeight(uInt32 h)
|
|||
// This method can't be used with 'scaled' surface (aka TIA surfaces)
|
||||
// That shouldn't really matter, though, as all the UI stuff isn't scaled,
|
||||
// and it's the only thing that uses it
|
||||
if(myImageH != h)
|
||||
{
|
||||
myImageH = BSPF_min(h, (uInt32)myTexHeight);
|
||||
myTexCoordH = (GLfloat) myImageH / myTexHeight;
|
||||
updateCoords();
|
||||
}
|
||||
mySrc.h = h;
|
||||
myDst.h = h;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::translateCoords(Int32& x, Int32& y) const
|
||||
{
|
||||
x -= myImageX;
|
||||
y -= myImageY;
|
||||
x -= myDst.x;
|
||||
y -= myDst.y;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -248,32 +225,11 @@ void FBSurfaceUI::update()
|
|||
{
|
||||
if(mySurfaceIsDirty)
|
||||
{
|
||||
// Texturemap complete texture to surface so we have free scaling
|
||||
// and antialiasing
|
||||
myGL.ActiveTexture(GL_TEXTURE0);
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID);
|
||||
myGL.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
myGL.PixelStorei(GL_UNPACK_ROW_LENGTH, myPitch);
|
||||
myGL.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myImageW, myImageH,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
myTexture->pixels);
|
||||
//cerr << "src: x=" << mySrc.x << ", y=" << mySrc.y << ", w=" << mySrc.w << ", h=" << mySrc.h << endl;
|
||||
//cerr << "dst: x=" << myDst.x << ", y=" << myDst.y << ", w=" << myDst.w << ", h=" << myDst.h << endl;
|
||||
|
||||
myGL.EnableClientState(GL_VERTEX_ARRAY);
|
||||
myGL.EnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
if(myFB.myVBOAvailable)
|
||||
{
|
||||
myGL.BindBuffer(GL_ARRAY_BUFFER, myVBOID);
|
||||
myGL.VertexPointer(2, GL_FLOAT, 0, (const GLvoid*)0);
|
||||
myGL.TexCoordPointer(2, GL_FLOAT, 0, (const GLvoid*)(8*sizeof(GLfloat)));
|
||||
}
|
||||
else
|
||||
{
|
||||
myGL.VertexPointer(2, GL_FLOAT, 0, myCoord);
|
||||
myGL.TexCoordPointer(2, GL_FLOAT, 0, myCoord+8);
|
||||
}
|
||||
myGL.DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
myGL.DisableClientState(GL_VERTEX_ARRAY);
|
||||
myGL.DisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
SDL_UpdateTexture(myTexture, NULL, mySurface->pixels, mySurface->pitch);
|
||||
SDL_RenderCopy(myFB.myRenderer, myTexture, &mySrc, &myDst);
|
||||
|
||||
mySurfaceIsDirty = false;
|
||||
|
||||
|
@ -282,85 +238,27 @@ void FBSurfaceUI::update()
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::invalidate()
|
||||
{
|
||||
SDL_FillRect(mySurface, NULL, 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::free()
|
||||
{
|
||||
myGL.DeleteTextures(1, &myTexID);
|
||||
if(myFB.myVBOAvailable)
|
||||
myGL.DeleteBuffers(1, &myVBOID);
|
||||
if(myTexture)
|
||||
{
|
||||
SDL_DestroyTexture(myTexture);
|
||||
myTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::reload()
|
||||
{
|
||||
// This does a 'soft' reset of the surface
|
||||
// It seems that on some system (notably, OSX), creating a new SDL window
|
||||
// destroys the GL context, requiring a reload of all textures
|
||||
// However, destroying the entire FBSurfaceUI object is wasteful, since
|
||||
// it will also regenerate SDL software surfaces (which are not required
|
||||
// to be regenerated)
|
||||
// Basically, all that needs to be done is to re-call glTexImage2D with a
|
||||
// new texture ID, so that's what we do here
|
||||
myGL.ActiveTexture(GL_TEXTURE0);
|
||||
myGL.Enable(GL_TEXTURE_2D);
|
||||
myGL.GenTextures(1, &myTexID);
|
||||
myGL.BindTexture(GL_TEXTURE_2D, myTexID);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
myGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Create the texture in the most optimal format
|
||||
myGL.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
myGL.PixelStorei(GL_UNPACK_ROW_LENGTH, myPitch);
|
||||
myGL.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, myTexWidth, myTexHeight, 0,
|
||||
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
myTexture->pixels);
|
||||
|
||||
// Cache vertex and texture coordinates using vertex buffer object
|
||||
if(myFB.myVBOAvailable)
|
||||
{
|
||||
myGL.GenBuffers(1, &myVBOID);
|
||||
myGL.BindBuffer(GL_ARRAY_BUFFER, myVBOID);
|
||||
myGL.BufferData(GL_ARRAY_BUFFER, 16*sizeof(GLfloat), myCoord, GL_STATIC_DRAW);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FBSurfaceUI::updateCoords()
|
||||
{
|
||||
// Vertex coordinates for texture
|
||||
// Upper left (x,y)
|
||||
myCoord[0] = (GLfloat)myImageX;
|
||||
myCoord[1] = (GLfloat)myImageY;
|
||||
// Upper right (x+w,y)
|
||||
myCoord[2] = (GLfloat)(myImageX + myImageW);
|
||||
myCoord[3] = (GLfloat)myImageY;
|
||||
// Lower left (x,y+h)
|
||||
myCoord[4] = (GLfloat)myImageX;
|
||||
myCoord[5] = (GLfloat)(myImageY + myImageH);
|
||||
// Lower right (x+w,y+h)
|
||||
myCoord[6] = (GLfloat)(myImageX + myImageW);
|
||||
myCoord[7] = (GLfloat)(myImageY + myImageH);
|
||||
|
||||
// Texture coordinates for texture
|
||||
// Upper left (x,y)
|
||||
myCoord[8] = 0.0f;
|
||||
myCoord[9] = 0.0f;
|
||||
// Upper right (x+w,y)
|
||||
myCoord[10] = myTexCoordW;
|
||||
myCoord[11] = 0.0f;
|
||||
// Lower left (x,y+h)
|
||||
myCoord[12] = 0.0f;
|
||||
myCoord[13] = myTexCoordH;
|
||||
// Lower right (x+w,y+h)
|
||||
myCoord[14] = myTexCoordW;
|
||||
myCoord[15] = myTexCoordH;
|
||||
|
||||
// Cache vertex and texture coordinates using vertex buffer object
|
||||
if(myFB.myVBOAvailable)
|
||||
{
|
||||
myGL.BindBuffer(GL_ARRAY_BUFFER, myVBOID);
|
||||
myGL.BufferData(GL_ARRAY_BUFFER, 16*sizeof(GLfloat), myCoord, GL_STATIC_DRAW);
|
||||
}
|
||||
// Re-create texture; the underlying SDL_Surface is fine as-is
|
||||
myTexture = SDL_CreateTexture(myFB.myRenderer,
|
||||
SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING,
|
||||
mySurface->w, mySurface->h);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "FrameBufferSDL2.hxx"
|
||||
|
||||
/**
|
||||
A surface suitable for OpenGL rendering mode, used for various UI dialogs.
|
||||
A surface suitable for SDL Render2D API, used for various UI dialogs.
|
||||
This class extends FrameBuffer::FBSurface.
|
||||
|
||||
@author Stephen Anthony
|
||||
|
@ -48,29 +48,22 @@ class FBSurfaceUI : public FBSurface
|
|||
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
|
||||
void getPos(uInt32& x, uInt32& y) const;
|
||||
void setPos(uInt32 x, uInt32 y);
|
||||
uInt32 getWidth() const { return myImageW; }
|
||||
uInt32 getHeight() const { return myImageH; }
|
||||
uInt32 getWidth() const { return mySrc.w; }
|
||||
uInt32 getHeight() const { return mySrc.h; }
|
||||
void setWidth(uInt32 w);
|
||||
void setHeight(uInt32 h);
|
||||
void translateCoords(Int32& x, Int32& y) const;
|
||||
void update();
|
||||
void invalidate();
|
||||
void free();
|
||||
void reload();
|
||||
|
||||
private:
|
||||
void updateCoords();
|
||||
|
||||
private:
|
||||
FrameBufferSDL2& myFB;
|
||||
const FrameBufferSDL2::GLpointers& myGL;
|
||||
SDL_Surface* myTexture;
|
||||
|
||||
GLuint myTexID, myVBOID;
|
||||
GLsizei myTexWidth;
|
||||
GLsizei myTexHeight;
|
||||
GLuint myImageX, myImageY, myImageW, myImageH;
|
||||
GLfloat myTexCoordW, myTexCoordH;
|
||||
GLfloat myCoord[16];
|
||||
SDL_Surface* mySurface;
|
||||
SDL_Texture* myTexture;
|
||||
SDL_Rect mySrc, myDst;
|
||||
|
||||
bool mySurfaceIsDirty;
|
||||
uInt32 myPitch;
|
||||
|
|
|
@ -39,19 +39,20 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
|
|||
: FrameBuffer(osystem),
|
||||
myFilterType(kNormal),
|
||||
myScreen(0),
|
||||
mySDLFlags(0),
|
||||
myWindow(NULL),
|
||||
myRenderer(NULL),
|
||||
myWindowFlags(0),
|
||||
myTiaSurface(NULL),
|
||||
myDirtyFlag(true)
|
||||
{
|
||||
// Initialize SDL2 context
|
||||
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||
return;
|
||||
|
||||
// Load OpenGL function pointers
|
||||
loadLibrary(osystem->settings().getString("gl_lib"));
|
||||
if(loadFuncs(kGL_BASIC))
|
||||
myVBOAvailable = myOSystem->settings().getBool("gl_vbo") && loadFuncs(kGL_VBO);
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// We need a pixel format for palette value calculations
|
||||
// It's done this way (vs directly accessing a FBSurfaceUI object)
|
||||
|
@ -59,7 +60,7 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
|
|||
// been created
|
||||
// Note: alpha disabled for now, since it's not used
|
||||
SDL_Surface* s = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32,
|
||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
|
||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
|
||||
|
||||
myPixelFormat = *(s->format);
|
||||
SDL_FreeSurface(s);
|
||||
|
@ -68,85 +69,13 @@ FrameBufferSDL2::FrameBufferSDL2(OSystem* osystem)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferSDL2::~FrameBufferSDL2()
|
||||
{
|
||||
// if(myWindow)
|
||||
// SDL_DestroyWindow(myWindow);
|
||||
|
||||
// We're taking responsibility for this surface
|
||||
delete myTiaSurface;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::loadLibrary(const string& library)
|
||||
{
|
||||
if(myLibraryLoaded)
|
||||
return true;
|
||||
|
||||
// Try both the specified library and auto-detection
|
||||
bool libLoaded = (library != "" && SDL_GL_LoadLibrary(library.c_str()) >= 0);
|
||||
bool autoLoaded = false;
|
||||
if(!libLoaded) autoLoaded = (SDL_GL_LoadLibrary(0) >= 0);
|
||||
if(!libLoaded && !autoLoaded)
|
||||
return false;
|
||||
|
||||
return myLibraryLoaded = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::loadFuncs(GLFunctionality functionality)
|
||||
{
|
||||
#define OGL_INIT(NAME,RET,FUNC,PARAMS) \
|
||||
p_gl.NAME = (RET(APIENTRY*)PARAMS) SDL_GL_GetProcAddress(#FUNC); if(!p_gl.NAME) return false
|
||||
|
||||
if(myLibraryLoaded)
|
||||
{
|
||||
// Fill the function pointers for GL functions
|
||||
// If anything fails, we'll know it immediately, and return false
|
||||
switch(functionality)
|
||||
{
|
||||
case kGL_BASIC:
|
||||
OGL_INIT(Clear,void,glClear,(GLbitfield));
|
||||
OGL_INIT(Enable,void,glEnable,(GLenum));
|
||||
OGL_INIT(Disable,void,glDisable,(GLenum));
|
||||
OGL_INIT(PushAttrib,void,glPushAttrib,(GLbitfield));
|
||||
OGL_INIT(GetString,const GLubyte*,glGetString,(GLenum));
|
||||
OGL_INIT(Hint,void,glHint,(GLenum, GLenum));
|
||||
OGL_INIT(ShadeModel,void,glShadeModel,(GLenum));
|
||||
OGL_INIT(MatrixMode,void,glMatrixMode,(GLenum));
|
||||
OGL_INIT(Ortho,void,glOrtho,(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble));
|
||||
OGL_INIT(Viewport,void,glViewport,(GLint, GLint, GLsizei, GLsizei));
|
||||
OGL_INIT(LoadIdentity,void,glLoadIdentity,(void));
|
||||
OGL_INIT(Translatef,void,glTranslatef,(GLfloat,GLfloat,GLfloat));
|
||||
OGL_INIT(EnableClientState,void,glEnableClientState,(GLenum));
|
||||
OGL_INIT(DisableClientState,void,glDisableClientState,(GLenum));
|
||||
OGL_INIT(VertexPointer,void,glVertexPointer,(GLint,GLenum,GLsizei,const GLvoid*));
|
||||
OGL_INIT(TexCoordPointer,void,glTexCoordPointer,(GLint,GLenum,GLsizei,const GLvoid*));
|
||||
OGL_INIT(DrawArrays,void,glDrawArrays,(GLenum,GLint,GLsizei));
|
||||
OGL_INIT(ReadPixels,void,glReadPixels,(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*));
|
||||
OGL_INIT(PixelStorei,void,glPixelStorei,(GLenum, GLint));
|
||||
OGL_INIT(TexEnvf,void,glTexEnvf,(GLenum, GLenum, GLfloat));
|
||||
OGL_INIT(GenTextures,void,glGenTextures,(GLsizei, GLuint*));
|
||||
OGL_INIT(DeleteTextures,void,glDeleteTextures,(GLsizei, const GLuint*));
|
||||
OGL_INIT(ActiveTexture,void,glActiveTexture,(GLenum));
|
||||
OGL_INIT(BindTexture,void,glBindTexture,(GLenum, GLuint));
|
||||
OGL_INIT(TexImage2D,void,glTexImage2D,(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*));
|
||||
OGL_INIT(TexSubImage2D,void,glTexSubImage2D,(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*));
|
||||
OGL_INIT(TexParameteri,void,glTexParameteri,(GLenum, GLenum, GLint));
|
||||
OGL_INIT(GetError,GLenum,glGetError,(void));
|
||||
OGL_INIT(Color4f,void,glColor4f,(GLfloat,GLfloat,GLfloat,GLfloat));
|
||||
OGL_INIT(BlendFunc,void,glBlendFunc,(GLenum,GLenum));
|
||||
break; // kGL_Full
|
||||
|
||||
case kGL_VBO:
|
||||
OGL_INIT(GenBuffers,void,glGenBuffers,(GLsizei,GLuint*));
|
||||
OGL_INIT(BindBuffer,void,glBindBuffer,(GLenum,GLuint));
|
||||
OGL_INIT(BufferData,void,glBufferData,(GLenum,GLsizei,const void*,GLenum));
|
||||
OGL_INIT(DeleteBuffers,void,glDeleteBuffers,(GLsizei, const GLuint*));
|
||||
break; // kGL_VBO
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, ResolutionList& res)
|
||||
{
|
||||
|
@ -157,9 +86,10 @@ bool FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, ResolutionList& res)
|
|||
const GUI::Size& s = myOSystem->settings().getSize("maxres");
|
||||
if(s.w <= 0 || s.h <= 0)
|
||||
{
|
||||
const SDL_VideoInfo* info = SDL_GetVideoInfo();
|
||||
w = info->current_w;
|
||||
h = info->current_h;
|
||||
SDL_DisplayMode desktop;
|
||||
SDL_GetDesktopDisplayMode(0, &desktop);
|
||||
w = desktop.w;
|
||||
h = desktop.h;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -223,73 +153,45 @@ bool FrameBufferSDL2::queryHardware(uInt32& w, uInt32& h, ResolutionList& res)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::initSubsystem(VideoMode& mode, bool full)
|
||||
bool FrameBufferSDL2::setVideoMode(const string& title, VideoMode& mode, bool full)
|
||||
{
|
||||
// Now (re)initialize the SDL video system
|
||||
// These things only have to be done one per FrameBuffer creation
|
||||
// If not initialized by this point, then immediately fail
|
||||
if(SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
||||
{
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||
{
|
||||
ostringstream buf;
|
||||
buf << "ERROR: Couldn't initialize SDL: " << SDL_GetError() << endl;
|
||||
myOSystem->logMessage(buf.str(), 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mySDLFlags |= SDL_OPENGL;
|
||||
setHint(kFullScreen, full);
|
||||
|
||||
// Set up the OpenGL attributes
|
||||
myDepth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
|
||||
switch(myDepth)
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
myRGB[0] = 5; myRGB[1] = 5; myRGB[2] = 5; myRGB[3] = 0;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
myRGB[0] = 8; myRGB[1] = 8; myRGB[2] = 8; myRGB[3] = 0;
|
||||
break;
|
||||
default: // This should never happen
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the screen
|
||||
if(!setVidMode(mode))
|
||||
return false;
|
||||
|
||||
// Now check to see what color components were actually created
|
||||
SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &myRGB[0] );
|
||||
SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &myRGB[1] );
|
||||
SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &myRGB[2] );
|
||||
SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &myRGB[3] );
|
||||
// (Re)create window and renderer
|
||||
if(myRenderer)
|
||||
{
|
||||
SDL_DestroyRenderer(myRenderer);
|
||||
myRenderer = NULL;
|
||||
}
|
||||
if(myWindow)
|
||||
{
|
||||
SDL_DestroyWindow(myWindow);
|
||||
myWindow = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
myWindow = SDL_CreateWindow(title.c_str(),
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
mode.image_w, mode.image_h,
|
||||
0);
|
||||
if(myWindow == NULL)
|
||||
{
|
||||
string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
|
||||
myOSystem->logMessage(msg, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FrameBufferSDL2::about() const
|
||||
{
|
||||
ostringstream out;
|
||||
out << "Video rendering: OpenGL mode" << endl
|
||||
<< " Vendor: " << p_gl.GetString(GL_VENDOR) << endl
|
||||
<< " Renderer: " << p_gl.GetString(GL_RENDERER) << endl
|
||||
<< " Version: " << p_gl.GetString(GL_VERSION) << endl
|
||||
<< " Color: " << myDepth << " bit, " << myRGB[0] << "-"
|
||||
<< myRGB[1] << "-" << myRGB[2] << "-" << myRGB[3] << ", "
|
||||
<< "GL_BGRA" << endl
|
||||
<< " Extensions: VBO " << (myVBOAvailable ? "enabled" : "disabled")
|
||||
<< endl;
|
||||
return out.str();
|
||||
}
|
||||
myRenderer = SDL_CreateRenderer(myWindow, -1,
|
||||
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
if(myWindow == NULL)
|
||||
{
|
||||
string msg = "ERROR: Unable to create SDL renderer: " + string(SDL_GetError());
|
||||
myOSystem->logMessage(msg, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::setVidMode(VideoMode& mode)
|
||||
{
|
||||
bool inTIAMode =
|
||||
myOSystem->eventHandler().state() != EventHandler::S_LAUNCHER &&
|
||||
myOSystem->eventHandler().state() != EventHandler::S_DEBUGGER;
|
||||
|
@ -298,6 +200,7 @@ bool FrameBufferSDL2::setVidMode(VideoMode& mode)
|
|||
// We need it for the creating the TIA surface
|
||||
uInt32 baseHeight = mode.image_h / mode.gfxmode.zoom;
|
||||
|
||||
#if 0
|
||||
// Aspect ratio and fullscreen stretching only applies to the TIA
|
||||
if(inTIAMode)
|
||||
{
|
||||
|
@ -362,18 +265,12 @@ bool FrameBufferSDL2::setVidMode(VideoMode& mode)
|
|||
// We leave it to the user to test and decide
|
||||
int vsync = myOSystem->settings().getBool("gl_vsync") ? 1 : 0;
|
||||
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, vsync );
|
||||
#endif
|
||||
|
||||
// Create screen containing GL context
|
||||
myScreen = SDL_SetVideoMode(mode.screen_w, mode.screen_h, 0, mySDLFlags);
|
||||
if(myScreen == NULL)
|
||||
{
|
||||
string msg = "ERROR: Unable to open SDL window: " + string(SDL_GetError());
|
||||
myOSystem->logMessage(msg, 0);
|
||||
return false;
|
||||
}
|
||||
// Make sure the flags represent the current screen state
|
||||
mySDLFlags = myScreen->flags;
|
||||
// myWindowFlags = myScreen->flags;
|
||||
|
||||
#if 0
|
||||
// Optimization hints
|
||||
p_gl.ShadeModel(GL_FLAT);
|
||||
p_gl.Disable(GL_CULL_FACE);
|
||||
|
@ -390,7 +287,7 @@ bool FrameBufferSDL2::setVidMode(VideoMode& mode)
|
|||
p_gl.MatrixMode(GL_MODELVIEW);
|
||||
p_gl.LoadIdentity();
|
||||
p_gl.Translatef(0.375, 0.375, 0.0); // fix scanline mis-draw issues
|
||||
|
||||
#endif
|
||||
//cerr << "dimensions: " << (fullScreen() ? "(full)" : "") << endl << mode << endl;
|
||||
|
||||
// The framebuffer only takes responsibility for TIA surfaces
|
||||
|
@ -422,25 +319,28 @@ bool FrameBufferSDL2::setVidMode(VideoMode& mode)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::setHint(FBHint hint, bool enabled)
|
||||
string FrameBufferSDL2::about() const
|
||||
{
|
||||
int flag = 0;
|
||||
switch(hint)
|
||||
{
|
||||
case kFullScreen:
|
||||
flag = SDL_FULLSCREEN;
|
||||
break;
|
||||
}
|
||||
if(enabled)
|
||||
mySDLFlags |= flag;
|
||||
else
|
||||
mySDLFlags &= ~flag;
|
||||
#if 0
|
||||
ostringstream out;
|
||||
out << "Video rendering: OpenGL mode" << endl
|
||||
<< " Vendor: " << p_gl.GetString(GL_VENDOR) << endl
|
||||
<< " Renderer: " << p_gl.GetString(GL_RENDERER) << endl
|
||||
<< " Version: " << p_gl.GetString(GL_VERSION) << endl
|
||||
<< " Color: " << myDepth << " bit, " << myRGB[0] << "-"
|
||||
<< myRGB[1] << "-" << myRGB[2] << "-" << myRGB[3] << ", "
|
||||
<< "GL_BGRA" << endl
|
||||
<< " Extensions: VBO " << (myVBOAvailable ? "enabled" : "disabled")
|
||||
<< endl;
|
||||
return out.str();
|
||||
#endif
|
||||
return EmptyString;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::invalidate()
|
||||
{
|
||||
p_gl.Clear(GL_COLOR_BUFFER_BIT);
|
||||
SDL_RenderClear(myRenderer);
|
||||
if(myTiaSurface)
|
||||
myTiaSurface->invalidate();
|
||||
}
|
||||
|
@ -448,34 +348,32 @@ void FrameBufferSDL2::invalidate()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::showCursor(bool show)
|
||||
{
|
||||
SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
|
||||
//FIXSDL SDL_ShowCursor(show ? SDL_ENABLE : SDL_DISABLE);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::grabMouse(bool grab)
|
||||
{
|
||||
SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
|
||||
//FIXSDL SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::fullScreen() const
|
||||
{
|
||||
#if 0//FIXSDL
|
||||
#ifdef WINDOWED_SUPPORT
|
||||
return mySDLFlags & SDL_FULLSCREEN;
|
||||
return myWindowFlags & SDL_FULLSCREEN;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::setWindowTitle(const string& title)
|
||||
{
|
||||
SDL_WM_SetCaption(title.c_str(), "stella");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::setWindowIcon()
|
||||
{
|
||||
#if 0 //FIXSDL
|
||||
#if !defined(BSPF_MAC_OSX) && !defined(BSPF_UNIX)
|
||||
#include "stella.xpm" // The Stella icon
|
||||
|
||||
|
@ -532,6 +430,7 @@ void FrameBufferSDL2::setWindowIcon()
|
|||
SDL_WM_SetIcon(surface, (unsigned char *) mask);
|
||||
SDL_FreeSurface(surface);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -547,7 +446,7 @@ void FrameBufferSDL2::postFrameUpdate()
|
|||
if(myDirtyFlag)
|
||||
{
|
||||
// Now show all changes made to the texture(s)
|
||||
SDL_GL_SwapBuffers();
|
||||
SDL_RenderPresent(myRenderer);
|
||||
myDirtyFlag = false;
|
||||
}
|
||||
}
|
||||
|
@ -570,7 +469,7 @@ void FrameBufferSDL2::enableNTSC(bool enable)
|
|||
if(myTiaSurface)
|
||||
{
|
||||
myFilterType = FilterType(enable ? myFilterType | 0x10 : myFilterType & 0x01);
|
||||
myTiaSurface->updateCoords();
|
||||
//FIXSDL myTiaSurface->updateCoords();
|
||||
|
||||
myTiaSurface->enableScanlines(ntscEnabled());
|
||||
myTiaSurface->setScanIntensity(myOSystem->settings().getInt("tv_scanlines"));
|
||||
|
@ -584,6 +483,7 @@ void FrameBufferSDL2::enableNTSC(bool enable)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 FrameBufferSDL2::enableScanlines(int relative, int absolute)
|
||||
{
|
||||
#if 0//FIXSDL
|
||||
int intensity = myTiaSurface->myScanlineIntensityI;
|
||||
if(myTiaSurface)
|
||||
{
|
||||
|
@ -596,6 +496,8 @@ uInt32 FrameBufferSDL2::enableScanlines(int relative, int absolute)
|
|||
myRedrawEntireFrame = true;
|
||||
}
|
||||
return intensity;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -627,6 +529,7 @@ FBSurface* FrameBufferSDL2::createSurface(int w, int h, bool isBase) const
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSDL2::scanline(uInt32 row, uInt8* data) const
|
||||
{
|
||||
#if 0
|
||||
// Invert the row, since OpenGL rows start at the bottom
|
||||
// of the framebuffer
|
||||
const GUI::Rect& image = imageRect();
|
||||
|
@ -634,6 +537,7 @@ void FrameBufferSDL2::scanline(uInt32 row, uInt8* data) const
|
|||
|
||||
p_gl.PixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
p_gl.ReadPixels(image.x(), row, image.width(), 1, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -650,20 +554,20 @@ string FrameBufferSDL2::effectsInfo() const
|
|||
break;
|
||||
case kBlarggNormal:
|
||||
buf << myNTSCFilter.getPreset() << ", scanlines="
|
||||
#if 0
|
||||
<< myTiaSurface->myScanlineIntensityI << "/"
|
||||
<< (myTiaSurface->myTexFilter[1] == GL_LINEAR ? "inter" : "nointer");
|
||||
#endif
|
||||
;
|
||||
break;
|
||||
case kBlarggPhosphor:
|
||||
buf << myNTSCFilter.getPreset() << ", phosphor, scanlines="
|
||||
#if 0
|
||||
<< myTiaSurface->myScanlineIntensityI << "/"
|
||||
<< (myTiaSurface->myTexFilter[1] == GL_LINEAR ? "inter" : "nointer");
|
||||
#endif
|
||||
;
|
||||
break;
|
||||
}
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::myLibraryLoaded = false;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSDL2::myVBOAvailable = false;
|
||||
|
|
|
@ -54,15 +54,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
virtual ~FrameBufferSDL2();
|
||||
|
||||
/**
|
||||
Check if OpenGL is available on this system, and then opens it.
|
||||
If any errors occur, we shouldn't attempt to instantiate a
|
||||
FrameBufferSDL2 object.
|
||||
|
||||
@param library The filename of the OpenGL library
|
||||
*/
|
||||
static bool loadLibrary(const string& library);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// The following are derived from public methods in FrameBuffer.hxx
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -82,11 +73,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
*/
|
||||
bool fullScreen() const;
|
||||
|
||||
/**
|
||||
Set the title for the main window.
|
||||
*/
|
||||
void setWindowTitle(const string& title);
|
||||
|
||||
/**
|
||||
Enable/disable phosphor effect.
|
||||
*/
|
||||
|
@ -157,34 +143,16 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
bool queryHardware(uInt32& w, uInt32& h, ResolutionList& res);
|
||||
|
||||
/**
|
||||
This method is called to initialize the video subsystem
|
||||
with the given video mode. Normally, it will also call setVidMode().
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
|
||||
@param title The title for the created window
|
||||
@param mode The video mode to use
|
||||
@param full Whether this is a fullscreen or windowed mode
|
||||
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
bool initSubsystem(VideoMode& mode, bool full);
|
||||
|
||||
/**
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
|
||||
@param mode The video mode to use
|
||||
|
||||
@return False on any errors (in which case 'mode' is invalid), else true
|
||||
*/
|
||||
bool setVidMode(VideoMode& mode);
|
||||
|
||||
/**
|
||||
Sets a hint that the underlying renderer may use; it is also free
|
||||
to ignore it completely.
|
||||
|
||||
@param hint The hint to set
|
||||
@param enabled Whether the hint should be turned on or off
|
||||
*/
|
||||
void setHint(FBHint hint, bool enabled);
|
||||
bool setVideoMode(const string& title, VideoMode& mode, bool full);
|
||||
|
||||
/**
|
||||
This method is called to invalidate the contents of the entire
|
||||
|
@ -240,11 +208,6 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
void enableScanlineInterpolation(bool enable);
|
||||
|
||||
private:
|
||||
enum GLFunctionality {
|
||||
kGL_BASIC, kGL_VBO
|
||||
};
|
||||
bool loadFuncs(GLFunctionality functionality);
|
||||
|
||||
// Enumeration created such that phosphor off/on is in LSB,
|
||||
// and Blargg off/on is in MSB
|
||||
enum FilterType {
|
||||
|
@ -255,23 +218,17 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
};
|
||||
FilterType myFilterType;
|
||||
|
||||
static uInt32 power_of_two(uInt32 input)
|
||||
{
|
||||
uInt32 value = 1;
|
||||
while( value < input )
|
||||
value <<= 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
private:
|
||||
// The SDL video buffer
|
||||
SDL_Surface* myScreen;
|
||||
SDL_Window* myWindow;
|
||||
SDL_Renderer* myRenderer;
|
||||
|
||||
// SDL initialization flags
|
||||
// This is set by the base FrameBuffer class, and read by the derived classes
|
||||
// If a FrameBuffer is successfully created, the derived classes must modify
|
||||
// it to point to the actual flags used by the SDL_Surface
|
||||
uInt32 mySDLFlags;
|
||||
uInt32 myWindowFlags;
|
||||
|
||||
// The lower-most base surface (will always be a TIA surface,
|
||||
// since Dialog surfaces are allocated by the Dialog class directly).
|
||||
|
@ -283,57 +240,8 @@ class FrameBufferSDL2 : public FrameBuffer
|
|||
// The depth of the texture buffer
|
||||
uInt32 myDepth;
|
||||
|
||||
// The size of color components for OpenGL
|
||||
Int32 myRGB[4];
|
||||
|
||||
// Indicates that the texture has been modified, and should be redrawn
|
||||
bool myDirtyFlag;
|
||||
|
||||
// Indicates if the OpenGL library has been properly loaded
|
||||
static bool myLibraryLoaded;
|
||||
|
||||
// Indicates whether Vertex Buffer Objects (VBO) are available
|
||||
static bool myVBOAvailable;
|
||||
|
||||
// Structure containing dynamically-loaded OpenGL function pointers
|
||||
#define OGL_DECLARE(NAME,RET,FUNC,PARAMS) RET (APIENTRY* NAME) PARAMS
|
||||
typedef struct {
|
||||
OGL_DECLARE(Clear,void,glClear,(GLbitfield));
|
||||
OGL_DECLARE(Enable,void,glEnable,(GLenum));
|
||||
OGL_DECLARE(Disable,void,glDisable,(GLenum));
|
||||
OGL_DECLARE(PushAttrib,void,glPushAttrib,(GLbitfield));
|
||||
OGL_DECLARE(GetString,const GLubyte*,glGetString,(GLenum));
|
||||
OGL_DECLARE(Hint,void,glHint,(GLenum, GLenum));
|
||||
OGL_DECLARE(ShadeModel,void,glShadeModel,(GLenum));
|
||||
OGL_DECLARE(MatrixMode,void,glMatrixMode,(GLenum));
|
||||
OGL_DECLARE(Ortho,void,glOrtho,(GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble));
|
||||
OGL_DECLARE(Viewport,void,glViewport,(GLint, GLint, GLsizei, GLsizei));
|
||||
OGL_DECLARE(LoadIdentity,void,glLoadIdentity,(void));
|
||||
OGL_DECLARE(Translatef,void,glTranslatef,(GLfloat,GLfloat,GLfloat));
|
||||
OGL_DECLARE(EnableClientState,void,glEnableClientState,(GLenum));
|
||||
OGL_DECLARE(DisableClientState,void,glDisableClientState,(GLenum));
|
||||
OGL_DECLARE(VertexPointer,void,glVertexPointer,(GLint,GLenum,GLsizei,const GLvoid*));
|
||||
OGL_DECLARE(TexCoordPointer,void,glTexCoordPointer,(GLint,GLenum,GLsizei,const GLvoid*));
|
||||
OGL_DECLARE(DrawArrays,void,glDrawArrays,(GLenum,GLint,GLsizei));
|
||||
OGL_DECLARE(ReadPixels,void,glReadPixels,(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*));
|
||||
OGL_DECLARE(PixelStorei,void,glPixelStorei,(GLenum, GLint));
|
||||
OGL_DECLARE(TexEnvf,void,glTexEnvf,(GLenum, GLenum, GLfloat));
|
||||
OGL_DECLARE(GenTextures,void,glGenTextures,(GLsizei, GLuint*));
|
||||
OGL_DECLARE(DeleteTextures,void,glDeleteTextures,(GLsizei, const GLuint*));
|
||||
OGL_DECLARE(ActiveTexture,void,glActiveTexture,(GLenum));
|
||||
OGL_DECLARE(BindTexture,void,glBindTexture,(GLenum, GLuint));
|
||||
OGL_DECLARE(TexImage2D,void,glTexImage2D,(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*));
|
||||
OGL_DECLARE(TexSubImage2D,void,glTexSubImage2D,(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*));
|
||||
OGL_DECLARE(TexParameteri,void,glTexParameteri,(GLenum, GLenum, GLint));
|
||||
OGL_DECLARE(GetError,GLenum,glGetError,(void));
|
||||
OGL_DECLARE(Color4f,void,glColor4f,(GLfloat,GLfloat,GLfloat,GLfloat));
|
||||
OGL_DECLARE(BlendFunc,void,glBlendFunc,(GLenum,GLenum));
|
||||
OGL_DECLARE(GenBuffers,void,glGenBuffers,(GLsizei,GLuint*));
|
||||
OGL_DECLARE(BindBuffer,void,glBindBuffer,(GLenum,GLuint));
|
||||
OGL_DECLARE(BufferData,void,glBufferData,(GLenum,GLsizei,const void*,GLenum));
|
||||
OGL_DECLARE(DeleteBuffers,void,glDeleteBuffers,(GLsizei, const GLuint*));
|
||||
} GLpointers;
|
||||
GLpointers p_gl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -310,6 +310,6 @@ typedef enum {
|
|||
|
||||
// Just pass SDLMod directly as int (placeholder for now)
|
||||
// The underlying code doesn't need to know how it's implemented
|
||||
typedef int StellaMod;
|
||||
typedef SDL_Keymod StellaMod;
|
||||
|
||||
#endif /* StellaKeys */
|
||||
|
|
|
@ -2041,7 +2041,7 @@ void EventHandler::setEventState(State state)
|
|||
case S_EMULATE:
|
||||
myOverlay = NULL;
|
||||
myOSystem->sound().mute(false);
|
||||
SDL_EnableUNICODE(0);
|
||||
//FIXME SDL_EnableUNICODE(0);
|
||||
if(myOSystem->console().controller(Controller::Left).type() ==
|
||||
Controller::CompuMate)
|
||||
myUseCtrlKeyFlag = false;
|
||||
|
@ -2050,28 +2050,28 @@ void EventHandler::setEventState(State state)
|
|||
case S_PAUSE:
|
||||
myOverlay = NULL;
|
||||
myOSystem->sound().mute(true);
|
||||
SDL_EnableUNICODE(0);
|
||||
//FIXME SDL_EnableUNICODE(0);
|
||||
break;
|
||||
|
||||
case S_MENU:
|
||||
myOverlay = &myOSystem->menu();
|
||||
SDL_EnableUNICODE(1);
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
|
||||
case S_CMDMENU:
|
||||
myOverlay = &myOSystem->commandMenu();
|
||||
SDL_EnableUNICODE(1);
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
|
||||
case S_LAUNCHER:
|
||||
myOverlay = &myOSystem->launcher();
|
||||
SDL_EnableUNICODE(1);
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
case S_DEBUGGER:
|
||||
myOverlay = &myOSystem->debugger();
|
||||
SDL_EnableUNICODE(1);
|
||||
//FIXME SDL_EnableUNICODE(1);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -186,11 +186,8 @@ FBInitStatus FrameBuffer::createDisplay(const string& title,
|
|||
VideoMode mode = getSavedVidMode();
|
||||
if(width <= mode.screen_w && height <= mode.screen_h)
|
||||
{
|
||||
setWindowTitle(title);
|
||||
if(initSubsystem(mode, useFullscreen))
|
||||
if(setVideoMode(title, mode, useFullscreen))
|
||||
{
|
||||
centerAppWindow(mode);
|
||||
|
||||
myImageRect.setWidth(mode.image_w);
|
||||
myImageRect.setHeight(mode.image_h);
|
||||
myImageRect.moveTo(mode.image_x, mode.image_y);
|
||||
|
@ -498,7 +495,7 @@ void FrameBuffer::refresh()
|
|||
// This method is in essence a FULL refresh, putting all rendering
|
||||
// buffers in a known, fully redrawn state
|
||||
|
||||
bool doubleBuffered = (type() == kDoubleBuffer);
|
||||
bool doubleBuffered = false;//FIXSDL(type() == kDoubleBuffer);
|
||||
switch(myOSystem->eventHandler().state())
|
||||
{
|
||||
case EventHandler::S_EMULATE:
|
||||
|
@ -756,6 +753,7 @@ void FrameBuffer::toggleFullscreen()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::setFullscreen(bool enable)
|
||||
{
|
||||
#if 0 //FIXSDL
|
||||
#ifdef WINDOWED_SUPPORT
|
||||
// '-1' means fullscreen mode is completely disabled
|
||||
bool full = enable && myOSystem->settings().getString("fullscreen") != "-1";
|
||||
|
@ -769,11 +767,13 @@ void FrameBuffer::setFullscreen(bool enable)
|
|||
// to changeVidMode()
|
||||
changeVidMode(0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBuffer::changeVidMode(int direction)
|
||||
{
|
||||
#if 0 //FIXSDL
|
||||
EventHandler::State state = myOSystem->eventHandler().state();
|
||||
bool inUIMode = (state == EventHandler::S_DEBUGGER ||
|
||||
state == EventHandler::S_LAUNCHER);
|
||||
|
@ -793,8 +793,6 @@ bool FrameBuffer::changeVidMode(int direction)
|
|||
VideoMode vidmode = myCurrentModeList->current(myOSystem->settings(), fullScreen());
|
||||
if(setVidMode(vidmode))
|
||||
{
|
||||
centerAppWindow(vidmode);
|
||||
|
||||
myImageRect.setWidth(vidmode.image_w);
|
||||
myImageRect.setHeight(vidmode.image_h);
|
||||
myImageRect.moveTo(vidmode.image_x, vidmode.image_y);
|
||||
|
@ -820,7 +818,7 @@ bool FrameBuffer::changeVidMode(int direction)
|
|||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
#endif
|
||||
return true;
|
||||
/*
|
||||
cerr << "New mode:" << endl
|
||||
|
@ -1025,22 +1023,6 @@ FrameBuffer::VideoMode FrameBuffer::getSavedVidMode()
|
|||
return myCurrentModeList->current(myOSystem->settings(), fullScreen());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::centerAppWindow(const VideoMode& mode)
|
||||
{
|
||||
// FIXSDL
|
||||
#if 0
|
||||
// Attempt to center the application window in non-fullscreen mode
|
||||
if(!fullScreen() && myOSystem->settings().getBool("center"))
|
||||
{
|
||||
int x = mode.screen_w >= myOSystem->desktopWidth() ? 0 :
|
||||
((myOSystem->desktopWidth() - mode.screen_w) >> 1);
|
||||
int y = mode.screen_h >= myOSystem->desktopHeight() ? 0 :
|
||||
((myOSystem->desktopHeight() - mode.screen_h) >> 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBuffer::VideoModeList::VideoModeList()
|
||||
: myIdx(-1)
|
||||
|
|
|
@ -348,11 +348,6 @@ class FrameBuffer
|
|||
*/
|
||||
virtual bool fullScreen() const = 0;
|
||||
|
||||
/**
|
||||
Set the title for the main window.
|
||||
*/
|
||||
virtual void setWindowTitle(const string& title) = 0;
|
||||
|
||||
/**
|
||||
Enable/disable/query NTSC filtering effects.
|
||||
*/
|
||||
|
@ -454,35 +449,16 @@ class FrameBuffer
|
|||
virtual bool queryHardware(uInt32& w, uInt32& h, ResolutionList& res) = 0;
|
||||
|
||||
/**
|
||||
This method is called to initialize the video subsystem
|
||||
with the given video mode. Normally, it will also call setVidMode().
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
|
||||
@param title The title for
|
||||
@param title The title for the created window
|
||||
@param mode The video mode to use
|
||||
@param full Whether this is a fullscreen or windowed mode
|
||||
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
virtual bool initSubsystem(VideoMode& mode, bool full) = 0;
|
||||
|
||||
/**
|
||||
This method is called to change to the given video mode. If the mode
|
||||
is successfully changed, 'mode' holds the actual dimensions used.
|
||||
|
||||
@param mode The video mode to use
|
||||
|
||||
@return False on any errors (in which case 'mode' is invalid), else true
|
||||
*/
|
||||
virtual bool setVidMode(VideoMode& mode) = 0;
|
||||
|
||||
/**
|
||||
Sets a hint that the underlying renderer may use; it is also free
|
||||
to ignore it completely.
|
||||
|
||||
@param hint The hint to set
|
||||
@param enabled Whether the hint should be turned on or off
|
||||
*/
|
||||
virtual void setHint(FBHint hint, bool enabled) = 0;
|
||||
virtual bool setVideoMode(const string& title, VideoMode& mode, bool full) = 0;
|
||||
|
||||
/**
|
||||
This method is called to invalidate the contents of the entire
|
||||
|
@ -600,11 +576,6 @@ class FrameBuffer
|
|||
*/
|
||||
VideoMode getSavedVidMode();
|
||||
|
||||
/**
|
||||
Attempt to center the application window in windowed mode.
|
||||
*/
|
||||
void centerAppWindow(const VideoMode& mode);
|
||||
|
||||
/**
|
||||
Set up the user interface palette for a screen of any depth > 8.
|
||||
*/
|
||||
|
|
|
@ -107,10 +107,11 @@ OSystem::OSystem()
|
|||
|
||||
// Get build info
|
||||
ostringstream info;
|
||||
const SDL_version* ver = SDL_Linked_Version();
|
||||
SDL_version ver;
|
||||
SDL_GetVersion(&ver);
|
||||
|
||||
info << "Build " << STELLA_BUILD << ", using SDL " << (int)ver->major
|
||||
<< "." << (int)ver->minor << "."<< (int)ver->patch
|
||||
info << "Build " << STELLA_BUILD << ", using SDL " << (int)ver.major
|
||||
<< "." << (int)ver.minor << "."<< (int)ver.patch
|
||||
<< " [" << BSPF_ARCH << "]";
|
||||
myBuildInfo = info.str();
|
||||
|
||||
|
|
|
@ -165,8 +165,8 @@ class DialogContainer
|
|||
// For continuous 'key down' events
|
||||
struct {
|
||||
StellaKey keycode;
|
||||
StellaMod flags;
|
||||
char ascii;
|
||||
int flags;
|
||||
} myCurrentKeyDown;
|
||||
uInt64 myKeyRepeatTime;
|
||||
|
||||
|
|
Loading…
Reference in New Issue