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.
364 lines
9.8 KiB
C++
364 lines
9.8 KiB
C++
#pragma once
|
|
#define COMPOSITE_HPP
|
|
|
|
#if !defined(STUFF_STUFF_HPP)
|
|
#include <Stuff\Stuff.hpp>
|
|
#endif
|
|
|
|
|
|
namespace Compost
|
|
{
|
|
|
|
enum {
|
|
Current_Compost_Version = 6,
|
|
Number_Of_Reserved_Textures = 50,
|
|
MAX_NUMBER_LAYERS=64,
|
|
Length_Of_Compost_Queue = 128,
|
|
Length_Of_Compost_Queue_Tracker = 4 // this value is (int)ln(Length_Of_Compost_Queue) + (fmod(ln(Length_Of_Compost_Queue))>0.0) ? 1 : 0
|
|
};
|
|
|
|
struct MaterialEntry
|
|
{
|
|
Stuff::MString MatName;
|
|
int darkEntryIndex;
|
|
DWORD color;
|
|
};
|
|
|
|
extern MaterialEntry MaterialEntries[128];
|
|
extern int MaterialEntriesCount;
|
|
extern int DarkFactor;
|
|
|
|
inline DWORD
|
|
DarkMachine(DWORD color)
|
|
{
|
|
for(int i=0;i<MaterialEntriesCount;i++)
|
|
{
|
|
if(MaterialEntries[i].color == color)
|
|
{
|
|
return MaterialEntries[MaterialEntries[i].darkEntryIndex].color;
|
|
}
|
|
}
|
|
return color;
|
|
}
|
|
|
|
inline int
|
|
GetPow(int value)
|
|
{
|
|
if(value<=0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int count = (sizeof(value)-1)<<3;
|
|
int mask = 1<<count;
|
|
|
|
while(!(value&mask))
|
|
{
|
|
count--;
|
|
mask>>=1;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
inline bool
|
|
IsPowerOf2(int X)
|
|
{
|
|
return !( X & ( X - 1 ) );
|
|
}
|
|
|
|
struct Feature_Texture :
|
|
public Stuff::Plug
|
|
{
|
|
Feature_Texture() : Plug (DefaultData) { data = NULL; flags = 0; dataSize = 0; }
|
|
|
|
enum {
|
|
TextureTypeBit = 0,
|
|
TextureTypeBits = 3,
|
|
TextureTypeMask =
|
|
(0xFFFFFFFF >> (Stuff::INT_BITS - TextureTypeBits)) << TextureTypeBit,
|
|
|
|
StatusBit = TextureTypeBit + TextureTypeBits,
|
|
StatusBits = 1,
|
|
StatusMask = (0xFFFFFFFF >> (Stuff::INT_BITS - StatusBits)) << StatusBit,
|
|
|
|
UsedBits = StatusBit + StatusBits,
|
|
UsedMask = 0xFFFFFFFF >> (Stuff::INT_BITS - UsedBits)
|
|
};
|
|
|
|
enum TextureMode {
|
|
NoMode = 0,
|
|
FTT_555 = 1 << TextureTypeBit,
|
|
FTT_4444 = 2 << TextureTypeBit,
|
|
FTT_1 = 3 << TextureTypeBit,
|
|
FTT_1_1 = 4 << TextureTypeBit,
|
|
FTT_1_M = 5 << TextureTypeBit
|
|
};
|
|
|
|
enum StatusMode {
|
|
NoStatus = 0,
|
|
Loaded = 1 << StatusBit
|
|
};
|
|
|
|
void
|
|
SetTextureMode(TextureMode mode)
|
|
{ flags &= ~TextureTypeMask; flags |= mode; }
|
|
TextureMode
|
|
GetTextureMode() const
|
|
{ return static_cast<TextureMode>(flags & TextureTypeMask); }
|
|
|
|
void
|
|
SetLoadedOn()
|
|
{ flags |= Loaded; }
|
|
void
|
|
SetLoadedOff()
|
|
{ flags &= ~Loaded; }
|
|
bool
|
|
GetLoadedMode() const
|
|
{ return (flags & Loaded)!=0;}
|
|
|
|
void
|
|
SetTextureDepth(int d)
|
|
{ Verify(d>0&&d<5); depth = d; }
|
|
|
|
int
|
|
RecalculateSize();
|
|
|
|
int width, height;
|
|
int width_mask, height_mask;
|
|
|
|
int depth;
|
|
|
|
int flags;
|
|
void *handle;
|
|
|
|
int dataSize;
|
|
unsigned char *data;
|
|
|
|
virtual Stuff::MString* GetName() { return NULL; }
|
|
};
|
|
|
|
struct Tool_Feature_Texture :
|
|
public Feature_Texture
|
|
{
|
|
Stuff::MString name;
|
|
|
|
virtual Stuff::MString* GetName() { return &name; }
|
|
};
|
|
|
|
extern void FetchTextureData(Feature_Texture*, int index, int);
|
|
extern void FetchTextureData(Feature_Texture*, const char *name, int);
|
|
|
|
extern void DestroyTextureData(Feature_Texture*);
|
|
|
|
class FeatureGrid;
|
|
class FeaturePool;
|
|
struct FeatureInstance;
|
|
|
|
class Feature {
|
|
friend class FeatureGrid;
|
|
friend class FeaturePool;
|
|
friend struct FeatureInstance;
|
|
public:
|
|
Feature()
|
|
{
|
|
flags = Paste;
|
|
featureTexture = featureMask0 = featureMask1 = NULL;
|
|
feature_width = feature_height = 256;
|
|
scaleXTexture=scaleXMask0=scaleXMask1=0;
|
|
scaleZTexture=scaleZMask0=scaleZMask1=0;
|
|
}
|
|
virtual ~Feature() {}
|
|
|
|
enum {
|
|
FlipBit = 0,
|
|
FlipBits = 6,
|
|
FlipMask =
|
|
(0xFFFFFFFF >> (Stuff::INT_BITS - FlipBits)) << FlipBit,
|
|
|
|
BlendBit = FlipBit + FlipBits,
|
|
BlendBits = 8,
|
|
BlendMask = (0xFFFFFFFF >> (Stuff::INT_BITS - BlendBits)) << BlendBit,
|
|
|
|
StretchBit = BlendBit + BlendBits,
|
|
StretchBits = 1,
|
|
StretchMask = (0xFFFFFFFF >> (Stuff::INT_BITS - StretchBits)) << StretchBit,
|
|
|
|
UsedBits = StretchBit + StretchBits,
|
|
UsedMask = 0xFFFFFFFF >> (Stuff::INT_BITS - UsedBits)
|
|
};
|
|
|
|
enum Flip_Mode {
|
|
Texture_Horizontal_Flip=1<<FlipBit,
|
|
Texture_Vertical_Flip=2<<FlipBit,
|
|
Mask0_Horizontal_Flip=4<<FlipBit,
|
|
Mask0_Vertical_Flip=8<<FlipBit,
|
|
Mask1_Horizontal_Flip=16<<FlipBit,
|
|
Mask1_Vertical_Flip=32<<FlipBit
|
|
};
|
|
|
|
enum Blend_Mode {
|
|
Paste=1<<BlendBit,
|
|
Added=2<<BlendBit,
|
|
Multiply=3<<BlendBit,
|
|
Blend555_1=4<<BlendBit, // 555 texture blended with one 8-bit mask
|
|
Blend555_2=5<<BlendBit, // 555 texture blended with two 8-bit masks
|
|
Blend4444=6<<BlendBit, // 4444 texture - alpha channel is mask
|
|
StretchMultiply=7<<BlendBit, // texture is stretched across feature and multiplied to destination
|
|
Blend555_1_1=8<<BlendBit, // 555 texture blended with one 1-bit mask
|
|
StretchPaste=9<<BlendBit, // 555 texture streched across feature and pasted
|
|
Blend555_1_S=10<<BlendBit // 555 texture blended with one 8-bit mask of the size of the feature
|
|
};
|
|
|
|
enum Stretch_Mode {
|
|
StretchOn=1<<StretchBit // this is tricky :) you can use odd-sized masks in this mode,
|
|
}; // scale[XZ]Mask[01] will be calculated in a way that following equation is true
|
|
// mask_width * (1<<scale_mask) > feature_width, scale_mask is the smallest
|
|
// possible value to make the equation true
|
|
|
|
virtual Stuff::MString* GetName() { return NULL; }
|
|
|
|
virtual int GetIndex() { return index; }
|
|
|
|
void SetFlipMode (Flip_Mode mode) { flags |= mode; }
|
|
void ClearFlipMode (Flip_Mode mode) { flags &= ~mode; }
|
|
int GetFlipMode ()
|
|
{ return (flags & FlipMask); }
|
|
|
|
void SetBlendMode (Blend_Mode mode) { flags &= ~BlendMask; flags |= mode; }
|
|
Blend_Mode GetBlendMode ()
|
|
{ return static_cast<Blend_Mode>(flags & BlendMask); }
|
|
static const char*
|
|
GetBlendModeName(Blend_Mode);
|
|
|
|
void SetStretchMode(bool b=true) { if(b) flags |= StretchOn; else flags &= ~StretchOn; }
|
|
|
|
bool
|
|
IsStretched() { return (flags & StretchOn)!=0; }
|
|
|
|
int IsValidFeature();
|
|
|
|
void SetFeatureTexture(Feature_Texture *texture) { featureTexture=texture; }
|
|
void SetFeatureMask0(Feature_Texture *texture)
|
|
{
|
|
featureMask0 = texture;
|
|
if(featureMask0)
|
|
{
|
|
SetXMask0Scale(GetPow(feature_width/featureMask0->width) + (IsPowerOf2(feature_width/featureMask0->width) ? 0 : 1));
|
|
SetZMask0Scale(GetPow(feature_height/featureMask0->height) + (IsPowerOf2(feature_height/featureMask0->height) ? 0 : 1));
|
|
}
|
|
}
|
|
void SetFeatureMask1(Feature_Texture *texture)
|
|
{
|
|
featureMask1 = texture;
|
|
if(featureMask1)
|
|
{
|
|
SetXMask1Scale(GetPow(feature_width/featureMask1->width) + (IsPowerOf2(feature_width/featureMask1->width) ? 0 : 1));
|
|
SetZMask1Scale(GetPow(feature_height/featureMask1->height) + (IsPowerOf2(feature_height/featureMask1->height) ? 0 : 1));
|
|
}
|
|
}
|
|
|
|
Feature_Texture *GetFeatureTexture() { return featureTexture;}
|
|
Feature_Texture *GetFeatureMask0() { return featureMask0;}
|
|
Feature_Texture *GetFeatureMask1() { return featureMask1;}
|
|
|
|
|
|
int GetFeatureWidth() { return feature_width; }
|
|
int GetFeatureHeight() { return feature_height; }
|
|
void SetFeatureWidth( unsigned short x) {feature_width=x;}
|
|
void SetFeatureHeight( unsigned short z) {feature_height=z;}
|
|
|
|
int GetXTextureScale () { return scaleXTexture; }
|
|
int GetZTextureScale () { return scaleZTexture; }
|
|
|
|
void SetXTextureScale(int s) { scaleXTexture = s; }
|
|
void SetZTextureScale(int s) { scaleZTexture = s; }
|
|
|
|
void SetXMask0Scale(int s) { scaleXMask0 = s; }
|
|
void SetZMask0Scale(int s) { scaleZMask0 = s; }
|
|
int GetXMask0Scale () { return scaleXMask0; }
|
|
int GetZMask0Scale () { return scaleZMask0; }
|
|
|
|
void SetXMask1Scale(int s) { scaleXMask1 = s; }
|
|
void SetZMask1Scale(int s) { scaleZMask1 = s; }
|
|
int GetXMask1Scale () { return scaleXMask1; }
|
|
int GetZMask1Scale () { return scaleZMask1; }
|
|
|
|
void ReCalculateScale()
|
|
{
|
|
if(featureMask0)
|
|
{
|
|
SetXMask0Scale(GetPow(feature_width/featureMask0->width) + (IsPowerOf2(feature_width/featureMask0->width) ? 0 : 1));
|
|
SetZMask0Scale(GetPow(feature_height/featureMask0->height) + (IsPowerOf2(feature_height/featureMask0->height) ? 0 : 1));
|
|
}
|
|
|
|
if(featureMask1)
|
|
{
|
|
SetXMask1Scale(GetPow(feature_width/featureMask1->width) + (IsPowerOf2(feature_width/featureMask1->width) ? 0 : 1));
|
|
SetZMask1Scale(GetPow(feature_height/featureMask1->height) + (IsPowerOf2(feature_height/featureMask1->height) ? 0 : 1));
|
|
}
|
|
}
|
|
protected:
|
|
// position of texture with feature in pixel
|
|
int feature_width, feature_height;
|
|
|
|
// scale of texture in x and z, we just store the power of 2
|
|
int scaleXTexture, scaleZTexture;
|
|
|
|
// scale of mask0 in x and z, we just store the power of 2
|
|
int scaleXMask0, scaleZMask0;
|
|
|
|
// scale of mask1 in x and z, we just store the power of 2
|
|
int scaleXMask1, scaleZMask1;
|
|
|
|
Feature_Texture *featureTexture;
|
|
|
|
Feature_Texture *featureMask0;
|
|
Feature_Texture *featureMask1;
|
|
|
|
int flags;
|
|
int index;
|
|
};
|
|
|
|
|
|
class Tool_Feature :
|
|
public Feature
|
|
{
|
|
friend class FeatureGrid;
|
|
friend class FeaturePool;
|
|
friend struct FeatureInstance;
|
|
protected:
|
|
Stuff::MString name;
|
|
Feature_Texture *HFTexture;
|
|
DWORD material;
|
|
public:
|
|
int HFBLendMode,BlendVal;
|
|
unsigned char StatFlags;
|
|
Tool_Feature() : Feature () {HFTexture=NULL; StatFlags=0; HFBLendMode=0; BlendVal=128; material=0;}
|
|
virtual ~Tool_Feature() {}
|
|
|
|
void SetHFTexture(Feature_Texture *texture) { HFTexture=texture; }
|
|
Feature_Texture *GetHFTexture() { return HFTexture;}
|
|
|
|
virtual Stuff::MString* GetName() { return &name; }
|
|
void SetName(const char* _name) { name = _name; index = name.GetHashValue(); }
|
|
|
|
void SetMaterial(int mat) { material = mat; }
|
|
int GetMaterial () { return material; }
|
|
|
|
virtual int GetIndex() { return name.GetHashValue(); }
|
|
};
|
|
|
|
void InitializeClasses(Stuff::NotationFile *startup_ini = NULL);
|
|
void TerminateClasses(Stuff::NotationFile *startup_ini=NULL);
|
|
|
|
extern HGOSHEAP Heap;
|
|
|
|
extern DWORD Number_Of_Worked_On_Textures;
|
|
DECLARE_TIMER(extern, Composting_Time);
|
|
extern DWORD Number_Of_Used_128_Textures;
|
|
extern DWORD Number_Of_Used_256_Textures;
|
|
|
|
#define BOUNDARY_TEST
|
|
|
|
}
|