123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- /*
- 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++;
- }
- }
- }
- }
|