# HG changeset patch # User Matti Hamalainen # Date 1349676065 -10800 # Node ID 79dac918c81e0b153679b1671ef2f0895d7ae164 # Parent e65fed571d7a7796d26d9861da192a1cd565857b Modularize line clipping etc. a lot, and export all line drawing and blitting functions. diff -r e65fed571d7a -r 79dac918c81e Makefile.gen --- 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) diff -r e65fed571d7a -r 79dac918c81e dmblitfunc.h --- 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" \ diff -r e65fed571d7a -r 79dac918c81e dmdrawline.h --- 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 diff -r e65fed571d7a -r 79dac918c81e dmlib.h --- 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 diff -r e65fed571d7a -r 79dac918c81e dmline.c --- 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); -} diff -r e65fed571d7a -r 79dac918c81e dmlineclip.h --- /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 diff -r e65fed571d7a -r 79dac918c81e dmscaledblit.h --- 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 diff -r e65fed571d7a -r 79dac918c81e dmunscaledblit.h --- 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 diff -r e65fed571d7a -r 79dac918c81e vptest.c --- 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) {