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:
stephena 2006-10-22 18:58:46 +00:00
parent e3b36b202c
commit c7a073c6a2
33 changed files with 11486 additions and 232 deletions

74
stella/configure vendored
View File

@ -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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 :
*
* &current -> E
* &current_left -> D
* &current_right -> F
* &current_upper -> B
* &current_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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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,

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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

View File

@ -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", "", "", "" },

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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,8 +217,10 @@ void EventHandler::pause(bool status)
{
myPauseFlag = status;
myOSystem->frameBuffer().pause(myPauseFlag);
myOSystem->sound().mute(myPauseFlag);
if(&myOSystem->frameBuffer())
myOSystem->frameBuffer().pause(myPauseFlag);
if(&myOSystem->sound())
myOSystem->sound().mute(myPauseFlag);
// Inform the OSystem of the change in pause
myOSystem->pauseChanged(myPauseFlag);
@ -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))

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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 }
};

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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];

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: 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&);

View File

@ -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;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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"