Updated GP2X to latest code changes, and added overscan compensation

when displaying output on a TV.  Thanks to D. MacCormack for this code.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1398 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-02-20 00:17:49 +00:00
parent 266f02e9d0
commit e5d3ddb467
6 changed files with 173 additions and 49 deletions

25
stella/configure vendored
View File

@ -33,6 +33,7 @@ _build_atarivox=no
_ranlib=ranlib
_install=install
_ar="ar cru"
_strip=strip
_mkdir="mkdir -p"
_echo=printf
_cat=cat
@ -383,6 +384,7 @@ psp)
gp2x)
_host_os=gp2x
_host_cpu=arm
_alt_tools=arm-open2x-linux
;;
*)
guessed_host=`$_srcdir/config.guess`
@ -436,20 +438,31 @@ else
compilers="$CXX g++ c++"
fi
for _tool in $_alt_tools ; do
if test -n "$_prefix"; then
compilers="$_prefix/bin/$_tool-g++ $compilers"
else
compilers="$_tool-g++ $compilers"
fi
done
CXX=
if [ "$_host" = "psp" ] ; then
compilers="$CXX psp-g++ psp-c++"
CXX="psp-c++"
fi
if [ "$_host" = "gp2x" ] ; then
compilers="$CXX arm-linux-g++ arm-linux-c++"
CXX="arm-linux-c++"
fi
for compiler in $compilers; do
if test_compiler $compiler; then
CXX=$compiler
echo $CXX
_toolprefix=`echo arm-open2x-linux-g++ | sed 's/.++//'`
if test -n "$_toolprefix"; then
_strip="${_toolprefix}strip"
fi
break
fi
done
@ -854,7 +867,7 @@ case $_host_os in
_ar="arm-linux-ar cru"
# GP2X ARM Linux Specific strip
GP2X_STRIP="arm-linux-strip"
GP2X_STRIP="$_strip"
;;
*)
echo "WARNING: host system not currenty supported"
@ -960,7 +973,7 @@ fi
if test $_host_os = "gp2x" ; then
cat >> config.mak << EOF
GP2X-STRIP := $GP2X_STRIP
GP2X-STRIP := \$(PREFIX)/bin/$GP2X_STRIP
EOF
fi

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGP2X.cxx,v 1.24 2008-02-06 13:45:23 stephena Exp $
// $Id: FrameBufferGP2X.cxx,v 1.25 2008-02-20 00:17:49 stephena Exp $
//============================================================================
#include <SDL.h>
@ -22,6 +22,8 @@
#include "MediaSrc.hxx"
#include "OSystem.hxx"
#include "Font.hxx"
#include "Surface.hxx"
#include "Settings.hxx"
#include "FrameBufferGP2X.hxx"
@ -36,6 +38,7 @@ FrameBufferGP2X::FrameBufferGP2X(OSystem* osystem)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGP2X::~FrameBufferGP2X()
{
myTvHeight = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -46,7 +49,7 @@ bool FrameBufferGP2X::initSubsystem(VideoMode mode)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrameBufferGP2X::about()
string FrameBufferGP2X::about() const
{
// TODO - add SDL info to this string
return "";
@ -55,6 +58,8 @@ string FrameBufferGP2X::about()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGP2X::setVidMode(VideoMode mode)
{
const SDL_VideoInfo* info = NULL;
// Make sure to clear the screen, since we're using different resolutions,
// and there tends to be lingering artifacts in hardware mode
if(myScreen)
@ -63,8 +68,14 @@ bool FrameBufferGP2X::setVidMode(VideoMode mode)
SDL_UpdateRect(myScreen, 0, 0, 0, 0);
}
// We start out with the TIA buffer and SDL screen being the same size
myImageDim = myScreenDim = myBaseDim;
myScreenDim.x = myScreenDim.y = 0;
myScreenDim.w = mode.screen_w;
myScreenDim.h = mode.screen_h;
myImageDim.x = mode.image_x;
myImageDim.y = mode.image_y;
myImageDim.w = mode.image_w;
myImageDim.h = mode.image_h;
// If we got a screenmode that won't be scaled, center it vertically
// Otherwise, SDL hardware scaling kicks in, and we won't mess with it
@ -77,6 +88,41 @@ bool FrameBufferGP2X::setVidMode(VideoMode mode)
myScreenDim.h = myScreenDim.y + myBaseDim.h;
}
// check to see if we're displaying on a TV
if (!myTvHeight) {
info = SDL_GetVideoInfo();
if (info && info->current_w == 720
&& (info->current_h == 480 || info->current_h == 576)) {
myTvHeight = info->current_h;
} else {
myTvHeight = -1;
}
}
// if I am displaying on a TV then I want to handle overscan
// I do this as per the following:
// http://www.gp32x.com/board/index.php?showtopic=23819&st=375&p=464689&#entry464689
// Basically, I set the screen bigger than the base image. Thus, the image
// should be (mostly) on screen. The SDL HW scaler will make sure the
// screen fills the TV.
if (myTvHeight > 0) {
myScreenDim.w = (int)(((float)myScreenDim.w)
* myOSystem->settings().getFloat("tv_scale_width"));
myScreenDim.h = (int)(((float)myScreenDim.h)
* myOSystem->settings().getFloat("tv_scale_height"));
if ((myScreenDim.w % 2))
myScreenDim.w++;
if ((myScreenDim.h % 2))
myScreenDim.h++;
myScreenDim.x = (myScreenDim.w - mode.screen_w)/2;
myScreenDim.y = (myScreenDim.h - mode.screen_h)/2;
}
// The GP2X always uses a 16-bit hardware buffer
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 16, mySDLFlags);
if(myScreen == NULL)
@ -87,6 +133,10 @@ bool FrameBufferGP2X::setVidMode(VideoMode mode)
myPitch = myScreen->pitch/2;
myBasePtr = (uInt16*) myScreen->pixels + myScreenDim.y * myPitch;
myDirtyFlag = true;
myFormat = myScreen->format;
// Make sure drawMediaSource() knows which renderer to use
stateChanged(myOSystem->eventHandler().state());
return true;
}
@ -170,7 +220,7 @@ void FrameBufferGP2X::postFrameUpdate()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGP2X::scanline(uInt32 row, uInt8* data)
void FrameBufferGP2X::scanline(uInt32 row, uInt8* data) const
{
// Make sure no pixels are being modified
SDL_LockSurface(myScreen);
@ -293,7 +343,48 @@ void FrameBufferGP2X::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGP2X::translateCoords(Int32* x, Int32* y)
void FrameBufferGP2X::drawSurface(const GUI::Surface* surface, Int32 x, Int32 y)
{
SDL_Rect clip;
clip.x = x;
clip.y = y;
SDL_BlitSurface(surface->myData, 0, myScreen, &clip);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGP2X::bytesToSurface(GUI::Surface* surface, int row,
uInt8* data) const
{
SDL_Surface* s = surface->myData;
int rowbytes = s->w * 3;
uInt16* pixels = (uInt16*) s->pixels;
int surfbytes = s->pitch/2;
pixels += (row * surfbytes);
// Calculate a scanline of zoomed surface data
for(int c = 0; c < rowbytes; c += 3)
{
uInt32 pixel = SDL_MapRGB(s->format, data[c], data[c+1], data[c+2]);
*pixels++ = pixel;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GUI::Surface* FrameBufferGP2X::createSurface(int width, int height) const
{
SDL_Surface* data =
SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
16, myFormat->Rmask, myFormat->Gmask,
myFormat->Bmask, myFormat->Amask);
return data ? new GUI::Surface(width, height, data) : NULL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGP2X::translateCoords(Int32& x, Int32& y) const
{
// Coordinates don't change
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrameBufferGP2X.hxx,v 1.11 2008-02-06 13:45:23 stephena Exp $
// $Id: FrameBufferGP2X.hxx,v 1.12 2008-02-20 00:17:49 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_GP2X_HXX
@ -32,7 +32,7 @@ class GUI::Font;
This class implements an SDL hardware framebuffer for the GP2X device.
@author Stephen Anthony
@version $Id: FrameBufferGP2X.hxx,v 1.11 2008-02-06 13:45:23 stephena Exp $
@version $Id: FrameBufferGP2X.hxx,v 1.12 2008-02-20 00:17:49 stephena Exp $
*/
class FrameBufferGP2X : public FrameBuffer
{
@ -54,35 +54,24 @@ class FrameBufferGP2X : public FrameBuffer
This method is called to initialize software video mode.
Return false if any operation fails, otherwise return true.
*/
virtual bool initSubsystem();
virtual bool initSubsystem(VideoMode mode);
/**
This method is called to query the type of the FrameBuffer.
*/
virtual BufferType type() { return kSoftBuffer; }
virtual BufferType type() const { return kSoftBuffer; }
/**
This method is called to provide information about the FrameBuffer.
*/
virtual string about();
virtual string about() const;
/**
This method is called to set the aspect ratio of the screen.
*/
virtual void setAspectRatio();
This method is called to change to the given videomode type.
/**
This method is called to change to the given scaler type.
@param scaler The scaler to use for rendering the mediasource
@param mode The video mode to use for rendering the mediasource
*/
virtual void setScaler(Scaler scaler);
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
*/
virtual bool createScreen();
bool setVidMode(VideoMode mode);
/**
Switches between the filtering options in software mode.
@ -112,7 +101,7 @@ class FrameBufferGP2X : public FrameBuffer
@param row The row we are looking for
@param data The actual pixel data (in bytes)
*/
virtual void scanline(uInt32 row, uInt8* data);
virtual void scanline(uInt32 row, uInt8* data) const;
/**
This method is called to map a given r,g,b triple to the screen palette.
@ -121,9 +110,18 @@ class FrameBufferGP2X : public FrameBuffer
@param g The green component of the color.
@param b The blue component of the color.
*/
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b) const
{ return SDL_MapRGB(myScreen->format, r, g, b); }
/**
This method is called to create a surface compatible with the one
currently in use, but having the given dimensions.
@param width The requested width of the new surface.
@param height The requested height of the new surface.
*/
GUI::Surface* createSurface(int width, int height) const;
/**
This method is called to draw a horizontal line.
@ -180,6 +178,26 @@ class FrameBufferGP2X : public FrameBuffer
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color,
Int32 h = 8);
/**
This method should be called to draw an SDL surface.
@param surface The data to draw
@param x The x coordinate
@param y The y coordinate
*/
void drawSurface(const GUI::Surface* surface, Int32 x, Int32 y);
/**
This method should be called to convert and copy a given row of RGB
data into an SDL surface.
@param surface The data to draw
@param row The row of the surface the data should be placed in
@param data The data in uInt8 R/G/B format
*/
void bytesToSurface(GUI::Surface* surface, int row, uInt8* data) const;
/**
This method translates the given coordinates to their
unzoomed/unscaled equivalents.
@ -187,7 +205,7 @@ class FrameBufferGP2X : public FrameBuffer
@param x X coordinate to translate
@param y Y coordinate to translate
*/
virtual void translateCoords(Int32* x, Int32* y);
virtual void translateCoords(Int32& x, Int32& y) const;
/**
This method adds a dirty rectangle
@ -220,6 +238,12 @@ class FrameBufferGP2X : public FrameBuffer
// Pitch (in bytes) of the current screen
int myPitch;
// surface pixel format
SDL_PixelFormat* myFormat;
// the height of the display for TV output
int myTvHeight;
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemGP2X.cxx,v 1.28 2008-02-06 13:45:23 stephena Exp $
// $Id: OSystemGP2X.cxx,v 1.29 2008-02-20 00:17:49 stephena Exp $
// Modified on 2006/01/06 by Alex Zaballa for use on GP2X
//============================================================================
@ -48,7 +48,7 @@
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystemGP2X::OSystemGP2X(const string& path) : OSystem()
OSystemGP2X::OSystemGP2X() : OSystem()
{
// GP2X needs all config files in exec directory
@ -57,9 +57,6 @@ OSystemGP2X::OSystemGP2X(const string& path) : OSystem()
free(currdir);
setBaseDir(basedir);
setStateDir(basedir + "/state");
setPropertiesDir(basedir);
setConfigFile(basedir + "/stellarc");
setCacheFile(basedir + "/stella.cache");
@ -67,9 +64,6 @@ OSystemGP2X::OSystemGP2X(const string& path) : OSystem()
// Set event arrays to a known state
myPreviousEvents = new uInt8[8]; memset(myPreviousEvents, 0, 8);
myCurrentEvents = new uInt8[8]; memset(myCurrentEvents, 0, 8);
// GP2X doesn't have windowed mode; it's always in fullscreen
clearCapability(CAP_WINDOWED);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -107,7 +101,7 @@ void OSystemGP2X::setDefaultJoymap()
myEventHandler->setDefaultJoyMapping(Event::ConsoleReset, kEmulationMode, 0, 10); // L
myEventHandler->setDefaultJoyMapping(Event::ConsoleSelect, kEmulationMode, 0, 11); // R
myEventHandler->setDefaultJoyMapping(Event::CmdMenuMode, kEmulationMode, 0, 12); // A
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroFire, kEmulationMode, 0, 13); // B
myEventHandler->setDefaultJoyMapping(Event::JoystickZeroFire1, kEmulationMode, 0, 13); // B
myEventHandler->setDefaultJoyMapping(Event::MenuMode, kEmulationMode, 0, 14); // Y
// myEventHandler->setDefaultJoyMapping(Event::Pause, kEmulationMode, 0, 15); // X
myEventHandler->setDefaultJoyMapping(Event::VolumeIncrease, kEmulationMode, 0, 16); // Vol+

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: OSystemGP2X.hxx,v 1.11 2008-02-06 13:45:23 stephena Exp $
// $Id: OSystemGP2X.hxx,v 1.12 2008-02-20 00:17:49 stephena Exp $
// Modified by Alex Zaballa on 2006/01/04 for use on GP2X
//============================================================================
@ -32,7 +32,7 @@ class OSystemGP2X : public OSystem
/**
Create a new GP2X-specific operating system object
*/
OSystemGP2X(const string& path);
OSystemGP2X();
/**
Destructor

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: SettingsGP2X.cxx,v 1.27 2008-02-06 13:45:23 stephena Exp $
// $Id: SettingsGP2X.cxx,v 1.28 2008-02-20 00:17:49 stephena Exp $
// Modified on 2006/02/05 by Alex Zaballa for use on GP2X
//============================================================================
@ -44,6 +44,8 @@ SettingsGP2X::SettingsGP2X(OSystem* osystem)
setInternal("p3speed", "15");
setInternal("launchersize", "1");
setInternal("uipalette", "2");
setInternal("tv_scale_width", "1.125");
setInternal("tv_scale_height", "1.2");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -