Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
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.
2026-06-24 21:28:16 -05:00

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();
}