forked from Mirrors/openclonk
Split C4Rect out to its own source file
Because much more depends on C4Rect than only C4Shape, and C4Shape uses lots of other stuff. Also move some other files which depend on C4Group to src/c4group, because I'm editing the build files anyway.
parent
52fe574835
commit
b46f4696e9
|
@ -18,12 +18,16 @@ set(OC_CLONK_SOURCES
|
|||
src/C4GraphicsSystem.cpp
|
||||
src/C4GraphicsSystem.h
|
||||
src/c4group/C4Components.h
|
||||
src/c4group/C4ComponentHost.cpp
|
||||
src/c4group/C4ComponentHost.h
|
||||
src/c4group/C4Extra.cpp
|
||||
src/c4group/C4Extra.h
|
||||
src/c4group/C4Group.cpp
|
||||
src/c4group/C4Group.h
|
||||
src/c4group/C4GroupSet.cpp
|
||||
src/c4group/C4GroupSet.h
|
||||
src/c4group/C4LangStringTable.cpp
|
||||
src/c4group/C4LangStringTable.h
|
||||
src/c4group/C4Language.cpp
|
||||
src/c4group/C4Language.h
|
||||
src/c4group/C4Update.cpp
|
||||
|
@ -217,12 +221,8 @@ set(OC_CLONK_SOURCES
|
|||
src/gui/C4UserMessages.h
|
||||
src/gui/C4Viewport.cpp
|
||||
src/gui/C4Viewport.h
|
||||
src/lib/C4ComponentHost.cpp
|
||||
src/lib/C4ComponentHost.h
|
||||
src/lib/C4InputValidation.cpp
|
||||
src/lib/C4InputValidation.h
|
||||
src/lib/C4LangStringTable.cpp
|
||||
src/lib/C4LangStringTable.h
|
||||
src/lib/C4LogBuf.cpp
|
||||
src/lib/C4LogBuf.h
|
||||
src/lib/C4Log.cpp
|
||||
|
@ -231,6 +231,8 @@ set(OC_CLONK_SOURCES
|
|||
src/lib/C4NameList.h
|
||||
src/lib/C4Random.cpp
|
||||
src/lib/C4Random.h
|
||||
src/lib/C4Rect.cpp
|
||||
src/lib/C4Rect.h
|
||||
src/lib/C4RTF.cpp
|
||||
src/lib/C4RTF.H
|
||||
src/lib/C4Stat.cpp
|
||||
|
|
105
Makefile.am
105
Makefile.am
|
@ -17,6 +17,8 @@ bin_PROGRAMS = clonk
|
|||
|
||||
EXTRA_PROGRAMS = tstc4netio puncher c4group gunzip4c4group
|
||||
|
||||
noinst_LIBRARIES = lib.a
|
||||
|
||||
# Some defines and warning options
|
||||
if RECENT_GCC
|
||||
GCC_FLAGS = -pipe
|
||||
|
@ -83,7 +85,56 @@ WARNING_FLAGS += -Winvalid-pch
|
|||
|
||||
endif
|
||||
|
||||
lib_a_SOURCES = \
|
||||
src/lib/C4InputValidation.cpp \
|
||||
src/lib/C4InputValidation.h \
|
||||
src/lib/C4LogBuf.cpp \
|
||||
src/lib/C4LogBuf.h \
|
||||
src/lib/C4Random.cpp \
|
||||
src/lib/C4Random.h \
|
||||
src/lib/C4Rect.cpp \
|
||||
src/lib/C4Rect.h \
|
||||
src/lib/C4RTF.cpp \
|
||||
src/lib/C4RTF.H \
|
||||
src/lib/C4Stat.cpp \
|
||||
src/lib/C4Stat.h \
|
||||
src/lib/Fixed.cpp \
|
||||
src/lib/Fixed.h \
|
||||
src/lib/PathFinder.cpp \
|
||||
src/lib/PathFinder.h \
|
||||
src/lib/Standard.cpp \
|
||||
src/lib/Standard.h \
|
||||
src/lib/StdAdaptors.h \
|
||||
src/lib/StdBase64.cpp \
|
||||
src/lib/StdBase64.h \
|
||||
src/lib/StdBuf.cpp \
|
||||
src/lib/StdBuf.h \
|
||||
src/lib/StdColors.h \
|
||||
src/lib/StdCompiler.cpp \
|
||||
src/lib/StdCompiler.h \
|
||||
src/lib/StdMarkup.cpp \
|
||||
src/lib/StdMarkup.h \
|
||||
src/lib/StdResStr2.cpp \
|
||||
src/lib/StdResStr2.h \
|
||||
src/lib/StdResStr.h \
|
||||
src/lib/texture/C4Facet.cpp \
|
||||
src/lib/texture/C4FacetEx.cpp \
|
||||
src/lib/texture/C4FacetEx.h \
|
||||
src/lib/texture/C4Facet.h \
|
||||
src/lib/texture/C4Surface.cpp \
|
||||
src/lib/texture/C4SurfaceFile.cpp \
|
||||
src/lib/texture/C4SurfaceFile.h \
|
||||
src/lib/texture/C4Surface.h \
|
||||
src/lib/texture/StdPNG.cpp \
|
||||
src/lib/texture/StdPNG.h
|
||||
|
||||
clonk_SOURCES = \
|
||||
src/lib/C4Log.cpp \
|
||||
src/lib/C4Log.h \
|
||||
src/lib/C4NameList.cpp \
|
||||
src/lib/C4NameList.h \
|
||||
src/lib/texture/C4GraphicsResource.cpp \
|
||||
src/lib/texture/C4GraphicsResource.h \
|
||||
src/C4Application.cpp \
|
||||
src/C4Application.h \
|
||||
src/C4FullScreen.cpp \
|
||||
|
@ -92,7 +143,11 @@ src/C4Game.cpp \
|
|||
src/C4Game.h \
|
||||
src/C4GraphicsSystem.cpp \
|
||||
src/C4GraphicsSystem.h \
|
||||
src/c4group/C4LangStringTable.cpp \
|
||||
src/c4group/C4LangStringTable.h \
|
||||
src/c4group/C4Components.h \
|
||||
src/c4group/C4ComponentHost.cpp \
|
||||
src/c4group/C4ComponentHost.h \
|
||||
src/c4group/C4Extra.cpp \
|
||||
src/c4group/C4Extra.h \
|
||||
src/c4group/C4Group.cpp \
|
||||
|
@ -292,55 +347,6 @@ src/gui/C4UpperBoard.h \
|
|||
src/gui/C4UserMessages.h \
|
||||
src/gui/C4Viewport.cpp \
|
||||
src/gui/C4Viewport.h \
|
||||
src/lib/C4ComponentHost.cpp \
|
||||
src/lib/C4ComponentHost.h \
|
||||
src/lib/C4InputValidation.cpp \
|
||||
src/lib/C4InputValidation.h \
|
||||
src/lib/C4LangStringTable.cpp \
|
||||
src/lib/C4LangStringTable.h \
|
||||
src/lib/C4LogBuf.cpp \
|
||||
src/lib/C4LogBuf.h \
|
||||
src/lib/C4Log.cpp \
|
||||
src/lib/C4Log.h \
|
||||
src/lib/C4NameList.cpp \
|
||||
src/lib/C4NameList.h \
|
||||
src/lib/C4Random.cpp \
|
||||
src/lib/C4Random.h \
|
||||
src/lib/C4RTF.cpp \
|
||||
src/lib/C4RTF.H \
|
||||
src/lib/C4Stat.cpp \
|
||||
src/lib/C4Stat.h \
|
||||
src/lib/Fixed.cpp \
|
||||
src/lib/Fixed.h \
|
||||
src/lib/PathFinder.cpp \
|
||||
src/lib/PathFinder.h \
|
||||
src/lib/Standard.cpp \
|
||||
src/lib/Standard.h \
|
||||
src/lib/StdAdaptors.h \
|
||||
src/lib/StdBase64.cpp \
|
||||
src/lib/StdBase64.h \
|
||||
src/lib/StdBuf.cpp \
|
||||
src/lib/StdBuf.h \
|
||||
src/lib/StdColors.h \
|
||||
src/lib/StdCompiler.cpp \
|
||||
src/lib/StdCompiler.h \
|
||||
src/lib/StdMarkup.cpp \
|
||||
src/lib/StdMarkup.h \
|
||||
src/lib/StdResStr2.cpp \
|
||||
src/lib/StdResStr2.h \
|
||||
src/lib/StdResStr.h \
|
||||
src/lib/texture/C4Facet.cpp \
|
||||
src/lib/texture/C4FacetEx.cpp \
|
||||
src/lib/texture/C4FacetEx.h \
|
||||
src/lib/texture/C4Facet.h \
|
||||
src/lib/texture/C4GraphicsResource.cpp \
|
||||
src/lib/texture/C4GraphicsResource.h \
|
||||
src/lib/texture/C4Surface.cpp \
|
||||
src/lib/texture/C4SurfaceFile.cpp \
|
||||
src/lib/texture/C4SurfaceFile.h \
|
||||
src/lib/texture/C4Surface.h \
|
||||
src/lib/texture/StdPNG.cpp \
|
||||
src/lib/texture/StdPNG.h \
|
||||
src/network/C4Client.cpp \
|
||||
src/network/C4Client.h \
|
||||
src/network/C4GameControlNetwork.cpp \
|
||||
|
@ -483,6 +489,7 @@ clonk_SOURCES += src/platform/StdGtkWindow.cpp src/platform/StdGtkWindow.h
|
|||
endif
|
||||
|
||||
clonk_LDADD = \
|
||||
lib.a \
|
||||
$(LIBICONV) \
|
||||
$(GTK_LIBS) \
|
||||
$(FREETYPE_LIBS) \
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "C4Include.h"
|
||||
#include "C4LangStringTable.h"
|
||||
#include "C4InputValidation.h"
|
||||
|
||||
struct C4StringTableEntry
|
||||
{
|
|
@ -50,152 +50,6 @@ C4Shape::C4Shape()
|
|||
Default();
|
||||
}
|
||||
|
||||
void C4Rect::Default()
|
||||
{
|
||||
x=y=Wdt=Hgt=0;
|
||||
}
|
||||
|
||||
void C4Rect::CompileFunc(StdCompiler *pComp)
|
||||
{
|
||||
pComp->Value(mkDefaultAdapt(x, 0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(y, 0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(Wdt, 0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(Hgt, 0));
|
||||
}
|
||||
|
||||
void C4TargetRect::Default()
|
||||
{
|
||||
C4Rect::Default();
|
||||
tx=ty=0;
|
||||
}
|
||||
|
||||
void C4TargetRect::Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY)
|
||||
{
|
||||
C4Rect::Set(iX,iY,iWdt,iHgt);
|
||||
tx=iTX; ty=iTY;
|
||||
}
|
||||
|
||||
bool C4TargetRect::ClipBy(C4TargetRect &rClip)
|
||||
{
|
||||
int32_t d;
|
||||
// clip left
|
||||
if ((d = x - rClip.x) < 0) { Wdt += d; x = rClip.x; } else tx += d;
|
||||
// clip top
|
||||
if ((d = y - rClip.y) < 0) { Hgt += d; y = rClip.y; } else ty += d;
|
||||
// clip right
|
||||
if ((d = (x+Wdt - rClip.x-rClip.Wdt)) > 0) Wdt -= d;
|
||||
// clip bottom
|
||||
if ((d = (y+Hgt - rClip.y-rClip.Hgt)) > 0) Hgt -= d;
|
||||
// check validity
|
||||
if (Wdt <= 0 || Hgt <= 0) return false;
|
||||
// add target pos
|
||||
tx += rClip.tx;
|
||||
ty += rClip.ty;
|
||||
// done
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4TargetRect::Set(const C4TargetFacet &rSrc)
|
||||
{
|
||||
// copy members
|
||||
x=rSrc.X; y=rSrc.Y; Wdt=rSrc.Wdt; Hgt=rSrc.Hgt; tx=rSrc.TargetX; ty=rSrc.TargetY;
|
||||
}
|
||||
|
||||
void C4TargetRect::CompileFunc(StdCompiler *pComp)
|
||||
{
|
||||
C4Rect::CompileFunc(pComp); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(tx,0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(ty,0));
|
||||
}
|
||||
|
||||
void C4Rect::Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt)
|
||||
{
|
||||
x=iX; y=iY; Wdt=iWdt; Hgt=iHgt;
|
||||
}
|
||||
|
||||
BOOL C4Rect::Overlap(C4Rect &rTarget)
|
||||
{
|
||||
if (x+Wdt<=rTarget.x) return FALSE;
|
||||
if (x>=rTarget.x+rTarget.Wdt) return FALSE;
|
||||
if (y+Hgt<=rTarget.y) return FALSE;
|
||||
if (y>=rTarget.y+rTarget.Hgt) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void C4Rect::Intersect(const C4Rect &r2)
|
||||
{
|
||||
// Narrow bounds
|
||||
if (r2.x > x)
|
||||
if (r2.x + r2.Wdt < x + Wdt)
|
||||
{ x = r2.x; Wdt = r2.Wdt; }
|
||||
else
|
||||
{ Wdt -= (r2.x - x); x = r2.x; }
|
||||
else
|
||||
if (r2.x + r2.Wdt < x + Wdt)
|
||||
Wdt = r2.x + r2.Wdt - x;
|
||||
if (r2.y > y)
|
||||
if (r2.y + r2.Hgt < y + Hgt)
|
||||
{ y = r2.y; Hgt = r2.Hgt; }
|
||||
else
|
||||
{ Hgt -= (r2.y - y); y = r2.y; }
|
||||
else
|
||||
if (r2.y + r2.Hgt < y + Hgt)
|
||||
Hgt = r2.y + r2.Hgt - y;
|
||||
// Degenerated? Will happen when the two rects don't overlap
|
||||
if (Wdt < 0) Wdt = 0;
|
||||
if (Hgt < 0) Hgt = 0;
|
||||
}
|
||||
|
||||
bool C4Rect::IntersectsLine(int32_t iX, int32_t iY, int32_t iX2, int32_t iY2)
|
||||
{
|
||||
// Easy cases first
|
||||
if(Contains(iX, iY)) return true;
|
||||
if(Contains(iX2, iY2)) return true;
|
||||
if(iX < x && iX2 < x) return false;
|
||||
if(iY < y && iY2 < y) return false;
|
||||
if(iX >= x+Wdt && iX2 >= x+Wdt) return false;
|
||||
if(iY >= y+Hgt && iY2 >= y+Hgt) return false;
|
||||
// check some special cases
|
||||
if (iX == iX2 || iY == iY2) return true;
|
||||
// Check intersection left/right
|
||||
int32_t iXI, iYI;
|
||||
iXI = (iX < x ? x : x+Wdt);
|
||||
iYI = iY + (iY2 - iY) * (iXI - iX) / (iX2 - iX);
|
||||
if(iYI >= y && iYI < y+Hgt) return true;
|
||||
// Check intersection up/down
|
||||
iYI = (iY < y ? y : y+Hgt);
|
||||
iXI = iX + (iX2 - iX) * (iYI - iY) / (iY2 - iY);
|
||||
return iXI >= x && iXI < x+Wdt;
|
||||
}
|
||||
|
||||
void C4Rect::Add(const C4Rect &r2)
|
||||
{
|
||||
// Null? Don't do anything
|
||||
if (!r2.Wdt || !r2.Hgt) return;
|
||||
if (!Wdt || !Hgt)
|
||||
{
|
||||
*this = r2;
|
||||
return;
|
||||
}
|
||||
// Expand bounds
|
||||
if (r2.x < x)
|
||||
if (r2.x + r2.Wdt > x + Wdt)
|
||||
{ x = r2.x; Wdt = r2.Wdt; }
|
||||
else
|
||||
{ Wdt += (x - r2.x); x = r2.x; }
|
||||
else
|
||||
if (r2.x + r2.Wdt > x + Wdt)
|
||||
Wdt = r2.x + r2.Wdt - x;
|
||||
if (r2.y < y)
|
||||
if (r2.y + r2.Hgt > y + Hgt)
|
||||
{ y = r2.y; Hgt = r2.Hgt; }
|
||||
else
|
||||
{ Hgt += (y - r2.y); y = r2.y; }
|
||||
else
|
||||
if (r2.y + r2.Hgt > y + Hgt)
|
||||
Hgt = r2.y + r2.Hgt - y;
|
||||
}
|
||||
|
||||
void C4Shape::Clear()
|
||||
{
|
||||
ZeroMem(this, sizeof (C4Shape));
|
||||
|
@ -679,95 +533,3 @@ void C4Shape::CompileFunc(StdCompiler *pComp, bool fRuntime)
|
|||
pComp->Value(mkNamingAdapt( iAttachVtx, "AttachVtx", 0 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---- C4RectList ----
|
||||
|
||||
|
||||
void C4RectList::ClipByRect(const C4Rect &rClip)
|
||||
{
|
||||
// split up all rectangles
|
||||
for (int32_t i = 0; i < GetCount(); ++i)
|
||||
{
|
||||
C4Rect *pTarget = &Get(i);
|
||||
// any overlap?
|
||||
if (rClip.x+rClip.Wdt <= pTarget->x) continue;
|
||||
if (rClip.y+rClip.Hgt <= pTarget->y) continue;
|
||||
if (rClip.x >= pTarget->x+pTarget->Wdt) continue;
|
||||
if (rClip.y >= pTarget->y+pTarget->Hgt) continue;
|
||||
// okay; split up rectangle
|
||||
// first split will just reduce the target rectangle size
|
||||
// if more splits are done, additional rectangles need to be added
|
||||
int32_t iSplitCount = 0, iOver; C4Rect rcThis(*pTarget);
|
||||
// clipped by right side
|
||||
if ((iOver=rcThis.x+rcThis.Wdt-rClip.x-rClip.Wdt)>0)
|
||||
{
|
||||
pTarget->x += pTarget->Wdt - iOver; pTarget->Wdt = iOver; rcThis.Wdt -= iOver;
|
||||
++iSplitCount;
|
||||
}
|
||||
// clipped by obttom side
|
||||
if ((iOver=rcThis.y+rcThis.Hgt-rClip.y-rClip.Hgt)>0)
|
||||
{
|
||||
if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
|
||||
pTarget->y += pTarget->Hgt - iOver; pTarget->Hgt = iOver; rcThis.Hgt -= iOver;
|
||||
++iSplitCount;
|
||||
}
|
||||
// clipped by left side
|
||||
if ((iOver=rClip.x-rcThis.x)>0)
|
||||
{
|
||||
if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
|
||||
pTarget->Wdt = iOver; rcThis.Wdt -= iOver; rcThis.x = rClip.x;
|
||||
++iSplitCount;
|
||||
}
|
||||
// clipped by top side
|
||||
if ((iOver=rClip.y-rcThis.y)>0)
|
||||
{
|
||||
if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); } else ++iSplitCount;
|
||||
pTarget->Hgt = iOver; /* rcThis.Hgt -= iOver; rcThis.y = rClip.y; not needed, since rcThis is no longer used */
|
||||
}
|
||||
// nothing split? This means this rectnagle is completely contained
|
||||
if (!iSplitCount)
|
||||
{
|
||||
// make it vanish
|
||||
RemoveIndexedRect(i); --i;
|
||||
}
|
||||
}
|
||||
// concat rectangles if possible
|
||||
bool fDone = false;
|
||||
while (!fDone)
|
||||
{
|
||||
fDone=true;
|
||||
for (int32_t i = 0, cnt=GetCount(); i < cnt && fDone; ++i)
|
||||
{
|
||||
C4Rect &rc1 = Get(i);
|
||||
for (int32_t j = i+1; j < cnt; ++j)
|
||||
{
|
||||
C4Rect &rc2 = Get(j);
|
||||
if (rc1.y == rc2.y && rc1.Hgt == rc2.Hgt)
|
||||
{
|
||||
if (rc1.x + rc1.Wdt == rc2.x)
|
||||
{
|
||||
rc1.Wdt += rc2.Wdt; RemoveIndexedRect(j); fDone=false; break;
|
||||
}
|
||||
else if (rc2.x + rc2.Wdt == rc1.x)
|
||||
{
|
||||
rc2.Wdt += rc1.Wdt; RemoveIndexedRect(i); fDone=false; break;
|
||||
}
|
||||
}
|
||||
else if (rc1.x == rc2.x && rc1.Wdt == rc2.Wdt)
|
||||
{
|
||||
if (rc1.y + rc1.Hgt == rc2.y)
|
||||
{
|
||||
rc1.Hgt += rc2.Hgt; RemoveIndexedRect(j); fDone=false; break;
|
||||
}
|
||||
else if (rc2.y + rc2.Hgt == rc1.y)
|
||||
{
|
||||
rc2.Hgt += rc1.Hgt; RemoveIndexedRect(i); fDone=false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,71 +26,10 @@
|
|||
|
||||
#include "C4FacetEx.h"
|
||||
#include "C4Constants.h"
|
||||
#include "C4Rect.h"
|
||||
|
||||
#define C4D_VertexCpyPos (C4D_MaxVertex/2)
|
||||
|
||||
class C4Rect
|
||||
{
|
||||
public:
|
||||
int32_t x,y,Wdt,Hgt;
|
||||
public:
|
||||
void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt);
|
||||
void Default();
|
||||
BOOL Overlap(C4Rect &rTarget);
|
||||
void Intersect(const C4Rect &r2);
|
||||
void Add(const C4Rect &r2);
|
||||
bool operator ==(const C4Rect &r2) { return !((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); }
|
||||
bool operator !=(const C4Rect &r2) { return 0 != ((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); }
|
||||
|
||||
bool Contains(int32_t iX, int32_t iY)
|
||||
{ return iX>=x && iX<x+Wdt && iY>=y && iY<y+Hgt; }
|
||||
bool Contains(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt)
|
||||
{ return iX>=x && iX+iWdt<x+Wdt && iY>=y && iY+iHgt<y+Hgt; }
|
||||
bool Contains(const C4Rect &rect)
|
||||
{ return Contains(rect.x, rect.y, rect.Wdt, rect.Hgt); }
|
||||
bool IntersectsLine(int32_t iX, int32_t iY, int32_t iX2, int32_t iY2);
|
||||
|
||||
void Normalize()
|
||||
{ if(Wdt < 0) { x+=Wdt+1; Wdt=-Wdt; } if(Hgt < 0) { y+=Hgt+1; Hgt=-Hgt; } }
|
||||
|
||||
void Enlarge(int32_t iBy)
|
||||
{ x -= iBy; y -= iBy; Wdt += 2*iBy; Hgt += 2*iBy; }
|
||||
|
||||
int32_t GetMiddleX() { return x+Wdt/2; }
|
||||
int32_t GetMiddleY() { return y+Hgt/2; }
|
||||
int32_t GetBottom() { return y+Hgt; }
|
||||
|
||||
C4Rect(int32_t tx, int32_t ty, int32_t twdt, int32_t thgt) // ctor
|
||||
{ x=tx; y=ty; Wdt=twdt; Hgt=thgt; }
|
||||
C4Rect() { } // default ctor; doesn't initialize
|
||||
C4Rect(const FLOAT_RECT &rcfOuter) // set to surround floating point rectangle
|
||||
{ x=static_cast<int32_t>(rcfOuter.left); y=static_cast<int32_t>(rcfOuter.top);
|
||||
Wdt=static_cast<int32_t>(ceilf(rcfOuter.right)-floorf(rcfOuter.left));
|
||||
Hgt=static_cast<int32_t>(ceilf(rcfOuter.bottom)-floorf(rcfOuter.top)); }
|
||||
|
||||
void CompileFunc(StdCompiler *pComp);
|
||||
};
|
||||
|
||||
class C4TargetRect: public C4Rect
|
||||
{
|
||||
public:
|
||||
int32_t tx,ty;
|
||||
public:
|
||||
C4TargetRect(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY)
|
||||
: C4Rect(iX, iY, iWdt, iHgt), tx(iTX), ty(iTY) { }
|
||||
C4TargetRect() { } // default ctor; doesn't initialize
|
||||
void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY);
|
||||
void Default();
|
||||
bool ClipBy(C4TargetRect &rClip); // clip this rectangle by the given one (adding target positions) - return false if they don't overlap
|
||||
|
||||
void Set(const C4TargetFacet &rSrc); // copy contents from facet
|
||||
|
||||
void CompileFunc(StdCompiler *pComp);
|
||||
};
|
||||
|
||||
const C4Rect Rect0(0,0,0,0);
|
||||
const C4TargetRect TargetRect0(0,0,0,0,0,0);
|
||||
|
||||
// a functional class to provide density for coordinates
|
||||
class C4DensityProvider
|
||||
{
|
||||
|
@ -145,22 +84,4 @@ class C4Shape: public C4Rect
|
|||
void CompileFunc(StdCompiler *pComp, bool fRuntime);
|
||||
};
|
||||
|
||||
|
||||
// a bunch of rectangles
|
||||
// rects NOT including pos+size-point
|
||||
class C4RectList : public std::vector<C4Rect>
|
||||
{
|
||||
public:
|
||||
void AddRect(const C4Rect &rNewRect)
|
||||
{ push_back(rNewRect); }
|
||||
void RemoveIndexedRect(int32_t idx)
|
||||
{ if (idx<GetCount()-1) Get(idx)=Get(GetCount()-1); pop_back(); }
|
||||
void Clear() { clear(); }
|
||||
int32_t GetCount() const { return size(); }
|
||||
C4Rect &Get(int32_t idx) { return (*this)[idx]; } // access w/o range check
|
||||
|
||||
void ClipByRect(const C4Rect &rClip); // split up rectangles
|
||||
};
|
||||
|
||||
|
||||
#endif // INC_C4Shape
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 1998-2000, 2005, 2007 Matthes Bender
|
||||
* Copyright (c) 2001-2007 Sven Eberhardt
|
||||
* Copyright (c) 2003, 2005-2007 Peter Wortmann
|
||||
* Copyright (c) 2006-2009 Günther Brammer
|
||||
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
|
||||
/* Basic classes for rectangles and vertex outlines */
|
||||
|
||||
#include "C4Include.h"
|
||||
#include "C4Rect.h"
|
||||
#include "C4FacetEx.h"
|
||||
|
||||
void C4Rect::Default()
|
||||
{
|
||||
x=y=Wdt=Hgt=0;
|
||||
}
|
||||
|
||||
void C4Rect::CompileFunc(StdCompiler *pComp)
|
||||
{
|
||||
pComp->Value(mkDefaultAdapt(x, 0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(y, 0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(Wdt, 0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(Hgt, 0));
|
||||
}
|
||||
|
||||
void C4TargetRect::Default()
|
||||
{
|
||||
C4Rect::Default();
|
||||
tx=ty=0;
|
||||
}
|
||||
|
||||
void C4TargetRect::Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY)
|
||||
{
|
||||
C4Rect::Set(iX,iY,iWdt,iHgt);
|
||||
tx=iTX; ty=iTY;
|
||||
}
|
||||
|
||||
bool C4TargetRect::ClipBy(C4TargetRect &rClip)
|
||||
{
|
||||
int32_t d;
|
||||
// clip left
|
||||
if ((d = x - rClip.x) < 0) { Wdt += d; x = rClip.x; } else tx += d;
|
||||
// clip top
|
||||
if ((d = y - rClip.y) < 0) { Hgt += d; y = rClip.y; } else ty += d;
|
||||
// clip right
|
||||
if ((d = (x+Wdt - rClip.x-rClip.Wdt)) > 0) Wdt -= d;
|
||||
// clip bottom
|
||||
if ((d = (y+Hgt - rClip.y-rClip.Hgt)) > 0) Hgt -= d;
|
||||
// check validity
|
||||
if (Wdt <= 0 || Hgt <= 0) return false;
|
||||
// add target pos
|
||||
tx += rClip.tx;
|
||||
ty += rClip.ty;
|
||||
// done
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4TargetRect::Set(const C4TargetFacet &rSrc)
|
||||
{
|
||||
// copy members
|
||||
x=rSrc.X; y=rSrc.Y; Wdt=rSrc.Wdt; Hgt=rSrc.Hgt; tx=rSrc.TargetX; ty=rSrc.TargetY;
|
||||
}
|
||||
|
||||
void C4TargetRect::CompileFunc(StdCompiler *pComp)
|
||||
{
|
||||
C4Rect::CompileFunc(pComp); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(tx,0)); pComp->Seperator();
|
||||
pComp->Value(mkDefaultAdapt(ty,0));
|
||||
}
|
||||
|
||||
void C4Rect::Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt)
|
||||
{
|
||||
x=iX; y=iY; Wdt=iWdt; Hgt=iHgt;
|
||||
}
|
||||
|
||||
BOOL C4Rect::Overlap(C4Rect &rTarget)
|
||||
{
|
||||
if (x+Wdt<=rTarget.x) return FALSE;
|
||||
if (x>=rTarget.x+rTarget.Wdt) return FALSE;
|
||||
if (y+Hgt<=rTarget.y) return FALSE;
|
||||
if (y>=rTarget.y+rTarget.Hgt) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void C4Rect::Intersect(const C4Rect &r2)
|
||||
{
|
||||
// Narrow bounds
|
||||
if (r2.x > x)
|
||||
if (r2.x + r2.Wdt < x + Wdt)
|
||||
{ x = r2.x; Wdt = r2.Wdt; }
|
||||
else
|
||||
{ Wdt -= (r2.x - x); x = r2.x; }
|
||||
else
|
||||
if (r2.x + r2.Wdt < x + Wdt)
|
||||
Wdt = r2.x + r2.Wdt - x;
|
||||
if (r2.y > y)
|
||||
if (r2.y + r2.Hgt < y + Hgt)
|
||||
{ y = r2.y; Hgt = r2.Hgt; }
|
||||
else
|
||||
{ Hgt -= (r2.y - y); y = r2.y; }
|
||||
else
|
||||
if (r2.y + r2.Hgt < y + Hgt)
|
||||
Hgt = r2.y + r2.Hgt - y;
|
||||
// Degenerated? Will happen when the two rects don't overlap
|
||||
if (Wdt < 0) Wdt = 0;
|
||||
if (Hgt < 0) Hgt = 0;
|
||||
}
|
||||
|
||||
bool C4Rect::IntersectsLine(int32_t iX, int32_t iY, int32_t iX2, int32_t iY2)
|
||||
{
|
||||
// Easy cases first
|
||||
if(Contains(iX, iY)) return true;
|
||||
if(Contains(iX2, iY2)) return true;
|
||||
if(iX < x && iX2 < x) return false;
|
||||
if(iY < y && iY2 < y) return false;
|
||||
if(iX >= x+Wdt && iX2 >= x+Wdt) return false;
|
||||
if(iY >= y+Hgt && iY2 >= y+Hgt) return false;
|
||||
// check some special cases
|
||||
if (iX == iX2 || iY == iY2) return true;
|
||||
// Check intersection left/right
|
||||
int32_t iXI, iYI;
|
||||
iXI = (iX < x ? x : x+Wdt);
|
||||
iYI = iY + (iY2 - iY) * (iXI - iX) / (iX2 - iX);
|
||||
if(iYI >= y && iYI < y+Hgt) return true;
|
||||
// Check intersection up/down
|
||||
iYI = (iY < y ? y : y+Hgt);
|
||||
iXI = iX + (iX2 - iX) * (iYI - iY) / (iY2 - iY);
|
||||
return iXI >= x && iXI < x+Wdt;
|
||||
}
|
||||
|
||||
void C4Rect::Add(const C4Rect &r2)
|
||||
{
|
||||
// Null? Don't do anything
|
||||
if (!r2.Wdt || !r2.Hgt) return;
|
||||
if (!Wdt || !Hgt)
|
||||
{
|
||||
*this = r2;
|
||||
return;
|
||||
}
|
||||
// Expand bounds
|
||||
if (r2.x < x)
|
||||
if (r2.x + r2.Wdt > x + Wdt)
|
||||
{ x = r2.x; Wdt = r2.Wdt; }
|
||||
else
|
||||
{ Wdt += (x - r2.x); x = r2.x; }
|
||||
else
|
||||
if (r2.x + r2.Wdt > x + Wdt)
|
||||
Wdt = r2.x + r2.Wdt - x;
|
||||
if (r2.y < y)
|
||||
if (r2.y + r2.Hgt > y + Hgt)
|
||||
{ y = r2.y; Hgt = r2.Hgt; }
|
||||
else
|
||||
{ Hgt += (y - r2.y); y = r2.y; }
|
||||
else
|
||||
if (r2.y + r2.Hgt > y + Hgt)
|
||||
Hgt = r2.y + r2.Hgt - y;
|
||||
}
|
||||
|
||||
// ---- C4RectList ----
|
||||
|
||||
|
||||
void C4RectList::ClipByRect(const C4Rect &rClip)
|
||||
{
|
||||
// split up all rectangles
|
||||
for (int32_t i = 0; i < GetCount(); ++i)
|
||||
{
|
||||
C4Rect *pTarget = &Get(i);
|
||||
// any overlap?
|
||||
if (rClip.x+rClip.Wdt <= pTarget->x) continue;
|
||||
if (rClip.y+rClip.Hgt <= pTarget->y) continue;
|
||||
if (rClip.x >= pTarget->x+pTarget->Wdt) continue;
|
||||
if (rClip.y >= pTarget->y+pTarget->Hgt) continue;
|
||||
// okay; split up rectangle
|
||||
// first split will just reduce the target rectangle size
|
||||
// if more splits are done, additional rectangles need to be added
|
||||
int32_t iSplitCount = 0, iOver; C4Rect rcThis(*pTarget);
|
||||
// clipped by right side
|
||||
if ((iOver=rcThis.x+rcThis.Wdt-rClip.x-rClip.Wdt)>0)
|
||||
{
|
||||
pTarget->x += pTarget->Wdt - iOver; pTarget->Wdt = iOver; rcThis.Wdt -= iOver;
|
||||
++iSplitCount;
|
||||
}
|
||||
// clipped by obttom side
|
||||
if ((iOver=rcThis.y+rcThis.Hgt-rClip.y-rClip.Hgt)>0)
|
||||
{
|
||||
if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
|
||||
pTarget->y += pTarget->Hgt - iOver; pTarget->Hgt = iOver; rcThis.Hgt -= iOver;
|
||||
++iSplitCount;
|
||||
}
|
||||
// clipped by left side
|
||||
if ((iOver=rClip.x-rcThis.x)>0)
|
||||
{
|
||||
if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); }
|
||||
pTarget->Wdt = iOver; rcThis.Wdt -= iOver; rcThis.x = rClip.x;
|
||||
++iSplitCount;
|
||||
}
|
||||
// clipped by top side
|
||||
if ((iOver=rClip.y-rcThis.y)>0)
|
||||
{
|
||||
if (iSplitCount) { AddRect(rcThis); pTarget = &Get(GetCount()-1); } else ++iSplitCount;
|
||||
pTarget->Hgt = iOver; /* rcThis.Hgt -= iOver; rcThis.y = rClip.y; not needed, since rcThis is no longer used */
|
||||
}
|
||||
// nothing split? This means this rectnagle is completely contained
|
||||
if (!iSplitCount)
|
||||
{
|
||||
// make it vanish
|
||||
RemoveIndexedRect(i); --i;
|
||||
}
|
||||
}
|
||||
// concat rectangles if possible
|
||||
bool fDone = false;
|
||||
while (!fDone)
|
||||
{
|
||||
fDone=true;
|
||||
for (int32_t i = 0, cnt=GetCount(); i < cnt && fDone; ++i)
|
||||
{
|
||||
C4Rect &rc1 = Get(i);
|
||||
for (int32_t j = i+1; j < cnt; ++j)
|
||||
{
|
||||
C4Rect &rc2 = Get(j);
|
||||
if (rc1.y == rc2.y && rc1.Hgt == rc2.Hgt)
|
||||
{
|
||||
if (rc1.x + rc1.Wdt == rc2.x)
|
||||
{
|
||||
rc1.Wdt += rc2.Wdt; RemoveIndexedRect(j); fDone=false; break;
|
||||
}
|
||||
else if (rc2.x + rc2.Wdt == rc1.x)
|
||||
{
|
||||
rc2.Wdt += rc1.Wdt; RemoveIndexedRect(i); fDone=false; break;
|
||||
}
|
||||
}
|
||||
else if (rc1.x == rc2.x && rc1.Wdt == rc2.Wdt)
|
||||
{
|
||||
if (rc1.y + rc1.Hgt == rc2.y)
|
||||
{
|
||||
rc1.Hgt += rc2.Hgt; RemoveIndexedRect(j); fDone=false; break;
|
||||
}
|
||||
else if (rc2.y + rc2.Hgt == rc1.y)
|
||||
{
|
||||
rc2.Hgt += rc1.Hgt; RemoveIndexedRect(i); fDone=false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 1998-2000, 2007 Matthes Bender
|
||||
* Copyright (c) 2001, 2003-2006 Sven Eberhardt
|
||||
* Copyright (c) 2005-2006 Peter Wortmann
|
||||
* Copyright (c) 2006, 2009 Günther Brammer
|
||||
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
|
||||
/* Basic classes for rectangles and vertex outlines */
|
||||
|
||||
#ifndef INC_C4Rect
|
||||
#define INC_C4Rect
|
||||
|
||||
#define C4D_VertexCpyPos (C4D_MaxVertex/2)
|
||||
|
||||
class C4Rect
|
||||
{
|
||||
public:
|
||||
int32_t x,y,Wdt,Hgt;
|
||||
public:
|
||||
void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt);
|
||||
void Default();
|
||||
BOOL Overlap(C4Rect &rTarget);
|
||||
void Intersect(const C4Rect &r2);
|
||||
void Add(const C4Rect &r2);
|
||||
bool operator ==(const C4Rect &r2) { return !((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); }
|
||||
bool operator !=(const C4Rect &r2) { return 0 != ((x-r2.x) | (y-r2.y) | (Wdt-r2.Wdt) | (Hgt-r2.Hgt)); }
|
||||
|
||||
bool Contains(int32_t iX, int32_t iY)
|
||||
{ return iX>=x && iX<x+Wdt && iY>=y && iY<y+Hgt; }
|
||||
bool Contains(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt)
|
||||
{ return iX>=x && iX+iWdt<x+Wdt && iY>=y && iY+iHgt<y+Hgt; }
|
||||
bool Contains(const C4Rect &rect)
|
||||
{ return Contains(rect.x, rect.y, rect.Wdt, rect.Hgt); }
|
||||
bool IntersectsLine(int32_t iX, int32_t iY, int32_t iX2, int32_t iY2);
|
||||
|
||||
void Normalize()
|
||||
{ if(Wdt < 0) { x+=Wdt+1; Wdt=-Wdt; } if(Hgt < 0) { y+=Hgt+1; Hgt=-Hgt; } }
|
||||
|
||||
void Enlarge(int32_t iBy)
|
||||
{ x -= iBy; y -= iBy; Wdt += 2*iBy; Hgt += 2*iBy; }
|
||||
|
||||
int32_t GetMiddleX() { return x+Wdt/2; }
|
||||
int32_t GetMiddleY() { return y+Hgt/2; }
|
||||
int32_t GetBottom() { return y+Hgt; }
|
||||
|
||||
C4Rect(int32_t tx, int32_t ty, int32_t twdt, int32_t thgt) // ctor
|
||||
{ x=tx; y=ty; Wdt=twdt; Hgt=thgt; }
|
||||
C4Rect() { } // default ctor; doesn't initialize
|
||||
C4Rect(const FLOAT_RECT &rcfOuter) // set to surround floating point rectangle
|
||||
{ x=static_cast<int32_t>(rcfOuter.left); y=static_cast<int32_t>(rcfOuter.top);
|
||||
Wdt=static_cast<int32_t>(ceilf(rcfOuter.right)-floorf(rcfOuter.left));
|
||||
Hgt=static_cast<int32_t>(ceilf(rcfOuter.bottom)-floorf(rcfOuter.top)); }
|
||||
|
||||
void CompileFunc(StdCompiler *pComp);
|
||||
};
|
||||
|
||||
class C4TargetRect: public C4Rect
|
||||
{
|
||||
public:
|
||||
int32_t tx,ty;
|
||||
public:
|
||||
C4TargetRect(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY)
|
||||
: C4Rect(iX, iY, iWdt, iHgt), tx(iTX), ty(iTY) { }
|
||||
C4TargetRect() { } // default ctor; doesn't initialize
|
||||
void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY);
|
||||
void Default();
|
||||
bool ClipBy(C4TargetRect &rClip); // clip this rectangle by the given one (adding target positions) - return false if they don't overlap
|
||||
|
||||
void Set(const C4TargetFacet &rSrc); // copy contents from facet
|
||||
|
||||
void CompileFunc(StdCompiler *pComp);
|
||||
};
|
||||
|
||||
const C4Rect Rect0(0,0,0,0);
|
||||
const C4TargetRect TargetRect0(0,0,0,0,0,0);
|
||||
|
||||
// a bunch of rectangles
|
||||
// rects NOT including pos+size-point
|
||||
class C4RectList : public std::vector<C4Rect>
|
||||
{
|
||||
public:
|
||||
void AddRect(const C4Rect &rNewRect)
|
||||
{ push_back(rNewRect); }
|
||||
void RemoveIndexedRect(int32_t idx)
|
||||
{ if (idx<GetCount()-1) Get(idx)=Get(GetCount()-1); pop_back(); }
|
||||
void Clear() { clear(); }
|
||||
int32_t GetCount() const { return size(); }
|
||||
C4Rect &Get(int32_t idx) { return (*this)[idx]; } // access w/o range check
|
||||
|
||||
void ClipByRect(const C4Rect &rClip); // split up rectangles
|
||||
};
|
||||
|
||||
|
||||
#endif // INC_C4Rect
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#ifndef BIG_C4INCLUDE
|
||||
#include <C4Random.h>
|
||||
#include <C4Shape.h>
|
||||
#include <C4Rect.h>
|
||||
#include <C4Group.h>
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue