Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
278 lines
6.2 KiB
C++
278 lines
6.2 KiB
C++
// ViewWindowInfo.cpp: implementation of the ViewWindowInfo class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "MW4GameEd2.h"
|
|
#include "ViewWindowInfo.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
ViewWindowInfo::ViewWindowInfo()
|
|
{
|
|
ClientArea=CSize(100,100);
|
|
BitmapArea=CSize(256,256);
|
|
|
|
ZoomFact.x=1.0f;
|
|
ZoomFact.y=0.0f;
|
|
ZoomFact.z=1.0f;
|
|
|
|
Pan.x=50.0f;
|
|
Pan.y=0.0f;
|
|
Pan.z=50.0f;
|
|
|
|
MapOrg.x=-50.0f;
|
|
MapOrg.y=0.0f;
|
|
MapOrg.z=-50.0f;
|
|
|
|
MapSize.x=100.0f;
|
|
MapSize.y=0.0f;
|
|
MapSize.z=100.0f;
|
|
|
|
CalcConstants();
|
|
}
|
|
|
|
ViewWindowInfo::~ViewWindowInfo()
|
|
{
|
|
|
|
}
|
|
|
|
void ViewWindowInfo::CalcConstants()
|
|
{
|
|
MapOrg.x=-MapSize.x*0.5f;
|
|
MapOrg.z=-MapSize.z*0.5f;
|
|
MapRatio=MapSize.z/MapSize.x;
|
|
ViewSizeX=MapSize.x/ZoomFact.x;
|
|
ViewSizeY=MapSize.z/ZoomFact.z;
|
|
|
|
ClientRatio=((float)ClientArea.cx/(float)ClientArea.cy);
|
|
|
|
if(ClientRatio>1)
|
|
ViewSizeY/=ClientRatio;
|
|
else
|
|
ViewSizeX*=ClientRatio;
|
|
|
|
HalfViewSizeX=ViewSizeX*0.5f;
|
|
HalfViewSizeY=ViewSizeY*0.5f;
|
|
SourcePixs_Per_MeterX=BitmapArea.cx/MapSize.x;
|
|
SourcePixs_Per_MeterY=BitmapArea.cy/MapSize.z;
|
|
DestPixs_Per_MeterX=ClientArea.cx/ViewSizeX;
|
|
DestPixs_Per_MeterY=ClientArea.cy/ViewSizeY;
|
|
MeterX_Per_DestPixs=1/DestPixs_Per_MeterX;
|
|
MeterY_Per_DestPixs=1/DestPixs_Per_MeterY;
|
|
DestPixs_Per_SourcePixsX=DestPixs_Per_MeterX/SourcePixs_Per_MeterX;
|
|
DestPixs_Per_SourcePixsY=DestPixs_Per_MeterY/SourcePixs_Per_MeterY;
|
|
}
|
|
|
|
void ViewWindowInfo::SetClientArea(CSize &rct)
|
|
{
|
|
ClientArea=rct;
|
|
if(ClientArea.cx==0) ClientArea.cx=1;
|
|
if(ClientArea.cy==0) ClientArea.cy=1;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::SetBitmapArea(CSize &rct)
|
|
{
|
|
BitmapArea=rct;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::SetZoom(float zf)
|
|
{
|
|
ZoomFact.z=ZoomFact.x=zf;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::SetPan(Point3D &pnt)
|
|
{
|
|
Pan=pnt;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::OffsetPan(Point3D &pnt)
|
|
{
|
|
Pan+=pnt;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::MultiplyZoom(float zf)
|
|
{
|
|
ZoomFact.x*=zf;
|
|
ZoomFact.z*=zf;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::SetViewLimits(Point3D min, Point3D max)
|
|
{
|
|
if(min.x>max.x)
|
|
{
|
|
Scalar tmp;
|
|
tmp=min.x; min.x=max.x; max.x=tmp;
|
|
}
|
|
|
|
if(min.z>max.z)
|
|
{
|
|
Scalar tmp;
|
|
tmp=min.z; min.z=max.z; max.z=tmp;
|
|
}
|
|
|
|
Verify((min.x<max.x && min.z<max.z));
|
|
|
|
Scalar xsize,zsize;
|
|
xsize=max.x-min.x;
|
|
zsize=max.z-min.z;
|
|
|
|
Pan.x=min.x+xsize*0.5f;
|
|
Pan.z=min.z+zsize*0.5f;
|
|
|
|
ZoomFact.x=MapSize.x/xsize;
|
|
ZoomFact.z=MapSize.z/zsize;
|
|
|
|
// Do this to force a square to avoid draw problems
|
|
ZoomFact.z=ZoomFact.x=ZoomFact.x<ZoomFact.z?ZoomFact.x:ZoomFact.z;
|
|
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
void ViewWindowInfo::SetMapSize(Point3D msze)
|
|
{
|
|
MapSize=msze;
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
CPoint ViewWindowInfo::DataToScreen(const Point3D &pnt)
|
|
{
|
|
CPoint retcpnt;
|
|
retcpnt.x=(ClientArea.cx-(int)((pnt.x-Pan.x+HalfViewSizeX)*DestPixs_Per_MeterX));
|
|
retcpnt.y=(ClientArea.cy-(int)((pnt.z-Pan.z+HalfViewSizeY)*DestPixs_Per_MeterY));
|
|
return retcpnt;
|
|
}
|
|
|
|
Point3D ViewWindowInfo::ScreenToData(CPoint &pnt)
|
|
{
|
|
Point3D retp3d;
|
|
retp3d.x=ViewSizeX*(0.5f-((Scalar)pnt.x/ClientArea.cx))+Pan.x;
|
|
retp3d.y=0.0f;
|
|
retp3d.z=ViewSizeY*(0.5f-((Scalar)pnt.y/ClientArea.cy))+Pan.z;
|
|
return retp3d;
|
|
}
|
|
|
|
void ViewWindowInfo::GetViewLimits(Point3D *min, Point3D *max)
|
|
{
|
|
|
|
min->y=max->y=0.0f;
|
|
min->x=Pan.x-HalfViewSizeX;
|
|
max->x=Pan.x+HalfViewSizeX;
|
|
min->z=Pan.z-HalfViewSizeY;
|
|
max->z=Pan.z+HalfViewSizeY;
|
|
|
|
}
|
|
|
|
|
|
bool ViewWindowInfo::GetBltRects(CRect *drct,CRect *srct)
|
|
{
|
|
|
|
float src_top,src_right,src_left,src_bottom;
|
|
|
|
drct->left=0;
|
|
drct->top=0;
|
|
drct->right=ClientArea.cx;
|
|
drct->bottom=ClientArea.cy;
|
|
|
|
Point3D flip_pan;
|
|
flip_pan.y=0.0f;
|
|
flip_pan.x=MapSize.x-(Pan.x-MapOrg.x);
|
|
flip_pan.z=MapSize.z-(Pan.z-MapOrg.z);
|
|
|
|
//Calulate percise Source window
|
|
src_left=(flip_pan.x-HalfViewSizeX)*SourcePixs_Per_MeterX;
|
|
src_right=(flip_pan.x+HalfViewSizeX)*SourcePixs_Per_MeterX;
|
|
src_top=(flip_pan.z-HalfViewSizeY)*SourcePixs_Per_MeterY;
|
|
src_bottom=(flip_pan.z+HalfViewSizeY)*SourcePixs_Per_MeterY;
|
|
|
|
//Truncate Source Window with overlap
|
|
srct->left=(int)floor(src_left);
|
|
srct->right=(int)ceil(src_right);
|
|
srct->top=(int)floor(src_top);
|
|
srct->bottom=(int)ceil(src_bottom);
|
|
|
|
|
|
//Adjust Dest Window for overlap
|
|
if(srct->Width()>1)
|
|
{
|
|
drct->left-=(int)((src_left-floor(src_left))*DestPixs_Per_SourcePixsX);
|
|
drct->right+=(int)((ceil(src_right)-src_right)*DestPixs_Per_SourcePixsX);
|
|
}
|
|
|
|
if(srct->Height()>1)
|
|
{
|
|
drct->top-=(int)((src_top-floor(src_top))*DestPixs_Per_SourcePixsY);
|
|
drct->bottom+=(int)((ceil(src_bottom)-src_bottom)*DestPixs_Per_SourcePixsY);
|
|
}
|
|
|
|
return (abs(srct->right-srct->left)<=1 || abs(srct->bottom-srct->top)<=1 );
|
|
}
|
|
|
|
void ViewWindowInfo::SetPan(CPoint &pnt)
|
|
{
|
|
SetPan(ScreenToData(pnt));
|
|
}
|
|
|
|
void ViewWindowInfo::OffsetPan(CSize &pnt)
|
|
{
|
|
//Reverser for no 180 flip
|
|
//Pan.x+=(float)((pnt.cx)*MapSize.x)/(ClientArea.cx*ZoomFact.x);
|
|
//Pan.z+=(float)((pnt.cy)*MapSize.z)/(ClientArea.cy*ZoomFact.z);
|
|
Pan.x-=(float)((pnt.cx)*MapSize.x)/(ClientArea.cx*ZoomFact.x);
|
|
Pan.z-=(float)((pnt.cy)*MapSize.z)/(ClientArea.cy*ZoomFact.z);
|
|
CorrectViewBounds();
|
|
}
|
|
|
|
|
|
void ViewWindowInfo::CorrectViewBounds()
|
|
{
|
|
if(ZoomFact.x<1.0f) ZoomFact.x=1.0f;
|
|
if(ZoomFact.z<1.0f) ZoomFact.z=1.0f;
|
|
|
|
CalcConstants();
|
|
|
|
float src_top,src_right,src_left,src_bottom;
|
|
bool change;
|
|
|
|
//Calulate percise Source window
|
|
src_left=((Pan.x-MapOrg.x)-HalfViewSizeX)*SourcePixs_Per_MeterX;
|
|
src_right=((Pan.x-MapOrg.x)+HalfViewSizeX)*SourcePixs_Per_MeterX;
|
|
src_top=((Pan.z-MapOrg.z)-HalfViewSizeY)*SourcePixs_Per_MeterY;
|
|
src_bottom=((Pan.z-MapOrg.z)+HalfViewSizeY)*SourcePixs_Per_MeterY;
|
|
|
|
if(src_left<0)
|
|
{
|
|
Pan.x=HalfViewSizeX+MapOrg.x;
|
|
change=true;
|
|
}
|
|
|
|
if(src_top<0)
|
|
{
|
|
Pan.z=HalfViewSizeY+MapOrg.z;
|
|
change=true;
|
|
}
|
|
|
|
if(src_right>BitmapArea.cx)
|
|
{
|
|
Pan.x=((BitmapArea.cx)/SourcePixs_Per_MeterX)-HalfViewSizeX+MapOrg.x;
|
|
change=true;
|
|
}
|
|
|
|
if(src_bottom>BitmapArea.cy)
|
|
{
|
|
Pan.z=((BitmapArea.cy)/SourcePixs_Per_MeterY)-HalfViewSizeY+MapOrg.z;
|
|
change=true;
|
|
}
|
|
|
|
if(change) CalcConstants();
|
|
}
|