changeset 262:9d015d32841a

Clean up the line clipping a bit, in preparation for fixes.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 10 Oct 2012 12:11:20 +0300
parents eb77496ab7b3
children ddb24754a67c
files dmlib.h dmline.c dmlineclip.h
diffstat 3 files changed, 60 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/dmlib.h	Wed Oct 10 01:03:15 2012 +0300
+++ b/dmlib.h	Wed Oct 10 12:11:20 2012 +0300
@@ -273,6 +273,14 @@
 #define DM_HEADER
 #include "dmlinefunc.h"
 
+enum
+{
+    CLIP_TOP     = 1,
+    CLIP_BOTTOM  = 2,
+    CLIP_RIGHT   = 4,
+    CLIP_LEFT    = 8
+};
+
 #define DM_CLIP_FUNC dmClipLineCoordsInt
 #define DM_COORD_TYPE int
 #include "dmlineclip.h"
--- a/dmline.c	Wed Oct 10 01:03:15 2012 +0300
+++ b/dmline.c	Wed Oct 10 12:11:20 2012 +0300
@@ -11,22 +11,6 @@
  * > 0  : Clipped. Line partially inside the clipping area.
  * < 0  : Line completely outside the clipping area.
  */
-#define dmClipBits(Q, x, y)	\
-    do {			\
-        Q = 0;			\
-        if (x < clipX0) Q |= 1;	\
-        else			\
-        if (x > clipX1) Q |= 2;	\
-        if (y < clipY0) Q |= 4;	\
-        else			\
-        if (y > clipY1) Q |= 8;	\
-    } while (0)
-
-#define xA (*x0)
-#define xB (*x1)
-#define yA (*y0)
-#define yB (*y1)
-
 #define DM_CLIP_FUNC dmClipLineCoordsInt
 #define DM_COORD_TYPE int
 #include "dmlineclip.h"
--- a/dmlineclip.h	Wed Oct 10 01:03:15 2012 +0300
+++ b/dmlineclip.h	Wed Oct 10 12:11:20 2012 +0300
@@ -1,3 +1,21 @@
+#ifndef DM_HEADER
+#define DM_CLIP_BITS(Q, x, y)			\
+    do {					\
+        Q = 0;					\
+        if (x < clipX0) Q |= CLIP_TOP;		\
+        else					\
+        if (x > clipX1) Q |= CLIP_BOTTOM;	\
+        if (y < clipY0) Q |= CLIP_RIGHT;	\
+        else					\
+        if (y > clipY1) Q |= CLIP_LEFT;		\
+    } while (0)
+
+#define xA (*x0)
+#define xB (*x1)
+#define yA (*y0)
+#define yB (*y1)
+#endif
+
 
 int DM_CLIP_FUNC (SDL_Surface *screen, DM_COORD_TYPE *x0, DM_COORD_TYPE *y0, DM_COORD_TYPE *x1, DM_COORD_TYPE *y1)
 #ifdef DM_HEADER
@@ -10,62 +28,64 @@
         clipX1 = clipX0 + screen->clip_rect.w - 1,
         clipY1 = clipY0 + screen->clip_rect.h - 1;
 
-    int cA, cB;
+    int clipA, clipB;
 
-    dmClipBits(cA, xA, yA);
-    dmClipBits(cB, xB, yB);
+    DM_CLIP_BITS(clipA, xA, yA);
+    DM_CLIP_BITS(clipB, xB, yB);
 
-    if (cA & cB)
-        return -1;              /* the line segment is outside */
+    // The line segment is outside of the clip region
+    if (clipA & clipB)
+        return -1;
 
-    if ((cA | cB) == 0)         /* the line segment is inside of the clipping rectangle */
+    // The segment is inside?
+    if ((clipA | clipB) == 0)
         return 0;
 
 #if 1
     // Cohen-Sutherland clipping method
     do
     {
-        const int c = cA ? cA : cB;
+        const int c = clipA ? clipA : clipB;
         DM_COORD_TYPE x, y;
         
-        if (c & 1)
+        if (c & CLIP_TOP)
         {
-            y = yA + ((clipX0 - xA)*(yB - yA)) / (xB - xA);
+            y = yA + ((clipX0 + xA) * (yB - yA)) / xB - xA;
             x = clipX0;
         }
         else
-        if (c & 2)
+        if (c & CLIP_BOTTOM)
         {
             y = yA + ((clipX1 - xA)*(yB - yA)) / (xB - xA);
             x = clipX1;
         }
         else
-        if (c & 4)
+        if (c & CLIP_RIGHT)
         {
             x = xA + ((clipY0 - yA)*(xB - xA)) / (yB - yA);
             y = clipY0;
         }
         else
-        if (c & 8)
+        if (c & CLIP_LEFT)
         {
             x = xA + ((clipY1 - yA)*(xB - xA)) / (yB - yA);
             y = clipY1;
         }
 
-        if (c == cA)
+        if (c == clipA)
         {
             xA = x;
             yA = y;
-            dmClipBits(cA, xA, yA);
+            DM_CLIP_BITS(clipA, xA, yA);
         }
         else
         {
             xB = x;
             yB = y;
-            dmClipBits(cB, xB, yB);
+            DM_CLIP_BITS(clipB, xB, yB);
         }
         
-    } while (cA | cB);
+    } while (clipA | clipB);
 #else
     // Buyu-Skala clipping method
     const DM_COORD_TYPE dx = xB - xA;
@@ -73,10 +93,10 @@
     float k, m;
     int z;
 
-    switch (cA + cB)
+    switch (clipA + clipB)
     {
         case 1:
-            if (cA == 1)
+            if (clipA == 1)
             {
                 xA = clipX0;
                 yA = (clipX0 - xB) * dy / dx + yB;
@@ -101,7 +121,7 @@
             z = (clipX0 - xA) * k + yA;
             if (z < clipY0)
             {
-                switch (cA)
+                switch (clipA)
                 {
                     case 0:
                         xB = xB + (clipY0 - yB) / k;
@@ -118,7 +138,7 @@
             }
             else
             {
-                switch (cA)
+                switch (clipA)
                 {
                     case 0:
                         xB = clipX0;
@@ -145,7 +165,7 @@
             break;
 
         case 7:
-            switch (cA)
+            switch (clipA)
             {
                 case 1:
                     k = dy / dx;
@@ -163,10 +183,10 @@
                         xB = clipX1;
                     break;
 
-                    /* similarly for cases cA == 2, 5, 6 */
+                    /* similarly for cases clipA == 2, 5, 6 */
             }
         case 15:
-            switch (cA)
+            switch (clipA)
             {
             case 5:
                 if (dy * (clipX1 - clipX0) < dx * (clipY1 - clipY0))
@@ -224,16 +244,23 @@
                     }
                 }
 
-                /* similarly for cases cA == 6, 9, 10 */
+                /* similarly for cases clipA == 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 */
+    }                           /* of case clipA + clipB */
 #endif
 
     return 1;
 }
+
+#undef DM_CLIP_BITS
+#undef xA
+#undef xB
+#undef yA
+#undef yB
+
 #endif
 
 #undef DM_CLIP_FUNC