Fixed missing code for 24bpp software rendering of fonts.

Fixed 24bpp rendering of fonts and mediasource; it wasn't endian-clean.

Completely removed advanced scaler stuff, since I don't see that I'll
ever have the time to develop/support it.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1283 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2007-01-15 00:07:52 +00:00
parent 7c3377f0fc
commit a2ec317329
21 changed files with 62 additions and 11269 deletions

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.85 2007-01-12 16:03:10 stephena Exp $
// $Id: FrameBufferGL.cxx,v 1.86 2007-01-15 00:07:51 stephena Exp $
//============================================================================
#ifdef DISPLAY_OPENGL
@ -231,8 +231,8 @@ bool FrameBufferGL::initSubsystem()
string FrameBufferGL::about()
{
string extensions;
if(myHaveTexRectEXT) extensions += "GL_TEXTURE_RECTANGLE_ARB ";
if(extensions == "") extensions = "None";
if(myHaveTexRectEXT) extensions += "GL_TEXTURE_RECTANGLE_ARB ";
if(extensions == "") extensions = "None";
ostringstream out;
out << "Video rendering: OpenGL mode" << endl

View File

@ -13,9 +13,10 @@
// 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.68 2007-01-01 18:04:40 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.69 2007-01-15 00:07:51 stephena Exp $
//============================================================================
#include <sstream>
#include <SDL.h>
#include "Console.hxx"
@ -67,7 +68,21 @@ bool FrameBufferSoft::initSubsystem()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrameBufferSoft::about()
{
return "Video rendering: Software mode\n";
ostringstream buf;
buf << "Video rendering: Software mode" << endl
<< " Color: " << (int)myFormat->BitsPerPixel << " bit" << endl
<< " Rmask = " << hex << setw(4) << (int)myFormat->Rmask
<< ", Rshift = "<< dec << setw(2) << (int)myFormat->Rshift
<< ", Rloss = " << dec << setw(2) << (int)myFormat->Rloss << endl
<< " Gmask = " << hex << setw(4) << (int)myFormat->Gmask
<< ", Gshift = "<< dec << setw(2) << (int)myFormat->Gshift
<< ", Gloss = " << dec << setw(2) << (int)myFormat->Gloss << endl
<< " Bmask = " << hex << setw(4) << (int)myFormat->Bmask
<< ", Bshift = "<< dec << setw(2) << (int)myFormat->Bshift
<< ", Bloss = " << dec << setw(2) << (int)myFormat->Bloss << endl;
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -114,6 +129,8 @@ bool FrameBufferSoft::createScreen()
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
return false;
}
myBytesPerPixel = myScreen->format->BytesPerPixel;
myFormat = myScreen->format;
// Make sure drawMediaSource() knows which renderer to use
stateChanged(myOSystem->eventHandler().state());
@ -353,9 +370,9 @@ void FrameBufferSoft::drawMediaSource()
if(v != w || theRedrawTIAIndicator)
{
uInt32 pixel = myDefPalette[v];
uInt8 r = pixel & 0xff;
uInt8 g = (pixel & 0xff00) >> 8;
uInt8 b = (pixel & 0xff0000) >> 16;
uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift;
uInt8 g = (pixel & myFormat->Gmask) >> myFormat->Gshift;
uInt8 b = (pixel & myFormat->Bmask) >> myFormat->Bshift;
while(xstride--)
{
@ -479,9 +496,9 @@ void FrameBufferSoft::drawMediaSource()
uInt8 v = currentFrame[bufofs];
uInt8 w = previousFrame[bufofs];
uInt32 pixel = myAvgPalette[v][w];
uInt8 r = pixel & 0xff;
uInt8 g = (pixel & 0xff00) >> 8;
uInt8 b = (pixel & 0xff0000) >> 16;
uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift;
uInt8 g = (pixel & myFormat->Gmask) >> myFormat->Gshift;
uInt8 b = (pixel & myFormat->Bmask) >> myFormat->Bshift;
while(xstride--)
{
@ -710,7 +727,37 @@ void FrameBufferSoft::drawChar(const GUI::Font* font, uInt8 chr,
}
case 3:
{
// TODO ...
// Get buffer position where upper-left pixel of the character will be drawn
uInt8* buffer = (uInt8*) myScreen->pixels + yorig * myPitch + xorig;
uInt32 pixel = myDefPalette[color];
uInt8 r = (pixel & myFormat->Rmask) >> myFormat->Rshift;
uInt8 g = (pixel & myFormat->Gmask) >> myFormat->Gshift;
uInt8 b = (pixel & myFormat->Bmask) >> myFormat->Bshift;
for(int y = h; y; --y)
{
const uInt16 fontbuf = *tmp++;
int ystride = myZoomLevel;
while(ystride--)
{
uInt16 mask = 0x8000;
int pos = screenofsY;
for(int x = 0; x < w; x++, mask >>= 1)
{
int xstride = myZoomLevel;
if((fontbuf & mask) != 0)
{
while(xstride--)
{
buffer[pos++] = r; buffer[pos++] = g; buffer[pos++] = b;
}
}
else
pos += xstride + xstride + xstride;
}
screenofsY += myPitch;
}
}
break;
}
case 4:
@ -826,7 +873,6 @@ void FrameBufferSoft::stateChanged(EventHandler::State state)
// Make sure drawMediaSource() knows which renderer to use
// Testing for dirty rects takes priority over phosphor mode,
// since phosphor mode only exists while emulating a ROM
myBytesPerPixel = myScreen->format->BytesPerPixel;
switch(myBytesPerPixel)
{
case 2: // 16-bit

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.hxx,v 1.44 2007-01-01 18:04:40 stephena Exp $
// $Id: FrameBufferSoft.hxx,v 1.45 2007-01-15 00:07:51 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX
@ -33,7 +33,7 @@ class RectList;
This class implements an SDL software framebuffer.
@author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.44 2007-01-01 18:04:40 stephena Exp $
@version $Id: FrameBufferSoft.hxx,v 1.45 2007-01-15 00:07:51 stephena Exp $
*/
class FrameBufferSoft : public FrameBuffer
{
@ -215,6 +215,7 @@ class FrameBufferSoft : public FrameBuffer
int myZoomLevel;
int myBytesPerPixel;
int myPitch;
SDL_PixelFormat* myFormat;
enum RenderType {
kDirtyRect,

View File

@ -1,251 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:40 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

@ -1,50 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:40 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

@ -1,104 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:40 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

@ -1,121 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,157 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,21 +0,0 @@
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

@ -1,538 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,77 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,256 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,57 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,374 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,63 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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

@ -1,132 +0,0 @@
//============================================================================
//
// 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-2007 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.4 2007-01-01 18:04:41 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2001-2006 The ScummVM project
//============================================================================
#include <assert.h>
#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

@ -1,45 +0,0 @@
//============================================================================
//
// 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-2007 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.3 2007-01-01 18:04:41 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