aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Visualization/vis_avs/linedraw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/Visualization/vis_avs/linedraw.cpp')
-rw-r--r--Src/Plugins/Visualization/vis_avs/linedraw.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/Src/Plugins/Visualization/vis_avs/linedraw.cpp b/Src/Plugins/Visualization/vis_avs/linedraw.cpp
new file mode 100644
index 00000000..f6ec9de3
--- /dev/null
+++ b/Src/Plugins/Visualization/vis_avs/linedraw.cpp
@@ -0,0 +1,261 @@
+/*
+ LICENSE
+ -------
+Copyright 2005 Nullsoft, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of Nullsoft nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+#include <windows.h>
+#include "r_defs.h"
+#include <math.h>
+
+#define SWAP(x,y,temp) ( temp ) = ( x ); ( x ) = ( y ); ( y ) = ( temp )
+#define ABS(x) (( x ) < 0 ? - ( x ) : ( x ))
+
+void line(int *fb, int x1,int y1,int x2,int y2, int width, int height, int color, int lw)
+{
+ int dy = ABS(y2-y1);
+ int dx = ABS(x2-x1);
+
+#ifdef LASER
+ lw=1;
+ #define BLEND_LINE(fb,color) (*(fb)=BLEND(*(fb),(color)))
+#else
+ if (lw<1) lw=1;
+ else if (lw>255)lw=255;
+#endif
+
+ int lw2=lw/2;
+ if (!dx) // optimize vertical draw
+ {
+ x1-=lw2;
+ if (x1+lw >= 0 && x1 < width)
+ {
+ int d=max(min(y1,y2),0);
+ int ye=min(max(y1,y2),height-1);
+ if (x1<0)
+ {
+ lw+=x1;
+ x1=0;
+ }
+ if (x1+lw >= width) lw=width-x1;
+ fb += d*width+x1;
+ width-=lw;
+ if (lw>0) while (d++ < ye)
+ {
+ int x=lw;
+ while (x--) { BLEND_LINE(fb, color); fb++; }
+ fb+=width;
+ }
+ }
+ return;
+ }
+ if (y1==y2) // optimize horizontal draw.
+ {
+ y1-=lw2;
+ if (y1+lw >= 0 && y1 < height)
+ {
+ int d=max(min(x1,x2),0);
+ int xe=min(max(x1,x2),width-1);
+ if (y1<0)
+ {
+ lw+=y1;
+
+
+ y1=0;
+ }
+ if (y1+lw >= height) lw=height-y1;
+ fb+=y1*width+d;
+ width-=xe-d;
+ int y=lw;
+ while (y--)
+ {
+ int lt=d;
+ while (lt++<xe) { BLEND_LINE(fb,color); fb++; }
+ fb+=width;
+ }
+ }
+ return;
+ }
+
+ if (dy <= dx) // x major, low slope
+ {
+ // first things first for better line drawing, let's see if we can't get the
+ // width calculated right.
+ // lw is the width in pixels. if dy = 0, then lw=lw. if dy=dx, then:
+ /*
+
+
+ __________ C=30d
+ |\
+ | \ lw
+ | \_____ A=90d
+ ? | /
+ | / pc2
+ |/ ____ B = 60d
+
+ tan(C) = sin(C)/cos(C) = (dy / dx)
+ cos(C) = lw / ?
+
+ sin(C)/(lw / ? ) = (dy / dx)
+ sin(C) * ? / lw = (dy/dx)
+ sin(C) * ? = lw * dy/dx;
+ ? = lw * dy/dx / sin(C)
+
+
+ cos(C) = lw / ? === ? = lw / cos(C)
+ tan(C) = dy / dx;
+
+ C = atan2(dy,dx);
+ ? = lw / cos(C)
+
+ */
+
+#if 0// lame
+ if (lw>1 && (GetAsyncKeyState(VK_SHIFT)&0x8000)){
+ double d=atan2((double)dy,(double)dx);
+ lw = (int) (lw / cos(d));
+ if (lw<1)lw=1;
+ }
+#endif
+
+
+ if (x2 < x1)
+ {
+ int temp;
+ SWAP(x1,x2,temp);
+ SWAP(y1,y2,temp);
+ }
+
+ int yincr = y2>y1?1:-1;
+ int offsincr= y2>y1?width:-width;
+ y1-=lw2;
+ int offs = y1 * width + x1;
+ int d = dy + dy - dx;
+ int Eincr = dy + dy;
+ int NEincr = d - dx;
+ if (x2 >= 0 && x1 < width)
+ {
+ if (x1<0)
+ {
+ int v;
+ v=yincr * -x1;
+ if (dx) v= (v * dy)/dx;
+
+ y1 += v;
+ offs += v*width - x1;
+ x1=0;
+ }
+
+ if (x2 > width) x2=width;
+ while (x1<x2)
+ {
+ int yp=y1;
+ int ype=y1+lw;
+ int *newfb=fb+offs;
+ if (yp < 0)
+ {
+ newfb-=yp*width;
+ yp=0;
+ }
+ if (ype>height) ype=height;
+ while (yp++ < ype)
+ {
+ BLEND_LINE(newfb,color);
+ newfb+=width;
+ }
+ if (d < 0) d += Eincr;
+ else
+ {
+ d += NEincr;
+ y1 += yincr;
+ offs += offsincr;
+ }
+ offs++;
+ x1++;
+ }
+ }
+ }
+ else
+ {
+#if 0//lame
+ if (lw>1 && (GetAsyncKeyState(VK_SHIFT)&0x8000)){
+ double d=atan2((double)dx,(double)dy);
+ lw = (int) (lw / cos(d));
+ if (lw<1)lw=1;
+ }
+#endif
+ if (y2 < y1)
+ {
+ int temp;
+ SWAP(x1,x2,temp);
+ SWAP(y1,y2,temp);
+ }
+
+ int yincr=(x2>x1)?1:-1;
+ int d = dx + dx - dy;
+ int Eincr = dx + dx;
+ int NEincr = d - dy;
+ x1-=lw2;
+ int offs = y1 * width + x1;
+ if (y2 >= 0 && y1 < height)
+ {
+ if (y1<0)
+ {
+ int v;
+ v=yincr * -y1;
+ if (dy) v= (v * dx)/dy;
+
+ x1 += v;
+ offs += v - y1*width;
+ y1=0;
+ }
+ if (y2 > height) y2 = height;
+ while (y1 < y2)
+ {
+ int xp=x1;
+ int xpe=x1+lw;
+ int *newfb=fb+offs;
+ if (xp<0)
+ {
+ newfb-=xp;
+ xp=0;
+ }
+ if (xpe > width) xpe=width;
+ while (xp++ < xpe) { BLEND_LINE(newfb, color); newfb++; }
+
+ if (d < 0) d += Eincr;
+ else
+ {
+ d += NEincr;
+ x1 += yincr;
+ offs += yincr;
+ }
+ offs += width;
+ y1++;
+ }
+ }
+ }
+}