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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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> #include <SDL.h>
@ -22,6 +22,8 @@
#include "MediaSrc.hxx" #include "MediaSrc.hxx"
#include "OSystem.hxx" #include "OSystem.hxx"
#include "Font.hxx" #include "Font.hxx"
#include "Surface.hxx"
#include "Settings.hxx"
#include "FrameBufferGP2X.hxx" #include "FrameBufferGP2X.hxx"
@ -36,6 +38,7 @@ FrameBufferGP2X::FrameBufferGP2X(OSystem* osystem)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGP2X::~FrameBufferGP2X() 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 // TODO - add SDL info to this string
return ""; return "";
@ -55,6 +58,8 @@ string FrameBufferGP2X::about()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGP2X::setVidMode(VideoMode mode) bool FrameBufferGP2X::setVidMode(VideoMode mode)
{ {
const SDL_VideoInfo* info = NULL;
// Make sure to clear the screen, since we're using different resolutions, // Make sure to clear the screen, since we're using different resolutions,
// and there tends to be lingering artifacts in hardware mode // and there tends to be lingering artifacts in hardware mode
if(myScreen) if(myScreen)
@ -63,8 +68,14 @@ bool FrameBufferGP2X::setVidMode(VideoMode mode)
SDL_UpdateRect(myScreen, 0, 0, 0, 0); SDL_UpdateRect(myScreen, 0, 0, 0, 0);
} }
// We start out with the TIA buffer and SDL screen being the same size myScreenDim.x = myScreenDim.y = 0;
myImageDim = myScreenDim = myBaseDim; 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 // 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 // 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; 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 // The GP2X always uses a 16-bit hardware buffer
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 16, mySDLFlags); myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 16, mySDLFlags);
if(myScreen == NULL) if(myScreen == NULL)
@ -87,6 +133,10 @@ bool FrameBufferGP2X::setVidMode(VideoMode mode)
myPitch = myScreen->pitch/2; myPitch = myScreen->pitch/2;
myBasePtr = (uInt16*) myScreen->pixels + myScreenDim.y * myPitch; myBasePtr = (uInt16*) myScreen->pixels + myScreenDim.y * myPitch;
myDirtyFlag = true; myDirtyFlag = true;
myFormat = myScreen->format;
// Make sure drawMediaSource() knows which renderer to use
stateChanged(myOSystem->eventHandler().state());
return true; 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 // Make sure no pixels are being modified
SDL_LockSurface(myScreen); 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 // Coordinates don't change
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 #ifndef FRAMEBUFFER_GP2X_HXX
@ -32,7 +32,7 @@ class GUI::Font;
This class implements an SDL hardware framebuffer for the GP2X device. This class implements an SDL hardware framebuffer for the GP2X device.
@author Stephen Anthony @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 class FrameBufferGP2X : public FrameBuffer
{ {
@ -54,35 +54,24 @@ class FrameBufferGP2X : public FrameBuffer
This method is called to initialize software video mode. This method is called to initialize software video mode.
Return false if any operation fails, otherwise return true. 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. 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. 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. This method is called to change to the given videomode type.
*/
virtual void setAspectRatio();
/** @param mode The video mode to use for rendering the mediasource
This method is called to change to the given scaler type.
@param scaler The scaler to use for rendering the mediasource
*/ */
virtual void setScaler(Scaler scaler); bool setVidMode(VideoMode mode);
/**
This method is called whenever the screen needs to be recreated.
It updates the global screen variable.
*/
virtual bool createScreen();
/** /**
Switches between the filtering options in software 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 row The row we are looking for
@param data The actual pixel data (in bytes) @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. 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 g The green component of the color.
@param b The blue 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); } { 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. 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, virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, int color,
Int32 h = 8); 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 This method translates the given coordinates to their
unzoomed/unscaled equivalents. unzoomed/unscaled equivalents.
@ -187,7 +205,7 @@ class FrameBufferGP2X : public FrameBuffer
@param x X coordinate to translate @param x X coordinate to translate
@param y Y 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 This method adds a dirty rectangle
@ -220,6 +238,12 @@ class FrameBufferGP2X : public FrameBuffer
// Pitch (in bytes) of the current screen // Pitch (in bytes) of the current screen
int myPitch; int myPitch;
// surface pixel format
SDL_PixelFormat* myFormat;
// the height of the display for TV output
int myTvHeight;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 // 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 // GP2X needs all config files in exec directory
@ -57,9 +57,6 @@ OSystemGP2X::OSystemGP2X(const string& path) : OSystem()
free(currdir); free(currdir);
setBaseDir(basedir); setBaseDir(basedir);
setStateDir(basedir + "/state");
setPropertiesDir(basedir);
setConfigFile(basedir + "/stellarc"); setConfigFile(basedir + "/stellarc");
setCacheFile(basedir + "/stella.cache"); setCacheFile(basedir + "/stella.cache");
@ -67,9 +64,6 @@ OSystemGP2X::OSystemGP2X(const string& path) : OSystem()
// Set event arrays to a known state // Set event arrays to a known state
myPreviousEvents = new uInt8[8]; memset(myPreviousEvents, 0, 8); myPreviousEvents = new uInt8[8]; memset(myPreviousEvents, 0, 8);
myCurrentEvents = new uInt8[8]; memset(myCurrentEvents, 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::ConsoleReset, kEmulationMode, 0, 10); // L
myEventHandler->setDefaultJoyMapping(Event::ConsoleSelect, kEmulationMode, 0, 11); // R myEventHandler->setDefaultJoyMapping(Event::ConsoleSelect, kEmulationMode, 0, 11); // R
myEventHandler->setDefaultJoyMapping(Event::CmdMenuMode, kEmulationMode, 0, 12); // A 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::MenuMode, kEmulationMode, 0, 14); // Y
// myEventHandler->setDefaultJoyMapping(Event::Pause, kEmulationMode, 0, 15); // X // myEventHandler->setDefaultJoyMapping(Event::Pause, kEmulationMode, 0, 15); // X
myEventHandler->setDefaultJoyMapping(Event::VolumeIncrease, kEmulationMode, 0, 16); // Vol+ 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 // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 // 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 Create a new GP2X-specific operating system object
*/ */
OSystemGP2X(const string& path); OSystemGP2X();
/** /**
Destructor Destructor

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // 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 // Modified on 2006/02/05 by Alex Zaballa for use on GP2X
//============================================================================ //============================================================================
@ -44,6 +44,8 @@ SettingsGP2X::SettingsGP2X(OSystem* osystem)
setInternal("p3speed", "15"); setInternal("p3speed", "15");
setInternal("launchersize", "1"); setInternal("launchersize", "1");
setInternal("uipalette", "2"); setInternal("uipalette", "2");
setInternal("tv_scale_width", "1.125");
setInternal("tv_scale_height", "1.2");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -