forked from Mirrors/openclonk
242 lines
6.3 KiB
C++
242 lines
6.3 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 1998-2000 Matthes Bender
|
|
* Copyright (c) 2005, 2007 Sven Eberhardt
|
|
* 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.
|
|
*/
|
|
|
|
/* Create map from dynamic landscape data in scenario */
|
|
|
|
#include <C4Include.h>
|
|
#include <C4Map.h>
|
|
|
|
#include <C4Random.h>
|
|
#include <C4Texture.h>
|
|
#include <C4Group.h>
|
|
|
|
#include <CSurface8.h>
|
|
#include <Bitmap256.h>
|
|
|
|
C4MapCreator::C4MapCreator()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
void C4MapCreator::Reset()
|
|
{
|
|
MapIFT=128;
|
|
MapBuf=NULL;
|
|
Exclusive=-1;
|
|
}
|
|
|
|
void C4MapCreator::SetPix(int32_t x, int32_t y, BYTE col)
|
|
{
|
|
// Safety
|
|
if (!Inside<int32_t>(x,0,MapWdt-1) || !Inside<int32_t>(y,0,MapHgt-1)) return;
|
|
// Exclusive
|
|
if (Exclusive>-1) if (GetPix(x,y)!=Exclusive) return;
|
|
// Set pix
|
|
MapBuf->SetPix(x,y,col);
|
|
}
|
|
|
|
void C4MapCreator::SetSpot(int32_t x, int32_t y, int32_t rad, BYTE col)
|
|
{
|
|
int32_t ycnt,xcnt,lwdt,dpy;
|
|
for (ycnt=-rad; ycnt<=rad; ycnt++)
|
|
{
|
|
lwdt= (int32_t) sqrt(double(rad*rad-ycnt*ycnt)); dpy=y+ycnt;
|
|
for (xcnt=-lwdt; xcnt<lwdt+(lwdt==0); xcnt++)
|
|
SetPix(x+xcnt,dpy,col);
|
|
}
|
|
}
|
|
|
|
void C4MapCreator::DrawLayer(int32_t x, int32_t y, int32_t size, BYTE col)
|
|
{
|
|
int32_t cnt,cnt2;
|
|
for (cnt=0; cnt<size; cnt++)
|
|
{
|
|
x+=Random(9)-4; y+=Random(3)-1;
|
|
for (cnt2=Random(3); cnt2<5; cnt2++)
|
|
{ SetPix(x+cnt2,y,col); SetPix(x+cnt2+1,y+1,col); }
|
|
}
|
|
}
|
|
|
|
BYTE C4MapCreator::GetPix(int32_t x, int32_t y)
|
|
{
|
|
// Safety
|
|
if (!Inside<int32_t>(x,0,MapWdt-1) || !Inside<int32_t>(y,0,MapHgt-1)) return 0;
|
|
// Get pix
|
|
return MapBuf->GetPix(x,y);
|
|
}
|
|
|
|
void C4MapCreator::Create(CSurface8 *sfcMap,
|
|
C4SLandscape &rLScape, C4TextureMap &rTexMap,
|
|
bool fLayers, int32_t iPlayerNum)
|
|
{
|
|
double fullperiod= 20.0 * M_PI;
|
|
BYTE ccol;
|
|
int32_t cx,cy;
|
|
|
|
// Safeties
|
|
if (!sfcMap) return;
|
|
iPlayerNum=BoundBy<int32_t>(iPlayerNum,1,C4S_MaxPlayer);
|
|
|
|
// Set creator variables
|
|
MapBuf = sfcMap;
|
|
MapWdt = MapBuf->Wdt; MapHgt = MapBuf->Hgt;
|
|
|
|
// Reset map (0 is sky)
|
|
MapBuf->ClearBox8Only(0,0,MapBuf->Wdt, MapBuf->Hgt);
|
|
|
|
// Surface
|
|
ccol=rTexMap.GetIndexMatTex(rLScape.Material)+MapIFT;
|
|
float amplitude= (float) rLScape.Amplitude.Evaluate();
|
|
float phase= (float) rLScape.Phase.Evaluate();
|
|
float period= (float) rLScape.Period.Evaluate();
|
|
if (rLScape.MapPlayerExtend) period *= Min(iPlayerNum, C4S_MaxMapPlayerExtend);
|
|
float natural= (float) rLScape.Random.Evaluate();
|
|
int32_t level0= Min(MapWdt,MapHgt)/2;
|
|
int32_t maxrange= level0*3/4;
|
|
double cy_curve,cy_natural; // -1.0 - +1.0 !
|
|
|
|
double rnd_cy,rnd_tend; // -1.0 - +1.0 !
|
|
rnd_cy= (double) (Random(2000+1)-1000)/1000.0;
|
|
rnd_tend= (double) (Random(200+1)-100)/20000.0;
|
|
|
|
for (cx=0; cx<MapWdt; cx++)
|
|
{
|
|
|
|
rnd_cy+=rnd_tend;
|
|
rnd_tend+= (double) (Random(100+1)-50)/10000;
|
|
if (rnd_tend>+0.05) rnd_tend=+0.05;
|
|
if (rnd_tend<-0.05) rnd_tend=-0.05;
|
|
if (rnd_cy<-0.5) rnd_tend+=0.01;
|
|
if (rnd_cy>+0.5) rnd_tend-=0.01;
|
|
|
|
cy_natural=rnd_cy*natural/100.0;
|
|
cy_curve=sin(fullperiod*period/100.0*(float)cx/(float)MapWdt
|
|
+2.0*M_PI*phase/100.0) * amplitude/100.0;
|
|
|
|
cy=level0+BoundBy((int32_t)((float)maxrange*(cy_curve+cy_natural)),
|
|
-maxrange,+maxrange);
|
|
|
|
|
|
SetPix(cx,cy,ccol);
|
|
}
|
|
|
|
// Raise bottom to surface
|
|
for (cx=0; cx<MapWdt; cx++)
|
|
for (cy=MapHgt-1; (cy>=0) && !GetPix(cx,cy); cy--)
|
|
SetPix(cx,cy,ccol);
|
|
// Raise liquid level
|
|
Exclusive=0;
|
|
ccol=rTexMap.GetIndexMatTex(rLScape.Liquid);
|
|
int32_t wtr_level=rLScape.LiquidLevel.Evaluate();
|
|
for (cx=0; cx<MapWdt; cx++)
|
|
for (cy=MapHgt*(100-wtr_level)/100; cy<MapHgt; cy++)
|
|
SetPix(cx,cy,ccol);
|
|
Exclusive=-1;
|
|
|
|
// Layers
|
|
if (fLayers)
|
|
{
|
|
|
|
// Base material
|
|
Exclusive=rTexMap.GetIndexMatTex(rLScape.Material)+MapIFT;
|
|
|
|
int32_t cnt,clayer,layer_num,sptx,spty;
|
|
|
|
// Process layer name list
|
|
for (clayer=0; clayer<C4MaxNameList; clayer++)
|
|
if (rLScape.Layers.Name[clayer][0])
|
|
{
|
|
// Draw layers
|
|
ccol=rTexMap.GetIndexMatTex(rLScape.Layers.Name[clayer])+MapIFT;
|
|
layer_num=rLScape.Layers.Count[clayer];
|
|
layer_num=layer_num*MapWdt*MapHgt/15000;
|
|
for (cnt=0; cnt<layer_num; cnt++)
|
|
{
|
|
// Place layer
|
|
sptx=Random(MapWdt);
|
|
for (spty=0; (spty<MapHgt) && (GetPix(sptx,spty)!=Exclusive); spty++) {}
|
|
spty+=5+Random((MapHgt-spty)-10);
|
|
DrawLayer(sptx,spty,Random(15),ccol);
|
|
|
|
}
|
|
}
|
|
|
|
Exclusive=-1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*bool C4MapCreator::Load(
|
|
BYTE **pbypBuffer,
|
|
int32_t &rBufWdt, int32_t &rMapWdt, int32_t &rMapHgt,
|
|
C4Group &hGroup, const char *szEntryName,
|
|
C4TextureMap &rTexMap)
|
|
{
|
|
bool fOwnBuf=false;
|
|
|
|
C4BMP256Info Bmp;
|
|
|
|
// Access entry in group, read bitmap info
|
|
if (!hGroup.AccessEntry(szEntryName)) return false;
|
|
if (!hGroup.Read(&Bmp,sizeof(Bmp))) return false;
|
|
if (!Bmp.Valid()) return false;
|
|
if (!hGroup.Advance(Bmp.FileBitsOffset())) return false;
|
|
|
|
// If buffer is present, check for sufficient size
|
|
if (*pbypBuffer)
|
|
{
|
|
if ((Bmp.Info.biWidth>rMapWdt)
|
|
|| (Bmp.Info.biHeight>rMapHgt) ) return false;
|
|
}
|
|
// Else, allocate buffer, set sizes
|
|
else
|
|
{
|
|
rMapWdt = Bmp.Info.biWidth;
|
|
rMapHgt = Bmp.Info.biHeight;
|
|
rBufWdt = rMapWdt; int dwBufWdt = rBufWdt; DWordAlign(dwBufWdt); rBufWdt = dwBufWdt;
|
|
if (!(*pbypBuffer = new BYTE [rBufWdt*rMapHgt]))
|
|
return false;
|
|
fOwnBuf=true;
|
|
}
|
|
|
|
// Read bits to buffer
|
|
for (int32_t cline=Bmp.Info.biHeight-1; cline>=0; cline--)
|
|
if (!hGroup.Read(*pbypBuffer+rBufWdt*cline,rBufWdt))
|
|
{ if (fOwnBuf) delete [] *pbypBuffer; return false; }
|
|
|
|
// Validate texture indices
|
|
MapBuf=*pbypBuffer;
|
|
MapBufWdt=rBufWdt;
|
|
MapWdt=rMapWdt; MapHgt=rMapHgt;
|
|
ValidateTextureIndices(rTexMap);
|
|
|
|
return true;
|
|
}*/
|
|
|
|
void C4MapCreator::ValidateTextureIndices(C4TextureMap &rTextureMap)
|
|
{
|
|
int32_t iX,iY;
|
|
for (iY=0; iY<MapHgt; iY++)
|
|
for (iX=0; iX<MapWdt; iX++)
|
|
if (!rTextureMap.GetEntry(GetPix(iX,iY)))
|
|
SetPix(iX,iY,0);
|
|
}
|