aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/main.cpp15
-rw-r--r--dists/msvc9/scummvm.vcproj10
-rw-r--r--graphics/VectorRenderer.cpp389
-rw-r--r--graphics/VectorRenderer.h344
-rw-r--r--graphics/module.mk3
5 files changed, 758 insertions, 3 deletions
diff --git a/base/main.cpp b/base/main.cpp
index 9129fcc7e1..a666110b83 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -43,7 +43,11 @@
#include "gui/newgui.h"
#include "gui/message.h"
-#if defined(_WIN32_WCE)
+#define _VECTOR_RENDERER_DBG 1
+
+#if defined(_VECTOR_RENDERER_DBG)
+#include "graphics/VectorRenderer.h"
+#elif defined(_WIN32_WCE)
#include "backends/platform/wince/CELauncherDialog.h"
#elif defined(__DC__)
#include "backends/platform/dc/DCLauncherDialog.h"
@@ -67,6 +71,13 @@ static bool launcherDialog(OSystem &system) {
// Clear the main screen
system.clearScreen();
+#if defined(_VECTOR_RENDERER_DBG)
+
+ Graphics::vector_renderer_test( &system );
+ return true;
+
+#else
+
#if defined(_WIN32_WCE)
CELauncherDialog dlg;
#elif defined(__DC__)
@@ -75,6 +86,8 @@ static bool launcherDialog(OSystem &system) {
GUI::LauncherDialog dlg;
#endif
return (dlg.runModal() != -1);
+
+#endif // vector renderer debug
}
static const Plugin *detectPlugin() {
diff --git a/dists/msvc9/scummvm.vcproj b/dists/msvc9/scummvm.vcproj
index afeafc3dd3..889ea04b75 100644
--- a/dists/msvc9/scummvm.vcproj
+++ b/dists/msvc9/scummvm.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="scummvm"
ProjectGUID="{8434CB15-D08F-427D-9E6D-581AE5B28440}"
RootNamespace="scummvm"
@@ -1300,6 +1300,14 @@
RelativePath="..\..\graphics\surface.h"
>
</File>
+ <File
+ RelativePath="..\..\graphics\VectorRenderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\graphics\VectorRenderer.h"
+ >
+ </File>
<Filter
Name="scaler"
>
diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp
new file mode 100644
index 0000000000..4a88eb94b4
--- /dev/null
+++ b/graphics/VectorRenderer.cpp
@@ -0,0 +1,389 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/util.h"
+#include "graphics/surface.h"
+#include "graphics/VectorRenderer.h"
+#include "graphics/colormasks.h"
+#include "common/system.h"
+#include "common/events.h"
+
+namespace Graphics {
+
+inline uint32 fp_sqroot(uint32 x);
+
+VectorRenderer *createRenderer() {
+ return new VectorRendererAA<uint16, ColorMasks<565> >;
+}
+
+
+void vector_renderer_test(OSystem *_system) {
+ Common::EventManager *eventMan = _system->getEventManager();
+
+ VectorRenderer *vr = createRenderer();
+
+ Surface _screen;
+ _screen.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
+
+ if (!_screen.pixels)
+ return;
+
+ _system->clearOverlay();
+ _system->grabOverlay((OverlayColor*)_screen.pixels, _screen.w);
+
+ vr->setSurface(&_screen);
+ vr->setColor(255, 0, 0);
+ vr->fillSurface();
+ vr->setColor(255, 255, 0);
+
+ _system->showOverlay();
+
+ while (true) { // draw!!
+ vr->setColor(255, 255, 255);
+ vr->fillSurface();
+ vr->setColor(255, 0, 0 );
+ vr->drawLine(25, 25, 125, 300);
+ vr->drawCircle(250, 250, 10);
+ vr->drawSquare(150, 25, 100, 100, true);
+ _system->copyRectToOverlay((OverlayColor*)_screen.getBasePtr(0, 0), _screen.w, 0, 0, _screen.w, _screen.w);
+ _system->updateScreen();
+
+ Common::Event event;
+ _system->delayMillis(100);
+ if (eventMan->pollEvent(event) && event.type == Common::EVENT_QUIT) {
+ break;
+ }
+ }
+
+ _system->hideOverlay();
+}
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererSpec<PixelType, PixelFormat>::
+drawSquare(int x, int y, int w, int h, bool fill) {
+ if ( fill ) {
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x, y);
+ int pitch = Base::surfacePitch();
+
+ while (h--) {
+ Common::set_to(ptr, ptr + w, (PixelType)_color);
+ ptr += pitch;
+ }
+ } else {
+ drawLine( x, y, x + w, y );
+ drawLine( x + w, y, x + w, y + w );
+ drawLine( x, y + w, x + w, y + w );
+ drawLine( x, y, x, y + w );
+ }
+}
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererSpec<PixelType,PixelFormat>::
+drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy) {
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x1, y1);
+ int pitch = Base::surfacePitch();
+ int xdir = (x2 > x1) ? 1 : -1;
+
+ *ptr = (PixelType)_color;
+
+ if (dx > dy) {
+ int ddy = dy * 2;
+ int dysub = ddy - (dx * 2);
+ int error_term = ddy - dx;
+
+ while (dx--) {
+ if (error_term >= 0) {
+ ptr += pitch;
+ error_term += dysub;
+ } else {
+ error_term += ddy;
+ }
+
+ ptr += xdir;
+ *ptr = (PixelType)_color;
+ }
+ } else {
+ int ddx = dx * 2;
+ int dxsub = ddx - (dy * 2);
+ int error_term = ddx - dy;
+
+ while (dy--) {
+ if (error_term >= 0) {
+ ptr += xdir;
+ error_term += dxsub;
+ } else {
+ error_term += ddx;
+ }
+
+ ptr += pitch;
+ *ptr = (PixelType)_color;
+ }
+ }
+
+ ptr = (PixelType *)_activeSurface->getBasePtr(x2, y2);
+ *ptr = (PixelType)_color;
+}
+
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererAA<PixelType, PixelFormat>::
+blendPixelPtr(PixelType *ptr, uint8 alpha) {
+ register int idst = *ptr;
+ register int isrc = Base::_color;
+
+ *ptr = (PixelType)(
+ (PixelFormat::kRedMask & ((idst & PixelFormat::kRedMask) +
+ ((int)(((int)(isrc & PixelFormat::kRedMask) -
+ (int)(idst & PixelFormat::kRedMask)) * alpha) >> 8))) |
+ (PixelFormat::kGreenMask & ((idst & PixelFormat::kGreenMask) +
+ ((int)(((int)(isrc & PixelFormat::kGreenMask) -
+ (int)(idst & PixelFormat::kGreenMask)) * alpha) >> 8))) |
+ (PixelFormat::kBlueMask & ((idst & PixelFormat::kBlueMask) +
+ ((int)(((int)(isrc & PixelFormat::kBlueMask) -
+ (int)(idst & PixelFormat::kBlueMask)) * alpha) >> 8))) );
+}
+
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererAA<PixelType, PixelFormat>::
+drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy) {
+
+ PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+ int pitch = Base::surfacePitch();
+ int xdir = (x2 > x1) ? 1 : -1;
+ uint16 error_tmp, error_acc, gradient;
+ uint8 alpha;
+
+ *ptr = (PixelType)Base::_color;
+
+ if (dx > dy) {
+ gradient = (uint32)(dy << 16) / (uint32)dx;
+ error_acc = 0;
+
+ while (--dx) {
+ error_tmp = error_acc;
+ error_acc += gradient;
+
+ if (error_acc <= error_tmp)
+ ptr += pitch;
+
+ ptr += xdir;
+ alpha = (error_acc >> 8);
+
+ blendPixelPtr(ptr, ~alpha);
+ blendPixelPtr(ptr + pitch, alpha);
+ }
+ } else {
+ gradient = (uint32)(dx << 16) / (uint32)dy;
+ error_acc = 0;
+
+ while (--dy) {
+ error_tmp = error_acc;
+ error_acc += gradient;
+
+ if (error_acc <= error_tmp)
+ ptr += xdir;
+
+ ptr += pitch;
+ alpha = (error_acc >> 8);
+
+ blendPixelPtr(ptr, ~alpha);
+ blendPixelPtr(ptr + xdir, alpha);
+ }
+ }
+
+ Base::putPixel(x2, y2);
+}
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererSpec<PixelType, PixelFormat>::
+drawLine(int x1, int y1, int x2, int y2) {
+ // we draw from top to bottom
+ if (y2 < y1) {
+ SWAP(x1, x2);
+ SWAP(y1, y2);
+ }
+
+ int dx = ABS(x2 - x1);
+ int dy = ABS(y2 - y1);
+
+ // this is a point, not a line. stoopid.
+ if (dy == 0 && dx == 0)
+ return;
+
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x1, y1);
+ int pitch = Base::surfacePitch();
+
+ if (dy == 0) { // horizontal lines
+ // these can be filled really fast with a single memset.
+ // TODO: Platform specific ASM in set_to, would make this thing fly
+ Common::set_to(ptr, ptr + dx + 1, (PixelType)_color);
+
+ } else if (dx == 0) { // vertical lines
+ // these ones use a static pitch increase.
+ while (y1++ <= y2) {
+ *ptr = (PixelType)_color;
+ ptr += pitch;
+ }
+
+ } else if (ABS(dx) == ABS(dy)) { // diagonal lines
+ // these ones also use a fixed pitch increase
+ pitch += (x2 > x1) ? 1 : -1;
+
+ while (dy--) {
+ *ptr = (PixelType)_color;
+ ptr += pitch;
+ }
+
+ } else { // generic lines, use the standard algorithm...
+ drawLineAlg(x1, y1, x2, y2, dx, dy);
+ }
+}
+
+inline uint32 fp_sqroot(uint32 x) {
+ register uint32 root, remHI, remLO, testDIV, count;
+
+ root = 0;
+ remHI = 0;
+ remLO = x;
+ count = 23;
+
+ do {
+ remHI = (remHI << 2) | (remLO >> 30);
+ remLO <<= 2;
+ root <<= 1;
+ testDIV = (root << 1 ) + 1;
+
+ if (remHI >= testDIV) {
+ remHI -= testDIV;
+ root++;
+ }
+ } while (count--);
+
+ return root;
+}
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererSpec<PixelType, PixelFormat>::
+drawCircleAlg(int x1, int y1, int r) {
+
+#define __CIRCLE_SIM(x,y) { \
+ putPixel(x1 + (x), y1 + (y)); /* 1st quad */ \
+ putPixel(x1 + (y), y1 - (x)); \
+ putPixel(x1 - (x), y1 - (y)); /* 2nd quad */ \
+ putPixel(x1 - (y), y1 - (x)); \
+ putPixel(x1 - (y), y1 + (x)); /* 3rd quad */ \
+ putPixel(x1 - (x), y1 + (y)); \
+ putPixel(x1 + (y), y1 + (x)); /* 4th quad */ \
+ putPixel(x1 + (x), y1 - (y)); \
+}
+
+ int f = 1 - r;
+ int ddF_x = 0;
+ int ddF_y = -2 * r;
+ int x = 0;
+ int y = r;
+
+ __CIRCLE_SIM(x,y);
+
+ while (x++ < y) {
+ if (f >= 0) {
+ y--;
+ ddF_y += 2;
+ f += ddF_y;
+ }
+
+ ddF_x += 2;
+ f += ddF_x + 1;
+
+ __CIRCLE_SIM(x,y);
+ }
+}
+
+template<typename PixelType, typename PixelFormat>
+void VectorRendererAA<PixelType, PixelFormat>::
+drawCircleAlg(int x1, int y1, int r) {
+ int x = r;
+ int y = 0;
+ int p = Base::surfacePitch(), px = 0, py = 0;
+ uint32 rsq = (r * r) << 16;
+ uint32 T = 0, oldT;
+ uint8 a1, a2;
+ bool fill = false;
+
+ PixelType *ptr = (PixelType *)Base::_activeSurface->getBasePtr(x1, y1);
+ px = p*x;
+ py = p*y;
+
+ *(ptr + x) = (PixelType)Base::_color;
+ *(ptr - x) = (PixelType)Base::_color;
+ *(ptr + px) = (PixelType)Base::_color;
+ *(ptr - px) = (PixelType)Base::_color;
+
+ if (fill) Common::set_to(ptr - x, ptr + x, Base::_color);
+
+ while (x > y++)
+ {
+ oldT = T;
+ T = fp_sqroot(rsq - ((y * y) << 16)) ^ 0xFFFF;
+
+ py += p;
+
+ if (T < oldT) {
+ x--;
+ px -= p;
+ }
+
+ a2 = (T >> 8);
+ a1 = ~a2;
+
+ if (fill) {
+ Common::set_to(ptr - x + py, ptr + x + py, Base::_color);
+ Common::set_to(ptr - x - py, ptr + x - py, Base::_color);
+ Common::set_to(ptr - y + px, ptr + y + px, Base::_color);
+ Common::set_to(ptr - y - px, ptr + y - px, Base::_color);
+ } else {
+ blendPixelPtr(ptr + x - 1 + py, a2);
+ blendPixelPtr(ptr + y - (px-p), a2);
+ blendPixelPtr(ptr - x + 1 - py, a2);
+ blendPixelPtr(ptr - y - (px-p), a2);
+ blendPixelPtr(ptr - y + (px-p), a2);
+ blendPixelPtr(ptr - x + 1 + py, a2);
+ blendPixelPtr(ptr + y + (px-p), a2);
+ blendPixelPtr(ptr + x - 1 - py, a2);
+ }
+
+ blendPixelPtr(ptr + x + py, a1);
+ blendPixelPtr(ptr + y - px, a1);
+ blendPixelPtr(ptr - x - py, a1);
+ blendPixelPtr(ptr - y - px, a1);
+ blendPixelPtr(ptr - y + px, a1);
+ blendPixelPtr(ptr - x + py, a1);
+ blendPixelPtr(ptr + y + px, a1);
+ blendPixelPtr(ptr + x - py, a1);
+ }
+}
+
+} // end of namespace Graphics
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
new file mode 100644
index 0000000000..96b0698de7
--- /dev/null
+++ b/graphics/VectorRenderer.h
@@ -0,0 +1,344 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef VECTOR_RENDERER_H
+#define VECTOR_RENDERER_H
+
+#include "common/scummsys.h"
+#include "graphics/surface.h"
+#include "graphics/colormasks.h"
+#include "common/system.h"
+
+namespace Graphics {
+
+void vector_renderer_test(OSystem *_system);
+
+/**
+ * VectorRenderer: The core Vector Renderer Class
+ *
+ * This virtual class exposes the API with all the vectorial
+ * rendering functions that may be used to draw on a given Surface.
+ *
+ * This class must be instantiated as one of its children, which implement
+ * the actual rendering functionality for each Byte Depth / Byte Format
+ * combination, and may also contain platform specific code.
+ *
+ * TODO: Expand documentation.
+ *
+ * @see VectorRendererSpec
+ * @see VectorRendererAA
+ */
+class VectorRenderer {
+
+public:
+ virtual ~VectorRenderer() {}
+
+ /**
+ * Draws a line by considering the special cases for optimization.
+ *
+ * @param x1 Horizontal (X) coordinate for the line start
+ * @param x2 Horizontal (X) coordinate for the line end
+ * @param y1 Vertical (Y) coordinate for the line start
+ * @param y2 Vertical (Y) coordinate for the line end
+ */
+ virtual void drawLine(int x1, int y1, int x2, int y2) = 0;
+
+ /**
+ * Draws a circle centered at (x,y) with radius r.
+ *
+ * @param x Horizontal (X) coordinate for the center of the circle
+ * @param y Vertical (Y) coordinate for the center of the circle
+ * @param r Radius of the circle.
+ */
+ virtual void drawCircle(int x, int y, int r) = 0;
+
+
+ virtual void drawSquare(int x, int y, int w, int h, bool fill) = 0;
+
+ /**
+ * Gets the pixel pitch for the current drawing surface.
+ * Note: This is a real pixel-pitch, not a byte-pitch.
+ * That means it can be safely used in pointer arithmetics and
+ * in pixel manipulation.
+ *
+ * @return integer with the active bytes per pixel
+ */
+ virtual uint16 surfacePitch() {
+ return _activeSurface->pitch / _activeSurface->bytesPerPixel;
+ }
+
+ /**
+ * Gets the BYTES (not bits) per Pixel we are working on,
+ * based on the active drawing surface.
+ *
+ * @return integer byte with the active bytes per pixel value
+ */
+ virtual uint8 bytesPerPixel() {
+ return _activeSurface->bytesPerPixel;
+ }
+
+ /**
+ * Set the active painting color for the renderer.
+ * All the drawing from then on will be done with that color, unless
+ * specified otherwise.
+ *
+ * @param r value of the red color byte
+ * @param g value of the green color byte
+ * @param b value of the blue color byte
+ */
+ virtual void setColor(uint8 r, uint8 g, uint8 b) = 0;
+
+ /**
+ * Sets the active drawing surface. All drawing from this
+ * point on will be done on that surface.
+ *
+ * @param surface Pointer to a Surface object.
+ */
+ virtual void setSurface(Surface *surface) {
+ _activeSurface = surface;
+ }
+
+ /**
+ * Fills the active surface with the currently active drawing color.
+ */
+ virtual void fillSurface() = 0;
+
+ /**
+ * Clears the active surface.
+ */
+ virtual void clearSurface() {
+ byte *src = (byte *)_activeSurface->pixels;
+ memset(src, 0, _activeSurface->w * _activeSurface->h * _activeSurface->bytesPerPixel);
+ }
+
+ /**
+ * Draws a single pixel on the surface with the given coordinates and
+ * the currently active drawing color.
+ *
+ * @param x Horizontal coordinate of the pixel.
+ * @param y Vertical coordinate of the pixel.
+ */
+ inline virtual void putPixel(int x, int y) = 0;
+
+ /**
+ * Blends a single pixel on the surface with the given coordinates, with
+ * the currently active drawing color and with the given Alpha intensity.
+ *
+ * @param x Horizontal coordinate of the pixel.
+ * @param y Vertical coordinate of the pixel.
+ * @param alpha Alpha intensity of the pixel (0-255)
+ */
+ inline virtual void blendPixel(int x, int y, uint8 alpha) = 0;
+
+protected:
+
+ /**
+ * Generic line drawing algorithm. May be implemented by each
+ * inheriting class, i.e. with platform specific code.
+ *
+ * @see VectorRenderer::drawLine()
+ * @param x1 Horizontal (X) coordinate for the line start
+ * @param x2 Horizontal (X) coordinate for the line end
+ * @param y1 Vertical (Y) coordinate for the line start
+ * @param y2 Vertical (Y) coordinate for the line end
+ * @param dx Horizontal (X) increasement.
+ * @param dy Vertical (Y) increasement.
+ */
+ virtual void drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy) = 0;
+
+ /**
+ * Specific circle drawing algorithm with symmetry. Must be implemented
+ * on each renderer.
+ *
+ * @param x Horizontal (X) coordinate for the center of the circle
+ * @param y Vertical (Y) coordinate for the center of the circle
+ * @param r Radius of the circle.
+ */
+ virtual void drawCircleAlg(int x, int y, int r) = 0;
+
+ Surface *_activeSurface; /** Pointer to the surface currently being drawn */
+};
+
+
+
+/**
+ * VectorRendererSpec: Specialized Vector Renderer Class
+ *
+ * This templated class implements the basic subset of vector operations for
+ * all platforms by allowing the user to provide the actual Pixel Type and
+ * pixel information structs.
+ *
+ * This class takes two template parameters:
+ *
+ * @param PixelType Defines a type which may hold the color value of a single
+ * pixel, such as "byte" or "uint16" for 8 and 16 BPP respectively.
+ *
+ * @param PixelFormat Defines the type of the PixelFormat struct which contains all
+ * the actual information of the pixels being used, as declared in "graphics/colormasks.h"
+ *
+ * TODO: Expand documentation.
+ *
+ * @see VectorRenderer
+ */
+template<typename PixelType, typename PixelFormat>
+class VectorRendererSpec : public VectorRenderer {
+ typedef VectorRenderer Base;
+
+public:
+ /**
+ * @see VectorRenderer::drawLine()
+ */
+ void drawLine(int x1, int y1, int x2, int y2);
+
+ void drawCircle(int x, int y, int r) {
+ drawCircleAlg(x, y, r);
+ }
+
+ void drawSquare(int x, int y, int w, int h, bool fill);
+
+ /**
+ * @see VectorRenderer::setColor()
+ */
+ void setColor(uint8 r, uint8 g, uint8 b) {
+ this->_color = RGBToColor<PixelFormat>(r, g, b);
+ }
+
+ /**
+ * @see VectorRenderer::fillSurface()
+ */
+ void fillSurface() {
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(0, 0);
+ int s = _activeSurface->w * _activeSurface->h;
+ Common::set_to(ptr, ptr + s, (PixelType)_color);
+ }
+
+ /**
+ * @see VectorRenderer::putPixel()
+ */
+ inline void putPixel( int x, int y ) {
+ PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x, y);
+ *ptr = _color;
+ }
+
+ /**
+ * On the Specialized Renderer, alpha blending is not supported.
+ *
+ * @see VectorRenderer::blendPixel()
+ */
+ virtual inline void blendPixel(int x, int y, uint8 alpha) {
+ putPixel(x, y);
+ }
+
+protected:
+
+ /*
+ * "Bresenham's Line Algorithm", as described in Wikipedia.
+ * Based on the current implementation in "graphics/primitives.cpp".
+ *
+ * Generic line drawing algorithm for the aliased renderer. Optimized with no
+ * floating point operations and direct access to pixel buffer, assumes no special cases.
+ *
+ * @see VectorRenderer::drawLineAlg()
+ */
+ virtual void drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy);
+
+ /**
+ * @see VectorRenderer::drawCircleAlg()
+ */
+ virtual void drawCircleAlg(int x, int y, int r);
+
+ PixelType _color; /** Color currently being used to draw on the renderer */
+};
+
+/**
+ * VectorRendererAA: Anti-Aliased Vector Renderer Class
+ *
+ * This templated class inherits all the functionality of the VectorRendererSpec
+ * class but uses better looking yet slightly slower AA algorithms for drawing
+ * most primivitves. May be used in faster platforms.
+ *
+ * TODO: Expand documentation.
+ *
+ * @see VectorRenderer
+ * @see VectorRendererSpec
+ */
+template<typename PixelType, typename PixelFormat>
+class VectorRendererAA : public VectorRendererSpec<PixelType, PixelFormat> {
+ typedef VectorRendererSpec<PixelType, PixelFormat> Base;
+protected:
+ /**
+ * "Wu's Line Antialiasing Algorithm" as published by Xiaolin Wu, July 1991
+ * Based on the implementation found in Michael Abrash's Graphics Programming Black Book.
+ *
+ * Generic line drawing algorithm for the Antialiased renderer. Optimized with no
+ * floating point operations, assumes no special cases.
+ *
+ * @see VectorRenderer::drawLineAlg()
+ */
+ void drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy);
+
+ /**
+ * Perform alpha blending on top of a given pixel, not on a given
+ * coordinate (just so we don't have to recalculate the surface
+ * pointer while we are blending consecutive pixels).
+ *
+ * Everything from blendPixel() applies here.
+ *
+ * @see VectorRenderer::blendPixel()
+ * @param ptr Pointer to the pixel where we must draw
+ * @param alpha Intensity of the pixel (0-255).
+ */
+ inline void blendPixelPtr(PixelType *ptr, uint8 alpha);
+
+ /**
+ * @see VectorRenderer::blendPixel()
+ *
+ * The AA renderer does support alpha blending. Special cases are
+ * handled separately.
+ */
+ inline void blendPixel(int x, int y, uint8 alpha) {
+ if (alpha == 0)
+ return;
+ else if (alpha < 255)
+ blendPixelPtr((PixelType*)Base::_activeSurface->getBasePtr(x, y), alpha);
+ else
+ Base::putPixel(x, y);
+ }
+
+ /**
+ * "Wu's Circle Antialiasing Algorithm" as published by Xiaolin Wu, July 1991
+ * Based on the theoretical concept of the algorithm.
+ *
+ * Implementation of Wu's algorithm for circles using fixed point arithmetics.
+ * Could be quite fast.
+ *
+ * @see VectorRenderer::drawCircleAlg()
+ */
+ virtual void drawCircleAlg(int x, int y, int r);
+};
+
+} // end of namespace Graphics
+
+#endif
diff --git a/graphics/module.mk b/graphics/module.mk
index 93e2db26c5..b8dfd94ad2 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -16,7 +16,8 @@ MODULE_OBJS := \
primitives.o \
scaler.o \
scaler/thumbnail.o \
- surface.o
+ surface.o \
+ VectorRenderer.o
ifndef DISABLE_SCALERS
MODULE_OBJS += \