OpenClonk
C4Landscape::P Struct Reference
Collaboration diagram for C4Landscape::P:
[legend]

Public Member Functions

void ClearMatCount ()
 
void ExecuteScan (C4Landscape *)
 
int32_t DoScan (C4Landscape *, int32_t x, int32_t y, int32_t mat, int32_t dir)
 
uint32_t ChunkyRandom (uint32_t &iOffset, uint32_t iRange) const
 
void DrawChunk (C4Landscape *, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, uint8_t mcol, uint8_t mcolBkg, C4MaterialCoreShape Shape, uint32_t cro)
 
void DrawSmoothOChunk (C4Landscape *, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, uint8_t mcol, uint8_t mcolBkg, int flip, uint32_t cro)
 
void ChunkOZoom (C4Landscape *, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX=0, int32_t iOffY=0)
 
bool TexOZoom (C4Landscape *, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, DWORD *dwpTextureUsage, int32_t iToX=0, int32_t iToY=0)
 
bool MapToSurface (C4Landscape *, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iToX, int32_t iToY, int32_t iToWdt, int32_t iToHgt, int32_t iOffX, int32_t iOffY)
 
bool MapToLandscape (C4Landscape *d, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iOffsX=0, int32_t iOffsY=0, bool noClear=false)
 
bool InitBorderPix ()
 
bool GetMapColorIndex (const char *szMaterial, const char *szTexture, BYTE &rbyCol) const
 
bool CreateMap (CSurface8 *&sfcMap, CSurface8 *&sfcMapBkg)
 
bool CreateMapS2 (C4Group &ScenFile, CSurface8 *&sfcMap, CSurface8 *&sfcMapBkg)
 
bool Mat2Pal ()
 
void UpdatePixCnt (const C4Landscape *, const C4Rect &Rect, bool fCheck=false)
 
void UpdateMatCnt (const C4Landscape *, C4Rect Rect, bool fPlus)
 
void PrepareChange (const C4Landscape *d, const C4Rect &BoundingBox, bool updateMatCnt=true)
 
void FinishChange (C4Landscape *d, C4Rect BoundingBox, bool updateMatAndPixCnt=true)
 
bool DrawLineLandscape (int32_t iX, int32_t iY, int32_t iGrade, uint8_t line_color, uint8_t line_color_bkg)
 
bool DrawLineMap (int32_t iX, int32_t iY, int32_t iRadius, uint8_t line_color, uint8_t line_color_bkg)
 
uint8_t * GetBridgeMatConversion (const C4Landscape *d, int32_t for_material_col) const
 
bool SaveInternal (const C4Landscape *d, C4Group &hGroup) const
 
bool SaveDiffInternal (const C4Landscape *d, C4Group &hGroup, bool fSyncSave) const
 
int32_t ForPolygon (C4Landscape *d, int *vtcs, int length, const std::function< bool(int32_t, int32_t)> &callback, C4MaterialList *mats_count=nullptr, uint8_t col=0, uint8_t colBkg=0, uint8_t *conversion_table=nullptr)
 
std::unique_ptr< CSurface8CreateDefaultBkgSurface (CSurface8 &sfcFg, bool msbAsIft) const
 
void DigMaterial2Objects (int32_t tx, int32_t ty, C4MaterialList *mat_list, C4Object *pCollect=nullptr)
 
void BlastMaterial2Objects (int32_t tx, int32_t ty, C4MaterialList *mat_list, int32_t caused_by, int32_t str, C4ValueArray *out_objects)
 
bool DigFreePix (C4Landscape *d, int32_t tx, int32_t ty)
 
bool DigFreePixNoInstability (C4Landscape *d, int32_t tx, int32_t ty)
 
bool BlastFreePix (C4Landscape *d, int32_t tx, int32_t ty)
 
bool ShakeFreePix (C4Landscape *d, int32_t tx, int32_t ty)
 
C4ValueArrayPrepareFreeShape (C4Rect &BoundingBox, C4Object *by_object)
 
void PostFreeShape (C4ValueArray *dig_objects, C4Object *by_object)
 
BYTE DefaultBkgMat (BYTE fg) const
 

Public Attributes

std::unique_ptr< CSurface8Surface8
 
std::unique_ptr< CSurface8Surface8Bkg
 
std::unique_ptr< CSurface8Map
 
std::unique_ptr< CSurface8MapBkg
 
std::unique_ptr< C4LandscapeRenderpLandscapeRender
 
std::vector< uint8_t > TopRowPix
 
std::vector< uint8_t > BottomRowPix
 
std::vector< uint8_t > LeftColPix
 
std::vector< uint8_t > RightColPix
 
int32_t Pix2Mat [C4M_MaxTexIndex]
 
int32_t Pix2Dens [C4M_MaxTexIndex]
 
int32_t Pix2Place [C4M_MaxTexIndex]
 
bool Pix2Light [C4M_MaxTexIndex]
 
int32_t PixCntPitch = 0
 
std::vector< uint8_t > PixCnt
 
std::array< C4Rect, C4LS_MaxRelightsRelights
 
std::array< std::unique_ptr< uint8_t[]>, C4M_MaxTexIndexBridgeMatConversion
 
LandscapeMode mode = LandscapeMode::Undefined
 
int32_t Width = 0
 
int32_t Height = 0
 
int32_t MapWidth = 0
 
int32_t MapHeight = 0
 
int32_t MapZoom = 0
 
std::array< DWORD, C4MaxMaterialMatCount {}
 
std::array< DWORD, C4MaxMaterialEffectiveMatCount {}
 
bool NoScan = false
 
int32_t ScanX = 0
 
int32_t ScanSpeed = 2
 
C4Real Gravity = DefaultGravAccel
 
uint32_t Modulation = 0
 
int32_t MapSeed = 0
 
C4Sky Sky
 
std::unique_ptr< C4MapCreatorS2pMapCreator
 
bool fMapChanged = false
 
std::unique_ptr< BYTE[]> pInitial
 
std::unique_ptr< BYTE[]> pInitialBkg
 
std::unique_ptr< C4FoWpFoW
 

Detailed Description

Definition at line 52 of file C4Landscape.cpp.

Member Function Documentation

◆ BlastFreePix()

bool C4Landscape::P::BlastFreePix ( C4Landscape d,
int32_t  tx,
int32_t  ty 
)

Definition at line 737 of file C4Landscape.cpp.

738 {
739  int32_t mat = d->GetMat(tx, ty);
740  if (MatValid(mat))
741  {
742  // for blast, either shift to different material or blast free
743  if (::MaterialMap.Map[mat].BlastFree)
744  {
745  d->ClearPix(tx, ty);
746  // check for instable materials to start moving by the cleared space
747  d->CheckInstabilityRange(tx, ty);
748  return true;
749  }
750  else
751  if (::MaterialMap.Map[mat].BlastShiftTo)
753  }
754  return false;
755 }
C4MaterialMap MaterialMap
Definition: C4Material.cpp:974
BYTE MatTex2PixCol(int32_t tex)
Definition: C4Material.h:230
bool MatValid(int32_t mat)
Definition: C4Material.h:210
static const uint8_t Transparent
Definition: C4Landscape.h:50
int32_t GetMat(int32_t x, int32_t y) const
void CheckInstabilityRange(int32_t tx, int32_t ty)
bool ClearPix(int32_t tx, int32_t ty)
bool SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
int32_t BlastFree
Definition: C4Material.h:95
int32_t BlastShiftTo
Definition: C4Material.h:151
C4Material * Map
Definition: C4Material.h:169

References C4MaterialCore::BlastFree, C4Material::BlastShiftTo, C4Landscape::CheckInstabilityRange(), C4Landscape::ClearPix(), C4Landscape::GetMat(), C4MaterialMap::Map, MaterialMap, MatTex2PixCol(), MatValid(), C4Landscape::SetPix2(), and C4Landscape::Transparent.

Here is the call graph for this function:

◆ BlastMaterial2Objects()

void C4Landscape::P::BlastMaterial2Objects ( int32_t  tx,
int32_t  ty,
C4MaterialList mat_list,
int32_t  caused_by,
int32_t  str,
C4ValueArray out_objects 
)

Definition at line 641 of file C4Landscape.cpp.

642 {
643  for (int32_t mat = 0; mat < ::MaterialMap.Num; mat++)
644  {
645  if (mat_list->Amount[mat])
646  {
647  int32_t cast_strength = str;
648  int32_t pxsamount = 0, blastamount = 0;
649 
650  if (::MaterialMap.Map[mat].Blast2PXSRatio != 0)
651  {
652  pxsamount = mat_list->Amount[mat] / ::MaterialMap.Map[mat].Blast2PXSRatio;
653  ::PXS.Cast(mat, pxsamount, tx, ty, cast_strength * 2);
654  }
655 
656  if (::MaterialMap.Map[mat].Blast2Object != C4ID::None)
657  {
658  if (::MaterialMap.Map[mat].Blast2ObjectRatio != 0)
659  {
660  blastamount = mat_list->Amount[mat] / ::MaterialMap.Map[mat].Blast2ObjectRatio;
661  Game.CastObjects(::MaterialMap.Map[mat].Blast2Object, nullptr, blastamount, cast_strength, tx, ty, NO_OWNER, caused_by, out_objects);
662  }
663  }
664 
665  mat_list->Amount[mat] -= std::max(blastamount * ::MaterialMap.Map[mat].Blast2ObjectRatio,
666  pxsamount * ::MaterialMap.Map[mat].Blast2PXSRatio);
667  }
668  }
669 }
const int NO_OWNER
Definition: C4Constants.h:137
C4Game Game
Definition: C4Globals.cpp:52
C4PXSSystem PXS
Definition: C4PXS.cpp:423
void CastObjects(C4ID id, C4Object *creator, int32_t num, int32_t level, int32_t x, int32_t y, int32_t owner=NO_OWNER, int32_t controller=NO_OWNER, C4ValueArray *out_objects=nullptr)
Definition: C4Game.cpp:1763
static const C4ID None
Definition: C4Id.h:39
int32_t Blast2ObjectRatio
Definition: C4Material.h:100
int32_t Blast2PXSRatio
Definition: C4Material.h:101
C4ID Blast2Object
Definition: C4Material.h:99
int32_t Amount[C4MaxMaterial]
int32_t Num
Definition: C4Material.h:168
void Cast(int32_t mat, int32_t num, int32_t tx, int32_t ty, int32_t level)
Definition: C4PXS.cpp:309

References C4MaterialList::Amount, C4MaterialCore::Blast2Object, C4MaterialCore::Blast2ObjectRatio, C4MaterialCore::Blast2PXSRatio, C4PXSSystem::Cast(), C4Game::CastObjects(), Game, C4MaterialMap::Map, MaterialMap, NO_OWNER, C4ID::None, C4MaterialMap::Num, and PXS.

Here is the call graph for this function:

◆ ChunkOZoom()

void C4Landscape::P::ChunkOZoom ( C4Landscape d,
const CSurface8 sfcMap,
const CSurface8 sfcMapBkg,
int32_t  iMapX,
int32_t  iMapY,
int32_t  iMapWdt,
int32_t  iMapHgt,
uint8_t  iTexture,
int32_t  iOffX = 0,
int32_t  iOffY = 0 
)

Definition at line 2187 of file C4Landscape.cpp.

2188 {
2189  const C4TexMapEntry *entry = ::TextureMap.GetEntry(iTexture);
2190  C4Material *pMaterial = entry->GetMaterial();
2191  if (!pMaterial) return;
2192  const char *texture_name = entry->GetTextureName();
2193  C4Texture *texture = ::TextureMap.GetTexture(texture_name);
2194  C4TextureShape *shape = texture ? texture->GetMaterialShape() : nullptr;
2195  // Chunk type by material
2197  // Get map & landscape size
2198  int iMapWidth, iMapHeight;
2199  sfcMap.GetSurfaceSize(iMapWidth, iMapHeight);
2200  // Clip desired map segment to map size
2201  iMapX = Clamp<int32_t>(iMapX, 0, iMapWidth - 1);
2202  iMapY = Clamp<int32_t>(iMapY, 0, iMapHeight - 1);
2203  iMapWdt = Clamp<int32_t>(iMapWdt, 0, iMapWidth - iMapX);
2204  iMapHgt = Clamp<int32_t>(iMapHgt, 0, iMapHeight - iMapY);
2205  // get chunk size
2206  int iChunkWidth = MapZoom, iChunkHeight = MapZoom;
2207  // Scan map lines
2208  for (int iY = iMapY; iY < iMapY + iMapHgt; iY++)
2209  {
2210  // Landscape target coordinate vertical
2211  int iToY = iY * iChunkHeight + iOffY;
2212  // Scan map line
2213  for (int iX = iMapX; iX < iMapX + iMapWdt; iX++)
2214  {
2215  // Map scan line start
2216  uint8_t MapPixel = sfcMap._GetPix(iX, iY);
2217  uint8_t MapPixelBkg = sfcMapBkg._GetPix(iX, iY);
2218  // Landscape target coordinate horizontal
2219  int iToX = iX * iChunkWidth + iOffX;
2220  // Here's a chunk of the texture-material to zoom
2221  if (MapPixel == iTexture)
2222  {
2223  // Draw chunk
2224  DrawChunk(d, iToX, iToY, iChunkWidth, iChunkHeight, MapPixel, MapPixelBkg, iChunkType, (iX << 16) + iY);
2225  }
2226  // Other chunk, check for slope smoothers
2227  else if (iChunkType == C4M_Smooth || iChunkType == C4M_Smoother || iChunkType == C4M_Octagon)
2228  {
2229  // Map scan line pixel below
2230  uint8_t below = sfcMap.GetPix(iX, iY + 1);
2231  uint8_t above = sfcMap.GetPix(iX, iY - 1);
2232  uint8_t left = sfcMap.GetPix(iX - 1, iY);
2233  uint8_t right = sfcMap.GetPix(iX + 1, iY);
2234  uint8_t leftBkg = sfcMapBkg.GetPix(iX - 1, iY);
2235  uint8_t rightBkg = sfcMapBkg.GetPix(iX + 1, iY);
2236  // do not fill a tiny hole
2237  if (below == iTexture && above == iTexture && left == iTexture && right == iTexture)
2238  continue;
2239  int flat = iChunkType == C4M_Octagon ? 4 : 0;
2240  // Smooth chunk & same texture-material below
2241  if (iY < iMapHeight - 1 && below == iTexture)
2242  {
2243  // Same texture-material on left
2244  if (iX > 0 && left == iTexture)
2245  {
2246  // Draw smoother
2247  DrawSmoothOChunk(d, iToX, iToY, iChunkWidth, iChunkHeight, left, leftBkg, 3 + flat, (iX << 16) + iY);
2248  }
2249  // Same texture-material on right
2250  if (iX < iMapWidth - 1 && right == iTexture)
2251  {
2252  // Draw smoother
2253  DrawSmoothOChunk(d, iToX, iToY, iChunkWidth, iChunkHeight, right, rightBkg, 0 + flat, (iX << 16) + iY);
2254  }
2255  }
2256  // Smooth chunk & same texture-material above
2257  if (iY > 0 && above == iTexture)
2258  {
2259  // Same texture-material on left
2260  if (iX > 0 && left == iTexture)
2261  {
2262  // Draw smoother
2263  DrawSmoothOChunk(d, iToX, iToY, iChunkWidth, iChunkHeight, left, leftBkg, 2 + flat, (iX << 16) + iY);
2264  }
2265  // Same texture-material on right
2266  if (iX < iMapWidth - 1 && right == iTexture)
2267  {
2268  // Draw smoother
2269  DrawSmoothOChunk(d, iToX, iToY, iChunkWidth, iChunkHeight, right, rightBkg, 1 + flat, (iX << 16) + iY);
2270  }
2271  }
2272  }
2273  }
2274  }
2275  // Draw custom shapes on top of regular materials
2276  if (shape && !::Game.C4S.Landscape.FlatChunkShapes) shape->Draw(sfcMap, sfcMapBkg, iMapX, iMapY, iMapWdt, iMapHgt, iTexture, iOffX, iOffY, MapZoom, pMaterial->MinShapeOverlap);
2277 }
C4MaterialCoreShape
Definition: C4Material.h:72
@ C4M_Smooth
Definition: C4Material.h:75
@ C4M_Octagon
Definition: C4Material.h:77
@ C4M_Smoother
Definition: C4Material.h:78
@ C4M_Flat
Definition: C4Material.h:73
C4TextureMap TextureMap
Definition: C4Texture.cpp:576
C4Scenario C4S
Definition: C4Game.h:74
C4MaterialCoreShape MapChunkType
Definition: C4Material.h:91
int32_t MinShapeOverlap
Definition: C4Material.h:137
bool FlatChunkShapes
Definition: C4Scenario.h:188
C4SLandscape Landscape
Definition: C4Scenario.h:236
Definition: C4Texture.h:49
const char * GetTextureName() const
Definition: C4Texture.h:61
C4Material * GetMaterial() const
Definition: C4Texture.h:63
class C4TextureShape * GetMaterialShape() const
Definition: C4Texture.h:40
const char * GetTexture(int32_t iIndex)
Definition: C4Texture.cpp:494
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85
void Draw(const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX, int32_t iOffY, int32_t MapZoom, int32_t min_overlap_ratio)
BYTE _GetPix(int x, int y) const
Definition: CSurface8.h:54
BYTE GetPix(int iX, int iY) const
Definition: CSurface8.h:49
void GetSurfaceSize(int &irX, int &irY) const
Definition: CSurface8.cpp:195
void DrawChunk(C4Landscape *, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, uint8_t mcol, uint8_t mcolBkg, C4MaterialCoreShape Shape, uint32_t cro)
void DrawSmoothOChunk(C4Landscape *, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, uint8_t mcol, uint8_t mcolBkg, int flip, uint32_t cro)

References CSurface8::_GetPix(), C4M_Flat, C4M_Octagon, C4M_Smooth, C4M_Smoother, C4Game::C4S, C4TextureShape::Draw(), C4SLandscape::FlatChunkShapes, Game, C4TextureMap::GetEntry(), C4TexMapEntry::GetMaterial(), C4Texture::GetMaterialShape(), CSurface8::GetPix(), CSurface8::GetSurfaceSize(), C4TextureMap::GetTexture(), C4TexMapEntry::GetTextureName(), C4Scenario::Landscape, C4ScriptGuiWindowPropertyName::left, C4MaterialCore::MapChunkType, C4MaterialCore::MinShapeOverlap, C4ScriptGuiWindowPropertyName::right, and TextureMap.

Here is the call graph for this function:

◆ ChunkyRandom()

uint32_t C4Landscape::P::ChunkyRandom ( uint32_t &  iOffset,
uint32_t  iRange 
) const

Definition at line 2117 of file C4Landscape.cpp.

2118 {
2119  if (!iRange) return 0;
2120  iOffset = (iOffset * 16807) % 2147483647;
2121  return (iOffset ^ MapSeed) % iRange;
2122 }

◆ ClearMatCount()

void C4Landscape::P::ClearMatCount ( )

Definition at line 1931 of file C4Landscape.cpp.

1932 {
1933  std::fill(MatCount.begin(), MatCount.end(), 0);
1934  std::fill(EffectiveMatCount.begin(), EffectiveMatCount.end(), 0);
1935 }
std::array< DWORD, C4MaxMaterial > MatCount
Definition: C4Landscape.cpp:71
std::array< DWORD, C4MaxMaterial > EffectiveMatCount
Definition: C4Landscape.cpp:72

◆ CreateDefaultBkgSurface()

std::unique_ptr< CSurface8 > C4Landscape::P::CreateDefaultBkgSurface ( CSurface8 sfcFg,
bool  msbAsIft 
) const

Definition at line 1101 of file C4Landscape.cpp.

1102 {
1103  auto sfcBg = std::make_unique<CSurface8>();
1104  if (!sfcBg->Create(sfcFg.Wdt, sfcFg.Hgt))
1105  {
1106  return nullptr;
1107  }
1108 
1109  for (int32_t y = 0; y < sfcFg.Hgt; ++y)
1110  {
1111  for (int32_t x = 0; x < sfcFg.Wdt; ++x)
1112  {
1113  BYTE fgPix = sfcFg._GetPix(x, y);
1114  BYTE bgPix;
1115 
1116  // If we treat the most significant bit as the IFT flag
1117  // (compatibility option for pre-7.0 maps), then set
1118  // the background pixel to 0 if the foreground does not
1119  // have IFT set, and remove the IFT flag from the
1120  // foreground pixel.
1121  if (msbAsIft)
1122  {
1123  if (fgPix & 0x80)
1124  {
1125  fgPix &= ~0x80;
1126  sfcFg._SetPix(x, y, fgPix);
1127  bgPix = DefaultBkgMat(fgPix);
1128  }
1129  else
1130  {
1131  bgPix = 0;
1132  }
1133  }
1134  else
1135  {
1136  bgPix = DefaultBkgMat(fgPix);
1137  }
1138 
1139  sfcBg->_SetPix(x, y, bgPix);
1140  }
1141  }
1142 
1143  return sfcBg;
1144 }
uint8_t BYTE
void _SetPix(int iX, int iY, BYTE byCol)
Definition: CSurface8.h:44
int Wdt
Definition: CSurface8.h:28
int Hgt
Definition: CSurface8.h:28
BYTE DefaultBkgMat(BYTE fg) const

References CSurface8::_GetPix(), CSurface8::_SetPix(), CSurface8::Hgt, and CSurface8::Wdt.

Here is the call graph for this function:

◆ CreateMap()

bool C4Landscape::P::CreateMap ( CSurface8 *&  sfcMap,
CSurface8 *&  sfcMapBkg 
)

Definition at line 2404 of file C4Landscape.cpp.

2405 {
2406  int32_t iWidth = 0, iHeight = 0;
2407 
2408  // Create map surface
2409  Game.C4S.Landscape.GetMapSize(iWidth, iHeight, Game.StartupPlayerCount);
2410  auto fg_map = std::make_unique<CSurface8>(iWidth, iHeight);
2411 
2412  // Fill sfcMap
2413  C4MapCreator MapCreator;
2414  MapCreator.Create(fg_map.get(),
2417 
2418  auto bg_map = CreateDefaultBkgSurface(*fg_map, false);
2419  if (!bg_map)
2420  return false;
2421 
2422  sfcMap = fg_map.release();
2423  sfcMapBkg = bg_map.release();
2424  return true;
2425 }
int32_t StartupPlayerCount
Definition: C4Game.h:109
void Create(CSurface8 *sfcMap, C4SLandscape &rLScape, C4TextureMap &rTexMap, int32_t iPlayerNum=1)
Definition: C4Map.cpp:78
void GetMapSize(int32_t &rWdt, int32_t &rHgt, int32_t iPlayerNum)
Definition: C4Scenario.cpp:319
std::unique_ptr< CSurface8 > CreateDefaultBkgSurface(CSurface8 &sfcFg, bool msbAsIft) const

References C4Game::C4S, C4MapCreator::Create(), Game, C4SLandscape::GetMapSize(), C4Scenario::Landscape, C4Game::StartupPlayerCount, and TextureMap.

Here is the call graph for this function:

◆ CreateMapS2()

bool C4Landscape::P::CreateMapS2 ( C4Group ScenFile,
CSurface8 *&  sfcMap,
CSurface8 *&  sfcMapBkg 
)

Definition at line 2427 of file C4Landscape.cpp.

2428 {
2429  // file present?
2430  if (!ScenFile.AccessEntry(C4CFN_DynLandscape)) return false;
2431 
2432  // create map creator
2433  if (!pMapCreator)
2434  pMapCreator = std::make_unique<C4MapCreatorS2>(&Game.C4S.Landscape, &::TextureMap, &::MaterialMap, Game.StartupPlayerCount);
2435 
2436  // read file
2437  pMapCreator->ReadFile(C4CFN_DynLandscape, &ScenFile);
2438  // render landscape
2439  if (!pMapCreator->Render(nullptr, sfcMap, sfcMapBkg))
2440  return false;
2441 
2442  // keep map creator until script callbacks have been done
2443  return true;
2444 }
#define C4CFN_DynLandscape
Definition: C4Components.h:115
bool AccessEntry(const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool needs_to_be_a_group=false)
Definition: C4Group.cpp:2104
std::unique_ptr< C4MapCreatorS2 > pMapCreator
Definition: C4Landscape.cpp:80

References C4Group::AccessEntry(), C4CFN_DynLandscape, C4Game::C4S, Game, C4Scenario::Landscape, MaterialMap, C4Game::StartupPlayerCount, and TextureMap.

Here is the call graph for this function:

◆ DefaultBkgMat()

BYTE C4Landscape::P::DefaultBkgMat ( BYTE  fg) const

Definition at line 1096 of file C4Landscape.cpp.

1097 {
1099 }
BYTE DefaultBkgMatTex(BYTE fg) const
Definition: C4Texture.cpp:504

References C4TextureMap::DefaultBkgMatTex(), and TextureMap.

Here is the call graph for this function:

◆ DigFreePix()

bool C4Landscape::P::DigFreePix ( C4Landscape d,
int32_t  tx,
int32_t  ty 
)

Definition at line 723 of file C4Landscape.cpp.

724 {
725  int32_t mat = d->GetMat(tx, ty);
726  if (MatValid(mat))
727  if (::MaterialMap.Map[mat].DigFree)
728  {
729  d->ClearPix(tx, ty);
730  // check for instable materials to start moving by the cleared space
731  d->CheckInstabilityRange(tx, ty);
732  return true;
733  }
734  return false;
735 }
int32_t DigFree
Definition: C4Material.h:94

References C4Landscape::CheckInstabilityRange(), C4Landscape::ClearPix(), C4MaterialCore::DigFree, C4Landscape::GetMat(), C4MaterialMap::Map, MaterialMap, and MatValid().

Here is the call graph for this function:

◆ DigFreePixNoInstability()

bool C4Landscape::P::DigFreePixNoInstability ( C4Landscape d,
int32_t  tx,
int32_t  ty 
)

Definition at line 711 of file C4Landscape.cpp.

712 {
713  int32_t mat = d->GetMat(tx, ty);
714  if (MatValid(mat))
715  if (::MaterialMap.Map[mat].DigFree)
716  {
717  d->ClearPix(tx, ty);
718  return true;
719  }
720  return false;
721 }

References C4Landscape::ClearPix(), C4MaterialCore::DigFree, C4Landscape::GetMat(), C4MaterialMap::Map, MaterialMap, and MatValid().

Here is the call graph for this function:

◆ DigMaterial2Objects()

void C4Landscape::P::DigMaterial2Objects ( int32_t  tx,
int32_t  ty,
C4MaterialList mat_list,
C4Object pCollect = nullptr 
)

Definition at line 671 of file C4Landscape.cpp.

672 {
673  C4AulParSet pars(pCollect);
674  for (int32_t mat = 0; mat < ::MaterialMap.Num; mat++)
675  {
676  if (mat_list->Amount[mat])
677  {
678  if (::MaterialMap.Map[mat].Dig2Object != C4ID::None)
679  if (::MaterialMap.Map[mat].Dig2ObjectRatio != 0)
680  while (mat_list->Amount[mat] >= ::MaterialMap.Map[mat].Dig2ObjectRatio)
681  {
682  mat_list->Amount[mat] -= ::MaterialMap.Map[mat].Dig2ObjectRatio;
683  C4Object *pObj = Game.CreateObject(::MaterialMap.Map[mat].Dig2Object, nullptr, NO_OWNER, tx, ty);
684  if (!pObj || !pObj->Status) continue;
685  // Set controller to the controller of the object responsible for digging out
686  if (pCollect && pCollect->Status)
687  pObj->Controller = pCollect->Controller;
688  // Do callbacks to dug object and digger
689  pObj->Call(PSF_OnDugOut, &pars);
690  if (!pObj->Status || !pCollect || !pCollect->Status || pObj->Contained) continue;
691  C4AulParSet pars(C4VObj(pObj));
692  pCollect->Call(PSF_DigOutObject, &pars);
693  if (!pObj->Status || !pCollect->Status || pObj->Contained) continue;
694  // Try to collect object
695  if (::MaterialMap.Map[mat].Dig2ObjectCollect)
696  if (pCollect && pCollect->Status && pObj && pObj->Status)
697  if (!pCollect->Collect(pObj))
698  // Collection forced? Don't generate objects
699  if (::MaterialMap.Map[mat].Dig2ObjectCollect == 2)
700  {
701  pObj->AssignRemoval();
702  // Cap so we never have more than one object worth of material in the store
703  mat_list->Amount[mat] = ::MaterialMap.Map[mat].Dig2ObjectRatio;
704  break;
705  }
706  }
707  }
708  }
709 }
#define PSF_OnDugOut
Definition: C4GameScript.h:100
#define PSF_DigOutObject
Definition: C4GameScript.h:99
C4Value C4VObj(C4Object *pObj)
Definition: C4Value.cpp:88
C4Object * CreateObject(C4PropList *type, C4Object *creator, int32_t owner=NO_OWNER, int32_t x=50, int32_t y=50, int32_t r=0, bool grow_from_center=false, C4Real xdir=Fix0, C4Real ydir=Fix0, C4Real rdir=Fix0, int32_t controller=NO_OWNER)
Definition: C4Game.cpp:1334
int32_t Dig2ObjectRatio
Definition: C4Material.h:97
int32_t Dig2ObjectCollect
Definition: C4Material.h:98
int32_t Controller
Definition: C4Object.h:109
void AssignRemoval(bool exit_contents=false)
Definition: C4Object.cpp:215
bool Collect(C4Object *pObj)
C4ObjectPtr Contained
Definition: C4Object.h:142
int32_t Status
Definition: C4PropList.h:173
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:114

References C4MaterialList::Amount, C4Object::AssignRemoval(), C4VObj(), C4PropList::Call(), C4Object::Collect(), C4Object::Contained, C4Object::Controller, C4Game::CreateObject(), C4MaterialCore::Dig2Object, C4MaterialCore::Dig2ObjectCollect, C4MaterialCore::Dig2ObjectRatio, Game, C4MaterialMap::Map, MaterialMap, NO_OWNER, C4ID::None, C4MaterialMap::Num, PSF_DigOutObject, PSF_OnDugOut, and C4PropList::Status.

Here is the call graph for this function:

◆ DoScan()

int32_t C4Landscape::P::DoScan ( C4Landscape d,
int32_t  x,
int32_t  y,
int32_t  mat,
int32_t  dir 
)

Definition at line 274 of file C4Landscape.cpp.

275 {
276  int32_t conv_to_tex = 0;
277  int32_t iTemperature = ::Weather.GetTemperature();
278  // Check below conv
279  if (::MaterialMap.Map[mat].BelowTempConvertDir == dir)
281  if (iTemperature< ::MaterialMap.Map[mat].BelowTempConvert)
282  conv_to_tex = ::MaterialMap.Map[mat].BelowTempConvertTo;
283  // Check above conv
284  if (::MaterialMap.Map[mat].AboveTempConvertDir == dir)
286  if (iTemperature>::MaterialMap.Map[mat].AboveTempConvert)
287  conv_to_tex = ::MaterialMap.Map[mat].AboveTempConvertTo;
288  // nothing to do?
289  if (!conv_to_tex) return 0;
290  // find material
291  int32_t conv_to = ::TextureMap.GetEntry(conv_to_tex)->GetMaterialIndex();
292  // find mat top
293  int32_t mconv = ::MaterialMap.Map[mat].TempConvStrength,
294  mconvs = mconv;
296  {
297  C4RCMatScan rc = { cx, cy, mat, conv_to, dir, mconvs };
298  AddDbgRec(RCT_MatScanDo, &rc, sizeof(C4RCMatScan));
299  }
300  int32_t ydir = (dir == 0 ? +1 : -1), cy2;
301 #ifdef PRETTY_TEMP_CONV
302  // get left pixel
303  int32_t lmat = (cx > 0 ? d->_GetMat(cx - 1, cy) : -1);
304  // left pixel not converted? do nothing
305  if (lmat == mat) return 0;
306  // left pixel converted? suppose it was done by a prior scan and skip check
307  if (lmat != conv_to)
308  {
309  int32_t iSearchRange = std::max<int32_t>(5, mconvs);
310  // search upper/lower bound
311  int32_t cys = cy, cxs = cx;
312  while (cxs < ::Landscape.GetWidth() - 1)
313  {
314  // one step right
315  cxs++;
316  if (d->_GetMat(cxs, cys) == mat)
317  {
318  // search surface
319  cys -= ydir;
320  while (Inside<int32_t>(cys, 0, ::Landscape.GetHeight() - 1) && d->_GetMat(cxs, cys) == mat)
321  {
322  cys -= ydir;
323  if ((mconvs = std::min(mconv - Abs(cys - cy), mconvs)) < 0)
324  return 0;
325  }
326  // out of bounds?
327  if (!Inside<int32_t>(cys, 0, ::Landscape.GetHeight() - 1)) break;
328  // back one step
329  cys += ydir;
330  }
331  else
332  {
333  // search surface
334  cys += ydir;
335  while (Inside<int32_t>(cys, 0, ::Landscape.GetHeight() - 1) && d->_GetMat(cxs, cys) != mat)
336  {
337  cys += ydir;
338  if (Abs(cys - cy) > iSearchRange)
339  break;
340  }
341  // out of bounds?
342  if (!Inside<int32_t>(cys, 0, ::Landscape.GetHeight() - 1)) break;
343  if (Abs(cys - cy) > iSearchRange) break;
344  }
345  }
346  }
347 #endif
348  // Conversion
349  bool conv_to_is_solid = (conv_to > -1) && DensitySolid(::MaterialMap.Map[conv_to].Density);
350  for (cy2 = cy; mconvs >= 0 && Inside<int32_t>(cy2, 0, ::Landscape.GetHeight() - 1); cy2 += ydir, mconvs--)
351  {
352  // material changed?
353  int32_t pix = d->_GetPix(cx, cy2);
354  if (PixCol2Mat(pix) != mat) break;
355 #ifdef PRETTY_TEMP_CONV
356  // get left pixel
357  int32_t lmat = (cx > 0 ? d->_GetMat(cx - 1, cy2) : -1);
358  // left pixel not converted? break
359  if (lmat == mat) break;
360 #endif
361  // set mat (and keep background material)
362  d->SetPix2(cx, cy2, MatTex2PixCol(conv_to_tex), Transparent);
363  if (!conv_to_is_solid) d->CheckInstabilityRange(cx, cy2);
364  }
365  // return pixel converted
366  return Abs(cy2 - cy);
367 }
C4Config Config
Definition: C4Config.cpp:930
constexpr bool DEBUGREC_MATSCAN
Definition: C4Include.h:33
C4Landscape Landscape
int32_t PixCol2Mat(BYTE pixc)
bool DensitySolid(int32_t dens)
Definition: C4Landscape.h:196
void AddDbgRec(C4RecordChunkType eType, const void *pData, int iSize)
Definition: C4Record.cpp:32
@ RCT_MatScanDo
Definition: C4Record.h:79
C4Weather Weather
Definition: C4Weather.cpp:206
T Abs(T val)
Definition: Standard.h:42
int32_t DebugRec
Definition: C4Config.h:63
C4ConfigGeneral General
Definition: C4Config.h:255
int32_t GetWidth() const
BYTE _GetPix(int32_t x, int32_t y) const
int32_t GetHeight() const
int32_t _GetMat(int32_t x, int32_t y) const
int32_t TempConvStrength
Definition: C4Material.h:129
int32_t Density
Definition: C4Material.h:92
int32_t AboveTempConvertDir
Definition: C4Material.h:127
int32_t AboveTempConvert
Definition: C4Material.h:126
int32_t BelowTempConvert
Definition: C4Material.h:123
int32_t BelowTempConvertDir
Definition: C4Material.h:124
int32_t AboveTempConvertTo
Definition: C4Material.h:154
int32_t BelowTempConvertTo
Definition: C4Material.h:153
int32_t GetMaterialIndex() const
Definition: C4Texture.h:62
int32_t GetTemperature()
Definition: C4Weather.cpp:100

References C4Landscape::_GetMat(), C4Landscape::_GetPix(), C4MaterialCore::AboveTempConvert, C4MaterialCore::AboveTempConvertDir, C4Material::AboveTempConvertTo, Abs(), AddDbgRec(), C4MaterialCore::BelowTempConvert, C4MaterialCore::BelowTempConvertDir, C4Material::BelowTempConvertTo, C4Landscape::CheckInstabilityRange(), Config, C4ConfigGeneral::DebugRec, DEBUGREC_MATSCAN, C4MaterialCore::Density, DensitySolid(), C4Config::General, C4TextureMap::GetEntry(), C4Landscape::GetHeight(), C4TexMapEntry::GetMaterialIndex(), C4Weather::GetTemperature(), C4Landscape::GetWidth(), Landscape, C4MaterialMap::Map, MaterialMap, MatTex2PixCol(), PixCol2Mat(), RCT_MatScanDo, C4Landscape::SetPix2(), C4MaterialCore::TempConvStrength, TextureMap, C4Landscape::Transparent, and Weather.

Referenced by ExecuteScan().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DrawChunk()

void C4Landscape::P::DrawChunk ( C4Landscape d,
int32_t  tx,
int32_t  ty,
int32_t  wdt,
int32_t  hgt,
uint8_t  mcol,
uint8_t  mcolBkg,
C4MaterialCoreShape  Shape,
uint32_t  cro 
)

Definition at line 2124 of file C4Landscape.cpp.

2125 {
2126  unsigned int top_rough = 0, side_rough = 0, bottom_rough = 0;
2127  // what to do?
2128  switch (Shape)
2129  {
2130  case C4M_Flat: case C4M_Octagon:
2131  if (mcol != Transparent) Surface8->Box(tx, ty, tx + wdt, ty + hgt, mcol);
2132  if (mcolBkg != Transparent) Surface8Bkg->Box(tx, ty, tx + wdt, ty + hgt, mcolBkg);
2133  return;
2134  case C4M_TopFlat:
2135  top_rough = 0; side_rough = 2; bottom_rough = 4;
2136  break;
2137  case C4M_Smooth:
2138  top_rough = 2; side_rough = 2; bottom_rough = 2;
2139  break;
2140  case C4M_Rough:
2141  top_rough = 4; side_rough = 4; bottom_rough = 4;
2142  break;
2143  case C4M_Smoother:
2144  top_rough = 1; side_rough = 1; bottom_rough = 1;
2145  break;
2146  }
2147  int vtcs[16];
2148  unsigned int rx = std::max(wdt / 2, 1);
2149 
2150  vtcs[0] = tx - ChunkyRandom(cro, rx * side_rough / 4); vtcs[1] = ty - ChunkyRandom(cro, rx * top_rough / 4);
2151  vtcs[2] = tx - ChunkyRandom(cro, rx * side_rough / 2); vtcs[3] = ty + hgt / 2;
2152  vtcs[4] = tx - ChunkyRandom(cro, rx * side_rough / 4); vtcs[5] = ty + hgt + ChunkyRandom(cro, rx * bottom_rough / 4);
2153  vtcs[6] = tx + wdt / 2; vtcs[7] = ty + hgt + ChunkyRandom(cro, rx * bottom_rough / 2);
2154  vtcs[8] = tx + wdt + ChunkyRandom(cro, rx * side_rough / 4); vtcs[9] = ty + hgt + ChunkyRandom(cro, rx * bottom_rough / 4);
2155  vtcs[10] = tx + wdt + ChunkyRandom(cro, rx * side_rough / 2); vtcs[11] = ty + hgt / 2;
2156  vtcs[12] = tx + wdt + ChunkyRandom(cro, rx * side_rough / 4); vtcs[13] = ty - ChunkyRandom(cro, rx * top_rough / 4);
2157  vtcs[14] = tx + wdt / 2; vtcs[15] = ty - ChunkyRandom(cro, rx * top_rough / 2);
2158 
2159  ForPolygon(d, vtcs, 8, nullptr, nullptr, mcol, mcolBkg);
2160 }
@ C4M_TopFlat
Definition: C4Material.h:74
@ C4M_Rough
Definition: C4Material.h:76
uint32_t ChunkyRandom(uint32_t &iOffset, uint32_t iRange) const
int32_t ForPolygon(C4Landscape *d, int *vtcs, int length, const std::function< bool(int32_t, int32_t)> &callback, C4MaterialList *mats_count=nullptr, uint8_t col=0, uint8_t colBkg=0, uint8_t *conversion_table=nullptr)
std::unique_ptr< CSurface8 > Surface8
Definition: C4Landscape.cpp:54
std::unique_ptr< CSurface8 > Surface8Bkg
Definition: C4Landscape.cpp:55

References C4M_Flat, C4M_Octagon, C4M_Rough, C4M_Smooth, C4M_Smoother, C4M_TopFlat, and C4Landscape::Transparent.

◆ DrawLineLandscape()

bool C4Landscape::P::DrawLineLandscape ( int32_t  iX,
int32_t  iY,
int32_t  iGrade,
uint8_t  line_color,
uint8_t  line_color_bkg 
)

Definition at line 3471 of file C4Landscape.cpp.

3472 {
3473  Surface8->Circle(iX, iY, iGrade, line_color);
3474  Surface8Bkg->Circle(iX, iY, iGrade, line_color_bkg);
3475  return true;
3476 }

◆ DrawLineMap()

bool C4Landscape::P::DrawLineMap ( int32_t  iX,
int32_t  iY,
int32_t  iRadius,
uint8_t  line_color,
uint8_t  line_color_bkg 
)

Definition at line 3478 of file C4Landscape.cpp.

3479 {
3480  if (!Map) return false;
3481  if (iRadius == 1)
3482  {
3483  Map->SetPix(iX, iY, line_color); MapBkg->SetPix(iX, iY, line_color_bkg);
3484  }
3485  else
3486  {
3487  Map->Circle(iX, iY, iRadius, line_color); MapBkg->Circle(iX, iY, iRadius, line_color_bkg);
3488  }
3489  return true;
3490 }
std::unique_ptr< CSurface8 > Map
Definition: C4Landscape.cpp:56
std::unique_ptr< CSurface8 > MapBkg
Definition: C4Landscape.cpp:57

◆ DrawSmoothOChunk()

void C4Landscape::P::DrawSmoothOChunk ( C4Landscape d,
int32_t  tx,
int32_t  ty,
int32_t  wdt,
int32_t  hgt,
uint8_t  mcol,
uint8_t  mcolBkg,
int  flip,
uint32_t  cro 
)

Definition at line 2162 of file C4Landscape.cpp.

2163 {
2164  int vtcs[8];
2165  unsigned int rx = std::max(wdt / 2, 1);
2166 
2167  vtcs[0] = tx; vtcs[1] = ty;
2168  vtcs[2] = tx; vtcs[3] = ty + hgt;
2169  vtcs[4] = tx + wdt; vtcs[5] = ty + hgt;
2170  vtcs[6] = tx + wdt; vtcs[7] = ty;
2171 
2172  switch (flip)
2173  {
2174  case 0: vtcs[0] = tx + wdt / 2; vtcs[1] += hgt / 3; vtcs[7] -= ChunkyRandom(cro, rx / 2); break;
2175  case 1: vtcs[2] = tx + wdt / 2; vtcs[3] -= hgt / 3; vtcs[5] += ChunkyRandom(cro, rx / 2); break;
2176  case 2: vtcs[4] = tx + wdt / 2; vtcs[5] -= hgt / 3; vtcs[3] += ChunkyRandom(cro, rx / 2); break;
2177  case 3: vtcs[6] = tx + wdt / 2; vtcs[7] += hgt / 3; vtcs[1] -= ChunkyRandom(cro, rx / 2); break;
2178  case 4: vtcs[0] = tx + wdt / 2; vtcs[1] += hgt / 2; break;
2179  case 5: vtcs[2] = tx + wdt / 2; vtcs[3] -= hgt / 2; break;
2180  case 6: vtcs[4] = tx + wdt / 2; vtcs[5] -= hgt / 2; break;
2181  case 7: vtcs[6] = tx + wdt / 2; vtcs[7] += hgt / 2; break;
2182  }
2183 
2184  ForPolygon(d, vtcs, 4, nullptr, nullptr, mcol, mcolBkg);
2185 }

◆ ExecuteScan()

void C4Landscape::P::ExecuteScan ( C4Landscape d)

Definition at line 220 of file C4Landscape.cpp.

221 {
222  int32_t cy, mat;
223 
224  // Check: Scan needed?
225  const int32_t iTemperature = ::Weather.GetTemperature();
226  for (mat = 0; mat < ::MaterialMap.Num; mat++)
227  if (MatCount[mat])
228  {
229  if (::MaterialMap.Map[mat].BelowTempConvertTo &&
230  iTemperature < ::MaterialMap.Map[mat].BelowTempConvert)
231  break;
232  else if (::MaterialMap.Map[mat].AboveTempConvertTo &&
233  iTemperature > ::MaterialMap.Map[mat].AboveTempConvert)
234  break;
235  }
236  if (mat >= ::MaterialMap.Num)
237  return;
238 
240  AddDbgRec(RCT_MatScan, &ScanX, sizeof(ScanX));
241 
242  for (int32_t cnt = 0; cnt < ScanSpeed; cnt++)
243  {
244 
245  // Scan landscape column: sectors down
246  int32_t last_mat = -1;
247  for (cy = 0; cy < Height; cy++)
248  {
249  mat = d->_GetMat(ScanX, cy);
250  // material change?
251  if (last_mat != mat)
252  {
253  // upwards
254  if (last_mat != -1)
255  DoScan(d, ScanX, cy - 1, last_mat, 1);
256  // downwards
257  if (mat != -1)
258  cy += DoScan(d, ScanX, cy, mat, 0);
259  }
260  last_mat = mat;
261  }
262 
263  // Scan advance & rewind
264  ScanX++;
265  if (ScanX >= Width)
266  ScanX = 0;
267 
268  }
269 
270 }
@ RCT_MatScan
Definition: C4Record.h:78
int32_t DoScan(C4Landscape *, int32_t x, int32_t y, int32_t mat, int32_t dir)
int32_t ScanSpeed
Definition: C4Landscape.cpp:75

References C4Landscape::_GetMat(), C4MaterialCore::AboveTempConvert, C4Material::AboveTempConvertTo, AddDbgRec(), C4MaterialCore::BelowTempConvert, C4Material::BelowTempConvertTo, Config, C4ConfigGeneral::DebugRec, DEBUGREC_MATSCAN, DoScan(), C4Config::General, C4Weather::GetTemperature(), Height, C4MaterialMap::Map, MatCount, MaterialMap, C4MaterialMap::Num, RCT_MatScan, ScanSpeed, ScanX, Weather, and Width.

Here is the call graph for this function:

◆ FinishChange()

void C4Landscape::P::FinishChange ( C4Landscape d,
C4Rect  BoundingBox,
bool  updateMatAndPixCnt = true 
)

Definition at line 3927 of file C4Landscape.cpp.

3928 {
3929  // Intersect bounding box with landscape
3930  BoundingBox.Intersect(C4Rect(0, 0, Width, Height));
3931  if (!BoundingBox.Wdt || !BoundingBox.Hgt) return;
3932  // update render
3933  if (pLandscapeRender)
3934  pLandscapeRender->Update(BoundingBox, d);
3935  if (updateMatAndPixCnt) UpdateMatCnt(d, BoundingBox, true);
3936  // Restore Solidmasks
3937  C4Rect SolidMaskRect = BoundingBox;
3938  if (pLandscapeRender)
3939  SolidMaskRect = pLandscapeRender->GetAffectedRect(pLandscapeRender->GetAffectedRect(SolidMaskRect));
3940  for (C4SolidMask * pSolid = C4SolidMask::First; pSolid; pSolid = pSolid->Next)
3941  {
3942  pSolid->Repair(SolidMaskRect);
3943  }
3945  if (updateMatAndPixCnt) UpdatePixCnt(d, BoundingBox);
3946  // update FoW
3947  if (pFoW)
3948  {
3949  pFoW->Invalidate(BoundingBox);
3950  pFoW->Ambient.UpdateFromLandscape(*d, BoundingBox);
3951  }
3952 }
Definition: C4Rect.h:28
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
void Intersect(const C4Rect &r2)
Definition: C4Rect.cpp:100
static bool CheckConsistency()
static C4SolidMask * First
Definition: C4SolidMask.h:71
C4SolidMask * Next
Definition: C4SolidMask.h:74
std::unique_ptr< C4FoW > pFoW
Definition: C4Landscape.cpp:84
void UpdateMatCnt(const C4Landscape *, C4Rect Rect, bool fPlus)
void UpdatePixCnt(const C4Landscape *, const C4Rect &Rect, bool fCheck=false)
std::unique_ptr< C4LandscapeRender > pLandscapeRender
Definition: C4Landscape.cpp:58

References C4SolidMask::CheckConsistency(), C4SolidMask::First, C4Rect::Hgt, C4Rect::Intersect(), C4SolidMask::Next, and C4Rect::Wdt.

Here is the call graph for this function:

◆ ForPolygon()

int32_t C4Landscape::P::ForPolygon ( C4Landscape d,
int *  vtcs,
int  length,
const std::function< bool(int32_t, int32_t)> &  callback,
C4MaterialList mats_count = nullptr,
uint8_t  col = 0,
uint8_t  colBkg = 0,
uint8_t *  conversion_table = nullptr 
)

Definition at line 1216 of file C4Landscape.cpp.

1218 {
1219  // Variables for polygon drawer
1220  int c, x1, x2, y;
1221  int top = INT_MAX;
1222  int bottom = INT_MIN;
1223  int *i1, *i2;
1224  CPolyEdge *edge, *next_edge, *edgebuf;
1225  CPolyEdge *active_edges = nullptr;
1226  CPolyEdge *inactive_edges = nullptr;
1227  bool use_qpb = false;
1228 
1229  // Return value
1230  int32_t amount = 0;
1231  // Poly Buf
1232  if (length <= QuickPolyBufSize)
1233  {
1234  edgebuf = QuickPolyBuf; use_qpb = true;
1235  }
1236  else if (!(edgebuf = new CPolyEdge[length])) { return 0; }
1237 
1238  // Fill the edge table
1239  edge = edgebuf;
1240  i1 = vtcs;
1241  i2 = vtcs + (length - 1) * 2;
1242  for (c = 0; c < length; c++)
1243  {
1244  if (i1[1] != i2[1])
1245  {
1246  fill_edge_structure(edge, i1, i2);
1247  if (edge->bottom >= edge->y)
1248  {
1249  if (edge->y < top) top = edge->y;
1250  if (edge->bottom > bottom) bottom = edge->bottom;
1251  inactive_edges = add_edge(inactive_edges, edge, false);
1252  edge++;
1253  }
1254  }
1255  i2 = i1; i1 += 2;
1256  }
1257 
1258  // For each scanline in the polygon...
1259  for (c = top; c <= bottom; c++)
1260  {
1261  // Check for newly active edges
1262  edge = inactive_edges;
1263  while ((edge) && (edge->y == c))
1264  {
1265  next_edge = edge->next;
1266  inactive_edges = remove_edge(inactive_edges, edge);
1267  active_edges = add_edge(active_edges, edge, true);
1268  edge = next_edge;
1269  }
1270 
1271  // Draw horizontal line segments
1272  edge = active_edges;
1273  while ((edge) && (edge->next))
1274  {
1275  x1 = edge->x >> POLYGON_FIX_SHIFT;
1276  x2 = (edge->next->x + edge->next->w) >> POLYGON_FIX_SHIFT;
1277  y = c;
1278  // Fix coordinates
1279  if (x1 > x2) std::swap(x1, x2);
1280  // Set line
1281  if (callback)
1282  {
1283  for (int xcnt = x2 - x1 - 1; xcnt >= 0; xcnt--)
1284  {
1285  uint8_t pix = d->GetPix(x1 + xcnt, y);
1286  if (!conversion_table || conversion_table[pix])
1287  {
1288  int32_t mat = d->GetPixMat(pix);
1289  if (callback(x1 + xcnt, y))
1290  if (mats_count)
1291  {
1292  mats_count->Add(mat, 1);
1293  amount++;
1294  }
1295  }
1296  }
1297  }
1298  else if (conversion_table)
1299  for (int xcnt = x2 - x1 - 1; xcnt >= 0; xcnt--)
1300  {
1301  const uint8_t pix = conversion_table[uint8_t(d->GetPix(x1 + xcnt, y))];
1302  Surface8->SetPix(x1 + xcnt, y, pix);
1303  if (colBkg != Transparent) Surface8Bkg->SetPix(x1 + xcnt, y, colBkg);
1304  }
1305  else
1306  for (int xcnt = x2 - x1 - 1; xcnt >= 0; xcnt--)
1307  {
1308  if (col != Transparent) Surface8->SetPix(x1 + xcnt, y, col);
1309  if (colBkg != Transparent) Surface8Bkg->SetPix(x1 + xcnt, y, colBkg);
1310  }
1311  edge = edge->next->next;
1312  }
1313 
1314  // Update edges, sorting and removing dead ones
1315  edge = active_edges;
1316  while (edge)
1317  {
1318  next_edge = edge->next;
1319  if (c >= edge->bottom)
1320  {
1321  active_edges = remove_edge(active_edges, edge);
1322  }
1323  else
1324  {
1325  edge->x += edge->dx;
1326  while ((edge->prev) && (edge->x + edge->w / 2 < edge->prev->x + edge->prev->w / 2))
1327  {
1328  if (edge->next) edge->next->prev = edge->prev;
1329  edge->prev->next = edge->next;
1330  edge->next = edge->prev;
1331  edge->prev = edge->prev->prev;
1332  edge->next->prev = edge;
1333  if (edge->prev) edge->prev->next = edge;
1334  else active_edges = edge;
1335  }
1336  }
1337  edge = next_edge;
1338  }
1339  }
1340 
1341  // Clear scratch memory
1342  if (!use_qpb) delete[] edgebuf;
1343 
1344  return amount;
1345 }
CPolyEdge QuickPolyBuf[QuickPolyBufSize]
const int QuickPolyBufSize
#define POLYGON_FIX_SHIFT
struct CPolyEdge * prev
struct CPolyEdge * next
BYTE GetPix(int32_t x, int32_t y) const
int32_t GetPixMat(BYTE byPix) const
void Add(int32_t iMaterial, int32_t iAmount)

References C4ScriptGuiWindowPropertyName::bottom, QuickPolyBuf, QuickPolyBufSize, C4ScriptGuiWindowPropertyName::top, and CPolyEdge::y.

◆ GetBridgeMatConversion()

uint8_t * C4Landscape::P::GetBridgeMatConversion ( const C4Landscape d,
int32_t  for_material_col 
) const

Definition at line 3864 of file C4Landscape.cpp.

3865 {
3866  // safety
3867  int32_t for_material = d->GetPixMat(for_material_col);
3868  if (for_material < 0 || for_material >= MaterialMap.Num) return nullptr;
3869  // query map. create if not done yet
3870  if (!BridgeMatConversion[for_material_col])
3871  {
3872  auto conv_map = std::make_unique<uint8_t[]>(C4M_MaxTexIndex);
3873  for (int32_t i = 0; i < C4M_MaxTexIndex; ++i)
3874  {
3875  if ((MatDensity(for_material) >= d->GetPixDensity(i)))
3876  {
3877  // bridge pixel OK here. change pixel.
3878  conv_map[i] = for_material_col;
3879  }
3880  else
3881  {
3882  // bridge pixel not OK - keep current pixel
3883  conv_map[i] = i;
3884  }
3885  }
3886  BridgeMatConversion[for_material_col] = std::move(conv_map);
3887  }
3888  return BridgeMatConversion[for_material_col].get();
3889 }
const int C4M_MaxTexIndex
Definition: C4Constants.h:51
int32_t MatDensity(int32_t mat)
Definition: C4Material.h:240
int32_t GetPixDensity(BYTE byPix) const
std::array< std::unique_ptr< uint8_t[]>, C4M_MaxTexIndex > BridgeMatConversion
Definition: C4Landscape.cpp:66

References C4M_MaxTexIndex, C4Landscape::GetPixDensity(), C4Landscape::GetPixMat(), MatDensity(), MaterialMap, and C4MaterialMap::Num.

Here is the call graph for this function:

◆ GetMapColorIndex()

bool C4Landscape::P::GetMapColorIndex ( const char *  szMaterial,
const char *  szTexture,
BYTE rbyCol 
) const

Definition at line 3400 of file C4Landscape.cpp.

3401 {
3402  // Sky
3403  if (SEqual(szMaterial, C4TLS_MatSky))
3404  rbyCol = 0;
3405  // Material-Texture
3406  else
3407  {
3408  rbyCol = ::TextureMap.GetIndex(szMaterial, szTexture);
3409  if (!rbyCol) return false;
3410  }
3411  // Found
3412  return true;
3413 }
#define C4TLS_MatSky
Definition: C4ToolsDlg.h:39
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
int32_t GetIndex(const char *szMaterial, const char *szTexture, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:414

References C4TLS_MatSky, C4TextureMap::GetIndex(), SEqual(), and TextureMap.

Here is the call graph for this function:

◆ InitBorderPix()

bool C4Landscape::P::InitBorderPix ( )

Definition at line 2024 of file C4Landscape.cpp.

2025 {
2026  assert(Width > 0);
2027  // Init Top-/BottomRowPix array, which determines if out-of-landscape pixels on top/bottom side of the map are solid or not
2028  // In case of Top-/BottomOpen=2, unit by map and not landscape to avoid runtime join sync losses
2029  if (!Width) return true;
2030  TopRowPix.clear();
2031  BottomRowPix.clear();
2032  LeftColPix.clear();
2033  RightColPix.clear();
2034  // must access Game.C4S here because Landscape.TopOpen / Landscape.BottomOpen may not be initialized yet
2035  // why is there a local copy of that static variable anyway?
2036  int32_t top_open_flag = Game.C4S.Landscape.TopOpen;
2037  int32_t bottom_open_flag = Game.C4S.Landscape.BottomOpen;
2038  if (top_open_flag == 2 && !Map) top_open_flag = 1;
2039  if (bottom_open_flag == 2 && !Map) bottom_open_flag = 1;
2040 
2041  // Init TopRowPix
2042  switch (top_open_flag)
2043  {
2044  // TopOpen=0: Top is closed
2045  case 0: TopRowPix.assign(Width, MCVehic); break;
2046  // TopOpen=2: Top is open when pixel below has sky background
2047  case 2:
2048  TopRowPix.resize(Width);
2049  for (int32_t x = 0; x < Width; ++x)
2050  {
2051  uint8_t map_pix = MapBkg->GetPix(x / MapZoom, 0);
2052  TopRowPix[x] = ((map_pix != 0) ? MCVehic : 0);
2053  }
2054  break;
2055  // TopOpen=1: Top is open
2056  default: TopRowPix.assign(Width, 0); break;
2057  }
2058 
2059  // Init BottomRowPix
2060  switch (bottom_open_flag)
2061  {
2062  // BottomOpen=0: Bottom is closed
2063  case 0: BottomRowPix.assign(Width, MCVehic); break;
2064  // BottomOpen=2: Bottom is open when pixel above has sky background
2065  case 2:
2066  BottomRowPix.resize(Width);
2067  for (int32_t x = 0; x < Width; ++x)
2068  {
2069  uint8_t map_pix = MapBkg->GetPix(x / MapZoom, Map->Hgt - 1);
2070  BottomRowPix[x] = ((map_pix != 0) ? MCVehic : 0);
2071  }
2072  break;
2073  // BottomOpen=1: Bottom is open
2074  default: BottomRowPix.assign(Width, 0); break;
2075  }
2076 
2078  {
2079  // Compatibility: check both foreground and background material per
2080  // default, Top/BottomOpen=2-like behavior with AutoScanSideOpen=2.
2081  bool only_bg = Game.C4S.Landscape.AutoScanSideOpen == 2;
2082  LeftColPix.resize(Height);
2083  RightColPix.resize(Height);
2084  uint8_t map_pix;
2085  for (int32_t y = 0; y < Height; ++y)
2086  {
2087  map_pix = MapBkg->GetPix(0, y / MapZoom);
2088  if (!only_bg) map_pix += Map->GetPix(0, y / MapZoom);
2089  LeftColPix[y] = ((map_pix != 0) ? MCVehic : 0);
2090  map_pix = MapBkg->GetPix(Map->Wdt - 1, y / MapZoom);
2091  if (!only_bg) map_pix += Map->GetPix(Map->Wdt - 1, y / MapZoom);
2092  RightColPix[y] = ((map_pix != 0) ? MCVehic : 0);
2093  }
2094  }
2095  else
2096  {
2097  int32_t LeftOpen = std::min(Height, Game.C4S.Landscape.LeftOpen);
2098  int32_t RightOpen = std::min(Height, Game.C4S.Landscape.RightOpen);
2099  LeftColPix.assign(Height, MCVehic);
2100  RightColPix.assign(Height, MCVehic);
2101  for (int32_t cy = 0; cy < LeftOpen; cy++)
2102  LeftColPix[cy] = 0;
2103  for (int32_t cy = 0; cy < RightOpen; cy++)
2104  RightColPix[cy] = 0;
2105  }
2106 
2107  return true;
2108 }
BYTE MCVehic
Definition: C4Material.cpp:37
int32_t AutoScanSideOpen
Definition: C4Scenario.h:172
int32_t RightOpen
Definition: C4Scenario.h:171
int32_t TopOpen
Definition: C4Scenario.h:170
int32_t LeftOpen
Definition: C4Scenario.h:171
int32_t BottomOpen
Definition: C4Scenario.h:170
std::vector< uint8_t > BottomRowPix
Definition: C4Landscape.cpp:60
std::vector< uint8_t > LeftColPix
Definition: C4Landscape.cpp:60
std::vector< uint8_t > RightColPix
Definition: C4Landscape.cpp:60
std::vector< uint8_t > TopRowPix
Definition: C4Landscape.cpp:60

References C4SLandscape::AutoScanSideOpen, C4SLandscape::BottomOpen, C4Game::C4S, Game, C4Scenario::Landscape, C4SLandscape::LeftOpen, MCVehic, C4SLandscape::RightOpen, C4SLandscape::TopOpen, CPolyEdge::x, and CPolyEdge::y.

◆ MapToLandscape()

bool C4Landscape::P::MapToLandscape ( C4Landscape d,
const CSurface8 sfcMap,
const CSurface8 sfcMapBkg,
int32_t  iMapX,
int32_t  iMapY,
int32_t  iMapWdt,
int32_t  iMapHgt,
int32_t  iOffsX = 0,
int32_t  iOffsY = 0,
bool  noClear = false 
)

Definition at line 2369 of file C4Landscape.cpp.

2370 {
2371  assert(Surface8 && Surface8Bkg);
2372  // Clip to map/landscape segment
2373  int iMapWidth, iMapHeight, iLandscapeWidth, iLandscapeHeight;
2374  // Get map & landscape size
2375  sfcMap.GetSurfaceSize(iMapWidth, iMapHeight);
2376  Surface8->GetSurfaceSize(iLandscapeWidth, iLandscapeHeight);
2377  // Clip map segment to map size
2378  iMapX = Clamp<int32_t>(iMapX, 0, iMapWidth - 1); iMapY = Clamp<int32_t>(iMapY, 0, iMapHeight - 1);
2379  iMapWdt = Clamp<int32_t>(iMapWdt, 0, iMapWidth - iMapX); iMapHgt = Clamp<int32_t>(iMapHgt, 0, iMapHeight - iMapY);
2380  // No segment
2381  if (!iMapWdt || !iMapHgt) return true;
2382 
2383  // Get affected landscape rect
2384  C4Rect To;
2385  To.x = iMapX*MapZoom + iOffsX;
2386  To.y = iMapY*MapZoom + iOffsY;
2387  To.Wdt = iMapWdt*MapZoom;
2388  To.Hgt = iMapHgt*MapZoom;
2389 
2390  PrepareChange(d, To);
2391 
2392  // clear the old landscape if not supressed
2393  if (!noClear)
2394  {
2395  Surface8->ClearBox8Only(To.x, To.y, To.Wdt, To.Hgt);
2396  Surface8Bkg->ClearBox8Only(To.x, To.y, To.Wdt, To.Hgt);
2397  }
2398 
2399  MapToSurface(d, sfcMap, sfcMapBkg, iMapX, iMapY, iMapWdt, iMapHgt, To.x, To.y, To.Wdt, To.Hgt, iOffsX, iOffsY);
2400  FinishChange(d, To);
2401  return true;
2402 }
int32_t y
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
void FinishChange(C4Landscape *d, C4Rect BoundingBox, bool updateMatAndPixCnt=true)
void PrepareChange(const C4Landscape *d, const C4Rect &BoundingBox, bool updateMatCnt=true)
bool MapToSurface(C4Landscape *, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, int32_t iToX, int32_t iToY, int32_t iToWdt, int32_t iToHgt, int32_t iOffX, int32_t iOffY)

References CSurface8::GetSurfaceSize(), C4Rect::Hgt, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Here is the call graph for this function:

◆ MapToSurface()

bool C4Landscape::P::MapToSurface ( C4Landscape d,
const CSurface8 sfcMap,
const CSurface8 sfcMapBkg,
int32_t  iMapX,
int32_t  iMapY,
int32_t  iMapWdt,
int32_t  iMapHgt,
int32_t  iToX,
int32_t  iToY,
int32_t  iToWdt,
int32_t  iToHgt,
int32_t  iOffX,
int32_t  iOffY 
)

Definition at line 2341 of file C4Landscape.cpp.

2342 {
2343 
2344  // assign clipper
2345  Surface8->Clip(iToX, iToY, iToX + iToWdt - 1, iToY + iToHgt - 1);
2346  Surface8Bkg->Clip(iToX, iToY, iToX + iToWdt - 1, iToY + iToHgt - 1);
2348 
2349  // Enlarge map segment for chunky rim
2350  iMapX -= 2 + MaterialMap.max_shape_width / MapZoom;
2351  iMapY -= 2 + MaterialMap.max_shape_height / MapZoom;
2352  iMapWdt += 4 + MaterialMap.max_shape_width / MapZoom * 2;
2353  iMapHgt += 4 + MaterialMap.max_shape_height / MapZoom * 2;
2354 
2355  // Determine texture usage in map segment
2356  DWORD dwTexUsage[C4M_MaxTexIndex];
2357  if (!GetTexUsage(sfcMap, sfcMapBkg, iMapX, iMapY, iMapWdt, iMapHgt, dwTexUsage)) return false;
2358  // Texture zoom map to landscape
2359  if (!TexOZoom(d, sfcMap, sfcMapBkg, iMapX, iMapY, iMapWdt, iMapHgt, dwTexUsage, iOffX, iOffY)) return false;
2360 
2361  // remove clipper
2362  Surface8->NoClip();
2363  Surface8Bkg->NoClip();
2364 
2365  // success
2366  return true;
2367 }
C4Draw * pDraw
Definition: C4Draw.cpp:42
uint32_t DWORD
bool NoPrimaryClipper()
Definition: C4Draw.cpp:237
int32_t max_shape_height
Definition: C4Material.h:171
int32_t max_shape_width
Definition: C4Material.h:171
bool TexOZoom(C4Landscape *, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, DWORD *dwpTextureUsage, int32_t iToX=0, int32_t iToY=0)

References C4M_MaxTexIndex, MaterialMap, C4MaterialMap::max_shape_height, C4MaterialMap::max_shape_width, C4Draw::NoPrimaryClipper(), and pDraw.

Here is the call graph for this function:

◆ Mat2Pal()

bool C4Landscape::P::Mat2Pal ( )

Definition at line 4238 of file C4Landscape.cpp.

4239 {
4240  if (!Surface8 || !Surface8Bkg) return false;
4241  // set landscape pal
4242  int32_t tex;
4243  for (tex = 0; tex < C4M_MaxTexIndex; tex++)
4244  {
4245  const C4TexMapEntry *pTex = ::TextureMap.GetEntry(tex);
4246  if (!pTex || pTex->isNull())
4247  continue;
4248  // colors
4249  DWORD dwPix = pTex->GetPattern().PatternClr(0, 0);
4250  Surface8->pPal->Colors[MatTex2PixCol(tex)] = dwPix;
4251  Surface8Bkg->pPal->Colors[MatTex2PixCol(tex)] = dwPix;
4252  }
4253  // success
4254  return true;
4255 }
DWORD PatternClr(unsigned int iX, unsigned int iY) const
Definition: C4Draw.cpp:159
const C4Pattern & GetPattern() const
Definition: C4Texture.h:64
bool isNull() const
Definition: C4Texture.h:59

References C4M_MaxTexIndex, C4TextureMap::GetEntry(), C4TexMapEntry::GetPattern(), C4TexMapEntry::isNull(), MatTex2PixCol(), C4Pattern::PatternClr(), and TextureMap.

Here is the call graph for this function:

◆ PostFreeShape()

void C4Landscape::P::PostFreeShape ( C4ValueArray dig_objects,
C4Object by_object 
)

Definition at line 530 of file C4Landscape.cpp.

531 {
532  // Do callbacks to digger and dug out objects for objects that are now dug free
533  if (by_object)
534  {
535  for (int32_t i = 0; i < dig_objects->GetSize(); ++i)
536  {
537  C4Object *dig_object = dig_objects->GetItem(i).getObj();
538  if (dig_object && !GBackSolid(dig_object->GetX(), dig_object->GetY()))
539  if (dig_object != by_object)
540  if (!dig_object->Contained && dig_object->Status)
541  {
542  C4AulParSet pars(by_object);
543  dig_object->Call(PSF_OnDugOut, &pars);
544  if (dig_object->Status && by_object->Status)
545  {
546  C4AulParSet pars(dig_object);
547  by_object->Call(PSF_DigOutObject, &pars);
548  }
549  }
550  }
551  }
552 }
bool GBackSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:229
int32_t GetX() const
Definition: C4Object.h:285
int32_t GetY() const
Definition: C4Object.h:286
const C4Value & GetItem(int32_t iElem) const
Definition: C4ValueArray.h:38
int32_t GetSize() const
Definition: C4ValueArray.h:36
C4Object * getObj() const
Definition: C4Value.cpp:68

References C4PropList::Call(), C4Object::Contained, GBackSolid(), C4ValueArray::GetItem(), C4Value::getObj(), C4ValueArray::GetSize(), C4Object::GetX(), C4Object::GetY(), PSF_DigOutObject, PSF_OnDugOut, and C4PropList::Status.

Here is the call graph for this function:

◆ PrepareChange()

void C4Landscape::P::PrepareChange ( const C4Landscape d,
const C4Rect BoundingBox,
bool  updateMatCnt = true 
)

Definition at line 3914 of file C4Landscape.cpp.

3915 {
3916  // move solidmasks out of the way
3917  C4Rect SolidMaskRect = BoundingBox;
3918  if (pLandscapeRender)
3919  SolidMaskRect = pLandscapeRender->GetAffectedRect(pLandscapeRender->GetAffectedRect(SolidMaskRect));
3920  for (C4SolidMask * pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
3921  {
3922  pSolid->RemoveTemporary(SolidMaskRect);
3923  }
3924  if (updateMatCnt) UpdateMatCnt(d, BoundingBox, false);
3925 }
static C4SolidMask * Last
Definition: C4SolidMask.h:72
C4SolidMask * Prev
Definition: C4SolidMask.h:73

References C4SolidMask::Last, and C4SolidMask::Prev.

◆ PrepareFreeShape()

C4ValueArray * C4Landscape::P::PrepareFreeShape ( C4Rect BoundingBox,
C4Object by_object 
)

Definition at line 519 of file C4Landscape.cpp.

520 {
521  // Remember any in-earth objects in area
522  C4FindObjectInRect fo_inrect(BoundingBox);
523  C4FindObjectOCF fo_insolid(OCF_InSolid);
524  C4FindObjectLayer fo_layer(by_object ? by_object->Layer : nullptr);
525  C4FindObject *fo_list[] = { &fo_inrect, &fo_insolid, &fo_layer };
526  C4FindObjectAndStatic fo_srch(3, fo_list);
527  return fo_srch.FindMany(::Objects, ::Objects.Sectors);
528 }
const uint32_t OCF_InSolid
Definition: C4Constants.h:99
C4GameObjects Objects
Definition: C4Globals.cpp:48
C4LSectors Sectors
Definition: C4GameObjects.h:42
C4ObjectPtr Layer
Definition: C4Object.h:134

References C4FindObject::FindMany(), C4Object::Layer, Objects, OCF_InSolid, and C4GameObjects::Sectors.

Here is the call graph for this function:

◆ SaveDiffInternal()

bool C4Landscape::P::SaveDiffInternal ( const C4Landscape d,
C4Group hGroup,
bool  fSyncSave 
) const

Definition at line 1742 of file C4Landscape.cpp.

1743 {
1744  assert(pInitial && pInitialBkg);
1745  if (!pInitial || !pInitialBkg) return false;
1746 
1747  // If it shouldn't be sync-save: Clear all bytes that have not changed, i.e.
1748  // set them to C4M_MaxTexIndex
1749  bool fChanged = false, fChangedBkg = false;;
1750  if (!fSyncSave)
1751  for (int y = 0; y < Height; y++)
1752  for (int x = 0; x < Width; x++)
1753  {
1754  if (pInitial[y * Width + x] == Surface8->_GetPix(x, y))
1755  Surface8->SetPix(x, y, C4M_MaxTexIndex);
1756  else
1757  fChanged = true;
1758 
1759  if (pInitialBkg[y * Width + x] == Surface8Bkg->_GetPix(x, y))
1760  Surface8Bkg->SetPix(x, y, C4M_MaxTexIndex);
1761  else
1762  fChangedBkg = true;
1763  }
1764 
1765  if (fSyncSave || fChanged)
1766  {
1767  // Save landscape surface
1769  return false;
1770 
1771  // Move temp file to group
1774  return false;
1775  }
1776 
1777  if (fSyncSave || fChangedBkg)
1778  {
1779  // Save landscape surface
1781  return false;
1782 
1783  // Move temp file to group
1786  return false;
1787  }
1788 
1789  // Restore landscape pixels
1790  if (!fSyncSave)
1791  for (int y = 0; y < Height; y++)
1792  for (int x = 0; x < Width; x++)
1793  {
1794  if (Surface8->_GetPix(x, y) == C4M_MaxTexIndex)
1795  Surface8->SetPix(x, y, pInitial[y * Width + x]);
1796  if (Surface8Bkg->_GetPix(x, y) == C4M_MaxTexIndex)
1797  Surface8Bkg->SetPix(x, y, pInitialBkg[y * Width + x]);
1798  }
1799 
1800  // Save changed map, too
1801  if (fMapChanged && Map)
1802  if (!d->SaveMap(hGroup)) return false;
1803 
1804  // and textures (if changed)
1805  if (!d->SaveTextures(hGroup)) return false;
1806 
1807  return true;
1808 }
#define C4CFN_DiffLandscape
Definition: C4Components.h:63
#define C4CFN_TempLandscapeBkg
Definition: C4Components.h:157
#define C4CFN_DiffLandscapeBkg
Definition: C4Components.h:64
#define C4CFN_TempLandscape
Definition: C4Components.h:156
const char * AtTempPath(const char *filename)
Definition: C4Config.cpp:600
bool Move(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1633
bool SaveTextures(C4Group &hGroup) const
bool SaveMap(C4Group &hGroup) const
std::unique_ptr< BYTE[]> pInitial
Definition: C4Landscape.cpp:82
std::unique_ptr< BYTE[]> pInitialBkg
Definition: C4Landscape.cpp:83

References C4Config::AtTempPath(), C4CFN_DiffLandscape, C4CFN_DiffLandscapeBkg, C4CFN_TempLandscape, C4CFN_TempLandscapeBkg, C4M_MaxTexIndex, Config, C4Group::Move(), C4Landscape::SaveMap(), C4Landscape::SaveTextures(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ SaveInternal()

bool C4Landscape::P::SaveInternal ( const C4Landscape d,
C4Group hGroup 
) const

Definition at line 1701 of file C4Landscape.cpp.

1702 {
1703  // Save landscape surface
1704  char szTempLandscape[_MAX_PATH_LEN];
1705  SCopy(Config.AtTempPath(C4CFN_TempLandscape), szTempLandscape);
1706  MakeTempFilename(szTempLandscape);
1707  if (!Surface8->Save(szTempLandscape))
1708  return false;
1709 
1710  // Move temp file to group
1711  if (!hGroup.Move(szTempLandscape, C4CFN_LandscapeFg))
1712  return false;
1713 
1714  // Same for background surface
1715  SCopy(Config.AtTempPath(C4CFN_TempLandscapeBkg), szTempLandscape);
1716  MakeTempFilename(szTempLandscape);
1717  if (!Surface8Bkg->Save(szTempLandscape))
1718  return false;
1719  if (!hGroup.Move(szTempLandscape, C4CFN_LandscapeBg))
1720  return false;
1721 
1722  // Save map
1723  if (fMapChanged && Map)
1724  if (!d->SaveMap(hGroup))
1725  return false;
1726 
1727  // save textures (if changed)
1728  if (!d->SaveTextures(hGroup))
1729  return false;
1730 
1731  return true;
1732 }
#define C4CFN_LandscapeFg
Definition: C4Components.h:61
#define C4CFN_LandscapeBg
Definition: C4Components.h:62
#define _MAX_PATH_LEN
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
void MakeTempFilename(char *szFilename)
Definition: StdFile.cpp:320

References _MAX_PATH_LEN, C4Config::AtTempPath(), C4CFN_LandscapeBg, C4CFN_LandscapeFg, C4CFN_TempLandscape, C4CFN_TempLandscapeBkg, Config, MakeTempFilename(), C4Group::Move(), C4Landscape::SaveMap(), C4Landscape::SaveTextures(), and SCopy().

Here is the call graph for this function:

◆ ShakeFreePix()

bool C4Landscape::P::ShakeFreePix ( C4Landscape d,
int32_t  tx,
int32_t  ty 
)

Definition at line 757 of file C4Landscape.cpp.

758 {
759  int32_t mat = d->GetMat(tx, ty);
760  if (MatValid(mat))
761  {
762  if (::MaterialMap.Map[mat].DigFree)
763  {
764  d->ClearPix(tx, ty);
765  ::PXS.Create(mat, itofix(tx), itofix(ty));
766  // check for instable materials to start moving by the cleared space
767  d->CheckInstabilityRange(tx, ty);
768  return true;
769  }
770  }
771  return false;
772 }
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
bool Create(int32_t mat, C4Real ix, C4Real iy, C4Real ixdir=Fix0, C4Real iydir=Fix0)
Definition: C4PXS.cpp:175

References C4Landscape::CheckInstabilityRange(), C4Landscape::ClearPix(), C4PXSSystem::Create(), C4MaterialCore::DigFree, C4Landscape::GetMat(), itofix(), C4MaterialMap::Map, MaterialMap, MatValid(), and PXS.

Here is the call graph for this function:

◆ TexOZoom()

bool C4Landscape::P::TexOZoom ( C4Landscape d,
const CSurface8 sfcMap,
const CSurface8 sfcMapBkg,
int32_t  iMapX,
int32_t  iMapY,
int32_t  iMapWdt,
int32_t  iMapHgt,
DWORD dwpTextureUsage,
int32_t  iToX = 0,
int32_t  iToY = 0 
)

Definition at line 2325 of file C4Landscape.cpp.

2326 {
2327  // ChunkOZoom all used textures
2328  for (auto iIndex : ::TextureMap.Order)
2329  {
2330  if (dwpTextureUsage[iIndex] > 0)
2331  {
2332  // ChunkOZoom map to landscape
2333  ChunkOZoom(d, sfcMap, sfcMapBkg, iMapX, iMapY, iMapWdt, iMapHgt, iIndex, iToX, iToY);
2334  }
2335  }
2336 
2337  // Done
2338  return true;
2339 }
std::vector< int32_t > Order
Definition: C4Texture.h:77
void ChunkOZoom(C4Landscape *, const CSurface8 &sfcMap, const CSurface8 &sfcMapBkg, int32_t iMapX, int32_t iMapY, int32_t iMapWdt, int32_t iMapHgt, uint8_t iTexture, int32_t iOffX=0, int32_t iOffY=0)

References C4TextureMap::Order, and TextureMap.

◆ UpdateMatCnt()

void C4Landscape::P::UpdateMatCnt ( const C4Landscape d,
C4Rect  Rect,
bool  fPlus 
)

Definition at line 4275 of file C4Landscape.cpp.

4276 {
4277  Rect.Intersect(C4Rect(0, 0, Width, Height));
4278  if (!Rect.Hgt || !Rect.Wdt) return;
4279  // Multiplicator for changes
4280  const int32_t iMul = fPlus ? +1 : -1;
4281  // Count pixels
4282  for (int32_t x = 0; x < Rect.Wdt; x++)
4283  {
4284  int iHgt = 0;
4285  int32_t y;
4286  for (y = 1; y < Rect.Hgt; y++)
4287  {
4288  int32_t iMat = d->_GetMat(Rect.x + x, Rect.y + y - 1);
4289  // Same material? Count it.
4290  if (iMat == d->_GetMat(Rect.x + x, Rect.y + y))
4291  iHgt++;
4292  else
4293  {
4294  if (iMat >= 0)
4295  {
4296  // Normal material counting
4297  MatCount[iMat] += iMul * (iHgt + 1);
4298  // Effective material counting enabled?
4299  if (int32_t iMinHgt = ::MaterialMap.Map[iMat].MinHeightCount)
4300  {
4301  // First chunk? Add any material above when checking chunk height
4302  int iAddedHeight = 0;
4303  if (Rect.y && iHgt + 1 == y)
4304  iAddedHeight = d->GetMatHeight(Rect.x + x, Rect.y - 1, -1, iMat, iMinHgt);
4305  // Check the chunk height
4306  if (iHgt + 1 + iAddedHeight >= iMinHgt)
4307  {
4308  EffectiveMatCount[iMat] += iMul * (iHgt + 1);
4309  if (iAddedHeight < iMinHgt)
4310  EffectiveMatCount[iMat] += iMul * iAddedHeight;
4311  }
4312  }
4313  }
4314  // Next chunk of material
4315  iHgt = 0;
4316  }
4317  }
4318  // Check last pixel
4319  int32_t iMat = d->_GetMat(Rect.x + x, Rect.y + Rect.Hgt - 1);
4320  if (iMat >= 0)
4321  {
4322  // Normal material counting
4323  MatCount[iMat] += iMul * (iHgt + 1);
4324  // Minimum height counting?
4325  if (int32_t iMinHgt = ::MaterialMap.Map[iMat].MinHeightCount)
4326  {
4327  int iAddedHeight1 = 0, iAddedHeight2 = 0;
4328  // Add any material above for chunk size check
4329  if (Rect.y && iHgt + 1 == Rect.Hgt)
4330  iAddedHeight1 = d->GetMatHeight(Rect.x + x, Rect.y - 1, -1, iMat, iMinHgt);
4331  // Add any material below for chunk size check
4332  if (Rect.y + y < Height)
4333  iAddedHeight2 = d->GetMatHeight(Rect.x + x, Rect.y + Rect.Hgt, 1, iMat, iMinHgt);
4334  // Chunk tall enough?
4335  if (iHgt + 1 + iAddedHeight1 + iAddedHeight2 >= ::MaterialMap.Map[iMat].MinHeightCount)
4336  {
4337  EffectiveMatCount[iMat] += iMul * (iHgt + 1);
4338  if (iAddedHeight1 < iMinHgt)
4339  EffectiveMatCount[iMat] += iMul * iAddedHeight1;
4340  if (iAddedHeight2 < iMinHgt)
4341  EffectiveMatCount[iMat] += iMul * iAddedHeight2;
4342  }
4343  }
4344  }
4345  }
4346 }
int32_t GetMatHeight(int32_t x, int32_t y, int32_t iYDir, int32_t iMat, int32_t iMax) const
int32_t MinHeightCount
Definition: C4Material.h:130

References C4Landscape::_GetMat(), C4Landscape::GetMatHeight(), C4Rect::Hgt, C4Rect::Intersect(), C4MaterialMap::Map, MaterialMap, C4MaterialCore::MinHeightCount, C4Rect::Wdt, CPolyEdge::x, C4Rect::x, CPolyEdge::y, and C4Rect::y.

Here is the call graph for this function:

◆ UpdatePixCnt()

void C4Landscape::P::UpdatePixCnt ( const C4Landscape d,
const C4Rect Rect,
bool  fCheck = false 
)

Definition at line 4258 of file C4Landscape.cpp.

4259 {
4260  int32_t PixCntWidth = (Width + 16) / 17;
4261  for (int32_t y = std::max<int32_t>(0, Rect.y / 15); y < std::min<int32_t>(PixCntPitch, (Rect.y + Rect.Hgt + 14) / 15); y++)
4262  for (int32_t x = std::max<int32_t>(0, Rect.x / 17); x < std::min<int32_t>(PixCntWidth, (Rect.x + Rect.Wdt + 16) / 17); x++)
4263  {
4264  int iCnt = 0;
4265  for (int32_t x2 = x * 17; x2 < std::min<int32_t>(x * 17 + 17, Width); x2++)
4266  for (int32_t y2 = y * 15; y2 < std::min<int32_t>(y * 15 + 15, Height); y2++)
4267  if (d->_GetDensity(x2, y2))
4268  iCnt++;
4269  if (fCheck)
4270  assert(iCnt == PixCnt[x * PixCntPitch + y]);
4271  PixCnt[x * PixCntPitch + y] = iCnt;
4272  }
4273 }
int iCnt
Definition: TstC4NetIO.cpp:32
int32_t _GetDensity(int32_t x, int32_t y) const
int32_t PixCntPitch
Definition: C4Landscape.cpp:63
std::vector< uint8_t > PixCnt
Definition: C4Landscape.cpp:64

References C4Landscape::_GetDensity(), C4Rect::Hgt, iCnt, C4Rect::Wdt, CPolyEdge::x, C4Rect::x, CPolyEdge::y, and C4Rect::y.

Here is the call graph for this function:

Member Data Documentation

◆ BottomRowPix

std::vector<uint8_t> C4Landscape::P::BottomRowPix

Definition at line 60 of file C4Landscape.cpp.

◆ BridgeMatConversion

std::array< std::unique_ptr< uint8_t[]>, C4M_MaxTexIndex > C4Landscape::P::BridgeMatConversion
mutable

Definition at line 66 of file C4Landscape.cpp.

◆ EffectiveMatCount

std::array<DWORD, C4MaxMaterial> C4Landscape::P::EffectiveMatCount {}

Definition at line 72 of file C4Landscape.cpp.

◆ fMapChanged

bool C4Landscape::P::fMapChanged = false

Definition at line 81 of file C4Landscape.cpp.

◆ Gravity

C4Real C4Landscape::P::Gravity = DefaultGravAccel

Definition at line 76 of file C4Landscape.cpp.

◆ Height

int32_t C4Landscape::P::Height = 0

Definition at line 69 of file C4Landscape.cpp.

Referenced by ExecuteScan().

◆ LeftColPix

std::vector<uint8_t> C4Landscape::P::LeftColPix

Definition at line 60 of file C4Landscape.cpp.

◆ Map

std::unique_ptr<CSurface8> C4Landscape::P::Map

Definition at line 56 of file C4Landscape.cpp.

◆ MapBkg

std::unique_ptr<CSurface8> C4Landscape::P::MapBkg

Definition at line 57 of file C4Landscape.cpp.

◆ MapHeight

int32_t C4Landscape::P::MapHeight = 0

Definition at line 70 of file C4Landscape.cpp.

◆ MapSeed

int32_t C4Landscape::P::MapSeed = 0

Definition at line 78 of file C4Landscape.cpp.

◆ MapWidth

int32_t C4Landscape::P::MapWidth = 0

Definition at line 70 of file C4Landscape.cpp.

◆ MapZoom

int32_t C4Landscape::P::MapZoom = 0

Definition at line 70 of file C4Landscape.cpp.

◆ MatCount

std::array<DWORD, C4MaxMaterial> C4Landscape::P::MatCount {}

Definition at line 71 of file C4Landscape.cpp.

Referenced by ExecuteScan().

◆ mode

LandscapeMode C4Landscape::P::mode = LandscapeMode::Undefined

Definition at line 68 of file C4Landscape.cpp.

◆ Modulation

uint32_t C4Landscape::P::Modulation = 0

Definition at line 77 of file C4Landscape.cpp.

◆ NoScan

bool C4Landscape::P::NoScan = false

Definition at line 74 of file C4Landscape.cpp.

◆ pFoW

std::unique_ptr<C4FoW> C4Landscape::P::pFoW

Definition at line 84 of file C4Landscape.cpp.

◆ pInitial

std::unique_ptr<BYTE[]> C4Landscape::P::pInitial

Definition at line 82 of file C4Landscape.cpp.

◆ pInitialBkg

std::unique_ptr<BYTE[]> C4Landscape::P::pInitialBkg

Definition at line 83 of file C4Landscape.cpp.

◆ Pix2Dens

int32_t C4Landscape::P::Pix2Dens

Definition at line 61 of file C4Landscape.cpp.

◆ Pix2Light

bool C4Landscape::P::Pix2Light

Definition at line 62 of file C4Landscape.cpp.

◆ Pix2Mat

int32_t C4Landscape::P::Pix2Mat

Definition at line 61 of file C4Landscape.cpp.

◆ Pix2Place

int32_t C4Landscape::P::Pix2Place

Definition at line 61 of file C4Landscape.cpp.

◆ PixCnt

std::vector<uint8_t> C4Landscape::P::PixCnt

Definition at line 64 of file C4Landscape.cpp.

◆ PixCntPitch

int32_t C4Landscape::P::PixCntPitch = 0

Definition at line 63 of file C4Landscape.cpp.

◆ pLandscapeRender

std::unique_ptr<C4LandscapeRender> C4Landscape::P::pLandscapeRender

Definition at line 58 of file C4Landscape.cpp.

◆ pMapCreator

std::unique_ptr<C4MapCreatorS2> C4Landscape::P::pMapCreator

Definition at line 80 of file C4Landscape.cpp.

◆ Relights

std::array<C4Rect, C4LS_MaxRelights> C4Landscape::P::Relights

Definition at line 65 of file C4Landscape.cpp.

◆ RightColPix

std::vector<uint8_t> C4Landscape::P::RightColPix

Definition at line 60 of file C4Landscape.cpp.

◆ ScanSpeed

int32_t C4Landscape::P::ScanSpeed = 2

Definition at line 75 of file C4Landscape.cpp.

Referenced by ExecuteScan().

◆ ScanX

int32_t C4Landscape::P::ScanX = 0

Definition at line 75 of file C4Landscape.cpp.

Referenced by ExecuteScan().

◆ Sky

C4Sky C4Landscape::P::Sky

Definition at line 79 of file C4Landscape.cpp.

◆ Surface8

std::unique_ptr< CSurface8 > C4Landscape::P::Surface8

Definition at line 54 of file C4Landscape.cpp.

◆ Surface8Bkg

std::unique_ptr<CSurface8> C4Landscape::P::Surface8Bkg

Definition at line 55 of file C4Landscape.cpp.

◆ TopRowPix

std::vector<uint8_t> C4Landscape::P::TopRowPix

Definition at line 60 of file C4Landscape.cpp.

◆ Width

int32_t C4Landscape::P::Width = 0

Definition at line 69 of file C4Landscape.cpp.

Referenced by ExecuteScan().


The documentation for this struct was generated from the following files: