| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * Archive : /Sun/RECT.H *
- * *
- * Author : Joe_b *
- * *
- * Modtime : 11/21/97 4:40p *
- * *
- * Revision : 20 *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * Union -- Combines two rectangles into one larger one. *
- * Intersect -- Find the intersection between two rectangles. *
- * Intersect -- Simple intersect between two rectangles. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #pragma once
- #ifndef RECT_H
- #define RECT_H
- #include <stddef.h>
- #include "point.h"
- /*
- ** This class manages a rectangle. Typically, this is used for tracking regions on a surface
- ** and for clipping operations. This is a lightweight class in that it defines few support
- ** functions and exposes the member variables for direct access.
- */
- template<class T>
- class TRect
- {
- public:
- TRect(void) {} // Default constructor does nothing by design.
- TRect(T x, T y, T w, T h) : X(x), Y(y), Width(w), Height(h) {}
- TRect(TPoint2D<T> const & point, T w, T h) : X(point.X), Y(point.Y), Width(w), Height(h) {}
- // Equality comparison operators.
- bool operator == (TRect<T> const & rvalue) const {return(X==rvalue.X && Y==rvalue.Y && Width==rvalue.Width && Height==rvalue.Height);}
- bool operator != (TRect<T> const & rvalue) const {return(X!=rvalue.X || Y!=rvalue.Y || Width!=rvalue.Width || Height!=rvalue.Height);}
- // Addition and subtraction operators.
- TRect<T> const & operator += (TPoint2D<T> const & point) {X += point.X;Y += point.Y;return(*this);}
- TRect<T> const & operator -= (TPoint2D<T> const & point) {X -= point.X;Y -= point.Y;return(*this);}
- TRect<T> const operator + (TPoint2D<T> const & point) {return(TRect<T>(Top_Left() + point, Width, Height));}
- TRect<T> const operator - (TPoint2D<T> const & point) {return(TRect<T>(Top_Left() - point, Width, Height));}
- /*
- ** Bias this rectangle within another.
- */
- TRect<T> const Bias_To(TRect<T> const & rect) const {return(TRect<T>(Top_Left() + rect.Top_Left(), Width, Height));}
- // Assign values
- void Set(T x, T y, T w, T h) {X = x; Y = y; Width = w; Height = h;}
- /*
- ** Determine if two rectangles overlap.
- */
- bool Is_Overlapping(TRect<T> const & rect) const {return(X < rect.X+rect.Width && Y < rect.Y+rect.Height && X+Width > rect.X && Y+Height > rect.Y);}
- /*
- ** Determine is rectangle is valid.
- */
- bool Is_Valid(void) const {return(Width > 0 && Height > 0);}
- __declspec(property(get=Is_Valid)) bool IsValid;
- /*
- ** Returns size of rectangle if each discrete location within it is presumed
- ** to be of size 1.
- */
- int Size(void) const {return(int(Width) * int(Height));}
- /*
- ** Fetch points of rectangle (used as a convenience for the programmer).
- */
- TPoint2D<T> Top_Left(void) const {return(TPoint2D<T>(X, Y));}
- __declspec(property(get=Top_Left)) TPoint2D<T> TopLeft;
- TPoint2D<T> Top_Right(void) const {return(TPoint2D<T>(T(X + Width - 1), Y));}
- __declspec(property(get=Top_Right)) TPoint2D<T> TopRight;
-
- TPoint2D<T> Bottom_Left(void) const {return(TPoint2D<T>(X, T(Y + Height - 1)));}
- __declspec(property(get=Bottom_Left)) TPoint2D<T> BottomLeft;
-
- TPoint2D<T> Bottom_Right(void) const {return(TPoint2D<T>(T(X + Width - 1), T(Y + Height - 1)));}
- __declspec(property(get=Bottom_Right)) TPoint2D<T> BottomRight;
- /*
- ** Determine if a point lies within the rectangle.
- */
- bool Is_Point_Within(TPoint2D<T> const & point) const {return(point.X >= X && point.X < X+Width && point.Y >= Y && point.Y < Y+Height);}
- public:
- /*
- ** Coordinate of upper left corner of rectangle.
- */
- T X;
- T Y;
- /*
- ** Dimensions of rectangle. If the width or height is less than or equal to
- ** zero, then the rectangle is in an invalid state.
- */
- T Width;
- T Height;
- };
- template<class T>
- TPoint2D<T> const Bias_To(TPoint2D<T> const & point, TRect<T> const & rect)
- {
- return(TPoint2D<T>(T(point.X + rect.X), T(point.Y + rect.Y)));
- }
- /***********************************************************************************************
- * Union -- Combines two rectangles into one larger one. *
- * *
- * This routine will combine the two specified rectangles such that a larger one is *
- * returned that encompasses both rectangles. *
- * *
- * INPUT: rect1 -- One rectangle to combine. *
- * rect2 -- The other rectangle to combine. *
- * *
- * OUTPUT: Returns with the smallest rectangle that encompasses both specified rectangles. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 06/04/1997 JLB : Created. *
- *=============================================================================================*/
- template<class T>
- TRect<T> const Union(TRect<T> const & rect1, TRect<T> const & rect2)
- {
- if (rect1.Is_Valid()) {
- if (rect2.Is_Valid()) {
- TRect<T> result = rect1;
- if (result.X > rect2.X) {
- result.Width += T(result.X-rect2.X);
- result.X = rect2.X;
- }
- if (result.Y > rect2.Y) {
- result.Height += T(result.Y-rect2.Y);
- result.Y = rect2.Y;
- }
- if (result.X+result.Width < rect2.X+rect2.Width) {
- result.Width = T(((rect2.X+rect2.Width)-result.X)+1);
- }
- if (result.Y+result.Height < rect2.Y+rect2.Height) {
- result.Height = T(((rect2.Y+rect2.Height)-result.Y)+1);
- }
- return(result);
- }
- return(rect1);
- }
- return(rect2);
- }
- /***********************************************************************************************
- * Intersect -- Find the intersection between two rectangles. *
- * *
- * This routine will take two rectangles and return the intersecting rectangle. It also *
- * tracks how much on rectangle was clipped off of the top and left edges and returns *
- * these values. It can be handy to use these returned clipping values for blit operations *
- * between rectangles. *
- * *
- * INPUT: bounding_rect -- The rectangle of the bounding box (clipping rectangle). *
- * *
- * draw_rect -- The rectangle that will be clipped into the bounding rectangle. *
- * *
- * x,y -- Place to store the clipping offset performed on the draw_rect. *
- * If this offset is applied to a subsiquent blit operation from *
- * the draw_rect source, it will appear to be properly clipped *
- * against the clipping rectangle rather than offset to the *
- * clipping rectangle. *
- * *
- * OUTPUT: Returns with the rectangle that is the intersection of the two rectangles. *
- * *
- * WARNINGS: The returned rectangle may be clipped into nothingness. Check for Is_Valid *
- * to catch this case. *
- * *
- * HISTORY: *
- * 06/04/1997 JLB : Created. *
- *=============================================================================================*/
- template<class T>
- TRect<T> const Intersect(TRect<T> const & bounding_rect, TRect<T> const & draw_rect, T * x, T * y)
- {
- TRect<T> bad_rect(0, 0, 0, 0); // Dummy (illegal) draw_rect.
- TRect<T> new_draw_rect = draw_rect; // Working draw_rect.
- /*
- ** Both draw_rects must be valid or else no intersection can occur. In such
- ** a case, return an illegal draw_rect.
- */
- if (!bounding_rect.Is_Valid() || !draw_rect.Is_Valid()) return(bad_rect);
- /*
- ** The draw_rect spills past the left edge.
- */
- if (new_draw_rect.X < bounding_rect.X) {
- new_draw_rect.Width -= T(bounding_rect.X - new_draw_rect.X);
- new_draw_rect.X = bounding_rect.X;
- }
- if (new_draw_rect.Width < 1) return(bad_rect);
- /*
- ** The draw_rect spills past top edge.
- */
- if (new_draw_rect.Y < bounding_rect.Y) {
- new_draw_rect.Height -= T(bounding_rect.Y - new_draw_rect.Y);
- new_draw_rect.Y = bounding_rect.Y;
- }
- if (new_draw_rect.Height < 1) return(bad_rect);
- /*
- ** The draw_rect spills past the right edge.
- */
- if (new_draw_rect.X + new_draw_rect.Width > bounding_rect.X + bounding_rect.Width) {
- new_draw_rect.Width -= T((new_draw_rect.X + new_draw_rect.Width) - (bounding_rect.X + bounding_rect.Width));
- }
- if (new_draw_rect.Width < 1) return(bad_rect);
- /*
- ** The draw_rect spills past the bottom edge.
- */
- if (new_draw_rect.Y + new_draw_rect.Height > bounding_rect.Y + bounding_rect.Height) {
- new_draw_rect.Height -= T((new_draw_rect.Y + new_draw_rect.Height) - (bounding_rect.Y + bounding_rect.Height));
- }
- if (new_draw_rect.Height < 1) return(bad_rect);
- /*
- ** Adjust Height relative draw position according to Height new draw_rect
- ** union.
- */
- if (x != NULL) {
- *x -= T(new_draw_rect.X - draw_rect.X);
- }
- if (y != NULL) {
- *y -= T(new_draw_rect.Y - draw_rect.Y);
- }
- return(new_draw_rect);
- }
- /***********************************************************************************************
- * Intersect -- Simple intersect between two rectangles. *
- * *
- * This will return with the rectangle that represents the intersection of the two *
- * rectangles specified. *
- * *
- * INPUT: rect1 -- The first rectangle. *
- * *
- * rect2 -- The second rectangle. *
- * *
- * OUTPUT: Returns with the intersecting rectangle between the two rectangles specified. *
- * *
- * WARNINGS: If there is no valid intersection between the two rectangles, then a rectangle *
- * of illegal value is returned. Check for this case by using the Is_Valid() *
- * function. *
- * *
- * HISTORY: *
- * 06/04/1997 JLB : Created. *
- *=============================================================================================*/
- template<class T>
- TRect<T> const Intersect(TRect<T> const & rect1, TRect<T> const & rect2)
- {
- return(Intersect(rect1, rect2, (T*)NULL, (T*)NULL));
- }
- /*
- ** This typedef provides an uncluttered type name for a rectangle that
- ** is composed of integers.
- */
- typedef TRect<int> Rect;
- const Rect RECT_NONE(0,0,0,0);
- #endif
|