changeset 232:79dac918c81e

Modularize line clipping etc. a lot, and export all line drawing and blitting functions.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 08 Oct 2012 09:01:05 +0300
parents e65fed571d7a
children e3c1aa3ba88e
files Makefile.gen dmblitfunc.h dmdrawline.h dmlib.h dmline.c dmlineclip.h dmscaledblit.h dmunscaledblit.h vptest.c
diffstat 9 files changed, 276 insertions(+), 288 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.gen	Mon Oct 08 06:44:35 2012 +0300
+++ b/Makefile.gen	Mon Oct 08 09:01:05 2012 +0300
@@ -270,7 +270,7 @@
 	@echo " CC $+"
 	@$(CC) $(CFLAGS) -c -o $@ $< $(DM_CFLAGS)
 
-$(OBJPATH)dmline.o: $(DMLIB)dmline.c $(DMLIB)dmdrawline.h $(DMLIB)dmlinefunc.h $(DMLIB)dmlib.h
+$(OBJPATH)dmline.o: $(DMLIB)dmline.c $(DMLIB)dmdrawline.h $(DMLIB)dmlinefunc.h $(DMLIB)dmlineclip.h $(DMLIB)dmlib.h
 	@echo " CC $+"
 	@$(CC) $(CFLAGS) -c -o $@ $< $(DM_CFLAGS)
 
--- a/dmblitfunc.h	Mon Oct 08 06:44:35 2012 +0300
+++ b/dmblitfunc.h	Mon Oct 08 09:01:05 2012 +0300
@@ -529,7 +529,7 @@
 #ifdef DM_USE_SIMD
 #define DM_BLITFUNC_SRC_TYPE Uint32
 #define DM_BLITFUNC_DST_TYPE Uint32
-#define DM_BLITFUNC_INNER				\
+#define DM_BLITFUNC_INNER			\
     asm("movd        %2,     %%mm1\n"		\
         "movd        %1,     %%mm2\n"		\
         "paddusb     %%mm2,  %%mm1\n"		\
--- a/dmdrawline.h	Mon Oct 08 06:44:35 2012 +0300
+++ b/dmdrawline.h	Mon Oct 08 09:01:05 2012 +0300
@@ -1,11 +1,20 @@
+/*
+ * DMLib
+ * -- Simple Bresenham's style line drawing
+ * Programmed and designed by Matti 'ccr' Hamalainen
+ * (C) Copyright 2011-2012 Tecnic Software productions (TNSP)
+ */
 
-static int DM_DRAWLINE_NAME (SDL_Surface *screen, int x0, int y0, int x1, int y1, const Uint32 col)
+int DM_DRAWLINE_NAME (SDL_Surface *screen, int x0, int y0, int x1, int y1, const Uint32 col)
+#ifdef DM_HEADER
+;
+#else
 {
     int dx, dy, xstep, ystep;
     const int qpitch = screen->pitch / DM_DRAWLINE_DST_BYTES;
 
     // Clipping
-    if (dmClipLineCoords(&x0, &y0, &x1, &y1, screen) < 0)
+    if (dmClipLineCoordsInt(&x0, &y0, &x1, &y1, screen) < 0)
         return -1;
 
     // Compute initial deltas
@@ -77,6 +86,7 @@
 
     return 0;
 }
+#endif
 
 #undef DM_DRAWLINE_NAME
 #undef DM_DRAWLINE_DST_BYTES
--- a/dmlib.h	Mon Oct 08 06:44:35 2012 +0300
+++ b/dmlib.h	Mon Oct 08 09:01:05 2012 +0300
@@ -270,9 +270,9 @@
 /* Arbitrary line drawing
  */
 #ifdef DM_GFX_LINES
-typedef int (*DMDrawLineFunc)(SDL_Surface *src, int x0, int y0, int x1, int y1, const Uint32 color);
-DMDrawLineFunc dmGetDrawLineFunc(SDL_PixelFormat *dst, int mode);
-int        dmDrawLineAny(SDL_Surface *src, int x0, int y0, int x1, int y1, const Uint32 color, int mode);
+#define DM_HEADER
+#include "dmlinefunc.h"
+#undef DM_HEADER
 #endif
 
 
@@ -280,18 +280,16 @@
  */
 #ifdef DM_GFX_BLITS
 typedef int (*DMScaledBlitFunc)(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst);
-
 DMScaledBlitFunc dmGetScaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode);
 int dmScaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst, int mode);
 
-int dmScaledBlitSurface32to32TransparentX(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst);
-int dmScaledBlitSurface32to32TransparentGA(SDL_Surface *src, const int x0, const int y0, const int dwidth, const int dheight, SDL_Surface *dst, Uint32 alpha);
-
-
 typedef int (*DMUnscaledBlitFunc)(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst);
-
 DMUnscaledBlitFunc dmGetUnscaledBlitFunc(SDL_PixelFormat *src, SDL_PixelFormat *dst, int mode);
 int dmUnscaledBlitSurfaceAny(SDL_Surface *src, const int x0, const int y0, SDL_Surface *dst, int mode);
+
+#define DM_HEADER
+#include "dmblitfunc.h"
+#undef DM_HEADER
 #endif
 
 
--- a/dmline.c	Mon Oct 08 06:44:35 2012 +0300
+++ b/dmline.c	Mon Oct 08 09:01:05 2012 +0300
@@ -6,7 +6,6 @@
  */
 #include "dmlib.h"
 
-
 /* Clip line coordinates. Return value:
  * = 0  : No clipping needed.
  * > 0  : Clipped. Line partially inside the clipping area.
@@ -28,276 +27,13 @@
 #define yA (*y0)
 #define yB (*y1)
 
-int dmClipLineCoords(int *x0, int *y0, int *x1, int *y1, SDL_Surface *screen)
-{
-    const int clipX0 = screen->clip_rect.x,
-              clipY0 = screen->clip_rect.y;
-    const int clipX1 = clipX0 + screen->clip_rect.w - 1,
-              clipY1 = clipY0 + screen->clip_rect.h - 1;
-
-    int cA, cB;
-
-    dmClipBits(cA, xA, yA);
-    dmClipBits(cB, xB, yB);
-
-    if (cA & cB)
-        return -1;              /* the line segment is outside */
-
-    if ((cA | cB) == 0)         /* the line segment is inside of the clipping rectangle */
-        return 0;
-
-#if 1
-    // Cohen-Sutherland clipping method
-    do
-    {
-        const int c = cA ? cA : cB;
-        int x, y;
-        
-        if (c & 1)
-        {
-            y = yA + ((clipX0 - xA)*(yB - yA)) / (xB - xA);
-            x = clipX0;
-        }
-        else
-        if (c & 2)
-        {
-            y = yA + ((clipX1 - xA)*(yB - yA)) / (xB - xA);
-            x = clipX1;
-        }
-        else
-        if (c & 4)
-        {
-            x = xA + ((clipY0 - yA)*(xB - xA)) / (yB - yA);
-            y = clipY0;
-        }
-        else
-        if (c & 8)
-        {
-            x = xA + ((clipY1 - yA)*(xB - xA)) / (yB - yA);
-            y = clipY1;
-        }
-
-        if (c == cA)
-        {
-            xA = x;
-            yA = y;
-            dmClipBits(cA, xA, yA);
-        }
-        else
-        {
-            xB = x;
-            yB = y;
-            dmClipBits(cB, xB, yB);
-        }
-        
-    } while (cA | cB);
-#else
-    // Buyu-Skala clipping method
-    const int dx = xB - xA;
-    const int dy = yB - yA;
-    float k, m;
-    int z;
-
-    switch (cA + cB)
-    {
-        case 1:
-            if (cA == 1)
-            {
-                xA = clipX0;
-                yA = (clipX0 - xB) * dy / dx + yB;
-            }
-            else
-            {
-                xB = clipX0;
-                yB = (clipX0 - xA) * dy / dx + yA;
-            }
-            break;
-
-        case 3:
-            k = dy / dx;
-            yA = (clipX0 - xA) * k + yA;
-            xA = clipX0;
-            yB = (clipX1 - xB) * k + yB;
-            xB = clipX1;
-            break;
-
-        case 5:
-            k = dy / dx;
-            z = (clipX0 - xA) * k + yA;
-            if (z < clipY0)
-            {
-                switch (cA)
-                {
-                    case 0:
-                        xB = xB + (clipY0 - yB) / k;
-                        yB = clipY0;
-                        break;
-                    case 5:
-                        xA = xA + (clipY0 - yA) / k;
-                        yA = clipY0;
-                        break;
+#define DM_CLIP_FUNC dmClipLineCoordsInt
+#define DM_COORD_TYPE int
+#include "dmlineclip.h"
 
-                    default:
-                        return -1;  /* the line segment is outside */
-                }
-            }
-            else
-            {
-                switch (cA)
-                {
-                    case 0:
-                        xB = clipX0;
-                        yB = z;
-                        break;
-                    case 1:
-                        xB = xB + (clipY0 - yB) / k;
-                        yB = clipY0;
-                        xA = clipX0;
-                        yA = z;
-                        break;
-                    case 4:
-                        xA = xA + (clipY0 - yA) / k;
-                        yA = clipY0;
-                        xB = clipX0;
-                        yB = z;
-                        break;
-                    case 5:
-                        xA = clipX0;
-                        yA = z;
-                        break;
-                }
-            }
-            break;
-
-        case 7:
-            switch (cA)
-            {
-                case 1:
-                    k = dy / dx;
-                    yA = (clipX0 - xB) * k + yB;
-                    if (yA < clipY0)
-                        return -1;  /* the line segment is outside */
-                    xA = clipX0;
-                    yB = (clipX1 - clipX0) * k + yA;
-                    if (yB < clipY0)
-                    {
-                        xB = (clipY0 - yB) / k + clipX1;
-                        yB = clipY0;
-                    }
-                    else
-                        xB = clipX1;
-                    break;
-
-                    /* similarly for cases cA == 2, 5, 6 */
-            }
-        case 15:
-            switch (cA)
-            {
-            case 5:
-                if (dy * (clipX1 - clipX0) < dx * (clipY1 - clipY0))
-                {
-                    k = dy / dx;
-                    yA = (clipX0 - xB) * k + yB;
-                    if (yA > clipY1)
-                        return -1;  /* the line segment is outside */
-                    yB = (clipX1 - clipX0) * k + yA;
-                    if (yB < clipY0)
-                        return -1;  /* the line segment is outside */
-                    if (yA < clipY0)
-                    {
-                        xA = (clipY0 - yA) / k + clipX0;
-                        yA = clipY0;
-                        xB = clipX1;
-                    }
-                    else
-                    {
-                        xA = clipX0;
-                        if (yB > clipY1)
-                        {
-                            xB = (clipY1 - yB) / k + clipX1;
-                            yB = clipY1;
-                        }
-                        else
-                            xB = clipX1;
-                    }
-                }
-                else
-                {
-                    m = dx / dy;
-                    xA = (clipY0 - yB) * m + xB;
-                    if (xA > clipX1)
-                        return -1;  /* the line segment is outside */
-                    xB = (clipY1 - clipY0) * m + xA;
-                    if (xB < clipX0)
-                        return -1;  /* the line segment is outside */
-                    if (xA < clipX0)
-                    {
-                        yA = (clipX0 - xA) / m + clipY0;
-                        xA = clipX0;
-                        yB = clipY1;
-                    }
-                    else
-                    {
-                        yA = clipY0;
-                        if (xB > clipX1)
-                        {
-                            yB = (clipX1 - xB) / m + clipY1;
-                            xB = clipX1;
-                        }
-                        else
-                            yB = clipY1;
-                    }
-                }
-
-                /* similarly for cases cA == 6, 9, 10 */
-            }
-
-            /* cases 2, 4, 8 are similar as case 1, cases 6, 9, 10 are similar as case 5 */
-            /* cases 11, 13, 14 are similar as case 7, case 12 is similar case 3 */
-    }                           /* of case cA + cB */
-#endif
-
-    return 1;
-}
-
+#define DM_CLIP_FUNC dmClipLineCoordsFloat
+#define DM_COORD_TYPE float
+#include "dmlineclip.h"
 
 
 #include "dmlinefunc.h"
-
-static const DMDrawLineFunc dmDrawLineTable[DMD_NMODES][DMD_NBITDEPTHS] =
-{
-    /* DMD_NONE          */ { dmDrawLine8              , dmDrawLine32 },
-    /* DMD_TRANSPARENT   */ { dmDrawLine8Transparent   , dmDrawLine32Transparent },
-    /* DMD_SATURATE      */ { dmDrawLine8Saturate      , dmDrawLine32Saturate },
-#if 0
-    /* DMD_NONE + AA     */ { NULL, NULL },
-    /* DMD_TRANSP + AA   */ { NULL, NULL },
-    /* DMD_SATURATE + AA */ { dmDrawLine8AASaturate    , dmDrawLine32AASaturate },
-#endif
-};
-
-static const int ndmDrawLineTable = sizeof(dmDrawLineTable) / sizeof(dmDrawLineTable[0]);
-
-
-DMDrawLineFunc dmGetDrawLineFunc(SDL_PixelFormat *dst, int mode)
-{
-    int index;
-    if (dst == NULL || mode < 0 || mode >= ndmDrawLineTable)
-        return NULL;
-
-    if ((index = dmBitsPerPixel2Index(dst->BitsPerPixel)) < 0)
-        return NULL;
-    
-    return dmDrawLineTable[mode][index];
-}
-
-
-int dmDrawLineAny(SDL_Surface *screen, int x0, int y0, int x1, int y1, const Uint32 col, int mode)
-{
-    DMDrawLineFunc bfunc = dmGetDrawLineFunc(screen->format, mode);
-
-    if (bfunc == NULL)
-        return -15;
-
-    return bfunc(screen, x0, y0, x1, y1, col);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmlineclip.h	Mon Oct 08 09:01:05 2012 +0300
@@ -0,0 +1,236 @@
+
+int DM_CLIP_FUNC (DM_COORD_TYPE *x0, DM_COORD_TYPE *y0, DM_COORD_TYPE *x1, DM_COORD_TYPE *y1, SDL_Surface *screen)
+{
+    const DM_COORD_TYPE
+        clipX0 = screen->clip_rect.x,
+        clipY0 = screen->clip_rect.y,
+        clipX1 = clipX0 + screen->clip_rect.w - 1,
+        clipY1 = clipY0 + screen->clip_rect.h - 1;
+
+    int cA, cB;
+
+    dmClipBits(cA, xA, yA);
+    dmClipBits(cB, xB, yB);
+
+    if (cA & cB)
+        return -1;              /* the line segment is outside */
+
+    if ((cA | cB) == 0)         /* the line segment is inside of the clipping rectangle */
+        return 0;
+
+#if 1
+    // Cohen-Sutherland clipping method
+    do
+    {
+        const int c = cA ? cA : cB;
+        DM_COORD_TYPE x, y;
+        
+        if (c & 1)
+        {
+            y = yA + ((clipX0 - xA)*(yB - yA)) / (xB - xA);
+            x = clipX0;
+        }
+        else
+        if (c & 2)
+        {
+            y = yA + ((clipX1 - xA)*(yB - yA)) / (xB - xA);
+            x = clipX1;
+        }
+        else
+        if (c & 4)
+        {
+            x = xA + ((clipY0 - yA)*(xB - xA)) / (yB - yA);
+            y = clipY0;
+        }
+        else
+        if (c & 8)
+        {
+            x = xA + ((clipY1 - yA)*(xB - xA)) / (yB - yA);
+            y = clipY1;
+        }
+
+        if (c == cA)
+        {
+            xA = x;
+            yA = y;
+            dmClipBits(cA, xA, yA);
+        }
+        else
+        {
+            xB = x;
+            yB = y;
+            dmClipBits(cB, xB, yB);
+        }
+        
+    } while (cA | cB);
+#else
+    // Buyu-Skala clipping method
+    const DM_COORD_TYPE dx = xB - xA;
+    const DM_COORD_TYPE dy = yB - yA;
+    float k, m;
+    int z;
+
+    switch (cA + cB)
+    {
+        case 1:
+            if (cA == 1)
+            {
+                xA = clipX0;
+                yA = (clipX0 - xB) * dy / dx + yB;
+            }
+            else
+            {
+                xB = clipX0;
+                yB = (clipX0 - xA) * dy / dx + yA;
+            }
+            break;
+
+        case 3:
+            k = dy / dx;
+            yA = (clipX0 - xA) * k + yA;
+            xA = clipX0;
+            yB = (clipX1 - xB) * k + yB;
+            xB = clipX1;
+            break;
+
+        case 5:
+            k = dy / dx;
+            z = (clipX0 - xA) * k + yA;
+            if (z < clipY0)
+            {
+                switch (cA)
+                {
+                    case 0:
+                        xB = xB + (clipY0 - yB) / k;
+                        yB = clipY0;
+                        break;
+                    case 5:
+                        xA = xA + (clipY0 - yA) / k;
+                        yA = clipY0;
+                        break;
+
+                    default:
+                        return -1;  /* the line segment is outside */
+                }
+            }
+            else
+            {
+                switch (cA)
+                {
+                    case 0:
+                        xB = clipX0;
+                        yB = z;
+                        break;
+                    case 1:
+                        xB = xB + (clipY0 - yB) / k;
+                        yB = clipY0;
+                        xA = clipX0;
+                        yA = z;
+                        break;
+                    case 4:
+                        xA = xA + (clipY0 - yA) / k;
+                        yA = clipY0;
+                        xB = clipX0;
+                        yB = z;
+                        break;
+                    case 5:
+                        xA = clipX0;
+                        yA = z;
+                        break;
+                }
+            }
+            break;
+
+        case 7:
+            switch (cA)
+            {
+                case 1:
+                    k = dy / dx;
+                    yA = (clipX0 - xB) * k + yB;
+                    if (yA < clipY0)
+                        return -1;  /* the line segment is outside */
+                    xA = clipX0;
+                    yB = (clipX1 - clipX0) * k + yA;
+                    if (yB < clipY0)
+                    {
+                        xB = (clipY0 - yB) / k + clipX1;
+                        yB = clipY0;
+                    }
+                    else
+                        xB = clipX1;
+                    break;
+
+                    /* similarly for cases cA == 2, 5, 6 */
+            }
+        case 15:
+            switch (cA)
+            {
+            case 5:
+                if (dy * (clipX1 - clipX0) < dx * (clipY1 - clipY0))
+                {
+                    k = dy / dx;
+                    yA = (clipX0 - xB) * k + yB;
+                    if (yA > clipY1)
+                        return -1;  /* the line segment is outside */
+                    yB = (clipX1 - clipX0) * k + yA;
+                    if (yB < clipY0)
+                        return -1;  /* the line segment is outside */
+                    if (yA < clipY0)
+                    {
+                        xA = (clipY0 - yA) / k + clipX0;
+                        yA = clipY0;
+                        xB = clipX1;
+                    }
+                    else
+                    {
+                        xA = clipX0;
+                        if (yB > clipY1)
+                        {
+                            xB = (clipY1 - yB) / k + clipX1;
+                            yB = clipY1;
+                        }
+                        else
+                            xB = clipX1;
+                    }
+                }
+                else
+                {
+                    m = dx / dy;
+                    xA = (clipY0 - yB) * m + xB;
+                    if (xA > clipX1)
+                        return -1;  /* the line segment is outside */
+                    xB = (clipY1 - clipY0) * m + xA;
+                    if (xB < clipX0)
+                        return -1;  /* the line segment is outside */
+                    if (xA < clipX0)
+                    {
+                        yA = (clipX0 - xA) / m + clipY0;
+                        xA = clipX0;
+                        yB = clipY1;
+                    }
+                    else
+                    {
+                        yA = clipY0;
+                        if (xB > clipX1)
+                        {
+                            yB = (clipX1 - xB) / m + clipY1;
+                            xB = clipX1;
+                        }
+                        else
+                            yB = clipY1;
+                    }
+                }
+
+                /* similarly for cases cA == 6, 9, 10 */
+            }
+
+            /* cases 2, 4, 8 are similar as case 1, cases 6, 9, 10 are similar as case 5 */
+            /* cases 11, 13, 14 are similar as case 7, case 12 is similar case 3 */
+    }                           /* of case cA + cB */
+#endif
+
+    return 1;
+}
+
+#undef DM_CLIP_FUNC
+#undef DM_COORD_TYPE
--- a/dmscaledblit.h	Mon Oct 08 06:44:35 2012 +0300
+++ b/dmscaledblit.h	Mon Oct 08 09:01:05 2012 +0300
@@ -5,6 +5,7 @@
  * (C) Copyright 2011-2012 Tecnic Software productions (TNSP)
  */
 
+
 int DM_BLITFUNC_NAME (SDL_Surface *src,
     const int x0, const int y0,
     const int dwidth, const int dheight,
@@ -13,6 +14,9 @@
     DM_BLITFUNC_ARGS
 #endif
     )
+#ifdef DM_HEADER
+;
+#else
 {
     int yc;
     DMFixedPoint32 xv, yv, dx, dy;
@@ -70,7 +74,7 @@
 
     return 0;
 }
-
+#endif
 
 #undef DM_BLITFUNC_NAME
 #undef DM_BLITFUNC_ARGS
--- a/dmunscaledblit.h	Mon Oct 08 06:44:35 2012 +0300
+++ b/dmunscaledblit.h	Mon Oct 08 09:01:05 2012 +0300
@@ -12,6 +12,9 @@
     DM_BLITFUNC_ARGS
 #endif
     )
+#ifdef DM_HEADER
+;
+#else
 {
     int yc;
     DMQValue xr, yr;
@@ -57,6 +60,7 @@
 #endif
     return 0;
 }
+#endif
 
 
 #undef DM_BLITFUNC_NAME
--- a/vptest.c	Mon Oct 08 06:44:35 2012 +0300
+++ b/vptest.c	Mon Oct 08 09:01:05 2012 +0300
@@ -292,10 +292,10 @@
             128 + sin(f*0.1) * 120.0f);
 #endif
 
-        dmDrawLineAny(screen, 30, 30, 600 + 200 * sin(f), 250              , lcol, DMD_NONE);
-        dmDrawLineAny(screen, 20, 30, 100              , 250 + 100 * sin(f), lcol, DMD_NONE);
-        dmDrawLineAny(screen, 100, 100, 100 + cos(f) * 50, 100 + sin(f) * 50, lcol, DMD_NONE);
-        dmDrawLineAny(screen, 100, 100, 100 + cos(f+0.5) * 250, 100 + sin(f+0.5) * 250, lcol, DMD_NONE);
+        dmDrawLine32(screen, 30, 30, 600 + 200 * sin(f), 250              , lcol);
+        dmDrawLine32(screen, 20, 30, 100              , 250 + 100 * sin(f), lcol);
+        dmDrawLine32(screen, 100, 100, 100 + cos(f) * 50, 100 + sin(f) * 50, lcol);
+        dmDrawLine32(screen, 100, 100, 100 + cos(f+0.5) * 250, 100 + sin(f+0.5) * 250, lcol);
 
         if (!optBenchmark)
         {