mirror of https://github.com/stella-emu/stella.git
Some configure work:
- removed TEXTURES_ARE_DIRTY logic, and just recreate the GL textures when a screenmode changes - enable checking for machine type and if nasm is available - logic to enable scaler mode only when in OpenGL mode (still not complete and defaults to off) First pass at adding scaler code to OpenGL. Still much work TODO, but the C version is working correctly (asm is causing crashes, haven't figured out why). GL quad coordinates aren't properly set yet, so the image always appears in the upper left corner, and is not scaled to the window size. CPU usage is also quite high, but I'm on a 1GHz laptop with i950 GL, so that may explain it. Fixed long-standing bug in software rendering, where switching to a lower-res screen while a message is being displayed would cause a segfault. Large refactoring of mainSDL. Specifically, OSystem now owns all the subsystems except for Settings, taking responsibility for creating and destroying them. Properties fixes for 'Tomarc the Barbarian' and 'Gyruss'. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1136 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
e3b36b202c
commit
c7a073c6a2
|
@ -283,8 +283,8 @@ Optional Libraries:
|
|||
|
||||
--with-sdl-prefix=DIR Prefix where the sdl-config script is installed (optional)
|
||||
|
||||
# --with-nasm-prefix=DIR Prefix where nasm executable is installed (optional)
|
||||
# --disable-nasm disable assembly language optimizations [autodetect]
|
||||
--with-nasm-prefix=DIR Prefix where nasm executable is installed (optional)
|
||||
--disable-nasm disable assembly language optimizations [autodetect]
|
||||
|
||||
--x-libraries Path to X11 libraries [${X_LIBS}]
|
||||
|
||||
|
@ -612,6 +612,26 @@ else
|
|||
esac
|
||||
fi
|
||||
|
||||
#
|
||||
# Check whether we can use x86 asm routines
|
||||
#
|
||||
echo_n "Running on x86... "
|
||||
case $_host_cpu in
|
||||
i386|i486|i586|i686)
|
||||
_have_x86=yes
|
||||
;;
|
||||
*)
|
||||
_have_x86=no
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$_have_x86" = yes ; then
|
||||
_def_x86='#define HAVE_X86'
|
||||
else
|
||||
_def_x86='#undef HAVE_X86'
|
||||
fi
|
||||
echo "$_have_x86"
|
||||
|
||||
#
|
||||
# Check for ZLib
|
||||
#
|
||||
|
@ -661,17 +681,18 @@ echo "$_opengl"
|
|||
#
|
||||
# Check for nasm
|
||||
#
|
||||
#if test "$_have_x86" = yes ; then
|
||||
# CheckNASM
|
||||
#fi
|
||||
#
|
||||
#if test "$_nasm" = yes ; then
|
||||
# _def_nasm='#define USE_NASM'
|
||||
# _make_def_HAVE_NASM='HAVE_NASM = 1'
|
||||
#else
|
||||
# _def_nasm='#undef USE_NASM'
|
||||
# _make_def_HAVE_NASM='# HAVE_NASM = 1'
|
||||
#fi
|
||||
if test "$_have_x86" = yes ; then
|
||||
CheckNASM
|
||||
fi
|
||||
|
||||
if test "$_nasm" = yes ; then
|
||||
DEFINES="$DEFINES -DUSE_NASM"
|
||||
_def_nasm='#define USE_NASM'
|
||||
_make_def_HAVE_NASM='HAVE_NASM = 1'
|
||||
else
|
||||
_def_nasm='#undef USE_NASM'
|
||||
_make_def_HAVE_NASM='# HAVE_NASM = 1'
|
||||
fi
|
||||
|
||||
#
|
||||
# figure out installation directories
|
||||
|
@ -784,6 +805,7 @@ DBGGUI="$SRC/debugger/gui"
|
|||
YACC="$SRC/yacc"
|
||||
CHEAT="$SRC/cheat"
|
||||
ATARIVOX="$SRC/emucore/rsynth"
|
||||
SCALER="$SRC/common/scaler"
|
||||
|
||||
INCLUDES="-I$CORE -I$CORE/m6502/src -I$CORE/m6502/src/bspf/src -I$COMMON -I$GUI"
|
||||
|
||||
|
@ -802,22 +824,12 @@ case $_host_os in
|
|||
DEFINES="$DEFINES -DBSPF_UNIX -DHAVE_GETTIMEOFDAY -DHAVE_INTTYPES"
|
||||
MODULES="$MODULES $SRC/unix"
|
||||
INCLUDES="$INCLUDES -I$SRC/unix"
|
||||
|
||||
# Add OpenGL stuff
|
||||
if test "$_build_gl" = yes ; then
|
||||
DEFINES="$DEFINES -DDISPLAY_OPENGL"
|
||||
fi
|
||||
;;
|
||||
win32)
|
||||
DEFINES="$DEFINES -DBSPF_WIN32 -DHAVE_GETTIMEOFDAY -DHAVE_INTTYPES"
|
||||
MODULES="$MODULES $SRC/win32"
|
||||
INCLUDES="$INCLUDES -I$SRC/win32"
|
||||
LIBS="$LIBS -lmingw32 -lwinmm"
|
||||
|
||||
# Add OpenGL stuff
|
||||
if test "$_build_gl" = yes ; then
|
||||
DEFINES="$DEFINES -DDISPLAY_OPENGL -DTEXTURES_ARE_LOST"
|
||||
fi
|
||||
;;
|
||||
psp)
|
||||
# -O3 is need for speed
|
||||
|
@ -872,6 +884,10 @@ case $_host_os in
|
|||
;;
|
||||
esac
|
||||
|
||||
if test "$_build_gl" = yes ; then
|
||||
DEFINES="$DEFINES -DDISPLAY_OPENGL"
|
||||
fi
|
||||
|
||||
if test "$_build_sound" = yes ; then
|
||||
DEFINES="$DEFINES -DSOUND_SUPPORT"
|
||||
fi
|
||||
|
@ -903,10 +919,20 @@ if test "$_build_atarivox" = yes ; then
|
|||
INCLUDES="$INCLUDES -I$ATARIVOX"
|
||||
fi
|
||||
|
||||
# For now, always include scalers, but only when in OpenGL mode
|
||||
_build_scalers="no"
|
||||
if test "$_build_scalers" = yes ; then
|
||||
if test "$_build_gl" = yes ; then
|
||||
MODULES="$MODULES $SCALER"
|
||||
INCLUDES="$INCLUDES -I$SCALER"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$_build_profile" = no ; then
|
||||
_build_profile=
|
||||
fi
|
||||
|
||||
|
||||
# 20051003 bkw: fix static Linux build.
|
||||
# No guarantee this will work for anyone other than me, and no
|
||||
# guarantee it's needed by anyone but me (and Steve)...
|
||||
|
@ -956,7 +982,7 @@ DATADIR := $_datadir
|
|||
PROFILE := $_build_profile
|
||||
|
||||
$_make_def_HAVE_GCC3
|
||||
#$_make_def_HAVE_NASM
|
||||
$_make_def_HAVE_NASM
|
||||
|
||||
INCLUDES += $INCLUDES
|
||||
OBJS += $OBJS
|
||||
|
|
|
@ -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: FrameBufferGL.cxx,v 1.64 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: FrameBufferGL.cxx,v 1.65 2006-10-22 18:58:45 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifdef DISPLAY_OPENGL
|
||||
|
@ -31,6 +31,10 @@
|
|||
#include "Font.hxx"
|
||||
#include "GuiUtils.hxx"
|
||||
|
||||
#ifdef SCALER_SUPPORT
|
||||
#include "scaler.hxx"
|
||||
#endif
|
||||
|
||||
// Maybe this code could be cleaner ...
|
||||
static void (APIENTRY* p_glClear)( GLbitfield );
|
||||
static void (APIENTRY* p_glEnable)( GLenum );
|
||||
|
@ -82,6 +86,10 @@ FrameBufferGL::FrameBufferGL(OSystem* osystem)
|
|||
myFSScaleFactor(1.0),
|
||||
myDirtyFlag(true)
|
||||
{
|
||||
#ifdef SCALER_SUPPORT
|
||||
myScalerProc = 0;
|
||||
InitScalers();
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -93,6 +101,10 @@ FrameBufferGL::~FrameBufferGL()
|
|||
SDL_FreeSurface(myScaledTexture);
|
||||
|
||||
p_glDeleteTextures(1, &myTextureID);
|
||||
|
||||
#ifdef SCALER_SUPPORT
|
||||
FreeScalers();
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -258,16 +270,18 @@ void FrameBufferGL::setScaler(Scaler scaler)
|
|||
myQuadRect.w = myBaseDim.w;
|
||||
myQuadRect.h = myBaseDim.h;
|
||||
break;
|
||||
|
||||
#ifdef SCALER_SUPPORT
|
||||
case kSCALE2X:
|
||||
myQuadRect.w = myBaseDim.w * 2;
|
||||
myQuadRect.h = myBaseDim.h * 2;
|
||||
cerr << "scaler: " << scaler.name << endl;
|
||||
myScalerProc = AdvMame2x;
|
||||
break;
|
||||
case kSCALE3X:
|
||||
myQuadRect.w = myBaseDim.w * 3;
|
||||
myQuadRect.h = myBaseDim.h * 3;
|
||||
cerr << "scaler: " << scaler.name << endl;
|
||||
myScalerProc = AdvMame3x;
|
||||
break;
|
||||
case kSCALE4X:
|
||||
myQuadRect.w = myBaseDim.w * 4;
|
||||
|
@ -279,17 +293,22 @@ void FrameBufferGL::setScaler(Scaler scaler)
|
|||
myQuadRect.w = myBaseDim.w * 2;
|
||||
myQuadRect.h = myBaseDim.h * 2;
|
||||
cerr << "scaler: " << scaler.name << endl;
|
||||
myScalerProc = HQ2x;
|
||||
break;
|
||||
case kHQ3X:
|
||||
myQuadRect.w = myBaseDim.w * 3;
|
||||
myQuadRect.h = myBaseDim.h * 3;
|
||||
cerr << "scaler: " << scaler.name << endl;
|
||||
myScalerProc = HQ3x;
|
||||
break;
|
||||
case kHQ4X:
|
||||
myQuadRect.w = myBaseDim.w * 4;
|
||||
myQuadRect.h = myBaseDim.h * 4;
|
||||
cerr << "scaler: " << scaler.name << endl;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,15 +427,18 @@ void FrameBufferGL::drawMediaSource()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SCALER_SUPPORT
|
||||
// At this point, myBaseTexture will be filled with a valid TIA image
|
||||
// Now we check if post-processing scalers should be applied
|
||||
// In any event, myCurrentTexture will point to the valid data to be
|
||||
// rendered to the screen
|
||||
/*
|
||||
switch(myScalerType)
|
||||
if(myDirtyFlag && myScalerProc)
|
||||
{
|
||||
case
|
||||
*/
|
||||
myScalerProc((uInt8*) myBaseTexture->pixels, myBaseTexture->pitch,
|
||||
(uInt8*) myScaledTexture->pixels, myScaledTexture->pitch,
|
||||
myBaseTexture->w, myBaseTexture->h);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -497,11 +519,11 @@ void FrameBufferGL::toggleFilter()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
|
||||
{
|
||||
/*
|
||||
#ifndef SCALER_SUPPORT
|
||||
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + y * myCurrentTexture->w + x;
|
||||
while(x++ <= x2)
|
||||
*buffer++ = (uInt16) myDefPalette[color];
|
||||
*/
|
||||
#else
|
||||
SDL_Rect tmp;
|
||||
|
||||
// Horizontal line
|
||||
|
@ -510,19 +532,20 @@ void FrameBufferGL::hLine(uInt32 x, uInt32 y, uInt32 x2, int color)
|
|||
tmp.w = (x2 - x + 1) * myScaleLevel;
|
||||
tmp.h = myScaleLevel;
|
||||
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
|
||||
{
|
||||
/*
|
||||
#ifndef SCALER_SUPPORT
|
||||
uInt16* buffer = (uInt16*) myCurrentTexture->pixels + y * myCurrentTexture->w + x;
|
||||
while(y++ <= y2)
|
||||
{
|
||||
*buffer = (uInt16) myDefPalette[color];
|
||||
buffer += myCurrentTexture->w;
|
||||
}
|
||||
*/
|
||||
#else
|
||||
SDL_Rect tmp;
|
||||
|
||||
// Vertical line
|
||||
|
@ -531,7 +554,7 @@ void FrameBufferGL::vLine(uInt32 x, uInt32 y, uInt32 y2, int color)
|
|||
tmp.w = myScaleLevel;
|
||||
tmp.h = (y2 - y + 1) * myScaleLevel;
|
||||
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -546,14 +569,6 @@ void FrameBufferGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|||
tmp.w = w * myScaleLevel;
|
||||
tmp.h = h * myScaleLevel;
|
||||
SDL_FillRect(myCurrentTexture, &tmp, myDefPalette[color]);
|
||||
/*
|
||||
cerr << "FrameBufferGL::fillRect:" << endl
|
||||
<< "x = " << tmp.x << endl
|
||||
<< "y = " << tmp.y << endl
|
||||
<< "w = " << tmp.w << endl
|
||||
<< "h = " << tmp.h << endl
|
||||
<< endl;
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -647,7 +662,6 @@ void FrameBufferGL::cls()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferGL::createTextures()
|
||||
{
|
||||
cerr << "FrameBufferGL::createTextures()\n";
|
||||
if(myBaseTexture)
|
||||
{
|
||||
SDL_FreeSurface(myBaseTexture);
|
||||
|
@ -661,12 +675,14 @@ cerr << "FrameBufferGL::createTextures()\n";
|
|||
myCurrentTexture = NULL;
|
||||
p_glDeleteTextures(1, &myTextureID);
|
||||
|
||||
/*
|
||||
cerr << "texture dimensions (before power of 2 scaling):" << endl
|
||||
<< "myBaseTexture->w = " << myBaseDim.w << endl
|
||||
<< "myBaseTexture->h = " << myBaseDim.h << endl
|
||||
<< "myScaledTexture->w = " << myQuadRect.w << endl
|
||||
<< "myScaledTexture->h = " << myQuadRect.h << endl
|
||||
<< endl;
|
||||
*/
|
||||
|
||||
uInt32 w1 = power_of_two(myBaseDim.w);
|
||||
uInt32 h1 = power_of_two(myBaseDim.h);
|
||||
|
@ -740,7 +756,6 @@ cerr << "texture dimensions (before power of 2 scaling):" << endl
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
|
||||
{
|
||||
cerr << "FrameBufferGL::setDimensions()\n";
|
||||
// We always know the initial image width and height
|
||||
// We have to determine final image dimensions as well as screen dimensions
|
||||
myImageDim.x = 0;
|
||||
|
|
|
@ -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: FrameBufferGL.hxx,v 1.33 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: FrameBufferGL.hxx,v 1.34 2006-10-22 18:58:45 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_GL_HXX
|
||||
|
@ -32,12 +32,15 @@ class GUI::Font;
|
|||
#include "GuiUtils.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
||||
#ifdef SCALER_SUPPORT
|
||||
#include "scaler.hxx"
|
||||
#endif
|
||||
|
||||
/**
|
||||
This class implements an SDL OpenGL framebuffer.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBufferGL.hxx,v 1.33 2006-10-16 01:08:59 stephena Exp $
|
||||
@version $Id: FrameBufferGL.hxx,v 1.34 2006-10-22 18:58:45 stephena Exp $
|
||||
*/
|
||||
class FrameBufferGL : public FrameBuffer
|
||||
{
|
||||
|
@ -237,7 +240,8 @@ class FrameBufferGL : public FrameBuffer
|
|||
SDL_Surface* myBaseTexture;
|
||||
SDL_Surface* myScaledTexture;
|
||||
|
||||
// Points to the current texture data, which is one of myBaseTexture or myScaledTexture
|
||||
// Points to the current texture data, which is one of
|
||||
// myBaseTexture or myScaledTexture
|
||||
SDL_Surface* myCurrentTexture;
|
||||
|
||||
SDL_Rect myQuadRect;
|
||||
|
@ -281,6 +285,10 @@ class FrameBufferGL : public FrameBuffer
|
|||
|
||||
// Indicates if the OpenGL functions have been properly loaded
|
||||
static bool myFuncsLoaded;
|
||||
|
||||
#ifdef SCALER_SUPPORT
|
||||
ScalerProc *myScalerProc;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // DISPLAY_OPENGL
|
||||
|
|
|
@ -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: FrameBufferSoft.cxx,v 1.55 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: FrameBufferSoft.cxx,v 1.56 2006-10-22 18:58:45 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <SDL.h>
|
||||
|
@ -129,6 +129,11 @@ bool FrameBufferSoft::createScreen()
|
|||
break;
|
||||
}
|
||||
|
||||
// Erase old rects, since they've probably been scaled for
|
||||
// a different sized screen
|
||||
myRectList->start();
|
||||
myOverlayRectList->start();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -443,7 +448,9 @@ void FrameBufferSoft::postFrameUpdate()
|
|||
// on the Win32 code. It seems that SDL_UpdateRects() is very
|
||||
// expensive in Windows, so we force a full screen update instead.
|
||||
if(myUseDirtyRects)
|
||||
{
|
||||
SDL_UpdateRects(myScreen, myRectList->numRects(), myRectList->rects());
|
||||
}
|
||||
else if(myRectList->numRects() > 0)
|
||||
{
|
||||
SDL_Flip(myScreen);
|
||||
|
@ -620,28 +627,14 @@ void FrameBufferSoft::translateCoords(Int32* x, Int32* y)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
|
||||
{
|
||||
x *= myZoomLevel;
|
||||
y *= myZoomLevel;
|
||||
w *= myZoomLevel;
|
||||
h *= myZoomLevel;
|
||||
|
||||
// Check if rect is in screen area
|
||||
// This is probably a bug, since the GUI code shouldn't be setting
|
||||
// a dirty rect larger than the screen
|
||||
int x1 = x, y1 = y, x2 = x + w, y2 = y + h;
|
||||
int sx1 = myScreenDim.x, sy1 = myScreenDim.y,
|
||||
sx2 = myScreenDim.x + myScreenDim.w, sy2 = myScreenDim.y + myScreenDim.h;
|
||||
if(x1 < sx1 || y1 < sy1 || x2 > sx2 || y2 > sy2)
|
||||
return;
|
||||
|
||||
// Add a dirty rect to the overlay rectangle list
|
||||
// They will actually be added to the main rectlist in preFrameUpdate()
|
||||
// TODO - intelligent merging of rectangles, to avoid overlap
|
||||
SDL_Rect temp;
|
||||
temp.x = x;
|
||||
temp.y = y;
|
||||
temp.w = w;
|
||||
temp.h = h;
|
||||
temp.x = x * myZoomLevel;
|
||||
temp.y = y * myZoomLevel;
|
||||
temp.w = w * myZoomLevel;
|
||||
temp.h = h * myZoomLevel;
|
||||
|
||||
myOverlayRectList->add(&temp);
|
||||
|
||||
|
@ -720,9 +713,6 @@ void RectList::add(SDL_Rect* newRect)
|
|||
rectArray = temp;
|
||||
}
|
||||
|
||||
//cerr << "RectList::add(): "
|
||||
// << "x=" << newRect->x << ", y=" << newRect->y << ", w=" << newRect->w << ", h=" << newRect->h << endl;
|
||||
|
||||
rectArray[currentRect].x = newRect->x;
|
||||
rectArray[currentRect].y = newRect->y;
|
||||
rectArray[currentRect].w = newRect->w;
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: mainSDL.cxx,v 1.65 2006-03-22 21:13:36 stephena Exp $
|
||||
// $Id: mainSDL.cxx,v 1.66 2006-10-22 18:58:45 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
@ -64,48 +62,10 @@
|
|||
#include "CheatManager.hxx"
|
||||
#endif
|
||||
|
||||
static void SetupProperties(PropertiesSet& set);
|
||||
static void Cleanup();
|
||||
|
||||
// Pointer to the main parent osystem object or the null pointer
|
||||
OSystem* theOSystem = (OSystem*) NULL;
|
||||
|
||||
|
||||
/**
|
||||
Setup the properties set by first checking for a user file,
|
||||
then a system-wide file.
|
||||
*/
|
||||
void SetupProperties(PropertiesSet& set)
|
||||
{
|
||||
// Several properties files can exist, so we attempt to load from
|
||||
// all of them. If the user has specified a properties file, use
|
||||
// that one. Otherwise, load both the system and user properties
|
||||
// files, and have the user file override all entries from the
|
||||
// system file.
|
||||
|
||||
ostringstream buf;
|
||||
|
||||
string altpro = theOSystem->settings().getString("pro");
|
||||
if(altpro != "")
|
||||
{
|
||||
buf << "User game properties: \'" << altpro << "\'\n";
|
||||
set.load(altpro, false); // don't save alternate properties
|
||||
}
|
||||
else
|
||||
{
|
||||
const string& props = theOSystem->propertiesFile();
|
||||
buf << "User game properties: \'" << props << "\'\n";
|
||||
set.load(props, true); // do save these properties
|
||||
}
|
||||
|
||||
if(theOSystem->settings().getBool("showinfo"))
|
||||
cout << buf.str() << endl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Does general Cleanup in case any operation failed (or at end of program).
|
||||
*/
|
||||
// Does general Cleanup in case any operation failed (or at end of program)
|
||||
void Cleanup()
|
||||
{
|
||||
if(theOSystem)
|
||||
|
@ -164,46 +124,20 @@ int main(int argc, char* argv[])
|
|||
// probably needed for defaults
|
||||
theOSystem->create();
|
||||
|
||||
// Create the event handler for the system
|
||||
EventHandler handler(theOSystem);
|
||||
|
||||
// Create a properties set for us to use and set it up
|
||||
PropertiesSet propertiesSet(theOSystem);
|
||||
SetupProperties(propertiesSet);
|
||||
theOSystem->attach(&propertiesSet);
|
||||
|
||||
// Check to see if the 'listroms' argument was given
|
||||
// If so, list the roms and immediately exit
|
||||
if(theOSystem->settings().getBool("listrominfo"))
|
||||
{
|
||||
propertiesSet.print();
|
||||
theOSystem->propSet().print();
|
||||
Cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Request that the SDL window be centered, if possible
|
||||
// At some point, this should be properly integrated into the UI
|
||||
if(theOSystem->settings().getBool("center"))
|
||||
putenv("SDL_VIDEO_CENTERED=1");
|
||||
|
||||
// Create the framebuffer(s)
|
||||
if(!theOSystem->createFrameBuffer())
|
||||
{
|
||||
cerr << "ERROR: Couldn't set up display.\n";
|
||||
Cleanup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create the sound object
|
||||
theOSystem->createSound();
|
||||
|
||||
// Setup the SDL joysticks (must be done after FrameBuffer is created)
|
||||
theOSystem->eventHandler().setupJoysticks();
|
||||
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
// Create internal cheat database for all ROMs
|
||||
theOSystem->cheat().loadCheatDatabase();
|
||||
#endif
|
||||
|
||||
//// Main loop ////
|
||||
// First we check if a ROM is specified on the commandline. If so, and if
|
||||
// the ROM actually exists, use it to create a new console.
|
||||
|
@ -237,7 +171,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
if(theOSystem->settings().getBool("debug"))
|
||||
handler.enterDebugMode();
|
||||
theOSystem->eventHandler().enterDebugMode();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: colormasks.hxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#ifndef GRAPHICS_COLORMASKS_H
|
||||
#define GRAPHICS_COLORMASKS_H
|
||||
|
||||
template<int bitFormat>
|
||||
struct ColorMasks {
|
||||
};
|
||||
|
||||
/*
|
||||
The ColorMasks template can be used to map bit format values
|
||||
(like 555, 565, 1555, 4444) to corresponding bit masks and shift values.
|
||||
Currently this is only meant for
|
||||
|
||||
The meaning of these is masks is the following:
|
||||
kBytesPerPixel
|
||||
-> how many bytes per pixel for that format
|
||||
|
||||
kRedMask, kGreenMask, kBlueMask
|
||||
-> bitmask, and this with the color to select only the bits of the corresponding color
|
||||
|
||||
The k*Bits and k*Shift values can be used to extract R,G,B. I.e. to get
|
||||
the red color component of a pixel, as a 8-bit value, you would write
|
||||
|
||||
R = ((color & kRedMask) >> kRedShift) << (8-kRedBits)
|
||||
|
||||
Actually, instead of the simple left shift, one might want to use somewhat
|
||||
more sophisticated code (which fills up the lower most bits.
|
||||
|
||||
|
||||
The highBits / lowBits / qhighBits / qlowBits are special values that are
|
||||
used in the super-optimized interpolation functions in scaler/intern.h
|
||||
and scaler/aspect.cpp. Currently they are only available in 555 and 565 mode.
|
||||
To be specific: They pack the masks for two 16 bit pixels at once. The pixels
|
||||
are split into "high" and "low" bits, which are then separately interpolated
|
||||
and finally re-composed. That way, 2x2 pixels or even 4x2 pixels can
|
||||
be interpolated in one go.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
template<>
|
||||
struct ColorMasks<565> {
|
||||
enum {
|
||||
highBits = 0xF7DEF7DE,
|
||||
lowBits = 0x08210821,
|
||||
qhighBits = 0xE79CE79C,
|
||||
qlowBits = 0x18631863,
|
||||
|
||||
|
||||
kBytesPerPixel = 2,
|
||||
|
||||
kAlphaBits = 0,
|
||||
kRedBits = 5,
|
||||
kGreenBits = 6,
|
||||
kBlueBits = 5,
|
||||
|
||||
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
|
||||
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
|
||||
|
||||
kRedBlueMask = kRedMask | kBlueMask
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColorMasks<555> {
|
||||
enum {
|
||||
highBits = 0x7BDE7BDE,
|
||||
lowBits = 0x04210421,
|
||||
qhighBits = 0x739C739C,
|
||||
qlowBits = 0x0C630C63,
|
||||
|
||||
|
||||
kBytesPerPixel = 2,
|
||||
|
||||
kAlphaBits = 0,
|
||||
kRedBits = 5,
|
||||
kGreenBits = 5,
|
||||
kBlueBits = 5,
|
||||
|
||||
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
|
||||
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
|
||||
|
||||
kRedBlueMask = kRedMask | kBlueMask
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColorMasks<1555> {
|
||||
enum {
|
||||
kBytesPerPixel = 2,
|
||||
|
||||
kAlphaBits = 1,
|
||||
kRedBits = 5,
|
||||
kGreenBits = 5,
|
||||
kBlueBits = 5,
|
||||
|
||||
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
|
||||
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
|
||||
|
||||
kRedBlueMask = kRedMask | kBlueMask
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColorMasks<4444> {
|
||||
enum {
|
||||
kBytesPerPixel = 2,
|
||||
|
||||
kAlphaBits = 4,
|
||||
kRedBits = 4,
|
||||
kGreenBits = 4,
|
||||
kBlueBits = 4,
|
||||
|
||||
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
|
||||
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
|
||||
|
||||
kRedBlueMask = kRedMask | kBlueMask
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColorMasks<888> {
|
||||
enum {
|
||||
kBytesPerPixel = 4,
|
||||
|
||||
kAlphaBits = 0,
|
||||
kRedBits = 8,
|
||||
kGreenBits = 8,
|
||||
kBlueBits = 8,
|
||||
|
||||
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
|
||||
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
|
||||
|
||||
kRedBlueMask = kRedMask | kBlueMask
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ColorMasks<8888> {
|
||||
enum {
|
||||
kBytesPerPixel = 4,
|
||||
|
||||
kAlphaBits = 8,
|
||||
kRedBits = 8,
|
||||
kGreenBits = 8,
|
||||
kBlueBits = 8,
|
||||
|
||||
kAlphaShift = kRedBits+kGreenBits+kBlueBits,
|
||||
kRedShift = kGreenBits+kBlueBits,
|
||||
kGreenShift = kBlueBits,
|
||||
kBlueShift = 0,
|
||||
|
||||
kAlphaMask = ((1 << kAlphaBits) - 1) << kAlphaShift,
|
||||
kRedMask = ((1 << kRedBits) - 1) << kRedShift,
|
||||
kGreenMask = ((1 << kGreenBits) - 1) << kGreenShift,
|
||||
kBlueMask = ((1 << kBlueBits) - 1) << kBlueShift,
|
||||
|
||||
kRedBlueMask = kRedMask | kBlueMask
|
||||
};
|
||||
};
|
||||
|
||||
#if 0
|
||||
template<class T>
|
||||
uint32 RGBToColor(uint8 r, uint8 g, uint8 b) {
|
||||
return T::kAlphaMask |
|
||||
(((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
|
||||
(((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
|
||||
(((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
uint32 ARGBToColor(uint8 a, uint8 r, uint8 g, uint8 b) {
|
||||
return (((a << T::kAlphaShift) >> (8 - T::kAlphaBits)) & T::kAlphaMask) |
|
||||
(((r << T::kRedShift) >> (8 - T::kRedBits)) & T::kRedMask) |
|
||||
(((g << T::kGreenShift) >> (8 - T::kGreenBits)) & T::kGreenMask) |
|
||||
(((b << T::kBlueShift) >> (8 - T::kBlueBits)) & T::kBlueMask);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void colorToRGB(uint32 color, uint8 &r, uint8 &g, uint8 &b) {
|
||||
r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
|
||||
g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
|
||||
b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void colorToARGB(uint32 color, uint8 &a, uint8 &r, uint8 &g, uint8 &b) {
|
||||
a = ((color & T::kAlphaMask) >> T::kAlphaShift) << (8 - T::kAlphaBits);
|
||||
r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
|
||||
g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
|
||||
b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: compat.hxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
/**
|
||||
Compatibility layer to convert ScummVM datatypes to Stella format.
|
||||
*/
|
||||
#ifndef COMPAT_TYPE_HXX
|
||||
#define COMPAT_TYPE_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
|
||||
typedef uInt8 byte;
|
||||
typedef uInt32 uint;
|
||||
typedef uInt8 uint8;
|
||||
typedef uInt16 uint16;
|
||||
typedef uInt32 uint32;
|
||||
typedef Int8 int8;
|
||||
typedef Int16 int16;
|
||||
typedef Int32 int32;
|
||||
|
||||
//
|
||||
// GCC specific stuff
|
||||
//
|
||||
#if defined(__GNUC__)
|
||||
#define GCC_PACK __attribute__((packed))
|
||||
#define NORETURN __attribute__((__noreturn__))
|
||||
#define GCC_PRINTF(x,y) __attribute__((format(printf, x, y)))
|
||||
#else
|
||||
#define GCC_PACK
|
||||
#define GCC_PRINTF(x,y)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,104 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: hq2x.cxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#include "intern.hxx"
|
||||
|
||||
#ifdef USE_NASM
|
||||
// Assembly version of HQ2x
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if !defined(_WIN32) && !defined(MACOSX)
|
||||
#define hq2x_16 _hq2x_16
|
||||
#endif
|
||||
|
||||
void hq2x_16(const byte *, byte *, uint32, uint32, uint32, uint32);
|
||||
|
||||
}
|
||||
|
||||
void HQ2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
|
||||
hq2x_16(srcPtr, dstPtr, width, height, srcPitch, dstPitch);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define PIXEL00_0 *(q) = w5;
|
||||
#define PIXEL00_10 *(q) = interpolate16_2<bitFormat,3,1>(w5, w1);
|
||||
#define PIXEL00_11 *(q) = interpolate16_2<bitFormat,3,1>(w5, w4);
|
||||
#define PIXEL00_12 *(q) = interpolate16_2<bitFormat,3,1>(w5, w2);
|
||||
#define PIXEL00_20 *(q) = interpolate16_3<bitFormat,2,1,1>(w5, w4, w2);
|
||||
#define PIXEL00_21 *(q) = interpolate16_3<bitFormat,2,1,1>(w5, w1, w2);
|
||||
#define PIXEL00_22 *(q) = interpolate16_3<bitFormat,2,1,1>(w5, w1, w4);
|
||||
#define PIXEL00_60 *(q) = interpolate16_3<bitFormat,5,2,1>(w5, w2, w4);
|
||||
#define PIXEL00_61 *(q) = interpolate16_3<bitFormat,5,2,1>(w5, w4, w2);
|
||||
#define PIXEL00_70 *(q) = interpolate16_3<bitFormat,6,1,1>(w5, w4, w2);
|
||||
#define PIXEL00_90 *(q) = interpolate16_3<bitFormat,2,3,3>(w5, w4, w2);
|
||||
#define PIXEL00_100 *(q) = interpolate16_3<bitFormat,14,1,1>(w5, w4, w2);
|
||||
|
||||
#define PIXEL01_0 *(q+1) = w5;
|
||||
#define PIXEL01_10 *(q+1) = interpolate16_2<bitFormat,3,1>(w5, w3);
|
||||
#define PIXEL01_11 *(q+1) = interpolate16_2<bitFormat,3,1>(w5, w2);
|
||||
#define PIXEL01_12 *(q+1) = interpolate16_2<bitFormat,3,1>(w5, w6);
|
||||
#define PIXEL01_20 *(q+1) = interpolate16_3<bitFormat,2,1,1>(w5, w2, w6);
|
||||
#define PIXEL01_21 *(q+1) = interpolate16_3<bitFormat,2,1,1>(w5, w3, w6);
|
||||
#define PIXEL01_22 *(q+1) = interpolate16_3<bitFormat,2,1,1>(w5, w3, w2);
|
||||
#define PIXEL01_60 *(q+1) = interpolate16_3<bitFormat,5,2,1>(w5, w6, w2);
|
||||
#define PIXEL01_61 *(q+1) = interpolate16_3<bitFormat,5,2,1>(w5, w2, w6);
|
||||
#define PIXEL01_70 *(q+1) = interpolate16_3<bitFormat,6,1,1>(w5, w2, w6);
|
||||
#define PIXEL01_90 *(q+1) = interpolate16_3<bitFormat,2,3,3>(w5, w2, w6);
|
||||
#define PIXEL01_100 *(q+1) = interpolate16_3<bitFormat,14,1,1>(w5, w2, w6);
|
||||
|
||||
#define PIXEL10_0 *(q+nextlineDst) = w5;
|
||||
#define PIXEL10_10 *(q+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w7);
|
||||
#define PIXEL10_11 *(q+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w8);
|
||||
#define PIXEL10_12 *(q+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w4);
|
||||
#define PIXEL10_20 *(q+nextlineDst) = interpolate16_3<bitFormat,2,1,1>(w5, w8, w4);
|
||||
#define PIXEL10_21 *(q+nextlineDst) = interpolate16_3<bitFormat,2,1,1>(w5, w7, w4);
|
||||
#define PIXEL10_22 *(q+nextlineDst) = interpolate16_3<bitFormat,2,1,1>(w5, w7, w8);
|
||||
#define PIXEL10_60 *(q+nextlineDst) = interpolate16_3<bitFormat,5,2,1>(w5, w4, w8);
|
||||
#define PIXEL10_61 *(q+nextlineDst) = interpolate16_3<bitFormat,5,2,1>(w5, w8, w4);
|
||||
#define PIXEL10_70 *(q+nextlineDst) = interpolate16_3<bitFormat,6,1,1>(w5, w8, w4);
|
||||
#define PIXEL10_90 *(q+nextlineDst) = interpolate16_3<bitFormat,2,3,3>(w5, w8, w4);
|
||||
#define PIXEL10_100 *(q+nextlineDst) = interpolate16_3<bitFormat,14,1,1>(w5, w8, w4);
|
||||
|
||||
#define PIXEL11_0 *(q+1+nextlineDst) = w5;
|
||||
#define PIXEL11_10 *(q+1+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w9);
|
||||
#define PIXEL11_11 *(q+1+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w6);
|
||||
#define PIXEL11_12 *(q+1+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w8);
|
||||
#define PIXEL11_20 *(q+1+nextlineDst) = interpolate16_3<bitFormat,2,1,1>(w5, w6, w8);
|
||||
#define PIXEL11_21 *(q+1+nextlineDst) = interpolate16_3<bitFormat,2,1,1>(w5, w9, w8);
|
||||
#define PIXEL11_22 *(q+1+nextlineDst) = interpolate16_3<bitFormat,2,1,1>(w5, w9, w6);
|
||||
#define PIXEL11_60 *(q+1+nextlineDst) = interpolate16_3<bitFormat,5,2,1>(w5, w8, w6);
|
||||
#define PIXEL11_61 *(q+1+nextlineDst) = interpolate16_3<bitFormat,5,2,1>(w5, w6, w8);
|
||||
#define PIXEL11_70 *(q+1+nextlineDst) = interpolate16_3<bitFormat,6,1,1>(w5, w6, w8);
|
||||
#define PIXEL11_90 *(q+1+nextlineDst) = interpolate16_3<bitFormat,2,3,3>(w5, w6, w8);
|
||||
#define PIXEL11_100 *(q+1+nextlineDst) = interpolate16_3<bitFormat,14,1,1>(w5, w6, w8);
|
||||
|
||||
#define YUV(x) RGBtoYUV[w ## x]
|
||||
|
||||
|
||||
#define bitFormat 565
|
||||
void HQ2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
|
||||
#include "hq2x.hxx"
|
||||
}
|
||||
#undef bitFormat
|
||||
|
||||
#endif //Assembly version
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,121 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: hq3x.cxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#include "intern.hxx"
|
||||
|
||||
#ifdef USE_NASM
|
||||
// Assembly version of HQ3x
|
||||
|
||||
extern "C" {
|
||||
|
||||
#if !defined(_WIN32) && !defined(MACOSX)
|
||||
#define hq3x_16 _hq3x_16
|
||||
#endif
|
||||
|
||||
|
||||
void hq3x_16(const byte *, byte *, uint32, uint32, uint32, uint32);
|
||||
|
||||
}
|
||||
|
||||
void HQ3x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
|
||||
hq3x_16(srcPtr, dstPtr, width, height, srcPitch, dstPitch);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define PIXEL00_1M *(q) = interpolate16_2<bitFormat,3,1>(w5, w1);
|
||||
#define PIXEL00_1U *(q) = interpolate16_2<bitFormat,3,1>(w5, w2);
|
||||
#define PIXEL00_1L *(q) = interpolate16_2<bitFormat,3,1>(w5, w4);
|
||||
#define PIXEL00_2 *(q) = interpolate16_3<bitFormat,2,1,1>(w5, w4, w2);
|
||||
#define PIXEL00_4 *(q) = interpolate16_3<bitFormat,2,7,7>(w5, w4, w2);
|
||||
#define PIXEL00_5 *(q) = interpolate16_2<bitFormat,1,1>(w4, w2);
|
||||
#define PIXEL00_C *(q) = w5;
|
||||
|
||||
#define PIXEL01_1 *(q+1) = interpolate16_2<bitFormat,3,1>(w5, w2);
|
||||
#define PIXEL01_3 *(q+1) = interpolate16_2<bitFormat,7,1>(w5, w2);
|
||||
#define PIXEL01_6 *(q+1) = interpolate16_2<bitFormat,3,1>(w2, w5);
|
||||
#define PIXEL01_C *(q+1) = w5;
|
||||
|
||||
#define PIXEL02_1M *(q+2) = interpolate16_2<bitFormat,3,1>(w5, w3);
|
||||
#define PIXEL02_1U *(q+2) = interpolate16_2<bitFormat,3,1>(w5, w2);
|
||||
#define PIXEL02_1R *(q+2) = interpolate16_2<bitFormat,3,1>(w5, w6);
|
||||
#define PIXEL02_2 *(q+2) = interpolate16_3<bitFormat,2,1,1>(w5, w2, w6);
|
||||
#define PIXEL02_4 *(q+2) = interpolate16_3<bitFormat,2,7,7>(w5, w2, w6);
|
||||
#define PIXEL02_5 *(q+2) = interpolate16_2<bitFormat,1,1>(w2, w6);
|
||||
#define PIXEL02_C *(q+2) = w5;
|
||||
|
||||
#define PIXEL10_1 *(q+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w4);
|
||||
#define PIXEL10_3 *(q+nextlineDst) = interpolate16_2<bitFormat,7,1>(w5, w4);
|
||||
#define PIXEL10_6 *(q+nextlineDst) = interpolate16_2<bitFormat,3,1>(w4, w5);
|
||||
#define PIXEL10_C *(q+nextlineDst) = w5;
|
||||
|
||||
#define PIXEL11 *(q+1+nextlineDst) = w5;
|
||||
|
||||
#define PIXEL12_1 *(q+2+nextlineDst) = interpolate16_2<bitFormat,3,1>(w5, w6);
|
||||
#define PIXEL12_3 *(q+2+nextlineDst) = interpolate16_2<bitFormat,7,1>(w5, w6);
|
||||
#define PIXEL12_6 *(q+2+nextlineDst) = interpolate16_2<bitFormat,3,1>(w6, w5);
|
||||
#define PIXEL12_C *(q+2+nextlineDst) = w5;
|
||||
|
||||
#define PIXEL20_1M *(q+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w7);
|
||||
#define PIXEL20_1D *(q+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w8);
|
||||
#define PIXEL20_1L *(q+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w4);
|
||||
#define PIXEL20_2 *(q+nextlineDst2) = interpolate16_3<bitFormat,2,1,1>(w5, w8, w4);
|
||||
#define PIXEL20_4 *(q+nextlineDst2) = interpolate16_3<bitFormat,2,7,7>(w5, w8, w4);
|
||||
#define PIXEL20_5 *(q+nextlineDst2) = interpolate16_2<bitFormat,1,1>(w8, w4);
|
||||
#define PIXEL20_C *(q+nextlineDst2) = w5;
|
||||
|
||||
#define PIXEL21_1 *(q+1+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w8);
|
||||
#define PIXEL21_3 *(q+1+nextlineDst2) = interpolate16_2<bitFormat,7,1>(w5, w8);
|
||||
#define PIXEL21_6 *(q+1+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w8, w5);
|
||||
#define PIXEL21_C *(q+1+nextlineDst2) = w5;
|
||||
|
||||
#define PIXEL22_1M *(q+2+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w9);
|
||||
#define PIXEL22_1D *(q+2+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w8);
|
||||
#define PIXEL22_1R *(q+2+nextlineDst2) = interpolate16_2<bitFormat,3,1>(w5, w6);
|
||||
#define PIXEL22_2 *(q+2+nextlineDst2) = interpolate16_3<bitFormat,2,1,1>(w5, w6, w8);
|
||||
#define PIXEL22_4 *(q+2+nextlineDst2) = interpolate16_3<bitFormat,2,7,7>(w5, w6, w8);
|
||||
#define PIXEL22_5 *(q+2+nextlineDst2) = interpolate16_2<bitFormat,1,1>(w6, w8);
|
||||
#define PIXEL22_C *(q+2+nextlineDst2) = w5;
|
||||
|
||||
#define YUV(x) RGBtoYUV[w ## x]
|
||||
|
||||
|
||||
#define bitFormat 565
|
||||
void HQ3x_565(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
|
||||
#include "hq3x.hxx"
|
||||
}
|
||||
#undef bitFormat
|
||||
|
||||
#define bitFormat 555
|
||||
void HQ3x_555(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
|
||||
#include "hq3x.hxx"
|
||||
}
|
||||
#undef bitFormat
|
||||
|
||||
|
||||
void HQ3x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
|
||||
if (gBitFormat == 565)
|
||||
HQ3x_565(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
|
||||
else
|
||||
HQ3x_555(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,157 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: intern.hxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#ifndef GRAPHICS_SCALER_INTERN_H
|
||||
#define GRAPHICS_SCALER_INTERN_H
|
||||
|
||||
//#include "common/stdafx.h"
|
||||
#include "compat.hxx"
|
||||
#include "colormasks.hxx"
|
||||
|
||||
|
||||
#define highBits ColorMasks<bitFormat>::highBits
|
||||
#define lowBits ColorMasks<bitFormat>::lowBits
|
||||
#define qhighBits ColorMasks<bitFormat>::qhighBits
|
||||
#define qlowBits ColorMasks<bitFormat>::qlowBits
|
||||
#define redblueMask ColorMasks<bitFormat>::kRedBlueMask
|
||||
#define greenMask ColorMasks<bitFormat>::kGreenMask
|
||||
|
||||
|
||||
/**
|
||||
* Interpolate two 16 bit pixel *pairs* at once with equal weights 1.
|
||||
* In particular, A and B can contain two pixels/each in the upper
|
||||
* and lower halves.
|
||||
*/
|
||||
template<int bitFormat>
|
||||
static inline uint32 interpolate32_1_1(uint32 A, uint32 B) {
|
||||
return (((A & highBits) >> 1) + ((B & highBits) >> 1) + (A & B & lowBits));
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate two 16 bit pixel *pairs* at once with weights 3 resp. 1.
|
||||
* In particular, A and B can contain two pixels/each in the upper
|
||||
* and lower halves.
|
||||
*/
|
||||
template<int bitFormat>
|
||||
static inline uint32 interpolate32_3_1(uint32 A, uint32 B) {
|
||||
register uint32 x = ((A & qhighBits) >> 2) * 3 + ((B & qhighBits) >> 2);
|
||||
register uint32 y = ((A & qlowBits) * 3 + (B & qlowBits)) >> 2;
|
||||
|
||||
y &= qlowBits;
|
||||
return x + y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate four 16 bit pixel pairs at once with equal weights 1.
|
||||
* In particular, A and B can contain two pixels/each in the upper
|
||||
* and lower halves.
|
||||
*/
|
||||
template<int bitFormat>
|
||||
static inline uint32 interpolate32_1_1_1_1(uint32 A, uint32 B, uint32 C, uint32 D) {
|
||||
register uint32 x = ((A & qhighBits) >> 2) + ((B & qhighBits) >> 2) + ((C & qhighBits) >> 2) + ((D & qhighBits) >> 2);
|
||||
register uint32 y = ((A & qlowBits) + (B & qlowBits) + (C & qlowBits) + (D & qlowBits)) >> 2;
|
||||
|
||||
y &= qlowBits;
|
||||
return x + y;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interpolate two 16 bit pixels with the weights specified in the template
|
||||
* parameters. Used by the hq scaler family.
|
||||
* @note w1 and w2 must sum up to 2, 4, 8 or 16.
|
||||
*/
|
||||
template<int bitFormat, int w1, int w2>
|
||||
static inline uint16 interpolate16_2(uint16 p1, uint16 p2) {
|
||||
return ((((p1 & redblueMask) * w1 + (p2 & redblueMask) * w2) / (w1 + w2)) & redblueMask) |
|
||||
((((p1 & greenMask) * w1 + (p2 & greenMask) * w2) / (w1 + w2)) & greenMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate three 16 bit pixels with the weights specified in the template
|
||||
* parameters. Used by the hq scaler family.
|
||||
* @note w1, w2 and w3 must sum up to 2, 4, 8 or 16.
|
||||
*/
|
||||
template<int bitFormat, int w1, int w2, int w3>
|
||||
static inline uint16 interpolate16_3(uint16 p1, uint16 p2, uint16 p3) {
|
||||
return ((((p1 & redblueMask) * w1 + (p2 & redblueMask) * w2 + (p3 & redblueMask) * w3) / (w1 + w2 + w3)) & redblueMask) |
|
||||
((((p1 & greenMask) * w1 + (p2 & greenMask) * w2 + (p3 & greenMask) * w3) / (w1 + w2 + w3)) & greenMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two YUV values (encoded 8-8-8) and check if they differ by more than
|
||||
* a certain hard coded threshold. Used by the hq scaler family.
|
||||
*/
|
||||
static inline bool diffYUV(int yuv1, int yuv2) {
|
||||
static const int Ymask = 0x00FF0000;
|
||||
static const int Umask = 0x0000FF00;
|
||||
static const int Vmask = 0x000000FF;
|
||||
static const int trY = 0x00300000;
|
||||
static const int trU = 0x00000700;
|
||||
static const int trV = 0x00000006;
|
||||
|
||||
int diff;
|
||||
int mask;
|
||||
|
||||
diff = ((yuv1 & Ymask) - (yuv2 & Ymask));
|
||||
mask = diff >> 31; // -1 if value < 0, 0 otherwise
|
||||
diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value
|
||||
if (diff > trY) return true;
|
||||
|
||||
diff = ((yuv1 & Umask) - (yuv2 & Umask));
|
||||
mask = diff >> 31; // -1 if value < 0, 0 otherwise
|
||||
diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value
|
||||
if (diff > trU) return true;
|
||||
|
||||
diff = ((yuv1 & Vmask) - (yuv2 & Vmask));
|
||||
mask = diff >> 31; // -1 if value < 0, 0 otherwise
|
||||
diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value
|
||||
if (diff > trV) return true;
|
||||
|
||||
return false;
|
||||
/*
|
||||
return
|
||||
( ( ABS((yuv1 & Ymask) - (yuv2 & Ymask)) > trY ) ||
|
||||
( ABS((yuv1 & Umask) - (yuv2 & Umask)) > trU ) ||
|
||||
( ABS((yuv1 & Vmask) - (yuv2 & Vmask)) > trV ) );
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* 16bit RGB to YUV conversion table. This table is setup by InitLUT().
|
||||
* Used by the hq scaler family.
|
||||
*/
|
||||
extern "C" uint32 *RGBtoYUV;
|
||||
|
||||
/** Auxiliary macro to simplify creating those template function wrappers. */
|
||||
#define MAKE_WRAPPER(FUNC) \
|
||||
void FUNC(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { \
|
||||
if (gBitFormat == 565) \
|
||||
FUNC ## Template<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); \
|
||||
else \
|
||||
FUNC ## Template<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); \
|
||||
}
|
||||
|
||||
/** Specifies the currently active 16bit pixel format, 555 or 565. */
|
||||
extern int gBitFormat;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,21 @@
|
|||
MODULE := src/common/scaler
|
||||
|
||||
MODULE_OBJS := \
|
||||
src/common/scaler/hq2x.o \
|
||||
src/common/scaler/hq3x.o \
|
||||
src/common/scaler/scaler.o \
|
||||
src/common/scaler/scalebit.o \
|
||||
src/common/scaler/scale2x.o \
|
||||
src/common/scaler/scale3x.o
|
||||
|
||||
ifdef HAVE_NASM
|
||||
MODULE_OBJS += \
|
||||
src/common/scaler/hq2x_i386.o \
|
||||
src/common/scaler/hq3x_i386.o
|
||||
endif
|
||||
|
||||
MODULE_DIRS += \
|
||||
src/common/scaler
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/common.rules
|
|
@ -0,0 +1,538 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scale2x.cxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains a C and MMX implementation of the Scale2x effect.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
//#include "common/stdafx.h"
|
||||
#include "compat.hxx"
|
||||
#include "intern.hxx"
|
||||
#include "scale2x.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* Scale2x C implementation */
|
||||
|
||||
static inline void scale2x_8_def_single(scale2x_uint8* __restrict__ dst, const scale2x_uint8* __restrict__ src0, const scale2x_uint8* __restrict__ src1, const scale2x_uint8* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_16_def_single(scale2x_uint16* __restrict__ dst, const scale2x_uint16* __restrict__ src0, const scale2x_uint16* __restrict__ src1, const scale2x_uint16* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale2x_32_def_single(scale2x_uint32* __restrict__ dst, const scale2x_uint32* __restrict__ src0, const scale2x_uint32* __restrict__ src1, const scale2x_uint32* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 8 bits.
|
||||
* The function is implemented in C.
|
||||
* The pixels over the left and right borders are assumed of the same color of
|
||||
* the pixels on the border.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
scale2x_8_def_single(dst0, src0, src1, src2, count);
|
||||
scale2x_8_def_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 16 bits.
|
||||
* This function operates like scale2x_8_def() but for 16 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
scale2x_16_def_single(dst0, src0, src1, src2, count);
|
||||
scale2x_16_def_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 32 bits.
|
||||
* This function operates like scale2x_8_def() but for 32 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
scale2x_32_def_single(dst0, src0, src1, src2, count);
|
||||
scale2x_32_def_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Scale2x MMX implementation */
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
/*
|
||||
* Apply the Scale2x effect at a single row.
|
||||
* This function must be called only by the other scale2x functions.
|
||||
*
|
||||
* Considering the pixel map :
|
||||
*
|
||||
* ABC (src0)
|
||||
* DEF (src1)
|
||||
* GHI (src2)
|
||||
*
|
||||
* this functions compute 2 new pixels in substitution of the source pixel E
|
||||
* like this map :
|
||||
*
|
||||
* ab (dst)
|
||||
*
|
||||
* with these variables :
|
||||
*
|
||||
* ¤t -> E
|
||||
* ¤t_left -> D
|
||||
* ¤t_right -> F
|
||||
* ¤t_upper -> B
|
||||
* ¤t_lower -> H
|
||||
*
|
||||
* %0 -> current_upper
|
||||
* %1 -> current
|
||||
* %2 -> current_lower
|
||||
* %3 -> dst
|
||||
* %4 -> counter
|
||||
*
|
||||
* %mm0 -> *current_left
|
||||
* %mm1 -> *current_next
|
||||
* %mm2 -> tmp0
|
||||
* %mm3 -> tmp1
|
||||
* %mm4 -> tmp2
|
||||
* %mm5 -> tmp3
|
||||
* %mm6 -> *current_upper
|
||||
* %mm7 -> *current
|
||||
*/
|
||||
static inline void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 16);
|
||||
assert(count % 8 == 0);
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* central runs */
|
||||
"shrl $3, %4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psrlq $56, %%mm0\n"
|
||||
"psllq $56, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $8, %%mm2\n"
|
||||
"psrlq $8, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqb %%mm6, %%mm2\n"
|
||||
"pcmpeqb %%mm6, %%mm4\n"
|
||||
"pcmpeqb (%2), %%mm3\n"
|
||||
"pcmpeqb (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqb %%mm1, %%mm2\n"
|
||||
"pcmpeqb %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklbw %%mm4, %%mm2\n"
|
||||
"punpckhbw %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void scale2x_16_mmx_single(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 8);
|
||||
assert(count % 4 == 0);
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* central runs */
|
||||
"shrl $2, %4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psrlq $48, %%mm0\n"
|
||||
"psllq $48, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $16, %%mm2\n"
|
||||
"psrlq $16, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqw %%mm6, %%mm2\n"
|
||||
"pcmpeqw %%mm6, %%mm4\n"
|
||||
"pcmpeqw (%2), %%mm3\n"
|
||||
"pcmpeqw (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqw %%mm1, %%mm2\n"
|
||||
"pcmpeqw %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklwd %%mm4, %%mm2\n"
|
||||
"punpckhwd %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void scale2x_32_mmx_single(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 4);
|
||||
assert(count % 2 == 0);
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* central runs */
|
||||
"shrl $1, %4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psrlq $32, %%mm0\n"
|
||||
"psllq $32, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $32, %%mm2\n"
|
||||
"psrlq $32, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqd %%mm6, %%mm2\n"
|
||||
"pcmpeqd %%mm6, %%mm4\n"
|
||||
"pcmpeqd (%2), %%mm3\n"
|
||||
"pcmpeqd (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqd %%mm1, %%mm2\n"
|
||||
"pcmpeqd %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpckldq %%mm4, %%mm2\n"
|
||||
"punpckhdq %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 8 bits.
|
||||
* This is a very fast MMX implementation.
|
||||
* The implementation uses a combination of cmp/and/not operations to
|
||||
* completly remove the need of conditional jumps. This trick give the
|
||||
* major speed improvement.
|
||||
* Also, using the 8 bytes MMX registers more than one pixel are computed
|
||||
* at the same time.
|
||||
* Before calling this function you must ensure that the currenct CPU supports
|
||||
* the MMX instruction set. After calling it you must be sure to call the EMMS
|
||||
* instruction before any floating-point operation.
|
||||
* The pixels over the left and right borders are assumed of the same color of
|
||||
* the pixels on the border.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||
* be at least 16 and a multiple of 8.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
if (count % 8 != 0 || count < 16) {
|
||||
scale2x_8_def(dst0, dst1, src0, src1, src2, count);
|
||||
} else {
|
||||
assert(count >= 16);
|
||||
assert(count % 8 == 0);
|
||||
|
||||
scale2x_8_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_8_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 16 bits.
|
||||
* This function operates like scale2x_8_mmx() but for 16 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||
* be at least 8 and a multiple of 4.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
if (count % 4 != 0 || count < 8) {
|
||||
scale2x_16_def(dst0, dst1, src0, src1, src2, count);
|
||||
} else {
|
||||
assert(count >= 8);
|
||||
assert(count % 4 == 0);
|
||||
|
||||
scale2x_16_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_16_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 32 bits.
|
||||
* This function operates like scale2x_8_mmx() but for 32 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||
* be at least 4 and a multiple of 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
if (count % 2 != 0 || count < 4) {
|
||||
scale2x_32_def(dst0, dst1, src0, src1, src2, count);
|
||||
} else {
|
||||
assert(count >= 4);
|
||||
assert(count % 2 == 0);
|
||||
|
||||
scale2x_32_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_32_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,77 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scale2x.hxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SCALE2X_H
|
||||
#define __SCALE2X_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define __restrict__
|
||||
#endif
|
||||
|
||||
typedef unsigned char scale2x_uint8;
|
||||
typedef unsigned short scale2x_uint16;
|
||||
typedef unsigned scale2x_uint32;
|
||||
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
|
||||
/**
|
||||
* End the use of the MMX instructions.
|
||||
* This function must be called before using any floating-point operations.
|
||||
*/
|
||||
static inline void scale2x_mmx_emms(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"emms"
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scale3x.cxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains a C and MMX implementation of the Scale2x effect.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
//#include "common/stdafx.h"
|
||||
#include "compat.hxx"
|
||||
#include "intern.hxx"
|
||||
#include "scale3x.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* Scale3x C implementation */
|
||||
|
||||
static inline void scale3x_8_def_border(scale3x_uint8* __restrict__ dst, const scale3x_uint8* __restrict__ src0, const scale3x_uint8* __restrict__ src1, const scale3x_uint8* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_8_def_center(scale3x_uint8* __restrict__ dst, const scale3x_uint8* __restrict__ src0, const scale3x_uint8* __restrict__ src1, const scale3x_uint8* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_16_def_border(scale3x_uint16* __restrict__ dst, const scale3x_uint16* __restrict__ src0, const scale3x_uint16* __restrict__ src1, const scale3x_uint16* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_16_def_center(scale3x_uint16* __restrict__ dst, const scale3x_uint16* __restrict__ src0, const scale3x_uint16* __restrict__ src1, const scale3x_uint16* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_32_def_border(scale3x_uint32* __restrict__ dst, const scale3x_uint32* __restrict__ src0, const scale3x_uint32* __restrict__ src1, const scale3x_uint32* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scale3x_32_def_center(scale3x_uint32* __restrict__ dst, const scale3x_uint32* __restrict__ src0, const scale3x_uint32* __restrict__ src1, const scale3x_uint32* __restrict__ src2, unsigned count)
|
||||
{
|
||||
/* central pixels */
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 3 a row of pixels of 8 bits.
|
||||
* The function is implemented in C.
|
||||
* The pixels over the left and right borders are assumed of the same color of
|
||||
* the pixels on the border.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, triple length in pixels.
|
||||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||
{
|
||||
scale3x_8_def_border(dst0, src0, src1, src2, count);
|
||||
scale3x_8_def_center(dst1, src0, src1, src2, count);
|
||||
scale3x_8_def_border(dst2, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 3 a row of pixels of 16 bits.
|
||||
* This function operates like scale3x_8_def() but for 16 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, triple length in pixels.
|
||||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||
{
|
||||
scale3x_16_def_border(dst0, src0, src1, src2, count);
|
||||
scale3x_16_def_center(dst1, src0, src1, src2, count);
|
||||
scale3x_16_def_border(dst2, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 3 a row of pixels of 32 bits.
|
||||
* This function operates like scale3x_8_def() but for 32 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, triple length in pixels.
|
||||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||
{
|
||||
scale3x_32_def_border(dst0, src0, src1, src2, count);
|
||||
scale3x_32_def_center(dst1, src0, src1, src2, count);
|
||||
scale3x_32_def_border(dst2, src2, src1, src0, count);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scale3x.hxx,v 1.1 2006-10-22 18:58:45 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SCALE3X_H
|
||||
#define __SCALE3X_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define __restrict__
|
||||
#endif
|
||||
|
||||
typedef unsigned char scale3x_uint8;
|
||||
typedef unsigned short scale3x_uint16;
|
||||
typedef unsigned scale3x_uint32;
|
||||
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,374 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scalebit.cxx,v 1.1 2006-10-22 18:58:46 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2003 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains an example implementation of the Scale effect
|
||||
* applyed to a generic bitmap.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
//#include "common/stdafx.h"
|
||||
#include "compat.hxx"
|
||||
#include "intern.hxx"
|
||||
#include "scale2x.hxx"
|
||||
#include "scale3x.hxx"
|
||||
|
||||
#if defined(HAVE_ALLOCA_H)
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DST(bits, num) (scale2x_uint ## bits *)dst ## num
|
||||
#define SRC(bits, num) (const scale2x_uint ## bits *)src ## num
|
||||
|
||||
/**
|
||||
* Apply the Scale2x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
case 1 : scale2x_8_mmx(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale2x_16_mmx(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale2x_32_mmx(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
|
||||
#else
|
||||
case 1 : scale2x_8_def(DST(8,0), DST(8,1), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale2x_16_def(DST(16,0), DST(16,1), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale2x_32_def(DST(32,0), DST(32,1), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale3x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
case 1 : scale3x_8_def(DST(8,0), DST(8,1), DST(8,2), SRC(8,0), SRC(8,1), SRC(8,2), pixel_per_row); break;
|
||||
case 2 : scale3x_16_def(DST(16,0), DST(16,1), DST(16,2), SRC(16,0), SRC(16,1), SRC(16,2), pixel_per_row); break;
|
||||
case 4 : scale3x_32_def(DST(32,0), DST(32,1), DST(32,2), SRC(32,0), SRC(32,1), SRC(32,2), pixel_per_row); break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
|
||||
stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
|
||||
}
|
||||
|
||||
#define SCDST(i) (dst+(i)*dst_slice)
|
||||
#define SCSRC(i) (src+(i)*src_slice)
|
||||
#define SCMID(i) (mid[(i)])
|
||||
|
||||
/**
|
||||
* Apply the Scale2x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 2x2 times the size of the source bitmap.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
unsigned count;
|
||||
|
||||
assert(height >= 2);
|
||||
|
||||
count = height;
|
||||
|
||||
while (count) {
|
||||
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(2);
|
||||
src = SCSRC(1);
|
||||
|
||||
--count;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
scale2x_mmx_emms();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale32x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 3x3 times the size of the source bitmap.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
unsigned count;
|
||||
|
||||
assert(height >= 2);
|
||||
|
||||
count = height;
|
||||
|
||||
while (count) {
|
||||
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(3);
|
||||
src = SCSRC(1);
|
||||
|
||||
--count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
|
||||
* \note This function requires also a small buffer bitmap used internally to store
|
||||
* intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
|
||||
* and a vertical size of 6 rows. The memory of this buffer must not be allocated
|
||||
* in video memory because it's also read and not only written. Generally
|
||||
* a heap (malloc) or a stack (alloca) buffer is the best choices.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_mid Pointer at the first pixel of the buffer bitmap.
|
||||
* \param mid_slice Size in bytes of a buffer bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (const unsigned char*)void_src;
|
||||
unsigned count;
|
||||
unsigned char* mid[6];
|
||||
|
||||
assert(height >= 4);
|
||||
|
||||
count = height;
|
||||
|
||||
/* set the 6 buffer pointers */
|
||||
mid[0] = (unsigned char*)void_mid;
|
||||
mid[1] = mid[0] + mid_slice;
|
||||
mid[2] = mid[1] + mid_slice;
|
||||
mid[3] = mid[2] + mid_slice;
|
||||
mid[4] = mid[3] + mid_slice;
|
||||
mid[5] = mid[4] + mid_slice;
|
||||
|
||||
while (count) {
|
||||
unsigned char* tmp;
|
||||
|
||||
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
|
||||
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
|
||||
|
||||
dst = SCDST(4);
|
||||
src = SCSRC(1);
|
||||
|
||||
tmp = SCMID(0); /* shift by 2 position */
|
||||
SCMID(0) = SCMID(2);
|
||||
SCMID(2) = SCMID(4);
|
||||
SCMID(4) = tmp;
|
||||
tmp = SCMID(1);
|
||||
SCMID(1) = SCMID(3);
|
||||
SCMID(3) = SCMID(5);
|
||||
SCMID(5) = tmp;
|
||||
|
||||
--count;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
scale2x_mmx_emms();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
|
||||
* \note This function operates like ::scale4x_buf() but the intermediate buffer is
|
||||
* automatically allocated in the stack.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned mid_slice;
|
||||
void* mid;
|
||||
|
||||
mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
|
||||
|
||||
mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
|
||||
|
||||
#if defined(HAVE_ALLOCA)
|
||||
mid = alloca(6 * mid_slice); /* allocate space for 6 row buffers */
|
||||
|
||||
assert(mid != 0); /* alloca should never fails */
|
||||
#else
|
||||
mid = malloc(6 * mid_slice); /* allocate space for 6 row buffers */
|
||||
|
||||
if (!mid)
|
||||
return;
|
||||
#endif
|
||||
|
||||
scale4x_buf(void_dst, dst_slice, mid, mid_slice, void_src, src_slice, pixel, width, height);
|
||||
|
||||
#if !defined(HAVE_ALLOCA)
|
||||
free(mid);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the scale implementation is applicable at the given arguments.
|
||||
* \param scale Scale factor. 2, 3 or 4.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
* \return
|
||||
* - -1 on precondition violated.
|
||||
* - 0 on success.
|
||||
*/
|
||||
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
if (scale != 2 && scale != 3 && scale != 4)
|
||||
return -1;
|
||||
|
||||
if (pixel != 1 && pixel != 2 && pixel != 4)
|
||||
return -1;
|
||||
|
||||
switch (scale) {
|
||||
case 2 :
|
||||
case 3 :
|
||||
if (height < 2)
|
||||
return -1;
|
||||
break;
|
||||
case 4 :
|
||||
if (height < 4)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
switch (scale) {
|
||||
case 2 :
|
||||
case 4 :
|
||||
if (width < (16 / pixel))
|
||||
return -1;
|
||||
if (width % (8 / pixel) != 0)
|
||||
return -1;
|
||||
break;
|
||||
case 3 :
|
||||
if (width < 2)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (width < 2)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale effect on a bitmap.
|
||||
* This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
|
||||
* \param scale Scale factor. 2, 3 or 4.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
switch (scale) {
|
||||
case 2 :
|
||||
scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
break;
|
||||
case 3 :
|
||||
scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
break;
|
||||
case 4 :
|
||||
scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scalebit.hxx,v 1.1 2006-10-22 18:58:46 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2003 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains an example implementation of the Scale effect
|
||||
* applyed to a generic bitmap.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
#ifndef __SCALEBIT_H
|
||||
#define __SCALEBIT_H
|
||||
|
||||
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,131 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scaler.cxx,v 1.1 2006-10-22 18:58:46 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#include "intern.hxx"
|
||||
#include "scalebit.hxx"
|
||||
#include "scaler.hxx"
|
||||
|
||||
|
||||
int gBitFormat = 565;
|
||||
|
||||
// RGB-to-YUV lookup table
|
||||
extern "C" {
|
||||
|
||||
#ifdef USE_NASM
|
||||
// NOTE: if your compiler uses different mangled names, add another
|
||||
// condition here
|
||||
|
||||
#if !defined(_WIN32) && !defined(MACOSX)
|
||||
#define RGBtoYUV _RGBtoYUV
|
||||
#define LUT16to32 _LUT16to32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// FIXME/TODO: The following two tables suck up 512 KB. This is bad.
|
||||
// In addition we never free them...
|
||||
//
|
||||
// Note: a memory lookup table is *not* necessarily faster than computing
|
||||
// these things on the fly, because of its size. Both tables together, plus
|
||||
// the code, plus the input/output GFX data, won't fit in the cache on many
|
||||
// systems, so main memory has to be accessed, which is about the worst thing
|
||||
// that can happen to code which tries to be fast...
|
||||
//
|
||||
// So we should think about ways to get these smaller / removed. The LUT16to32
|
||||
// is only used by the HQX asm right now; maybe somebody can modify the code
|
||||
// there to work w/o it (and do some benchmarking, too?). To do that, just
|
||||
// do the conversion on the fly, or even do w/o it (as the C++ code manages to),
|
||||
// by making different versions of the code based on gBitFormat (or by writing
|
||||
// bit masks into registers which are computed based on gBitFormat).
|
||||
//
|
||||
// RGBtoYUV is also used by the C(++) version of the HQX code. Maybe we can
|
||||
// use the same technique which is employed by our MPEG code to reduce the
|
||||
// size of the lookup tables at the cost of some additional computations? That
|
||||
// might actually result in a speedup, too, if done right (and the code code
|
||||
// might actually be suitable for AltiVec/MMX/SSE speedup).
|
||||
//
|
||||
// Of course, the above is largely a conjecture, and the actual speed
|
||||
// differences are likely to vary a lot between different architectures and
|
||||
// CPUs.
|
||||
uint32 *RGBtoYUV = 0;
|
||||
uint32 *LUT16to32 = 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void InitLUT() {
|
||||
int r, g, b;
|
||||
int Y, u, v;
|
||||
|
||||
assert(T::kBytesPerPixel == 2);
|
||||
|
||||
// Allocate the YUV/LUT buffers on the fly if needed.
|
||||
if (RGBtoYUV == 0)
|
||||
RGBtoYUV = (uint32 *)malloc(65536 * sizeof(uint32));
|
||||
if (LUT16to32 == 0)
|
||||
LUT16to32 = (uint32 *)malloc(65536 * sizeof(uint32));
|
||||
|
||||
for (int color = 0; color < 65536; ++color) {
|
||||
r = ((color & T::kRedMask) >> T::kRedShift) << (8 - T::kRedBits);
|
||||
g = ((color & T::kGreenMask) >> T::kGreenShift) << (8 - T::kGreenBits);
|
||||
b = ((color & T::kBlueMask) >> T::kBlueShift) << (8 - T::kBlueBits);
|
||||
LUT16to32[color] = (r << 16) | (g << 8) | b;
|
||||
|
||||
Y = (r + g + b) >> 2;
|
||||
u = 128 + ((r - b) >> 2);
|
||||
v = 128 + ((-r + 2 * g - b) >> 3);
|
||||
RGBtoYUV[color] = (Y << 16) | (u << 8) | v;
|
||||
}
|
||||
}
|
||||
|
||||
/** Always use 16-bit, since OpenGL will always use it */
|
||||
void InitScalers() {
|
||||
InitLUT<ColorMasks<565> >();
|
||||
}
|
||||
|
||||
void FreeScalers() {
|
||||
if (RGBtoYUV != 0) {
|
||||
free(RGBtoYUV);
|
||||
RGBtoYUV = 0;
|
||||
}
|
||||
if (LUT16to32 != 0)
|
||||
{
|
||||
free(LUT16to32);
|
||||
LUT16to32 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Scale2x filter, also known as AdvMame2x.
|
||||
* See also http://scale2x.sourceforge.net
|
||||
*/
|
||||
void AdvMame2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
|
||||
int width, int height) {
|
||||
scale(2, dstPtr, dstPitch, srcPtr - srcPitch, srcPitch, 2, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Scale3x filter, also known as AdvMame3x.
|
||||
* See also http://scale2x.sourceforge.net
|
||||
*/
|
||||
void AdvMame3x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
|
||||
int width, int height) {
|
||||
scale(3, dstPtr, dstPitch, srcPtr - srcPitch, srcPitch, 2, width, height);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: scaler.hxx,v 1.1 2006-10-22 18:58:46 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2001-2006 The ScummVM project
|
||||
//============================================================================
|
||||
|
||||
#ifndef GRAPHICS_SCALER_H
|
||||
#define GRAPHICS_SCALER_H
|
||||
|
||||
//#include "common/stdafx.h"
|
||||
#include "compat.hxx"
|
||||
//#include "graphics/surface.h"
|
||||
|
||||
extern void InitScalers();
|
||||
extern void FreeScalers();
|
||||
|
||||
typedef void ScalerProc(const uint8 *srcPtr, uint32 srcPitch,
|
||||
uint8 *dstPtr, uint32 dstPitch,
|
||||
int width, int height);
|
||||
|
||||
#define DECLARE_SCALER(x) \
|
||||
extern void x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, \
|
||||
uint32 dstPitch, int width, int height)
|
||||
|
||||
DECLARE_SCALER(AdvMame2x);
|
||||
DECLARE_SCALER(AdvMame3x);
|
||||
DECLARE_SCALER(HQ2x);
|
||||
DECLARE_SCALER(HQ3x);
|
||||
|
||||
#endif
|
|
@ -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: Console.cxx,v 1.95 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: Console.cxx,v 1.96 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -64,7 +64,8 @@
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Console::Console(const uInt8* image, uInt32 size, const string& md5,
|
||||
OSystem* osystem)
|
||||
: myOSystem(osystem)
|
||||
: myOSystem(osystem),
|
||||
myIsInitializedFlag(false)
|
||||
{
|
||||
myControllers[0] = 0;
|
||||
myControllers[1] = 0;
|
||||
|
@ -434,14 +435,13 @@ void Console::initialize()
|
|||
myOSystem->debugger().setConsole(this);
|
||||
myOSystem->debugger().initialize();
|
||||
#endif
|
||||
|
||||
myIsInitializedFlag = true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Console::initializeVideo()
|
||||
{
|
||||
cerr << " ==> Console::initializeVideo(): w = " << (myMediaSource->width() << 1)
|
||||
<< ", h = " << myMediaSource->height() << endl;
|
||||
|
||||
string title = string("Stella ") + STELLA_VERSION +
|
||||
": \"" + myProperties.get(Cartridge_Name) + "\"";
|
||||
myOSystem->frameBuffer().initialize(title,
|
||||
|
|
|
@ -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: Console.hxx,v 1.46 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: Console.hxx,v 1.47 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef CONSOLE_HXX
|
||||
|
@ -38,7 +38,7 @@ class System;
|
|||
This class represents the entire game console.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: Console.hxx,v 1.46 2006-10-16 01:08:59 stephena Exp $
|
||||
@version $Id: Console.hxx,v 1.47 2006-10-22 18:58:46 stephena Exp $
|
||||
*/
|
||||
class Console
|
||||
{
|
||||
|
@ -168,6 +168,11 @@ class Console
|
|||
*/
|
||||
void initialize();
|
||||
|
||||
/**
|
||||
Determine whether the console was successfully initialized
|
||||
*/
|
||||
bool isInitialized() { return myIsInitializedFlag; }
|
||||
|
||||
/**
|
||||
Initialize the video subsystem wrt this class.
|
||||
*/
|
||||
|
@ -279,6 +284,10 @@ class Console
|
|||
#ifdef ATARIVOX_SUPPORT
|
||||
AtariVox *vox;
|
||||
#endif
|
||||
|
||||
// Indicates whether the console was correctly initialized
|
||||
// We don't really care why it wasn't initialized ...
|
||||
bool myIsInitializedFlag;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1941,7 +1941,7 @@ static const char* DefProps[][21] = {
|
|||
{ "e558be88eef569f33716e8e330d2f5bc", "", "", "Keystone Kapers (Shock Vision) [!]", "", "", "", "", "", "", "", "", "", "", "", "8", "152", "39", "200", "", "" },
|
||||
{ "e5d5085123a98c1e61818caa2971e999", "", "", "Euchre (PAL) (Erik Eid) (PD)", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "", "", "", "" },
|
||||
{ "e5ecd78edd24326a968809decbc7b916", "", "", "Cheese 98 (Dragonfire Hack)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "e600f5e98a20fafa47676198efe6834d", "", "", "Gyruss (1984) (Parker Bros) (PAL) [!]", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Yes", "" },
|
||||
{ "e600f5e98a20fafa47676198efe6834d", "", "", "Gyruss (1984) (Parker Bros) (PAL) [!]", "", "", "", "E0", "", "", "", "", "", "", "PAL", "", "", "", "250", "YES", "" },
|
||||
{ "e63a87c231ee9a506f9599aa4ef7dfb9", "Tigervision", "7-003", "Threshold (1982) (Tigervision)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "22", "", "", "" },
|
||||
{ "e64a8008812327853877a37befeb6465", "", "ASC1002", "Gauntlet (1983) (Answer Software)", "", "Unbelievably Rare", "", "", "", "", "", "", "", "", "", "8", "152", "35", "201", "", "" },
|
||||
{ "e6de4ef9ab62e2196962aa6b0dedac59", "Imagic", "O3206", "Solar Storm (1983) (Imagic) (PAL) [!]", "Uses the Paddle Controllers", "Rare", "", "4K", "", "", "", "", "Paddles", "Paddles", "PAL", "8", "144", "64", "194", "", "" },
|
||||
|
@ -3185,7 +3185,7 @@ static const char* DefProps[][21] = {
|
|||
{ "8b556c3d9ca8e5e6e665bd759b93ffae", "", "", "Synthcart (2002) (Paul Slocum) (PAL) [!]", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "55", "250", "Yes", "" },
|
||||
{ "8b7ca29a55432f886cee3d452fb00481", "Starpath", "AR-4201", "Sword of Saros (1983) (Starpath) (PAL)", "", "Extremely Rare", "", "AR", "", "", "", "", "", "", "PAL", "8", "144", "60", "200", "", "" },
|
||||
{ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "8bc0d2052b4f259e7a50a7c771b45241", "Xonox", "", "Tomarc the Barbarian (1983) (Xonox)", "", "Rare", "", "FE", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "8bc0d2052b4f259e7a50a7c771b45241", "Xonox", "", "Tomarc the Barbarian (1983) (Xonox)", "", "Rare", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "8bebac614571135933116045204f0f00", "", "", "Missile Command (CX-22 Trackball) (PAL) (2002) (TJ)", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "40", "256", "Yes", "" },
|
||||
{ "8c136e97c0a4af66da4a249561ed17db", "", "", "Poker Squares (V0.27) (2001) (B. Watson)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },
|
||||
{ "8c36ed2352801031516695d1eeefe617", "Epyx", "", "Winter Games (1987) (Epyx) (PAL) [!]", "", "", "", "", "", "", "", "", "", "", "PAL", "", "", "56", "", "", "" },
|
||||
|
|
|
@ -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: EventHandler.cxx,v 1.165 2006-10-14 20:08:29 stephena Exp $
|
||||
// $Id: EventHandler.cxx,v 1.166 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -74,9 +74,6 @@ EventHandler::EventHandler(OSystem* osystem)
|
|||
{
|
||||
int i, j, k, m;
|
||||
|
||||
// Add this eventhandler object to the OSystem
|
||||
myOSystem->attach(this);
|
||||
|
||||
// Create the streamer used for accessing eventstreams/recordings
|
||||
myEventStreamer = new EventStreamer(myOSystem);
|
||||
|
||||
|
@ -220,7 +217,9 @@ void EventHandler::pause(bool status)
|
|||
{
|
||||
myPauseFlag = status;
|
||||
|
||||
if(&myOSystem->frameBuffer())
|
||||
myOSystem->frameBuffer().pause(myPauseFlag);
|
||||
if(&myOSystem->sound())
|
||||
myOSystem->sound().mute(myPauseFlag);
|
||||
|
||||
// Inform the OSystem of the change in pause
|
||||
|
@ -234,16 +233,19 @@ void EventHandler::setupJoysticks()
|
|||
|
||||
#ifdef JOYSTICK_SUPPORT
|
||||
// Keep track of how many Stelladaptors we've found
|
||||
uInt8 saCount = 0;
|
||||
int saCount = 0;
|
||||
|
||||
// First clear the joystick array
|
||||
for(uInt32 i = 0; i < kNumJoysticks; i++)
|
||||
// First clear the joystick array, closing previously opened sticks
|
||||
for(int i = 0; i < kNumJoysticks; i++)
|
||||
{
|
||||
if(ourJoysticks[i].stick && SDL_JoystickOpened(i))
|
||||
SDL_JoystickClose(ourJoysticks[i].stick);
|
||||
|
||||
ourJoysticks[i].stick = (SDL_Joystick*) NULL;
|
||||
ourJoysticks[i].type = JT_NONE;
|
||||
}
|
||||
|
||||
// Initialize the joystick subsystem
|
||||
// (Re)-Initialize the joystick subsystem
|
||||
if(showinfo)
|
||||
cout << "Joystick devices found:" << endl;
|
||||
if((SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) || (SDL_NumJoysticks() <= 0))
|
||||
|
|
|
@ -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: FrameBuffer.cxx,v 1.93 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: FrameBuffer.cxx,v 1.94 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -301,24 +301,16 @@ inline void FrameBuffer::drawMessage()
|
|||
|
||||
// Either erase the entire message (when time is reached),
|
||||
// or show again this frame
|
||||
if(myMessage.counter == 0)
|
||||
{
|
||||
// Force an immediate update
|
||||
if(myMessage.counter == 0) // Force an immediate update
|
||||
myOSystem->eventHandler().refreshDisplay(true);
|
||||
}
|
||||
/* FIXME ?? - this sometimes causes a crash when switching from
|
||||
bigger to smaller launcher windows and showing a message
|
||||
I'm sure there's a bug somewhere, but this code no longer
|
||||
seems to be needed, so I may just delete it at some point ...
|
||||
else
|
||||
addDirtyRect(myMessage.x, myMessage.y, myMessage.w, myMessage.h);
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::pause(bool status)
|
||||
{
|
||||
if(&myOSystem->console())
|
||||
if(&myOSystem->console() && myOSystem->console().isInitialized())
|
||||
{
|
||||
enablePhosphor(myOSystem->console().properties().get(Display_Phosphor) == "YES");
|
||||
setPalette(myOSystem->console().mediaSource().palette());
|
||||
|
@ -726,12 +718,6 @@ void FrameBuffer::setAvailableScalers()
|
|||
state == EventHandler::S_MENU ||
|
||||
state == EventHandler::S_CMDMENU);
|
||||
|
||||
cerr << " ====> setAvailableScalers() <====" << endl << endl
|
||||
<< "TIA mode: " << (inTIAMode ? "yes" : "no") << ", state: " << state << endl
|
||||
<< "maxsize: " << maxsize << endl
|
||||
<< "type: " << (type() == kSoftBuffer ? "soft buffer" : "GL buffer") << endl
|
||||
<< endl;
|
||||
|
||||
// Next, determine which mode we're in and update the appropriate scaler list
|
||||
if(type() == kSoftBuffer)
|
||||
{
|
||||
|
@ -752,9 +738,15 @@ void FrameBuffer::setAvailableScalers()
|
|||
{
|
||||
if(inTIAMode)
|
||||
{
|
||||
#ifdef SCALER_SUPPORT
|
||||
for(int i = 0; i < kTIAScalerListSize; ++i)
|
||||
if(ourTIAScalers[i].scale <= maxsize && ourTIAScalers[i].zoom <= maxsize)
|
||||
ourTIAScalers[i].available = true;
|
||||
#else
|
||||
for(int i = 0; i < kTIAScalerListSize; ++i)
|
||||
if(ourTIAScalers[i].scale == 1 && ourTIAScalers[i].zoom <= maxsize)
|
||||
ourTIAScalers[i].available = true;
|
||||
#endif
|
||||
}
|
||||
else // UI mode
|
||||
{
|
||||
|
@ -763,15 +755,6 @@ void FrameBuffer::setAvailableScalers()
|
|||
ourUIScalers[i].available = true;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "UI Scalers available:\n";
|
||||
for(int i = 0; i < kUIScalerListSize; ++i)
|
||||
if(ourUIScalers[i].available)
|
||||
cerr << ourUIScalers[i].name << endl;
|
||||
for(int i = 0; i < kTIAScalerListSize; ++i)
|
||||
if(ourTIAScalers[i].available)
|
||||
cerr << ourTIAScalers[i].name << endl;
|
||||
cerr << " =================================" << endl << endl;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -789,7 +772,6 @@ void FrameBuffer::getScaler(Scaler& scaler, int direction, const string& name)
|
|||
switch(direction)
|
||||
{
|
||||
case 0: // search for the actual scaler specified in 'name'
|
||||
cerr << "get scaler = " << name << endl;
|
||||
for(int i = 0; i < size; ++i)
|
||||
{
|
||||
if(list[i].name == name && list[i].available)
|
||||
|
@ -924,9 +906,7 @@ Scaler FrameBuffer::ourTIAScalers[kTIAScalerListSize] = {
|
|||
|
||||
{ kSCALE2X, "Scale2x", 1, 2, false },
|
||||
{ kSCALE3X, "Scale3x", 1, 3, false },
|
||||
{ kSCALE4X, "Scale4x", 1, 4, false },
|
||||
|
||||
{ kHQ2X, "HQ2x", 1, 2, false },
|
||||
{ kHQ3X, "HQ3x", 1, 3, false },
|
||||
{ kHQ4X, "HQ4x", 1, 4, false }
|
||||
};
|
||||
|
|
|
@ -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: FrameBuffer.hxx,v 1.72 2006-10-16 01:08:59 stephena Exp $
|
||||
// $Id: FrameBuffer.hxx,v 1.73 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef FRAMEBUFFER_HXX
|
||||
|
@ -96,7 +96,7 @@ struct Scaler {
|
|||
All GUI elements (ala ScummVM) are drawn here as well.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: FrameBuffer.hxx,v 1.72 2006-10-16 01:08:59 stephena Exp $
|
||||
@version $Id: FrameBuffer.hxx,v 1.73 2006-10-22 18:58:46 stephena Exp $
|
||||
*/
|
||||
class FrameBuffer
|
||||
{
|
||||
|
@ -138,7 +138,7 @@ class FrameBuffer
|
|||
*/
|
||||
void showMessage(const string& message,
|
||||
MessagePosition position = kBottomCenter,
|
||||
int color = kTextColor);
|
||||
int color = kTextColorHi);
|
||||
|
||||
/**
|
||||
Hides any onscreen messages.
|
||||
|
@ -566,7 +566,7 @@ class FrameBuffer
|
|||
// from using the more advanced scalers
|
||||
enum {
|
||||
kUIScalerListSize = 6,
|
||||
kTIAScalerListSize = 12
|
||||
kTIAScalerListSize = 10
|
||||
};
|
||||
static Scaler ourUIScalers[kUIScalerListSize];
|
||||
static Scaler ourTIAScalers[kTIAScalerListSize];
|
||||
|
|
|
@ -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: OSystem.cxx,v 1.72 2006-10-16 01:09:00 stephena Exp $
|
||||
// $Id: OSystem.cxx,v 1.73 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
@ -91,6 +91,9 @@ OSystem::~OSystem()
|
|||
#ifdef CHEATCODE_SUPPORT
|
||||
delete myCheatManager;
|
||||
#endif
|
||||
|
||||
delete myPropSet;
|
||||
delete myEventHandler;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -110,8 +113,20 @@ bool OSystem::create()
|
|||
#endif
|
||||
#ifdef CHEATCODE_SUPPORT
|
||||
myCheatManager = new CheatManager(this);
|
||||
myCheatManager->loadCheatDatabase();
|
||||
#endif
|
||||
|
||||
// Create the event handler for the system
|
||||
myEventHandler = new EventHandler(this);
|
||||
|
||||
// Create a properties set for us to use and set it up
|
||||
myPropSet = new PropertiesSet(this);
|
||||
|
||||
// Create the sound object; the sound subsystem isn't actually
|
||||
// opened until needed, so this is non-blocking (on those systems
|
||||
// that only have a single sound device (no hardware mixing)
|
||||
createSound();
|
||||
|
||||
// Determine which features were conditionally compiled into Stella
|
||||
#ifdef DISPLAY_OPENGL
|
||||
myFeatures += "OpenGL ";
|
||||
|
@ -214,6 +229,9 @@ bool OSystem::createFrameBuffer(bool showmessage)
|
|||
break;
|
||||
}
|
||||
|
||||
// Setup the SDL joysticks (must be done after FrameBuffer is created)
|
||||
myEventHandler->setupJoysticks();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -306,15 +324,17 @@ bool OSystem::createConsole(const string& romfile)
|
|||
#ifdef CHEATCODE_SUPPORT
|
||||
myCheatManager->loadCheats(md5);
|
||||
#endif
|
||||
setFramerate(60); // We need to set framerate to see messages
|
||||
myEventHandler->reset(EventHandler::S_EMULATE);
|
||||
createFrameBuffer(false);
|
||||
myFrameBuffer->setCursorState();
|
||||
myConsole->initialize(); // Must be done *after* the framebuffer is created
|
||||
|
||||
if(showmessage)
|
||||
myFrameBuffer->showMessage("New console created");
|
||||
if(mySettings->getBool("showinfo"))
|
||||
cout << "Game console created: " << myRomFile << endl;
|
||||
|
||||
myEventHandler->reset(EventHandler::S_EMULATE);
|
||||
createFrameBuffer(false);
|
||||
myFrameBuffer->setCursorState();
|
||||
myConsole->initialize(); // Must be done *after* the framebuffer is created
|
||||
retval = true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -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: OSystem.hxx,v 1.42 2006-03-27 12:52:19 stephena Exp $
|
||||
// $Id: OSystem.hxx,v 1.43 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef OSYSTEM_HXX
|
||||
|
@ -26,6 +26,7 @@ class CommandMenu;
|
|||
class Launcher;
|
||||
class Debugger;
|
||||
class CheatManager;
|
||||
class VideoDialog;
|
||||
|
||||
#include "EventHandler.hxx"
|
||||
#include "FrameBuffer.hxx"
|
||||
|
@ -44,10 +45,13 @@ class CheatManager;
|
|||
other objects belong.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: OSystem.hxx,v 1.42 2006-03-27 12:52:19 stephena Exp $
|
||||
@version $Id: OSystem.hxx,v 1.43 2006-10-22 18:58:46 stephena Exp $
|
||||
*/
|
||||
class OSystem
|
||||
{
|
||||
friend class EventHandler;
|
||||
friend class VideoDialog;
|
||||
|
||||
public:
|
||||
/**
|
||||
Create a new OSystem abstract class
|
||||
|
@ -65,13 +69,6 @@ class OSystem
|
|||
virtual bool create();
|
||||
|
||||
public:
|
||||
/**
|
||||
Adds the specified eventhandler to the system.
|
||||
|
||||
@param eventhandler The eventhandler to add
|
||||
*/
|
||||
void attach(EventHandler* eventhandler) { myEventHandler = eventhandler; }
|
||||
|
||||
/**
|
||||
Adds the specified settings object to the system.
|
||||
|
||||
|
@ -79,13 +76,6 @@ class OSystem
|
|||
*/
|
||||
void attach(Settings* settings) { mySettings = settings; }
|
||||
|
||||
/**
|
||||
Adds the specified game properties set to the system.
|
||||
|
||||
@param propset The properties set to add
|
||||
*/
|
||||
void attach(PropertiesSet* propset) { myPropSet = propset; }
|
||||
|
||||
/**
|
||||
Get the event handler of the system
|
||||
|
||||
|
@ -201,7 +191,7 @@ class OSystem
|
|||
|
||||
@return The video framerate currently in use
|
||||
*/
|
||||
uInt32 frameRate() const { return myDisplayFrameRate; }
|
||||
inline uInt32 frameRate() const { return myDisplayFrameRate; }
|
||||
|
||||
/**
|
||||
Return the default directory for storing data.
|
||||
|
@ -244,25 +234,11 @@ class OSystem
|
|||
*/
|
||||
const string& romFile() const { return myRomFile; }
|
||||
|
||||
/**
|
||||
Creates the various framebuffers/renderers available in this system
|
||||
(for now, that means either 'software' or 'opengl').
|
||||
|
||||
@return Success or failure of the framebuffer creation
|
||||
*/
|
||||
bool createFrameBuffer(bool showmessage = false);
|
||||
|
||||
/**
|
||||
Switches between software and OpenGL framebuffer modes.
|
||||
*/
|
||||
void toggleFrameBuffer();
|
||||
|
||||
/**
|
||||
Creates the various sound devices available in this system
|
||||
(for now, that means either 'SDL' or 'Null').
|
||||
*/
|
||||
void createSound();
|
||||
|
||||
/**
|
||||
Creates a new game console from the specified romfile.
|
||||
|
||||
|
@ -451,6 +427,20 @@ class OSystem
|
|||
GUI::Font* myConsoleFont;
|
||||
|
||||
private:
|
||||
/**
|
||||
Creates the various framebuffers/renderers available in this system
|
||||
(for now, that means either 'software' or 'opengl').
|
||||
|
||||
@return Success or failure of the framebuffer creation
|
||||
*/
|
||||
bool createFrameBuffer(bool showmessage = false);
|
||||
|
||||
/**
|
||||
Creates the various sound devices available in this system
|
||||
(for now, that means either 'SDL' or 'Null').
|
||||
*/
|
||||
void createSound();
|
||||
|
||||
// Copy constructor isn't supported by this class so make it private
|
||||
OSystem(const OSystem&);
|
||||
|
||||
|
|
|
@ -13,14 +13,17 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: PropsSet.cxx,v 1.22 2006-09-06 21:51:15 stephena Exp $
|
||||
// $Id: PropsSet.cxx,v 1.23 2006-10-22 18:58:46 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "GuiUtils.hxx"
|
||||
#include "DefProps.hxx"
|
||||
#include "Props.hxx"
|
||||
#include "PropsSet.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
PropertiesSet::PropertiesSet(OSystem* osystem)
|
||||
|
@ -28,6 +31,28 @@ PropertiesSet::PropertiesSet(OSystem* osystem)
|
|||
myRoot(NULL),
|
||||
mySize(0)
|
||||
{
|
||||
// Several properties files can exist, so we attempt to load from
|
||||
// all of them. If the user has specified a properties file, use
|
||||
// that one. Otherwise, load both the system and user properties
|
||||
// files, and have the user file override all entries from the
|
||||
// system file.
|
||||
ostringstream buf;
|
||||
|
||||
string altpro = myOSystem->settings().getString("pro");
|
||||
if(altpro != "")
|
||||
{
|
||||
buf << "User game properties: \'" << altpro << "\'\n";
|
||||
load(altpro, false); // don't save alternate properties
|
||||
}
|
||||
else
|
||||
{
|
||||
const string& props = myOSystem->propertiesFile();
|
||||
buf << "User game properties: \'" << props << "\'\n";
|
||||
load(props, true); // do save these properties
|
||||
}
|
||||
|
||||
if(myOSystem->settings().getBool("showinfo"))
|
||||
cout << buf.str() << endl;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -11524,7 +11524,6 @@
|
|||
"Cartridge.Name" "Tomarc the Barbarian (1983) (Xonox)"
|
||||
"Cartridge.Manufacturer" "Xonox"
|
||||
"Cartridge.Rarity" "Rare"
|
||||
"Cartridge.Type" "FE"
|
||||
""
|
||||
|
||||
"Cartridge.MD5" "8c136e97c0a4af66da4a249561ed17db"
|
||||
|
@ -18607,7 +18606,10 @@
|
|||
|
||||
"Cartridge.MD5" "e600f5e98a20fafa47676198efe6834d"
|
||||
"Cartridge.Name" "Gyruss (1984) (Parker Bros) (PAL) [!]"
|
||||
"Display.Phosphor" "Yes"
|
||||
"Cartridge.Type" "E0"
|
||||
"Display.Format" "PAL"
|
||||
"Display.Height" "250"
|
||||
"Display.Phosphor" "YES"
|
||||
""
|
||||
|
||||
"Cartridge.MD5" "e609e8a007127b8fcff79ffc380da6b1"
|
||||
|
|
Loading…
Reference in New Issue