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.
193 lines
4.9 KiB
C++
193 lines
4.9 KiB
C++
// HeightField.cpp: implementation of the HeightField class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "imagegrinder.h"
|
|
#include "HeightField.h"
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
HeightField::HeightField()
|
|
{
|
|
|
|
}
|
|
|
|
void HeightField::HFBlendBlt(HeightField &img,RECT dst,RECT &src,HFBLENDMODE bmode,int UserVal)
|
|
{
|
|
int dr,db;
|
|
int xd,yd;
|
|
int ddx,ddy;
|
|
ddx=dst.right-dst.left;
|
|
ddy=dst.bottom-dst.top;
|
|
xd=src.right-src.left;
|
|
yd=src.bottom-src.top;
|
|
|
|
dst.right-=xpos;
|
|
dst.left-=xpos;
|
|
dst.bottom-=ypos;
|
|
dst.top-=ypos;
|
|
|
|
|
|
if(src.left>=(img.xpos+img.xlen) || src.top>=(img.ypos+img.ylen) ||
|
|
src.right<=img.xpos || src.bottom<img.ypos ) return;
|
|
|
|
|
|
//left clip
|
|
if(src.left<=img.xpos) //fix source move dest.
|
|
{ dst.left+=(img.xpos-src.left)*ddx/xd; src.left=0;}
|
|
else //fix destination move source
|
|
src.left-=img.xpos;
|
|
|
|
if(src.top<=img.ypos) //fix source move dest.
|
|
{ dst.top+=(img.ypos-src.top)*ddy/yd; src.top=0; }
|
|
else //fix destination move source
|
|
src.top-=img.ypos;
|
|
|
|
//right clip
|
|
|
|
if(src.right>(img.xpos+img.xlen))
|
|
{
|
|
dst.right-=(src.right-(img.xpos+img.xlen))*ddx/xd;
|
|
src.right=img.xlen;
|
|
}
|
|
else
|
|
src.right=img.xlen-((img.xlen+img.xpos)-src.right);
|
|
|
|
if(src.bottom>(img.ypos+img.ylen))
|
|
{
|
|
dst.bottom-=(src.bottom-(img.ypos+img.ylen))*ddy/yd;
|
|
src.bottom=img.ylen;
|
|
}
|
|
else
|
|
src.bottom=img.ylen-((img.ylen+img.ypos)-src.bottom);
|
|
|
|
|
|
if(dst.left<0) { src.left-=dst.left*img.xlen/ddx; dst.left=0; }
|
|
if(dst.top<0) { src.top-=dst.top*img.ylen/ddy; dst.top=0; }
|
|
|
|
|
|
if(dst.right>xlen) { src.right=src.left+(xlen-dst.left)*xd/ddx; dr=xlen;}
|
|
else {dr=dst.right; }
|
|
|
|
if(dst.bottom>ylen){ src.bottom=src.top+(ylen-dst.top)*yd/ddy; db=ylen; }
|
|
else {db=dst.bottom; }
|
|
|
|
dst.right=dr;
|
|
dst.bottom=db;
|
|
|
|
|
|
if(src.right<=0 || src.bottom<=0 ||
|
|
src.left>=img.xlen || src.top>=img.ylen) return;
|
|
|
|
|
|
BYTE *dptS=img.Lock(),*dptD=Lock();
|
|
|
|
if((dst.right-dst.left)==(src.right-src.left) && (dst.bottom-dst.top)==(src.bottom-src.top))
|
|
{//Pure Copy
|
|
int psizeS=(img.Bpp>>3),psizeD=(Bpp>>3);
|
|
int sp=img.GetPitch()-(src.right-src.left)*psizeS,dp=GetPitch()-(dst.right-dst.left)*psizeD;
|
|
int x,y;
|
|
ImgRGBColor srccol,dstcol;
|
|
RGBPixel *tptr;
|
|
BYTE *tdptS=dptS+(src.left+src.top*img.GetWidth())*psizeS,*tdptD=dptD+(dst.left+dst.top*GetWidth())*psizeD;
|
|
|
|
switch(bmode)
|
|
{
|
|
case HFB_COPY:
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
srccol.Set(*tptr,img.Mask);
|
|
|
|
tptr=(RGBPixel *)(tdptD);
|
|
tptr->Set(srccol,Mask);
|
|
}
|
|
break;
|
|
|
|
case HFB_ADD:
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
srccol.Set(*tptr,img.Mask);
|
|
|
|
tptr=(RGBPixel *)(tdptD);
|
|
dstcol.Set(*tptr,Mask);
|
|
dstcol+=srccol;
|
|
dstcol.Bound();
|
|
tptr->Set(dstcol,Mask);
|
|
}
|
|
break;
|
|
|
|
case HFB_SUBTRACT:
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
srccol.Set(*tptr,img.Mask);
|
|
|
|
tptr=(RGBPixel *)(tdptD);
|
|
dstcol.Set(*tptr,Mask);
|
|
dstcol.SetBounded(dstcol.r-srccol.r,dstcol.g-srccol.g,dstcol.b-srccol.b);
|
|
tptr->Set(dstcol,Mask);
|
|
}
|
|
break;
|
|
|
|
case HFB_BLEND:
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
srccol.Set(*tptr,img.Mask);
|
|
|
|
tptr=(RGBPixel *)(tdptD);
|
|
dstcol.Set(*tptr,Mask);
|
|
dstcol.SetBounded(dstcol.r+(((srccol.r)*UserVal)>>8),
|
|
dstcol.g+(((srccol.g)*UserVal)>>8),
|
|
dstcol.b+(((srccol.b)*UserVal)>>8));
|
|
tptr->Set(dstcol,Mask);
|
|
}
|
|
break;
|
|
|
|
case HFB_INVBLEND:
|
|
for(y=dst.top;y<dst.bottom;y++,tdptS+=sp,tdptD+=dp)
|
|
for(x=dst.left;x<dst.right;x++,tdptS+=psizeS,tdptD+=psizeD)
|
|
{
|
|
tptr=(RGBPixel *)(tdptS);
|
|
srccol.Set(*tptr,img.Mask);
|
|
|
|
tptr=(RGBPixel *)(tdptD);
|
|
dstcol.Set(*tptr,Mask);
|
|
dstcol.SetBounded( ((dstcol.r*(255-srccol.r))>>8)+(((srccol.r)*UserVal)>>8),
|
|
((dstcol.g*(255-srccol.g))>>8)+(((srccol.g)*UserVal)>>8),
|
|
((dstcol.b*(255-srccol.b))>>8)+(((srccol.b)*UserVal)>>8));
|
|
tptr->Set(dstcol,Mask);
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
GENFERR("Unimplemented Blend Mode");
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
GENFERR("Stretchy Blts not supported in HF's");
|
|
}
|
|
UnLock();
|
|
img.UnLock();
|
|
}
|
|
|
|
HeightField::~HeightField()
|
|
{
|
|
|
|
}
|
|
|