1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 //		Rect.H		Rectangle routines header file
20 //		Rex E. Bradford (REX)
21 /*
22 * $Header: n:/project/lib/src/dstruct/RCS/rect.h 1.5 1994/04/05 11:02:15 rex Exp $
23 * $Log: rect.h $
24  * Revision 1.5  1994/04/05  11:02:15  rex
25  * One should endeavor to spend less time writing diatribes about the compiler,.
26  * and more time ensuring the veracity of one's code.
27  *
28  * Revision 1.4  1994/04/05  04:04:24  dc
29  * how about a make point that isnt a function and works better and so on....
30  *
31  * Revision 1.3  1993/11/08  18:53:28  mahk
32  * WHOOOPS
33  *
34  * Revision 1.2  1993/11/08  18:33:47  mahk
35  * Added RECT_FILL and MakePoint
36  *
37  * Revision 1.1  1993/04/22  13:06:17  rex
38  * Initial revision
39  *
40  * Revision 1.2  1993/04/19  18:35:01  rex
41  * Added macro versions of most functions
42  *
43  * Revision 1.1  1992/08/31  17:03:04  unknown
44  * Initial revision
45  *
46 */
47 
48 
49 #ifndef RECT_H
50 #define RECT_H
51 
52 //	Here are the Point and LGRect structs
53 
54 typedef struct {
55 	short x;
56 	short y;
57 } LGPoint;
58 
59 typedef struct {
60 	LGPoint ul;
61 	LGPoint lr;
62 } LGRect;
63 
64 //	Point macros
65 
66 #define PointsEqual(p1,p2) (*(int32_t*)(&(p1)) == *(int32_t*)(&(p2)))
67 #define PointSetNull(p) do {(p).x = -1; (p).y = -1;} while (0);
68 #define PointCheckNull(p) ((p).x == -1 && (p).y == -1)
69 
70 //	LGRect macros: get width & height
71 
72 #define RectWidth(pr) ((pr)->lr.x - (pr)->ul.x)
73 #define RectHeight(pr) ((pr)->lr.y - (pr)->ul.y)
74 
75 // Unwrap macros
76 
77 #define RECT_UNWRAP(pr)  ((pr)->ul.x),((pr)->ul.y),((pr)->lr.x),((pr)->lr.y)
78 #define PT_UNWRAP(pt)    ((pt).x),((pt).y)
79 
80 //	These macros are faster, fatter versions of their function counterparts
81 
82 #define RECT_TEST_SECT(pr1,pr2) ( \
83 	((pr1)->ul.y < (pr2)->lr.y) && \
84 	((pr1)->lr.y > (pr2)->ul.y) && \
85 	((pr1)->ul.x < (pr2)->lr.x) && \
86 	((pr1)->lr.x > (pr2)->ul.x))
87 
88 #define RECT_UNION(pr1,pr2,prunion) { \
89 	(prunion)->ul.x = (pr1)->ul.x < (pr2)->ul.x ? (pr1)->ul.x : (pr2)->ul.x; \
90 	(prunion)->lr.x = (pr1)->lr.x > (pr2)->lr.x ? (pr1)->lr.x : (pr2)->lr.x; \
91 	(prunion)->ul.y = (pr1)->ul.y < (pr2)->ul.y ? (pr1)->ul.y : (pr2)->ul.y; \
92 	(prunion)->lr.y = (pr1)->lr.y > (pr2)->lr.y ? (pr1)->lr.y : (pr2)->lr.y; \
93 	}
94 
95 #define RECT_ENCLOSES(pr1,pr2) ( \
96 	((pr1)->ul.y <= (pr2)->ul.y) && \
97 	((pr1)->lr.y >= (pr2)->lr.y) && \
98 	((pr1)->ul.x <= (pr2)->ul.x) && \
99 	((pr1)->lr.x >= (pr2)->lr.x))
100 
101 #define RECT_TEST_PT(prect,pt) ( \
102 	((pt).y >= (prect)->ul.y) && ((pt).y < (prect)->lr.y) && \
103 	((pt).x >= (prect)->ul.x) && ((pt).x < (prect)->lr.x))
104 
105 #define RECT_MOVE(prect,pt) { \
106 	(prect)->ul.x += pt.x; \
107 	(prect)->ul.y += pt.y; \
108 	(prect)->lr.x += pt.x; \
109 	(prect)->lr.y += pt.y; \
110 	}
111 
112 #define RECT_OFFSETTED_RECT(pr1,pt,proff) { \
113 	(proff)->ul.x = (pr1)->ul.x + (pt).x; \
114 	(proff)->ul.y = (pr1)->ul.y + (pt).y; \
115 	(proff)->lr.x = (pr1)->lr.x + (pt).x; \
116 	(proff)->lr.y = (pr1)->lr.y + (pt).y; \
117 	}
118 
119 #define RECT_FILL(pr,x1,y1,x2,y2) \
120    { \
121       (pr)->ul.x = (x1); \
122       (pr)->ul.y = (y1); \
123       (pr)->lr.x = (x2); \
124       (pr)->lr.y = (y2); \
125    }
126 
127 //	These are the functional versions of the above macros
128 
129 int RectTestSect(LGRect *pr1, LGRect *pr2);
130 void RectUnion(LGRect *pr1, LGRect *pr2, LGRect *prunion);
131 int RectEncloses(LGRect *pr1, LGRect *pr2);
132 int RectTestPt(LGRect *prect, LGPoint pt);
133 void RectMove(LGRect *pr, LGPoint delta);
134 void RectOffsettedRect(LGRect *pr, LGPoint delta, LGRect *proff);
135 
136 //	These functions have no macro counterparts
137 int RectSect(LGRect *pr1, LGRect *pr2, LGRect *prsect);
138 int RectClipCode(LGRect *prect, LGPoint pt);
139 
140 // guess why this isnt a macro        // hah, you cant
141 //Point MakePoint(short x, short y);  // Guess what this does.
142 //#define MakePoint(x,y) (Point)(((ushort)y<<16)+((ushort)x))
143 // oh, doug is mocked, you cant cast to a non-scaler type
144 LGPoint MakePoint(short x, short y);
145 
146 /*
147 // take this, note ax and bx passed but use whole thing... oooooh
148 Point MakePointInline(ushort x, ushort y);
149 #pragma aux MakePointInline = \
150    "shl     ebx,10H"          \
151    "and     eax,0000ffffH"    \
152    "add     eax,ebx"          \
153    parm [ax] [bx]             \
154    modify [eax ebx];
155 // and this
156 #define MakePoint(x,y) MakePointInline((ushort)x,(ushort)y)
157 // curse you
158 // note i had to specify ax and bx even though i dont care what is really used
159 // we would like to say [ax bx cx dx] and then have the code use arg1 and arg2
160 // however, we cant, because there is no way of doing that, because lifeispain
161 // so the compiler generates things like mov eax,ebx;mov ebx,ecx;code as above
162 // which is dumb, since we could do the above with bx and cx just as well. ick
163 */
164 #endif
165