Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

818 lines
19 KiB
C++

#include "ProxyHeaders.hpp"
#include <imagelib\image.h>
#include <GameOs\PNG\png.h>
#include <GameOS\ToolOS.hpp>
//
//############################################################################
//########################### TextureProxy ############################
//############################################################################
//
MemoryBlock*
TextureProxy::AllocatedMemory = NULL;
TextureProxy::ClassData*
TextureProxy::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::InitializeClass()
{
Verify(!AllocatedMemory);
AllocatedMemory =
new MemoryBlock(
sizeof(TextureProxy),
10,
10,
"TextureProxy"
);
Register_Object(AllocatedMemory);
Verify(!DefaultData);
DefaultData =
new ClassData(
TextureProxyClassID,
"TextureProxy",
GenericProxy::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Unregister_Object(AllocatedMemory);
delete AllocatedMemory;
AllocatedMemory = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy::TextureProxy(
ClassData *class_data,
TextureLibrary *library
):
GenericProxy(class_data),
libraryProxy(library)
{
Check_Pointer(this);
Check_Object(libraryProxy);
libraryProxy->AttachTextureProxy(this);
textureSize.x = textureSize.y = 0;
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy::TextureProxy(
const char* name,
const Vector2DOf<int> &size,
TextureLibrary *library
):
GenericProxy(DefaultData),
libraryProxy(library),
textureName(name),
textureSize(size)
{
Check_Pointer(this);
Verify(GetClassID() == TextureProxyClassID);
redDepth = greenDepth = blueDepth = alphaDepth = 0;
libraryProxy->AttachReference();
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy::~TextureProxy()
{
Check_Object(this);
if (libraryProxy)
{
Check_Object(libraryProxy);
libraryProxy->DetachReference();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::Destroy()
{
Check_Object(this);
Verify(referenceCount == 1);
DetachReference();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
TextureProxy::IsEqualTo(TextureProxy *texture)
{
Check_Object(this);
Check_Object(texture);
//
//-----------------------------------------
// Make sure we aren't comparing to ourself
//-----------------------------------------
//
if (this == texture)
return true;
//
//------------------
// Compare the names
//------------------
//
MString filename_1;
if (GetName(&filename_1))
{
MString filename_2;
if (texture->GetName(&filename_2))
return filename_1 == filename_2;
return false;
}
return !texture->GetName(&filename_1);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy*
TextureProxy::UseNextTextureProxyInLibrary()
{
Check_Object(this);
Verify(GetClassID() == TextureProxyClassID);
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy*
TextureProxy::UsePreviousTextureProxyInLibrary()
{
Check_Object(this);
Verify(GetClassID() == TextureProxyClassID);
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
TextureProxy::GetName(MString *filename)
{
Check_Object(this);
Check_Pointer(filename);
Verify(GetClassID() == TextureProxyClassID);
//
//------------------------
// Set the name and return
//------------------------
//
*filename = textureName;
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::SetName(const char* filename)
{
Check_Object(this);
Check_Pointer(filename);
Verify(GetClassID() == TextureProxyClassID);
textureName = filename;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::GetImageSize(Vector2DOf<int> *size)
{
Check_Object(this);
Check_Pointer(size);
Verify(GetClassID() == TextureProxyClassID);
*size = textureSize;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::GetChannelDepth(
unsigned *red_depth,
unsigned *blue_depth,
unsigned *green_depth,
unsigned *alpha_depth
)
{
Check_Object(this);
Check_Pointer(red_depth);
Check_Pointer(blue_depth);
Check_Pointer(green_depth);
Check_Pointer(alpha_depth);
Verify(GetClassID() == TextureProxyClassID);
//
//--------------------------------------------------------
// Get the texture attribute, and find out if we got alpha
//--------------------------------------------------------
//
*red_depth = redDepth;
*blue_depth = blueDepth;
*green_depth = greenDepth;
*alpha_depth = alphaDepth;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::GetChannels(
Stuff::DynamicArrayOf<BYTE> *red,
Stuff::DynamicArrayOf<BYTE> *green,
Stuff::DynamicArrayOf<BYTE> *blue,
Stuff::DynamicArrayOf<BYTE> *alpha
)
{
Check_Object(this);
Check_Object(red);
Check_Object(green);
Check_Object(blue);
Verify(GetClassID() == TextureProxyClassID);
//
//---------------------
// Now copy the channel
//---------------------
//
*red = redChannel;
*green = greenChannel;
*blue = blueChannel;
if (alpha)
{
Check_Object(alpha);
*alpha = alphaChannel;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::SetChannels(
const DynamicArrayOf<BYTE> *red,
const DynamicArrayOf<BYTE> *green,
const DynamicArrayOf<BYTE> *blue,
const DynamicArrayOf<BYTE> *alpha
)
{
Check_Object(this);
Verify(GetClassID() == TextureProxyClassID);
Check_Object(red);
Check_Object(green);
Check_Object(blue);
//
//---------------------
// Now copy the channel
//---------------------
//
Verify(red->GetLength() == textureSize.x*textureSize.y);
redChannel = *red;
redDepth = 8;
Verify(green->GetLength() == textureSize.x*textureSize.y);
greenChannel = *green;
greenDepth = 8;
Verify(blue->GetLength() == textureSize.x*textureSize.y);
blueChannel = *blue;
blueDepth = 8;
if (alpha)
{
Check_Object(alpha);
alphaChannel = *alpha;
alphaDepth = 8;
}
else
{
alphaChannel.SetLength(0);
alphaDepth = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::SaveAsTarga(const char* filename)
{
Check_Object(this);
Check_Pointer(filename);
//
//---------------------------------------------
// Get the size of the image we will be copying
//---------------------------------------------
//
Vector2DOf<int> size;
GetImageSize(&size);
Verify(size.x > 0 && size.y > 0);
//
//----------------------------
// Analyze the type of texture
//----------------------------
//
unsigned
red_depth,
green_depth,
blue_depth,
alpha_depth;
GetChannelDepth(
&red_depth,
&green_depth,
&blue_depth,
&alpha_depth
);
Verify(red_depth == 8 && green_depth == 8 && blue_depth == 8);
Verify(!alpha_depth || alpha_depth == 8);
unsigned channel_size = size.x * size.y;
if (::gos_FileReadOnly(filename))
{
MString str;
str = MString(filename) + " is READ-ONLY. Remove the Read-Only permission and save?";
if (IDNO == MessageBox(NULL,str,"Save TGA",MB_YESNO))
{
return;
}
::gos_FileSetReadWrite(filename);
}
//
//----------------------------------------------------------------------
// If this is an alpha texture, write out an alpha TGA after compositing
// the colors for it
//----------------------------------------------------------------------
//
DynamicArrayOf<BYTE> red;
DynamicArrayOf<BYTE> green;
DynamicArrayOf<BYTE> blue;
DynamicArrayOf<BYTE> alpha;
if (alpha_depth == 8)
{
GetChannels(&red, &green, &blue, &alpha);
Verify(red.GetLength() == channel_size);
Verify(green.GetLength() == channel_size);
Verify(blue.GetLength() == channel_size);
Verify(alpha.GetLength() == channel_size);
DynamicArrayOf<TargaColorA> buffer(channel_size);
for (int i=0; i<channel_size; ++i)
{
buffer[i].red = red[i];
buffer[i].green = green[i];
buffer[i].blue = blue[i];
buffer[i].alpha = alpha[i];
}
WriteTargaFile(
filename,
size.x,
size.y,
buffer
);
}
//
//--------------------------------------------------------------------
// This is not an alpha texture, so just write out a regular TGA after
// compositing
//--------------------------------------------------------------------
//
else
{
GetChannels(&red, &green, &blue, NULL);
Verify(red.GetLength() == channel_size);
Verify(green.GetLength() == channel_size);
Verify(blue.GetLength() == channel_size);
DynamicArrayOf<TargaColor> buffer(channel_size);
for (int i=0; i<channel_size; ++i)
{
buffer[i].red = red[i];
buffer[i].green = green[i];
buffer[i].blue = blue[i];
}
WriteTargaFile(
filename,
size.x,
size.y,
buffer
);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::ReadTarga(
const char* filename,
unsigned *red_depth,
unsigned *blue_depth,
unsigned *green_depth,
unsigned *alpha_depth,
Vector2DOf<int> *size,
DynamicArrayOf<BYTE> *red,
DynamicArrayOf<BYTE> *green,
DynamicArrayOf<BYTE> *blue,
DynamicArrayOf<BYTE> *alpha
)
{
Check_Object(this);
Check_Pointer(filename);
//
//--------------
// Open the file
//--------------
//
FileStream targa_file(filename);
if (!targa_file.IsFileOpened())
{
size->x = size->y = 0;
*red_depth = *green_depth = *blue_depth = *alpha_depth = 0;
return;
}
//
//----------------------
// Read the targa header
//----------------------
//
TargaHeader header;
ReadTargaHeader(
&header,
&targa_file,
&size->x,
&size->y,
red_depth,
green_depth,
blue_depth,
alpha_depth
);
Verify(size->x > 0 && size->y > 0);
Verify(*red_depth == 8 && *green_depth == 8 && *blue_depth == 8);
Verify(!*alpha_depth || *alpha_depth == 8);
//
//------------------------
// Set the channel lengths
//------------------------
//
unsigned channel_size = size->x * size->y;
red->SetLength(channel_size);
green->SetLength(channel_size);
blue->SetLength(channel_size);
//
//----------------------------------------------
// If this is an alpha texture, read it that way
//----------------------------------------------
//
if (*alpha_depth > 0)
{
alpha->SetLength(channel_size);
DynamicArrayOf<TargaColorA> raw(channel_size);
ReadTargaChannels(&targa_file, &header, &raw);
for (int i=0; i<channel_size; ++i)
{
(*red)[i] = raw[i].red;
(*green)[i] = raw[i].green;
(*blue)[i] = raw[i].blue;
(*alpha)[i] = raw[i].alpha;
}
}
//
//-----------------------------
// This is not an alpha texture
//-----------------------------
//
else
{
DynamicArrayOf<TargaColor> raw(channel_size);
ReadTargaChannels(&targa_file, &header, &raw);
for (int i=0; i<channel_size; ++i)
{
(*red)[i] = raw[i].red;
(*green)[i] = raw[i].green;
(*blue)[i] = raw[i].blue;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::ReadPNG(
const char* filename,
unsigned *red_depth,
unsigned *blue_depth,
unsigned *green_depth,
unsigned *alpha_depth,
Vector2DOf<int> *size,
DynamicArrayOf<BYTE> *red,
DynamicArrayOf<BYTE> *green,
DynamicArrayOf<BYTE> *blue,
DynamicArrayOf<BYTE> *alpha
)
{
Check_Object(this);
Check_Pointer(filename);
//
//--------------
// Open the file
//--------------
//
if (!::gos_DoesFileExist(filename))
{
size->x = size->y = 0;
*red_depth = *green_depth = *blue_depth = *alpha_depth = 0;
return;
}
Image image;
image.Load((char *)filename);
size->x = image.GetWidth();
size->y = image.GetHeight();
*red_depth = 8;
*green_depth = 8;
*blue_depth = 8;
/* default mask in Image::CreateBlank has red in the most significant byte */
/* so make sure here the right mask is set */
RGBMask mask;
if(image.GetBpp()==32)
{
mask.Set(0x0000ff,0x00ff00,0xff0000);
*alpha_depth = 8;
}
else {
mask.Set(0x000000ff,0x0000ff00,0x00ff0000,0xff000000);
*alpha_depth = 0;
}
image.MaskTo(mask);
Verify(size->x > 0 && size->y > 0);
Verify(*red_depth == 8 && *green_depth == 8 && *blue_depth == 8);
Verify(!*alpha_depth || *alpha_depth == 8);
//
//------------------------
// Set the channel lengths
//------------------------
//
unsigned channel_size = size->x * size->y;
red->SetLength(channel_size);
green->SetLength(channel_size);
blue->SetLength(channel_size);
//
//----------------------------------------------
// If this is an alpha texture, read it that way
//----------------------------------------------
//
BYTE *dat = (BYTE *)image.Lock();
if (*alpha_depth > 0)
{
alpha->SetLength(channel_size);
for (int i=0; i<channel_size; ++i)
{
(*red)[i] = *(dat+i*4+0);
(*green)[i] = *(dat+i*4+1);
(*blue)[i] = *(dat+i*4+2);
(*alpha)[i] = *(dat+i*4+3);
}
}
//
//-----------------------------
// This is not an alpha texture
//-----------------------------
//
else
{
for (int i=0; i<channel_size; ++i)
{
(*red)[i] = *(dat+i*3+0);
(*green)[i] = *(dat+i*3+1);
(*blue)[i] = *(dat+i*3+2);
}
}
image.UnLock();
}
/*******************************************************************************
/* function name: SaveAsPng
/* description:
/*******************************************************************************/
void TextureProxy::SaveAsPng(const char* filename)
{
Check_Object(this);
Check_Pointer(filename);
//
//---------------------------------------------
// Get the size of the image we will be copying
//---------------------------------------------
//
Vector2DOf<int> size;
GetImageSize(&size);
Verify(size.x > 0 && size.y > 0);
//
//----------------------------
// Analyze the type of texture
//----------------------------
//
unsigned
red_depth,
green_depth,
blue_depth,
alpha_depth;
GetChannelDepth(
&red_depth,
&green_depth,
&blue_depth,
&alpha_depth
);
Verify(red_depth == 8 && green_depth == 8 && blue_depth == 8);
Verify(!alpha_depth || alpha_depth == 8);
unsigned channel_size = size.x * size.y;
/* default mask in Image::CreateBlank has red in the most significant byte */
/* so make sure here the right mask is set */
RGBMask mask;
if(alpha_depth==0)
mask.Set(0x0000ff,0x00ff00,0xff0000);
else
mask.Set(0x000000ff,0x0000ff00,0x00ff0000,0xff000000);
Image pngImage;
pngImage.CreateBlank(size.x, size.y, ITYPE_RGB, alpha_depth?32:24, mask);
BYTE *dat=(BYTE *)pngImage.Lock();
//
//----------------------------------------------------------------------
// If this is an alpha texture, write out RGBA
//----------------------------------------------------------------------
//
DynamicArrayOf<BYTE> red;
DynamicArrayOf<BYTE> green;
DynamicArrayOf<BYTE> blue;
DynamicArrayOf<BYTE> alpha;
if (alpha_depth == 8)
{
GetChannels(&red, &green, &blue, &alpha);
Verify(red.GetLength() == channel_size);
Verify(green.GetLength() == channel_size);
Verify(blue.GetLength() == channel_size);
Verify(alpha.GetLength() == channel_size);
for (int i=0; i<channel_size; ++i)
{
*(dat+i*4+0) = red[i];
*(dat+i*4+1) = green[i];
*(dat+i*4+2) = blue[i];
*(dat+i*4+3) = alpha[i];
}
}
//
//--------------------------------------------------------------------
// This is not an alpha texture, so just write out RGB
//--------------------------------------------------------------------
//
else
{
GetChannels(&red, &green, &blue, NULL);
Verify(red.GetLength() == channel_size);
Verify(green.GetLength() == channel_size);
Verify(blue.GetLength() == channel_size);
for (int i=0; i<channel_size; ++i)
{
*(dat+i*3+0) = red[i];
*(dat+i*3+1) = green[i];
*(dat+i*3+2) = blue[i];
}
}
pngImage.UnLock();
if (::gos_FileReadOnly(filename))
{
MString str;
str = MString(filename) + " is READ-ONLY. Remove the Read-Only permission and save?";
if (IDNO == MessageBox(NULL,str,"Save PNG",MB_YESNO))
{
return;
}
::gos_FileSetReadWrite(filename);
}
pngImage.SavePng((char* )filename);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool TextureProxy:: GetFormat(Proxies::TextureProxy::FormatType* format)
{
Check_Object(this);
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void TextureProxy:: SetFormat(Proxies::TextureProxy::FormatType format)
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureProxy::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}
//
//############################################################################
//###################### TextureLibrary ##########################
//############################################################################
//
TextureLibrary::ClassData*
TextureLibrary::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureLibrary::InitializeClass()
{
Verify(!DefaultData);
DefaultData =
new ClassData(
TextureLibraryClassID,
"TextureLibrary",
GenericProxy::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureLibrary::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureLibrary::TextureLibrary(
ClassData *class_data,
StateLibrary *state_library
):
GenericProxy(class_data),
stateLibrary(state_library),
activeTextureProxies(NULL)
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureLibrary::~TextureLibrary()
{
Check_Object(this);
Verify(activeTextureProxies.IsEmpty());
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TextureLibrary::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
}