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.
287 lines
6.5 KiB
C++
287 lines
6.5 KiB
C++
#include "MLRHeaders.hpp"
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
GOSImagePool::GOSImagePool() :
|
|
imageHash(
|
|
4099,
|
|
NULL,
|
|
true
|
|
)
|
|
{
|
|
Verify(gos_GetCurrentHeap() == TexturePoolHeap);
|
|
texturePath = *MString::s_Empty;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
GOSImagePool::~GOSImagePool()
|
|
{
|
|
imageHash.DeletePlugs();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
GOSImage*
|
|
GOSImagePool::GetImage(const char* image_name)
|
|
{
|
|
Check_Object(this);
|
|
|
|
// MString imageName = image_name;
|
|
Verify(strlen(image_name) > 0);
|
|
|
|
//
|
|
//---------------------------
|
|
// Get the image for the name
|
|
//---------------------------
|
|
//
|
|
GOSImage *image;
|
|
|
|
gos_PushCurrentHeap(TexturePoolHeap);
|
|
if ((image = imageHash.Find(image_name)) == NULL)
|
|
{
|
|
image = new GOSImage(image_name);
|
|
Register_Object(image);
|
|
imageHash.AddValue(image, image->imageName);
|
|
}
|
|
Check_Object(image);
|
|
gos_PopCurrentHeap();
|
|
|
|
return image;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
GOSImage*
|
|
GOSImagePool::GetImage(const char *image_name, gos_TextureFormat format, int size, gos_TextureHints hints)
|
|
{
|
|
Check_Object(this);
|
|
|
|
// MString imageName = image_name;
|
|
// Verify(imageName.GetLength() > 0);
|
|
Verify(strlen(image_name) > 0);
|
|
|
|
//
|
|
//---------------------------
|
|
// Get the image for the name
|
|
//---------------------------
|
|
//
|
|
GOSImage *image;
|
|
|
|
gos_PushCurrentHeap(TexturePoolHeap);
|
|
if ((image = imageHash.Find(image_name)) == NULL)
|
|
{
|
|
image = new GOSImage(format, image_name, size, hints);
|
|
Register_Object(image);
|
|
imageHash.AddValue(image, image->imageName);
|
|
}
|
|
#ifdef _ARMOR
|
|
else
|
|
{
|
|
}
|
|
#endif
|
|
|
|
Check_Object(image);
|
|
gos_PopCurrentHeap();
|
|
|
|
return image;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
GOSImagePool::RemoveImage(GOSImage *image)
|
|
{
|
|
Check_Object(this);
|
|
Unregister_Object(image);
|
|
delete image;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
GOSImagePool::ReadHint(Stuff::Page *page)
|
|
{
|
|
int hints = 0;
|
|
bool flag = false;
|
|
const char *string;
|
|
if (page->GetEntry("Mipmap", &string))
|
|
{
|
|
if (!_stricmp(string, "Explicit"))
|
|
hints |= gosHint_UserMipMaps;
|
|
else if (!_stricmp(string, "None"))
|
|
hints |= gosHint_DisableMipmap|gosHint_DontShrink;
|
|
}
|
|
if (page->GetEntry("Memory", &string))
|
|
{
|
|
if (!_stricmp(string, "AGP"))
|
|
hints |= gosHint_AGPMemory;
|
|
else if (!_stricmp(string, "Video"))
|
|
hints |= gosHint_VideoMemory;
|
|
}
|
|
if (page->GetEntry("DontShrink", &flag) && flag)
|
|
hints |= gosHint_DontShrink;
|
|
if (page->GetEntry("PageOut", &string))
|
|
{
|
|
if (!_stricmp(string, "Last"))
|
|
hints |= gosHint_PageLast;
|
|
else if (!_stricmp(string, "First"))
|
|
hints |= gosHint_PageFirst;
|
|
}
|
|
if (page->GetEntry("MipFilter", &string))
|
|
{
|
|
if (!_stricmp(string, "Box"))
|
|
hints |= gosHint_MipmapFilter0;
|
|
else if (!_stricmp(string, "Point"))
|
|
hints |= gosHint_MipmapFilter1;
|
|
}
|
|
if (page->GetEntry("PinkIsTransparent", &flag) && flag)
|
|
hints |= gosHint_PinkColorKey;
|
|
if (page->GetEntry("BlueIsAlpha", &flag) && flag)
|
|
hints |= gosHint_ForceAlpha;
|
|
if (page->GetEntry("Compression", &string))
|
|
{
|
|
if (!_stricmp(string, "Some"))
|
|
hints |= gosHint_Compress0;
|
|
else if (!_stricmp(string, "Very"))
|
|
hints |= gosHint_Compress1;
|
|
}
|
|
return hints;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
DWORD
|
|
GOSImagePool::SkinThis(
|
|
const char* name,
|
|
gos_TextureFormat format,
|
|
DWORD skin,
|
|
DWORD detail
|
|
)
|
|
{
|
|
TEXTUREPTR skin_ptr, detail_ptr, dest_ptr;
|
|
|
|
gos_LockTexture(skin, 0, true, &skin_ptr);
|
|
gos_LockTexture(detail, 0, true, &detail_ptr);
|
|
DWORD dest = gos_NewEmptyTexture(format, name, detail_ptr.Height, gosHint_AGPMemory);
|
|
gos_LockTexture(dest, 0, false, &dest_ptr);
|
|
|
|
SkinThis(dest_ptr, skin_ptr, detail_ptr);
|
|
|
|
gos_UnLockTexture(skin);
|
|
gos_UnLockTexture(detail);
|
|
gos_UnLockTexture(dest);
|
|
|
|
return dest;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
GOSImagePool::SkinThis(
|
|
TEXTUREPTR dest_ptr,
|
|
TEXTUREPTR skin_ptr,
|
|
TEXTUREPTR detail_ptr
|
|
)
|
|
{
|
|
Verify(skin_ptr.Height==detail_ptr.Height && skin_ptr.Height==dest_ptr.Height);
|
|
Verify(skin_ptr.Width==detail_ptr.Width && skin_ptr.Width==dest_ptr.Width);
|
|
|
|
int count = detail_ptr.Height*detail_ptr.Width;
|
|
BYTE *s = (BYTE*)skin_ptr.pTexture;
|
|
BYTE *d = (BYTE*)detail_ptr.pTexture;
|
|
BYTE *n = (BYTE*)dest_ptr.pTexture;
|
|
for(int i=0;i<count;i++)
|
|
{
|
|
int alpha = d[3];
|
|
if(alpha>0)
|
|
{
|
|
int col = (*s++)*(0xff-alpha) + (*d++)*alpha;
|
|
*n++ = static_cast<unsigned char>(col>>8);
|
|
|
|
col = (*s++)*(0xff-alpha) + (*d++)*alpha;
|
|
*n++ = static_cast<unsigned char>(col>>8);
|
|
|
|
col = (*s++)*(0xff-alpha) + (*d++)*alpha;
|
|
*n++ = static_cast<unsigned char>(col>>8);
|
|
|
|
d++;
|
|
}
|
|
else
|
|
{
|
|
*n++ = *s++;
|
|
*n++ = *s++;
|
|
*n++ = *s++;
|
|
d += 4;
|
|
}
|
|
n++;
|
|
s++;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TGAFilePool::TGAFilePool(
|
|
const char* path,
|
|
const char* hint_file
|
|
)
|
|
{
|
|
Verify(gos_GetCurrentHeap() == TexturePoolHeap);
|
|
texturePath = path;
|
|
if (hint_file)
|
|
{
|
|
MString temp(texturePath);
|
|
temp += hint_file;
|
|
hintFile = new NotationFile(temp);
|
|
}
|
|
else
|
|
hintFile = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
TGAFilePool::~TGAFilePool()
|
|
{
|
|
if (hintFile)
|
|
{
|
|
Check_Object(hintFile);
|
|
delete hintFile;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
TGAFilePool::LoadImageGOS(GOSImage *image, int hint)
|
|
{
|
|
if( (image->flags & GOSImage::Loaded) != 0)
|
|
return true;
|
|
|
|
Verify(gos_GetCurrentHeap() == TexturePoolHeap);
|
|
MString full_name,file_name = texturePath;
|
|
file_name += image->imageName;
|
|
full_name =file_name;
|
|
full_name +=".png";
|
|
if(!gos_DoesFileExist(full_name))
|
|
{
|
|
full_name=file_name;
|
|
full_name += ".tga";
|
|
}
|
|
|
|
if (hintFile)
|
|
{
|
|
Page *page = hintFile->FindPage(image->imageName);
|
|
if (page)
|
|
{
|
|
Check_Object(page);
|
|
hint = ReadHint(page);
|
|
}
|
|
}
|
|
|
|
image->imageHandle = gos_NewTextureFromFile(gos_Texture_Detect, full_name, hint);
|
|
image->flags |= (image->imageHandle ? GOSImage::Loaded : 0);
|
|
return ((image->flags & GOSImage::Loaded) != 0);
|
|
}
|
|
|