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.
845 lines
20 KiB
C++
845 lines
20 KiB
C++
// TextureLibDiag.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "ImageGrinder.h"
|
|
#include "TextureLibDiag.h"
|
|
#include "ModifyPath.h"
|
|
#include "ImageCache.h"
|
|
#include "ImageGrinderDoc.h"
|
|
#include <Compost\TexturePool.hpp>
|
|
#include "..\..\Libraries\ImageLib\Image.h"
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
|
|
extern CImageGrinderApp theApp;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTextureLibDiag dialog
|
|
bool IsPowerOf2(int num);
|
|
|
|
|
|
CTextureLibDiag::CTextureLibDiag(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CTextureLibDiag::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CTextureLibDiag)
|
|
m_TexturePath = _T("");
|
|
m_TSpace = _T("");
|
|
//}}AFX_DATA_INIT
|
|
ImgTot=0;
|
|
for(int i=0;i<MAXTEXTURES;i++)
|
|
ImgLoaded[i]=false;
|
|
|
|
}
|
|
|
|
|
|
void CTextureLibDiag::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CTextureLibDiag)
|
|
DDX_Control(pDX, IDC_TEXTURELIST, m_TextureList);
|
|
DDX_Text(pDX, IDC_TEXTPATH, m_TexturePath);
|
|
DDX_Text(pDX, IDC_TSPACE, m_TSpace);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTextureLibDiag, CDialog)
|
|
//{{AFX_MSG_MAP(CTextureLibDiag)
|
|
ON_BN_CLICKED(IDC_ADD, OnAdd)
|
|
ON_NOTIFY(LVN_BEGINDRAG, IDC_TEXTURELIST, OnBegindragTexturelist)
|
|
ON_BN_CLICKED(IDC_CHANGEPATH, OnChangepath)
|
|
ON_BN_CLICKED(IDC_DELETE, OnDelete)
|
|
ON_BN_CLICKED(IDC_ADD1BIT, OnAdd1bit)
|
|
ON_BN_CLICKED(IDC_ADDMIPMASK, OnAddmipmask)
|
|
ON_BN_CLICKED(IDC_UPDATE, OnUpdate)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTextureLibDiag message handlers
|
|
|
|
void CTextureLibDiag::OnOK()
|
|
{
|
|
// TODO: Add extra validation here
|
|
|
|
// CDialog::OnOK();
|
|
}
|
|
|
|
void CTextureLibDiag::OnCancel()
|
|
{
|
|
// TODO: Add extra cleanup here
|
|
|
|
// CDialog::OnCancel();
|
|
}
|
|
|
|
void CTextureLibDiag::OnAdd()
|
|
{
|
|
CFileDialog dlg(TRUE,NULL,NULL,OFN_ALLOWMULTISELECT,"Targa Images (*.tga)|*.tga||",NULL);
|
|
char *filebuf=new char[MAX_PATH*200];
|
|
filebuf[0]=0;
|
|
dlg.m_ofn.lpstrFile=filebuf;
|
|
dlg.m_ofn.nMaxFile=MAX_PATH*200;
|
|
|
|
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
|
|
POSITION pos;
|
|
pos=dlg.GetStartPosition();
|
|
CString fname,SPath;
|
|
|
|
|
|
while(pos!=NULL)
|
|
{
|
|
fname=dlg.GetNextPathName(pos);
|
|
Image img;
|
|
img.GetTgaInfo((char *)(LPCSTR)fname);
|
|
|
|
/* We now allow for special features to load now power-of-2 images
|
|
if(!IsPowerOf2(img.GetWidth()) || !IsPowerOf2(img.GetHeight()) )
|
|
{
|
|
MessageBox("Image Size Not Power of 2","Image Dim Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
*/
|
|
|
|
SPath=fname.Left(fname.ReverseFind('\\')+1);
|
|
fname=fname.Right(fname.GetLength()-(fname.ReverseFind('\\')+1));
|
|
if(NULL==CopyFile(SPath+fname,m_TexturePath+"\\"+fname,FALSE))
|
|
{ //Copy Failed
|
|
|
|
}
|
|
fname = fname.Left(fname.ReverseFind('.'));
|
|
|
|
Compost::Feature_Texture::TextureMode tmde;
|
|
|
|
|
|
if(img.GetIType()==ITYPE_INDEXED)
|
|
{
|
|
tmde = Compost::Feature_Texture::FTT_1;
|
|
}
|
|
else
|
|
{
|
|
if(img.HasAlpha())
|
|
tmde = Compost::Feature_Texture::FTT_4444;
|
|
else
|
|
tmde = Compost::Feature_Texture::FTT_555;
|
|
}
|
|
|
|
Compost::TexturePool::Instance->Add(
|
|
Stuff::MString((LPCSTR)fname),
|
|
img.GetWidth(),
|
|
img.GetHeight(),
|
|
tmde
|
|
);
|
|
}
|
|
|
|
|
|
delete filebuf;
|
|
}
|
|
RefreshList();
|
|
}
|
|
|
|
BOOL CTextureLibDiag::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
CDC *pDC=GetDC(),memdc;
|
|
|
|
UnLoadedBmp.CreateCompatibleBitmap(pDC,PREVIEWSZE,PREVIEWSZE);
|
|
memdc.CreateCompatibleDC(pDC);
|
|
memdc.SelectObject(UnLoadedBmp);
|
|
BOOL res=memdc.BitBlt(0,0,PREVIEWSZE,PREVIEWSZE,NULL,0,0,WHITENESS);
|
|
Verify(res!=0);
|
|
memdc.DeleteDC();
|
|
ReleaseDC(pDC);
|
|
|
|
|
|
ImgLst.Create(PREVIEWSZE,PREVIEWSZE,ILC_COLOR24,16,16);
|
|
m_TextureList.SetImageList(&ImgLst,LVSIL_NORMAL);
|
|
|
|
CString AppName;
|
|
AppName.LoadString(AFX_IDS_APP_TITLE);
|
|
CString tpath;
|
|
tpath=theApp.GetProfileString("Settings","TexturePath","");
|
|
if(tpath.GetLength()==0)
|
|
{
|
|
OnChangepath();
|
|
}
|
|
else
|
|
{
|
|
m_TexturePath=tpath;
|
|
Compost::TexturePool::Instance->SetTexturePath(m_TexturePath);
|
|
Compost::TexturePool::Instance->LoadIndex();
|
|
RefreshList();
|
|
UpdateData(FALSE);
|
|
}
|
|
|
|
if(gos_DoesFileExist(m_TexturePath+"\\Material.txt"))
|
|
{
|
|
Stuff::NotationFile mat_file(m_TexturePath+"\\Material.txt");
|
|
Stuff::Page *page = mat_file.GetPage("Materials");
|
|
Check_Object(page);
|
|
|
|
Stuff::Page::NoteIterator *note_list=page->MakeNoteIterator();
|
|
|
|
note_list->First();
|
|
|
|
Stuff::Note *note;
|
|
Compost::MaterialEntriesCount = 0;
|
|
Stuff::RGBColor color;
|
|
DWORD mat_color;
|
|
while((note=note_list->ReadAndNext())!=NULL && Compost::MaterialEntriesCount<128)
|
|
{
|
|
Compost::MaterialEntries[Compost::MaterialEntriesCount].MatName=note->GetName();
|
|
note->GetEntry(&color);
|
|
|
|
Stuff::Scalar f;
|
|
f = color.red * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
mat_color = Stuff::Truncate_Float_To_Byte (f);
|
|
|
|
f = color.green * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
mat_color = (mat_color << 8) | Stuff::Truncate_Float_To_Byte (f);
|
|
|
|
f = color.blue * 255.99f;
|
|
Clamp(f, 0.0f, 255.f);
|
|
mat_color = (mat_color << 8) | Stuff::Truncate_Float_To_Byte (f);
|
|
|
|
Compost::MaterialEntries[Compost::MaterialEntriesCount].color = mat_color;
|
|
Compost::MaterialEntries[Compost::MaterialEntriesCount].darkEntryIndex = Compost::MaterialEntriesCount;
|
|
Compost::MaterialEntriesCount++;
|
|
}
|
|
|
|
page = mat_file.GetPage("Darkening");
|
|
Check_Object(page);
|
|
|
|
note_list=page->MakeNoteIterator();
|
|
|
|
note_list->First();
|
|
|
|
Stuff::MString name;
|
|
const char *dark_name;
|
|
|
|
while((note=note_list->ReadAndNext())!=NULL && Compost::MaterialEntriesCount<128)
|
|
{
|
|
name = note->GetName();
|
|
|
|
if(!strcmp(name, "darkfactor"))
|
|
{
|
|
note->GetEntry(&Compost::DarkFactor);
|
|
}
|
|
else
|
|
{
|
|
note->GetEntry(&dark_name);
|
|
for(int i=0;i<Compost::MaterialEntriesCount;i++)
|
|
{
|
|
if(name == Compost::MaterialEntries[i].MatName)
|
|
{
|
|
for(int j=0;j<Compost::MaterialEntriesCount;j++)
|
|
{
|
|
if(NULL==strcmp(dark_name, Compost::MaterialEntries[j].MatName))
|
|
{
|
|
Compost::MaterialEntries[i].darkEntryIndex = j;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
Compost::MaterialEntriesCount=1;
|
|
Compost::MaterialEntries[0].MatName="none";
|
|
Compost::MaterialEntries[0].color = 0;
|
|
Compost::MaterialEntries[0].darkEntryIndex = 0;
|
|
}
|
|
|
|
// while(LoadNextImage());
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
void CTextureLibDiag::OnBegindragTexturelist(NMHDR* pNMHDR, LRESULT* pResult)
|
|
{
|
|
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
|
|
|
|
*pResult = 0;
|
|
}
|
|
|
|
void CTextureLibDiag::OnChangepath()
|
|
{
|
|
CModifyPath dlg;
|
|
|
|
dlg.m_path=m_TexturePath;
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
m_TexturePath=dlg.m_path;
|
|
|
|
CString AppName;
|
|
AppName.LoadString(AFX_IDS_APP_TITLE);
|
|
theApp.WriteProfileString("Settings","TexturePath",m_TexturePath);
|
|
Compost::TexturePool::Instance->SetTexturePath(m_TexturePath);
|
|
Compost::TexturePool::Instance->LoadIndex();
|
|
|
|
UpdateData(FALSE);
|
|
RefreshList();
|
|
}
|
|
|
|
}
|
|
|
|
void CTextureLibDiag::RefreshList()
|
|
{
|
|
Compost::Feature_Texture *FTexture;
|
|
int CurImg=0,DataTotal=0,SubTot;
|
|
m_TextureList.DeleteAllItems();
|
|
// Image img2,img;
|
|
// img.CreateBlank(PREVIEWSZE,PREVIEWSZE,ITYPE_RGB,24);
|
|
CString fname;
|
|
|
|
|
|
|
|
|
|
{
|
|
Stuff::TableIteratorOf<Compost::Feature_Texture*, int> imageTableIterator(Compost::TexturePool::Instance->GetImageTable());
|
|
while(NULL!=(FTexture=imageTableIterator.ReadAndNext()))
|
|
{
|
|
LVITEM itm;
|
|
fname=m_TexturePath;
|
|
fname+="\\";
|
|
fname+=(char *)(*(FTexture->GetName()));
|
|
fname+=".tga";
|
|
|
|
ZeroMemory(&itm,sizeof(LVITEM));
|
|
itm.mask=LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM;
|
|
itm.iItem=1;
|
|
itm.lParam=(long)FTexture;
|
|
itm.pszText=(char *)(*(FTexture->GetName()));
|
|
itm.iImage=GetIndex(fname);
|
|
|
|
SubTot=FTexture->width*FTexture->height;
|
|
if(FTexture->GetTextureMode() != Compost::Feature_Texture::TextureMode::FTT_1)
|
|
{ SubTot*=2; }
|
|
DataTotal+=SubTot;
|
|
CurImg++;
|
|
m_TextureList.InsertItem(&itm);
|
|
}
|
|
}
|
|
if(DataTotal<1000000)
|
|
m_TSpace.Format("%3.2f KB",DataTotal/1000.0);
|
|
else
|
|
m_TSpace.Format("%3.2f MB",DataTotal/1000000.0);
|
|
|
|
UpdateData(FALSE);
|
|
if(!Compost::TexturePool::Instance->SaveIndex(NULL))
|
|
{
|
|
MessageBox("Index file is Read only, Texture Lib Changes will not be saved","Texture Lib Error",MB_OK|MB_ICONHAND);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
Compost::FetchTextureData(Compost::Feature_Texture *tex, int index, int type)
|
|
{
|
|
tex->data = NULL;
|
|
tex->handle = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
Compost::FetchTextureData(Compost::Feature_Texture *tex, const char *name, int type)
|
|
{
|
|
CString str(name);
|
|
str+=".Tga";
|
|
Image img, mip1, mip2;
|
|
|
|
img.LoadTga((char *)(LPCSTR)str);
|
|
|
|
switch(type & Compost::Feature_Texture::TextureTypeMask)
|
|
{
|
|
case Compost::Feature_Texture::TextureMode::FTT_555:
|
|
{
|
|
mip1.CreateBlank(img.GetWidth()/2,img.GetHeight()/2,ITYPE_RGB,32);
|
|
mip1.Blt(img,CRect(0,0,mip1.GetWidth(),mip1.GetHeight()),CRect(0,0,img.GetWidth(),img.GetHeight()));
|
|
// mip1.SaveTiff("c:\\mp1.Tif");
|
|
mip1.Pad(1);
|
|
|
|
mip2.CreateBlank(img.GetWidth()/4,img.GetHeight()/4,ITYPE_RGB,32);
|
|
mip2.Blt(img,CRect(0,0, mip2.GetWidth(), mip2.GetHeight()),CRect(0,0,img.GetWidth(),img.GetHeight()));
|
|
// mip2.SaveTiff("c:\\mp2.Tif");
|
|
mip2.Pad(1);
|
|
}
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_4444:
|
|
{
|
|
mip1.CreateBlank(img.GetWidth()/2,img.GetHeight()/2,ITYPE_RGB,32,RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000));
|
|
mip1.Blt(img,CRect(0,0,mip1.GetWidth(),mip1.GetHeight()),CRect(0,0,img.GetWidth(),img.GetHeight()));
|
|
// mip1.SaveTiff("c:\\mp1.Tif");
|
|
mip1.Pad(1);
|
|
|
|
mip2.CreateBlank(img.GetWidth()/4,img.GetHeight()/4,ITYPE_RGB,32,RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000));
|
|
mip2.Blt(img,CRect(0,0, mip2.GetWidth(), mip2.GetHeight()),CRect(0,0,img.GetWidth(),img.GetHeight()));
|
|
// mip2.SaveTiff("c:\\mp2.Tif");
|
|
mip2.Pad(1);
|
|
}
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_1_M:
|
|
{
|
|
mip1.CreateBlank(img.GetWidth()/2,img.GetHeight()/2,ITYPE_INDEXED, 8);
|
|
mip1.Blt(img,CRect(0,0,mip1.GetWidth(),mip1.GetHeight()),CRect(0,0,img.GetWidth(),img.GetHeight()));
|
|
|
|
mip1.MakeGrayscalePalette();
|
|
mip1.Pad(1);
|
|
// mip1.SaveGif("c:\\mp1.gif");
|
|
|
|
mip2.CreateBlank(img.GetWidth()/4,img.GetHeight()/4,ITYPE_INDEXED, 8);
|
|
mip2.Blt(img,CRect(0,0, mip2.GetWidth(), mip2.GetHeight()),CRect(0,0,img.GetWidth(),img.GetHeight()));
|
|
|
|
mip2.MakeGrayscalePalette();
|
|
mip2.Pad(1);
|
|
// mip2.SaveGif("c:\\mp2.gif");
|
|
}
|
|
break;
|
|
|
|
case Compost::Feature_Texture::TextureMode::FTT_1:
|
|
case Compost::Feature_Texture::TextureMode::FTT_1_1:
|
|
break;
|
|
}
|
|
|
|
if(type != Compost::Feature_Texture::TextureMode::FTT_1_1)
|
|
{
|
|
img.Pad(1);
|
|
}
|
|
|
|
switch(type & Compost::Feature_Texture::TextureTypeMask)
|
|
{
|
|
case Compost::Feature_Texture::TextureMode::FTT_555:
|
|
{
|
|
img.MakeRGB16(RGBMask(0x007C00,0x0003E0,0x00001f,0x00));
|
|
mip1.MakeRGB16(RGBMask(0x007C00,0x0003E0,0x00001f,0x00));
|
|
mip2.MakeRGB16(RGBMask(0x007C00,0x0003E0,0x00001f,0x00));
|
|
// img.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff,0x00));
|
|
}
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_4444:
|
|
{
|
|
img.MakeRGB16(RGBMask(0xF000,0xF00,0xF0,0xF));
|
|
mip1.MakeRGB16(RGBMask(0xF000,0xF00,0xF0,0xF));
|
|
mip2.MakeRGB16(RGBMask(0xF000,0xF00,0xF0,0xF));
|
|
// img.MaskTo(RGBMask(0xff000000,0x00ff0000,0x0000ff00,0x000000ff));
|
|
}
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_1:
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_1_1:
|
|
break;
|
|
}
|
|
|
|
int dsize;
|
|
unsigned char *tdat = NULL;
|
|
|
|
switch(type & Compost::Feature_Texture::TextureTypeMask)
|
|
{
|
|
case Compost::Feature_Texture::TextureMode::FTT_555:
|
|
case Compost::Feature_Texture::TextureMode::FTT_4444:
|
|
case Compost::Feature_Texture::TextureMode::FTT_1_M:
|
|
{
|
|
int dsize1, dsize2;
|
|
|
|
dsize = (img.GetBpp()>>3)*img.GetWidth()*img.GetHeight();
|
|
dsize1 = (mip1.GetBpp()>>3)*mip1.GetWidth()*mip1.GetHeight();
|
|
dsize2 = (mip2.GetBpp()>>3)*mip2.GetWidth()*mip2.GetHeight();
|
|
|
|
tex->dataSize = dsize + dsize1 + dsize2;
|
|
tdat = new unsigned char[tex->dataSize];
|
|
|
|
CopyMemory(tdat, img.Lock() , dsize);
|
|
img.UnLock();
|
|
|
|
CopyMemory(tdat+dsize, mip1.Lock() , dsize1);
|
|
mip1.UnLock();
|
|
|
|
CopyMemory(tdat+dsize+dsize1, mip2.Lock() , dsize2);
|
|
mip2.UnLock();
|
|
}
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_1:
|
|
{
|
|
dsize = (img.GetBpp()>>3)*img.GetWidth()*img.GetHeight();
|
|
tex->dataSize = dsize;
|
|
|
|
tdat = new unsigned char[tex->dataSize];
|
|
CopyMemory(tdat, img.Lock() , dsize);
|
|
img.UnLock();
|
|
}
|
|
break;
|
|
case Compost::Feature_Texture::TextureMode::FTT_1_1:
|
|
{
|
|
dsize = (img.GetBpp()>>3)*(2+ (img.GetWidth()>>3))*(2+img.GetHeight());
|
|
tex->dataSize = dsize;
|
|
|
|
tdat = new unsigned char[tex->dataSize];
|
|
|
|
int i, j, k, mask=0;
|
|
unsigned char *imgptr = img.Lock();
|
|
unsigned char *tdatptr = tdat + (2+(img.GetWidth()>>3));
|
|
|
|
for(i=0;i<img.GetHeight();i++)
|
|
{
|
|
if(*imgptr > 0x80)
|
|
{
|
|
*tdatptr = 0xff;
|
|
}
|
|
else
|
|
{
|
|
*tdatptr = 0x00;
|
|
}
|
|
tdatptr++;
|
|
for(j=0;j<img.GetWidth();j+=8)
|
|
{
|
|
|
|
*tdatptr = 0;
|
|
mask = 1;
|
|
for(k=0;k<8;k++)
|
|
{
|
|
if(*imgptr>0x80)
|
|
{
|
|
*tdatptr |= mask;
|
|
}
|
|
mask <<= 1;
|
|
imgptr++;
|
|
}
|
|
tdatptr++;
|
|
}
|
|
|
|
if(*(imgptr-1) > 0x80)
|
|
{
|
|
*tdatptr = 0xff;
|
|
}
|
|
else
|
|
{
|
|
*tdatptr = 0x00;
|
|
}
|
|
tdatptr++;
|
|
}
|
|
|
|
img.UnLock();
|
|
|
|
CopyMemory(tdat, tdat + (2+(img.GetWidth()>>3)), (2+(img.GetWidth()>>3)));
|
|
CopyMemory(tdatptr, tdatptr - (2+(img.GetWidth()>>3)), (2+(img.GetWidth()>>3)));
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(tex->data!=NULL)
|
|
{
|
|
delete [] tex->data;
|
|
}
|
|
tex->data = tdat;
|
|
tex->handle = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
Compost::DestroyTextureData(Compost::Feature_Texture *tex)
|
|
{
|
|
delete [] tex->data;
|
|
}
|
|
|
|
void CTextureLibDiag::OnDelete()
|
|
{
|
|
|
|
POSITION pos;
|
|
pos=m_TextureList.GetFirstSelectedItemPosition();
|
|
|
|
while(pos!=NULL)
|
|
{
|
|
int nItem = m_TextureList.GetNextSelectedItem(pos);
|
|
Compost::Feature_Texture *feature_Texture = (Compost::Feature_Texture *)m_TextureList.GetItemData(nItem);
|
|
bool used=false;
|
|
int i;
|
|
for(i=0;i<DocCount;i++)
|
|
{
|
|
used = (NULL != DocList[i]->FPool->IsUsed(feature_Texture)) ? true : false;
|
|
|
|
if(used==true)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(used==true)
|
|
{
|
|
MessageBox("Texture is currently in use and cannot be deleted\n Close Documment and try again","Delete Error",MB_OK|MB_ICONSTOP);
|
|
}
|
|
else
|
|
{
|
|
Compost::TexturePool::Instance->Remove(feature_Texture);
|
|
}
|
|
}
|
|
|
|
RefreshList();
|
|
}
|
|
|
|
|
|
int CTextureLibDiag::GetIndex(CString fname)
|
|
{
|
|
int i;
|
|
for(i=0;i<ImgTot;i++)
|
|
if(!fname.CompareNoCase(ImageName[i]))
|
|
return i;
|
|
|
|
return AddImage(fname);
|
|
}
|
|
|
|
bool CTextureLibDiag::LoadNextImage()
|
|
{
|
|
int nidx;
|
|
|
|
for(nidx=0;nidx<ImgTot && ImgLoaded[nidx];nidx++);
|
|
if(nidx>=ImgTot) return false;
|
|
|
|
|
|
CString fname=ImageName[nidx];
|
|
|
|
CDC *pDC=GetDC();
|
|
|
|
ImageChain *imgchn=CImageCache::Instance->GetChain(fname);
|
|
Image *img=imgchn->GetTNImage();
|
|
if(!img)
|
|
{
|
|
imgchn->BuildTNImg(PREVIEWSZE,PREVIEWSZE);
|
|
img=imgchn->GetTNImage();
|
|
}
|
|
|
|
CBitmap *bmp=new CBitmap;
|
|
|
|
bmp->CreateCompatibleBitmap(pDC,img->GetWidth(),img->GetHeight());
|
|
CDC memDC;
|
|
memDC.CreateCompatibleDC(pDC);
|
|
HBITMAP hBmpOld = (HBITMAP)SelectObject(memDC, *bmp);
|
|
|
|
BITMAPINFO binf;
|
|
ZeroMemory(&binf,sizeof(binf));
|
|
binf.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
|
binf.bmiHeader.biWidth=img->GetWidth();
|
|
binf.bmiHeader.biHeight=-img->GetHeight();
|
|
binf.bmiHeader.biPlanes=1;
|
|
binf.bmiHeader.biBitCount=img->GetBpp();
|
|
binf.bmiHeader.biCompression=BI_RGB;
|
|
|
|
int res;
|
|
res=SetDIBitsToDevice(memDC,0,0,img->GetWidth(),img->GetHeight(),0,0,0,img->GetHeight(),img->Lock(),&binf,DIB_RGB_COLORS);
|
|
img->UnLock();
|
|
if(res==0)
|
|
{
|
|
DWORD err;
|
|
err=GetLastError();
|
|
}
|
|
Verify(res!=0);
|
|
|
|
SelectObject(memDC, hBmpOld);
|
|
memDC.DeleteDC();
|
|
|
|
ImgLst.Replace(nidx,bmp,NULL);
|
|
ImgLoaded[nidx]=true;
|
|
ReleaseDC(pDC);
|
|
delete bmp;
|
|
m_TextureList.InvalidateRect(NULL);
|
|
return true;
|
|
}
|
|
|
|
int CTextureLibDiag::AddImage(CString fname)
|
|
{
|
|
|
|
int idx=ImgLst.Add(&UnLoadedBmp,(COLORREF)0);
|
|
ImageName[idx]=fname;
|
|
ImgLoaded[idx]=false;
|
|
ImgTot++;
|
|
return idx;
|
|
}
|
|
|
|
|
|
bool IsPowerOf2(int X)
|
|
{
|
|
return !( X & ( X - 1 ) );
|
|
}
|
|
|
|
void CTextureLibDiag::OnAdd1bit()
|
|
{
|
|
CFileDialog dlg(TRUE,NULL,NULL,OFN_ALLOWMULTISELECT,"Targa Images (*.tga)|*.tga||",NULL);
|
|
char *filebuf=new char[MAX_PATH*200];
|
|
filebuf[0]=0;
|
|
dlg.m_ofn.lpstrFile=filebuf;
|
|
dlg.m_ofn.nMaxFile=MAX_PATH*200;
|
|
|
|
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
|
|
POSITION pos;
|
|
pos=dlg.GetStartPosition();
|
|
CString fname,SPath;
|
|
|
|
|
|
while(pos!=NULL)
|
|
{
|
|
fname=dlg.GetNextPathName(pos);
|
|
Image img;
|
|
img.GetTgaInfo((char *)(LPCSTR)fname);
|
|
|
|
if(img.GetBpp()!=8)
|
|
{
|
|
MessageBox("Image is not 8 Bit","Image Depth Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
|
|
/* We now allow for special features to load now power-of-2 images
|
|
if(!IsPowerOf2(img.GetWidth()) || !IsPowerOf2(img.GetHeight()) )
|
|
{
|
|
MessageBox("Image Size Not Power of 2","Image Dim Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
*/
|
|
|
|
SPath=fname.Left(fname.ReverseFind('\\')+1);
|
|
fname=fname.Right(fname.GetLength()-(fname.ReverseFind('\\')+1));
|
|
if(NULL==CopyFile(SPath+fname,m_TexturePath+"\\"+fname,FALSE))
|
|
{ //Copy Failed
|
|
|
|
}
|
|
fname = fname.Left(fname.ReverseFind('.'));
|
|
|
|
Compost::Feature_Texture::TextureMode tmde;
|
|
|
|
|
|
if(img.GetIType()==ITYPE_INDEXED)
|
|
{
|
|
tmde = Compost::Feature_Texture::FTT_1_1;
|
|
}
|
|
else
|
|
{
|
|
MessageBox("Image is not 8 Bit","Image Depth Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
|
|
Compost::TexturePool::Instance->Add(
|
|
Stuff::MString((LPCSTR)fname),
|
|
img.GetWidth(),
|
|
img.GetHeight(),
|
|
tmde
|
|
);
|
|
}
|
|
|
|
|
|
delete filebuf;
|
|
}
|
|
RefreshList();
|
|
|
|
}
|
|
|
|
void CTextureLibDiag::OnAddmipmask()
|
|
{
|
|
CFileDialog dlg(TRUE,NULL,NULL,OFN_ALLOWMULTISELECT,"Targa Images (*.tga)|*.tga||",NULL);
|
|
char *filebuf=new char[MAX_PATH*200];
|
|
filebuf[0]=0;
|
|
dlg.m_ofn.lpstrFile=filebuf;
|
|
dlg.m_ofn.nMaxFile=MAX_PATH*200;
|
|
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
POSITION pos;
|
|
pos=dlg.GetStartPosition();
|
|
CString fname,SPath;
|
|
|
|
while(pos!=NULL)
|
|
{
|
|
fname=dlg.GetNextPathName(pos);
|
|
Image img;
|
|
img.GetTgaInfo((char *)(LPCSTR)fname);
|
|
|
|
if(img.GetBpp()!=8)
|
|
{
|
|
MessageBox("Image is not 8 Bit","Image Depth Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
|
|
/* We now allow for special features to load now power-of-2 images
|
|
if(!IsPowerOf2(img.GetWidth()) || !IsPowerOf2(img.GetHeight()) )
|
|
{
|
|
MessageBox("Image Size Not Power of 2","Image Dim Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
*/
|
|
|
|
SPath=fname.Left(fname.ReverseFind('\\')+1);
|
|
fname=fname.Right(fname.GetLength()-(fname.ReverseFind('\\')+1));
|
|
if(NULL==CopyFile(SPath+fname,m_TexturePath+"\\"+fname,FALSE))
|
|
{ //Copy Failed
|
|
|
|
}
|
|
fname = fname.Left(fname.ReverseFind('.'));
|
|
|
|
Compost::Feature_Texture::TextureMode tmde;
|
|
|
|
if(img.GetIType()==ITYPE_INDEXED)
|
|
{
|
|
tmde = Compost::Feature_Texture::FTT_1_M;
|
|
}
|
|
else
|
|
{
|
|
MessageBox("Image is not 8 Bit","Image Depth Error",MB_OK|MB_ICONERROR);
|
|
return;
|
|
}
|
|
|
|
Compost::TexturePool::Instance->Add(
|
|
Stuff::MString((LPCSTR)fname),
|
|
img.GetWidth(),
|
|
img.GetHeight(),
|
|
tmde
|
|
);
|
|
}
|
|
|
|
delete filebuf;
|
|
}
|
|
RefreshList();
|
|
}
|
|
|
|
void CTextureLibDiag::OnUpdate()
|
|
{
|
|
|
|
POSITION pos;
|
|
pos=m_TextureList.GetFirstSelectedItemPosition();
|
|
|
|
while(pos!=NULL)
|
|
{
|
|
int nItem = m_TextureList.GetNextSelectedItem(pos);
|
|
Compost::Feature_Texture *feature_Texture = (Compost::Feature_Texture *)m_TextureList.GetItemData(nItem);
|
|
|
|
feature_Texture->SetLoadedOff();
|
|
Compost::TexturePool::Instance->Load(feature_Texture);
|
|
}
|
|
|
|
for(int i=0;i<DocCount;i++)
|
|
{
|
|
DocList[i]->SetDrawFlags();
|
|
DocList[i]->UpdateAllViews(NULL);
|
|
}
|
|
|
|
RefreshList();
|
|
}
|
|
|
|
BOOL CTextureLibDiag::OnIdle()
|
|
{
|
|
return LoadNextImage();
|
|
|
|
}
|