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