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.
1068 lines
29 KiB
C++
1068 lines
29 KiB
C++
// MultitronDlg.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "Multitron.h"
|
|
#include "MultitronDlg.h"
|
|
#include "MainFrm.h"
|
|
#include "TextureDoc.h"
|
|
|
|
#include <GameOs\TooLOS.hpp>
|
|
#include <imagelib\image.h>
|
|
#include <direct.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMultitronDlg dialog
|
|
|
|
|
|
CMultitronDlg::CMultitronDlg(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CMultitronDlg::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CMultitronDlg)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
m_pDocument = NULL;
|
|
m_pNoteFile = NULL;
|
|
}
|
|
|
|
|
|
void CMultitronDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CMultitronDlg)
|
|
DDX_Control(pDX, IDC_PREVIEW_USED, m_wndPreviewUsed);
|
|
DDX_Control(pDX, IDC_PREVIEW_UNUSED, m_wndPreviewUnused);
|
|
DDX_Control(pDX, IDC_LIST_USED, m_wndUsed);
|
|
DDX_Control(pDX, IDC_LIST_UNUSED, m_wndUnused);
|
|
DDX_Control(pDX, IDC_USED_IMAGEPROP, m_wndUsedImageProp);
|
|
DDX_Control(pDX, IDC_UNUSED_IMAGEPROP, m_wndUnusedImageProp);
|
|
DDX_Control(pDX, IDC_CHECK_SHOWSEUDO, m_checkShowSeudo);
|
|
DDX_Control(pDX, IDC_CHECK_SEARCHSUB, m_checkSearchSubDir);
|
|
DDX_Control(pDX, IDC_CHECK_SHOWMIPMAP, m_checkShowMipmap);
|
|
DDX_Control(pDX, IDC_CHECK_SHOWSOLID, m_checkShowSolid);
|
|
DDX_Control(pDX, IDC_CHECK_SHOWALPHA, m_checkShowAlpha);
|
|
DDX_Control(pDX, IDC_CHECK_PREVIEWALPHA, m_checkPreviewAlpha);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CMultitronDlg, CDialog)
|
|
//{{AFX_MSG_MAP(CMultitronDlg)
|
|
ON_WM_DRAWITEM()
|
|
//ON_WM_CONTEXTMENU()
|
|
ON_LBN_SELCHANGE(IDC_LIST_UNUSED, OnSelchangeListUnused)
|
|
ON_LBN_SELCHANGE(IDC_LIST_USED, OnSelchangeListUsed)
|
|
ON_BN_CLICKED(IDC_CHECK_PREVIEWALPHA, OnCheckPreviewAlpha)
|
|
ON_BN_CLICKED(IDC_CHECK_SHOWSEUDO, UpdateUsedList)
|
|
ON_BN_CLICKED(IDC_CHECK_SHOWMIPMAP, UpdateUsedList)
|
|
ON_BN_CLICKED(IDC_CHECK_SHOWSOLID, UpdateUsedList)
|
|
ON_BN_CLICKED(IDC_CHECK_SHOWALPHA, UpdateUsedList)
|
|
ON_BN_CLICKED(IDC_CHECK_SEARCHSUB, FindAllTextures)
|
|
ON_COMMAND(ID_DELETEFROMDISK, OnDeleteTextureFromDisk)
|
|
ON_COMMAND(ID_ADD_MEGATEXTURE, OnAddMegatexture)
|
|
ON_COMMAND(ID_ADD_TEXTUREHINT, OnAdd)
|
|
ON_COMMAND(ID_REMOVE_TEXTUREHINT, OnRemove)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CMultitronDlg message handlers
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnInitialUpdate
|
|
/* description: Called when window is displayed for the first time,
|
|
/* set up window size and position
|
|
/*******************************************************************************/
|
|
BOOL CMultitronDlg::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
m_checkShowSolid.SetCheck(true);
|
|
m_checkShowAlpha.SetCheck(true);
|
|
|
|
FindTextures("content\\textures\\");
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnDrawItem
|
|
/* description: Draw the preview bitmaps for selected textures
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
|
{
|
|
switch (lpDrawItemStruct->CtlID)
|
|
{
|
|
case IDC_PREVIEW_UNUSED:
|
|
{
|
|
HBITMAP hBitmap = m_bmUnused;
|
|
if (hBitmap)
|
|
{
|
|
CDC memDC;
|
|
int res;
|
|
|
|
BITMAP bmp;
|
|
res=m_bmUnused.GetBitmap(&bmp);
|
|
Verify(res);
|
|
|
|
BOOL bres;
|
|
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
|
bres=memDC.CreateCompatibleDC(pDC);
|
|
Verify(bres);
|
|
memDC.SelectObject(&m_bmUnused);
|
|
CRect hfrct;
|
|
m_wndPreviewUnused.GetClientRect(&hfrct);
|
|
|
|
pDC->SetStretchBltMode(COLORONCOLOR);
|
|
bres=pDC->StretchBlt(0,0,hfrct.Width(),hfrct.Height(),&memDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
|
|
|
|
//bres=pDC->BitBlt(0,0,hfrct.Width(),hfrct.Height(),NULL,0,0,BLACKNESS);
|
|
//bres=pDC->BitBlt(0,0,hfrct.Width(),hfrct.Height(),&memDC,0,0,SRCCOPY);
|
|
Verify(bres);
|
|
memDC.DeleteDC();
|
|
}
|
|
return;
|
|
}
|
|
case IDC_PREVIEW_USED:
|
|
{
|
|
HBITMAP hBitmap = m_bmUsed;
|
|
if (hBitmap)
|
|
{
|
|
CDC memDC;
|
|
int res;
|
|
|
|
BITMAP bmp;
|
|
res=m_bmUsed.GetBitmap(&bmp);
|
|
Verify(res);
|
|
|
|
BOOL bres;
|
|
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
|
bres=memDC.CreateCompatibleDC(pDC);
|
|
Verify(bres);
|
|
memDC.SelectObject(&m_bmUsed);
|
|
CRect hfrct;
|
|
m_wndPreviewUnused.GetClientRect(&hfrct);
|
|
|
|
pDC->SetStretchBltMode(COLORONCOLOR);
|
|
bres=pDC->StretchBlt(0,0,hfrct.Width(),hfrct.Height(),&memDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY);
|
|
|
|
//bres=pDC->BitBlt(0,0,hfrct.Width(),hfrct.Height(),NULL,0,0,BLACKNESS);
|
|
//bres=pDC->BitBlt(0,0,hfrct.Width(),hfrct.Height(),&memDC,0,0,SRCCOPY);
|
|
Verify(bres);
|
|
memDC.DeleteDC();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnSelchangeListUnused
|
|
/* description: Selection changed in the unused texture list, load the texture
|
|
/* and update the preview bitmap
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnSelchangeListUnused()
|
|
{
|
|
m_wndPreviewUnused.Invalidate();
|
|
|
|
int count = m_wndUnused.GetSelCount();
|
|
GetDlgItem(ID_ADD_MEGATEXTURE)->EnableWindow(count>1);
|
|
if (count == 0) {
|
|
GetDlgItem(ID_ADD_TEXTUREHINT)->EnableWindow(false);
|
|
GetDlgItem(ID_DELETEFROMDISK)->EnableWindow(false);
|
|
return;
|
|
}
|
|
GetDlgItem(ID_ADD_TEXTUREHINT)->EnableWindow(true);
|
|
GetDlgItem(ID_DELETEFROMDISK)->EnableWindow(true);
|
|
|
|
|
|
int *items = new int[count];
|
|
m_wndUnused.GetSelItems(count,items);
|
|
|
|
int x = count-1;
|
|
CString name;
|
|
m_wndUnused.GetText(items[x],name);
|
|
name.TrimLeft();
|
|
name = "content\\textures\\"+name;
|
|
|
|
Image image;
|
|
CString fullname = name+".png";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
image.Load((char *)(LPCTSTR)fullname);
|
|
}
|
|
else
|
|
{
|
|
fullname = name+".tga";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
image.Load((char *)(LPCTSTR)fullname);
|
|
}
|
|
else
|
|
{
|
|
delete[] items;
|
|
return;
|
|
}
|
|
}
|
|
|
|
delete[] items;
|
|
|
|
bool bPreviewAlpha = m_checkPreviewAlpha.GetCheck()?true:false;
|
|
UpdateImageBitmap(&m_bmUnused, &image, bPreviewAlpha);
|
|
UpdateImageProp(&m_wndUnusedImageProp, &image);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnSelchangeListUsed
|
|
/* description: Selection changed in the used texture list, load the texture
|
|
/* and update the preview bitmap
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnSelchangeListUsed()
|
|
{
|
|
m_wndPreviewUsed.Invalidate();
|
|
|
|
int count = m_wndUsed.GetSelCount();
|
|
if (count == 0) {
|
|
GetDlgItem(ID_REMOVE_TEXTUREHINT)->EnableWindow(false);
|
|
return;
|
|
}
|
|
GetDlgItem(ID_REMOVE_TEXTUREHINT)->EnableWindow(true);
|
|
|
|
OnEditTextureHint();
|
|
|
|
bool bPreviewAlpha = m_checkPreviewAlpha.GetCheck()?true:false;
|
|
CDocument* pDoc = m_pDocument->GetTextureDoc();
|
|
if (pDoc) {
|
|
CTextureDoc* pTextureDoc = (CTextureDoc*) pDoc;
|
|
Image* pImage = pTextureDoc->GetImage(0);
|
|
|
|
int *items = new int[count];
|
|
m_wndUsed.GetSelItems(count,items);
|
|
Stuff::Page *page = (Stuff::Page *)m_wndUsed.GetItemData(items[0]);
|
|
Check_Object(page);
|
|
|
|
UpdateImageBitmap(&m_bmUsed, pImage, bPreviewAlpha);
|
|
UpdateImageProp(&m_wndUsedImageProp, pImage, page);
|
|
delete[] items;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnAdd
|
|
/* description: Add seleted textures from the unused list to hint file, and update
|
|
/* used and unused texture lists
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnAdd()
|
|
{
|
|
int count = m_wndUnused.GetSelCount();
|
|
if (count == 0)
|
|
return;
|
|
|
|
int *items = new int[count];
|
|
CString *strings = new CString[count];
|
|
CPtrList listNewPages;
|
|
|
|
m_wndUnused.GetSelItems(count,items);
|
|
|
|
for (int x=0;x<count;x++)
|
|
{
|
|
m_wndUnused.GetText(items[x], strings[x]);
|
|
}
|
|
|
|
// Delete the textures from the unused list
|
|
for (x=0;x<count;x++)
|
|
{
|
|
m_wndUnused.DeleteString(m_wndUnused.FindStringExact(items[0], strings[x]));
|
|
}
|
|
|
|
// Add the textures the hint file
|
|
Stuff::NotationFile *pFile = m_pNoteFile;
|
|
for (x=0;x<count;x++)
|
|
{
|
|
Stuff::Page *page = pFile->AddPage(strings[x]);
|
|
Check_Object(page);
|
|
listNewPages.AddTail((LPVOID)page);
|
|
|
|
// If the texture's name ends with a number,
|
|
// then it is most likely an explicit mipmap
|
|
if (strings[x].GetAt(strings[x].GetLength()-1) <= '9' &&
|
|
strings[x].GetAt(strings[x].GetLength()-1) >= '0')
|
|
page->SetEntry("mipmap", "explicit");
|
|
}
|
|
|
|
// Update the used list
|
|
m_pDocument->UpdateAllViews(NULL, 0, NULL);
|
|
|
|
// Select the first hint in the list that has just been added
|
|
int index = m_wndUsed.FindStringExact(0, strings[0]);
|
|
if (index>=0) {
|
|
m_wndUsed.SetSel(-1, false);
|
|
m_wndUsed.SetSel(index, true);
|
|
OnSelchangeListUsed();
|
|
}
|
|
|
|
// Update selection in the unused list
|
|
m_wndUnused.SetSel(items[0], true);
|
|
OnSelchangeListUnused();
|
|
|
|
delete[] items;
|
|
delete[] strings;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnRemove
|
|
/* description: Remove seleted texture hints from the to hint file, and update
|
|
/* used and unused texture lists
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnRemove()
|
|
{
|
|
int count = m_wndUsed.GetSelCount();
|
|
if (count == 0)
|
|
return;
|
|
|
|
int *items = new int[count];
|
|
CString *strings = new CString[count];
|
|
|
|
m_wndUsed.GetSelItems(count,items);
|
|
|
|
// Remove the textures from the used list, and the hint file
|
|
for (int x=0;x<count;x++)
|
|
{
|
|
m_wndUsed.GetText(items[x], strings[x]);
|
|
Stuff::Page *page = (Stuff::Page *)m_wndUsed.GetItemData(items[x]);
|
|
if (page) {
|
|
Check_Object(page);
|
|
CString name = m_pDocument->RemoveTexture(page);
|
|
m_wndUsed.SetItemData(items[x], NULL);
|
|
}
|
|
}
|
|
|
|
// Update the used list and the unused list
|
|
m_pDocument->UpdateAllViews(NULL, 0, NULL);
|
|
m_pDocument->UpdateAllViews(NULL, 1, NULL);
|
|
|
|
// Update selection in the unused list
|
|
int index = m_wndUnused.FindStringExact(0, strings[0]);
|
|
if (index>=0) {
|
|
m_wndUnused.SetSel(-1, false);
|
|
m_wndUnused.SetSel(index, true);
|
|
OnSelchangeListUnused();
|
|
}
|
|
|
|
// Update selection in the used list
|
|
m_wndUsed.SetSel(items[0], true);
|
|
OnSelchangeListUsed();
|
|
|
|
delete[] items;
|
|
delete[] strings;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnDeleteTextureFromDisk
|
|
/* description: Delete the select textures from hard disk
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnDeleteTextureFromDisk()
|
|
{
|
|
m_bmUnused.DeleteObject();
|
|
m_wndPreviewUnused.Invalidate();
|
|
int count = m_wndUnused.GetSelCount();
|
|
if (count == 0)
|
|
return;
|
|
|
|
if (IDNO == MessageBox("Are you sure you want to DELETE selected files from the DISK?","Confirm File Deletion",MB_ICONWARNING | MB_YESNO))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int *items = new int[count];
|
|
m_wndUnused.GetSelItems(count,items);
|
|
|
|
for (int x=0;x<count;x++)
|
|
{
|
|
CString name;
|
|
m_wndUnused.GetText(items[x],name);
|
|
|
|
name.MakeLower();
|
|
POSITION pos = m_listTextures.Find(name);
|
|
if (pos)
|
|
{
|
|
m_listTextures.RemoveAt(pos);
|
|
}
|
|
|
|
name = "content\\textures\\"+name;
|
|
|
|
CString fullname = name+".png";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
gos_DeleteFile(fullname);
|
|
}
|
|
|
|
fullname = name+".tga";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
gos_DeleteFile(fullname);
|
|
}
|
|
}
|
|
delete[] items;
|
|
|
|
// Update the unused list
|
|
m_pDocument->UpdateAllViews(NULL, 1, NULL);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnEditTextureHint
|
|
/* description: Update texture views
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnEditTextureHint()
|
|
{
|
|
int count = m_wndUsed.GetSelCount();
|
|
int *items = new int[count];
|
|
m_wndUsed.GetSelItems(count,items);
|
|
|
|
if (m_pDocument->GetTextureDoc()) {
|
|
m_pDocument->GetTextureDoc()->SetPathName(NULL);
|
|
}
|
|
|
|
for (int x=0;x<count;x++)
|
|
{
|
|
DWORD data = m_wndUsed.GetItemData(items[x]);
|
|
if (0==x)
|
|
m_pDocument->OpenTexture((Stuff::Page *)data);
|
|
else
|
|
m_pDocument->GetTextureDoc()->SetPathName((LPCTSTR)data);
|
|
}
|
|
delete[] items;
|
|
if (m_pDocument->GetTextureDoc()) {
|
|
m_pDocument->GetTextureDoc()->UpdateAllViews(NULL,0,NULL);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: UpdateUnusedList
|
|
/* description:
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::UpdateUnusedList(CObject* pHint)
|
|
{
|
|
m_wndUnused.ResetContent();
|
|
POSITION pos = m_listTextures.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CString str = m_listTextures.GetNext(pos);
|
|
|
|
if (!m_listUsed.Find(str)) {
|
|
m_wndUnused.AddString(str);
|
|
}
|
|
}
|
|
|
|
int count = m_wndUnused.GetSelCount();
|
|
if (count == 0) {
|
|
m_wndUnused.SetSel(0, true);
|
|
OnSelchangeListUnused();
|
|
}
|
|
}
|
|
|
|
bool g_bWarnDuplicateAlias = true;
|
|
/*******************************************************************************
|
|
/* function name: UpdateUsedList
|
|
/* description:
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::UpdateUsedList(CObject* pHint)
|
|
{
|
|
Stuff::NotationFile *pFile = m_pNoteFile;
|
|
m_wndUsed.ResetContent();
|
|
m_listUsed.RemoveAll();
|
|
|
|
m_mapAliasNames.RemoveAll();
|
|
|
|
CMapStringToOb listMipmaps;
|
|
|
|
bool bShowSeudo = m_checkShowSeudo.GetCheck()?true:false;
|
|
bool bShowSolid = m_checkShowSolid.GetCheck()?true:false;
|
|
bool bShowAlpha = m_checkShowAlpha.GetCheck()?true:false;
|
|
|
|
Stuff::NotationFile::PageIterator *pages = pFile->MakePageIterator();
|
|
Stuff::Page *page;
|
|
while (NULL != (page = pages->ReadAndNext()))
|
|
{
|
|
CString pagename = page->GetName();
|
|
pagename.MakeLower();
|
|
|
|
const char *entry = NULL;
|
|
|
|
// Mipmaps are going to be added differently
|
|
// So for now, add them to a table to use later
|
|
if (page->GetEntry("mipmap",&entry)) {
|
|
if (stricmp(entry, "explicit") == 0) {
|
|
CObject *value;
|
|
if (listMipmaps.Lookup(pagename.Left(pagename.GetLength()-1), value))
|
|
{
|
|
bool bAdded = false;
|
|
CStringList* pMipmaps = (CStringList*)value;
|
|
|
|
CString mipmapName = pMipmaps->GetHead();
|
|
if (mipmapName>pagename) {
|
|
bAdded = true;
|
|
pMipmaps->AddHead(pagename);
|
|
}
|
|
|
|
POSITION pos = pMipmaps->GetHeadPosition();
|
|
while(pos) {
|
|
if (bAdded)
|
|
break;
|
|
|
|
CString mipmapName = pMipmaps->GetNext(pos);
|
|
if (mipmapName>pagename) {
|
|
bAdded = true;
|
|
if (!pos) {
|
|
POSITION temp = pMipmaps->GetTailPosition();
|
|
pMipmaps->InsertBefore(temp, pagename);
|
|
}
|
|
else {
|
|
POSITION temp = pos;
|
|
pMipmaps->GetPrev(temp);
|
|
pMipmaps->InsertBefore(temp, pagename);
|
|
}
|
|
}
|
|
}
|
|
if (!bAdded)
|
|
pMipmaps->AddTail(pagename);
|
|
}
|
|
else
|
|
{
|
|
CStringList* pMipmaps = new CStringList;
|
|
pMipmaps->AddTail(pagename);
|
|
listMipmaps[pagename.Left(pagename.GetLength()-1)] = pMipmaps;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If it has an alias, then add it to a alias list that'll be used later
|
|
if (page->GetEntry("Alias",&entry))
|
|
{
|
|
CString aliasName(entry);
|
|
aliasName.MakeLower();
|
|
|
|
CString originalName;
|
|
if (m_mapAliasNames.Lookup(aliasName,originalName) && g_bWarnDuplicateAlias)
|
|
MessageBox(CString("Two or more textures are using the same alias ")+entry, "Error!", MB_OK);
|
|
|
|
m_mapAliasNames[aliasName]=pagename;
|
|
}
|
|
|
|
// Could be a megatexture
|
|
else {
|
|
Stuff::Page::NoteIterator *noteIt = page->MakeNoteIterator();
|
|
Stuff::Note *note;
|
|
|
|
while ((note = noteIt->ReadAndNext()) != NULL)
|
|
{
|
|
const char *name = NULL;
|
|
const char *entry = NULL;
|
|
note->GetEntry(&entry);
|
|
name = note->GetName();
|
|
int x, y;
|
|
int param_count = sscanf(entry, "%d %d", &x, &y);
|
|
if (param_count==2 && stricmp(name, "PageSize")) {
|
|
CString originalName;
|
|
if (m_mapAliasNames.Lookup(entry,originalName))
|
|
MessageBox(CString("Two or more textures are using the same alias ")+entry, "Error!", MB_OK);
|
|
m_mapAliasNames[pagename]=name;
|
|
break;
|
|
}
|
|
}
|
|
delete noteIt;
|
|
}
|
|
}
|
|
|
|
delete pages;
|
|
pages = pFile->MakePageIterator();
|
|
while (NULL != (page = pages->ReadAndNext()))
|
|
{
|
|
CString pagename = page->GetName();
|
|
pagename.MakeLower();
|
|
m_listUsed.AddTail(pagename);
|
|
|
|
// Add explicit mipmaps later
|
|
const char *entry = NULL;
|
|
if (page->GetEntry("mipmap",&entry)) {
|
|
if (stricmp(entry, "explicit") == 0)
|
|
continue;
|
|
}
|
|
|
|
if (page->GetEntry("Resourcify",&entry))
|
|
{
|
|
// If a non-resourcified / seudo texture
|
|
if (!bShowSeudo && ::stricmp(entry, "false")==0)
|
|
continue;
|
|
}
|
|
|
|
if (page->GetEntry("Format",&entry))
|
|
{
|
|
// If a solid texture
|
|
if (::stricmp(entry, "solid")==0) {
|
|
if (!bShowSolid)
|
|
continue;
|
|
}
|
|
// Else if an alpha texture
|
|
else {
|
|
if (!bShowAlpha)
|
|
continue;
|
|
}
|
|
}
|
|
else {
|
|
if (!bShowSolid)
|
|
continue;
|
|
}
|
|
|
|
CString textureInfo = pagename;
|
|
CString originalName;
|
|
if (m_mapAliasNames.Lookup(pagename,originalName) && originalName.GetLength())
|
|
textureInfo += "("+originalName+")";
|
|
|
|
int index = m_wndUsed.AddString(textureInfo);
|
|
|
|
m_wndUsed.SetItemData(index,(DWORD)page);
|
|
|
|
}
|
|
|
|
// Add the head of explicit mipmaps
|
|
POSITION pos = listMipmaps.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
CObject *pObj;
|
|
CString name;
|
|
listMipmaps.GetNextAssoc(pos,name,pObj);
|
|
|
|
CStringList *pMipmaps = (CStringList*)pObj;
|
|
CString mipmapName = pMipmaps->GetHead();
|
|
mipmapName.MakeLower();
|
|
|
|
Stuff::Page *page = pFile->FindPage(mipmapName);
|
|
if (page) {
|
|
|
|
const char *entry = NULL;
|
|
if (page->GetEntry("Resourcify",&entry))
|
|
{
|
|
// If a non-resourcified / seudo texture
|
|
if (!bShowSeudo && ::stricmp(entry, "false")==0)
|
|
continue;
|
|
}
|
|
|
|
if (page->GetEntry("Format",&entry))
|
|
{
|
|
// If a solid texture
|
|
if (::stricmp(entry, "solid")==0) {
|
|
if (!bShowSolid)
|
|
continue;
|
|
}
|
|
// Else if an alpha texture
|
|
else {
|
|
if (!bShowAlpha)
|
|
continue;
|
|
}
|
|
}
|
|
else {
|
|
if (!bShowSolid)
|
|
continue;
|
|
}
|
|
|
|
CString textureInfo = mipmapName;
|
|
CString originalName;
|
|
if (m_mapAliasNames.Lookup(mipmapName,originalName) && originalName.GetLength())
|
|
textureInfo += "("+originalName+")";
|
|
|
|
int index = m_wndUsed.AddString(textureInfo);
|
|
Check_Object(page);
|
|
m_wndUsed.SetItemData(index,(DWORD)page);
|
|
}
|
|
}
|
|
|
|
// Add the rest of the mipmaps, which will be indented after the first one
|
|
pos = listMipmaps.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
CObject *pObj;
|
|
CString name;
|
|
listMipmaps.GetNextAssoc(pos,name,pObj);
|
|
|
|
CStringList *pMipmaps = (CStringList*)pObj;
|
|
int index = m_wndUsed.FindString(0, pMipmaps->RemoveHead());
|
|
if (index >= 0)
|
|
ListExplicitMipmaps(pMipmaps, index);
|
|
delete pMipmaps;
|
|
}
|
|
|
|
delete pages;
|
|
|
|
int count = m_wndUsed.GetSelCount();
|
|
if (count == 0) {
|
|
m_wndUsed.SetSel(0, true);
|
|
OnSelchangeListUsed();
|
|
}
|
|
|
|
g_bWarnDuplicateAlias = false;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnAddMegatexture
|
|
/* description: Add a megatexture from multiple unused textures
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnAddMegatexture()
|
|
{
|
|
int nCount = m_wndUnused.GetSelCount();
|
|
if (0==nCount)
|
|
return;
|
|
|
|
Check_Object(m_pNoteFile);
|
|
|
|
// Add the hint for the seudo textures
|
|
int *items = new int[nCount];
|
|
CPtrList list;
|
|
|
|
m_wndUnused.GetSelItems(nCount,items);
|
|
for (int x=0;x<nCount;x++)
|
|
{
|
|
CString name;
|
|
m_wndUnused.GetText(items[x],name);
|
|
Stuff::Page *page = m_pNoteFile->AddPage(name);
|
|
Check_Object(page);
|
|
page->SetEntry("resourcify","false");
|
|
list.AddTail((LPVOID)page);
|
|
}
|
|
delete[] items;
|
|
|
|
// Now add the megatexture hint
|
|
Stuff::Page *page = (Stuff::Page *)list.GetHead();
|
|
Check_Object(page);
|
|
|
|
// Create a megatexture with the name of the first item with underscore first character
|
|
CString meganame = CString("_")+page->GetName();
|
|
meganame.MakeLower();
|
|
if (m_pNoteFile->FindPage(meganame)) {
|
|
MessageBox(meganame + "already exists", "Rename", MB_OK);
|
|
}
|
|
|
|
// Put all of the textures at 0 0 and let the TextureView arrange them
|
|
Stuff::Page *megapage = m_pNoteFile->AddPage(meganame);
|
|
|
|
megapage->AppendEntry("PageSize","512 512");
|
|
POSITION pos = list.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
Stuff::Page *page = (Stuff::Page *)list.GetNext(pos);
|
|
Check_Object(page);
|
|
|
|
CString name = page->GetName();
|
|
const char *entry;
|
|
if (page->GetEntry("Alias",&entry))
|
|
{
|
|
name = entry;
|
|
}
|
|
megapage->AppendEntry(name,"");
|
|
}
|
|
|
|
CPtrList listNewPages;
|
|
listNewPages.AddHead((LPVOID)megapage);
|
|
m_pDocument->UpdateAllViews(NULL, 0, NULL);
|
|
|
|
int index = m_wndUsed.FindStringExact(0, meganame);
|
|
if (index>=0) {
|
|
m_wndUsed.SetSel(-1, false);
|
|
m_wndUsed.SetSel(index, true);
|
|
OnSelchangeListUsed();
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: OnCheckPreviewAlpha
|
|
/* description:
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::OnCheckPreviewAlpha()
|
|
{
|
|
OnSelchangeListUsed();
|
|
OnSelchangeListUnused();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: SetDocument
|
|
/* description:
|
|
/*******************************************************************************/
|
|
CDocument *CMultitronDlg::SetDocument(CMultitronDoc *pDoc)
|
|
{
|
|
CMultitronDoc *pBack = m_pDocument;
|
|
if (-1 != (DWORD)pDoc)
|
|
m_pDocument = pDoc;
|
|
|
|
m_pNoteFile = m_pDocument->GetHintFile();
|
|
|
|
UpdateUsedList();
|
|
UpdateUnusedList();
|
|
return pBack;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: FindTextures
|
|
/* description:
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::FindTextures(CString dir)
|
|
{
|
|
CFileFind find;
|
|
int icount = 0;
|
|
|
|
// Find all png texture
|
|
bool bmore = find.FindFile(dir+"*.png")?true:false;
|
|
while (bmore)
|
|
{
|
|
bmore = find.FindNextFile()?true:false;
|
|
CString str = find.GetFilePath();
|
|
str.MakeLower();
|
|
str = str.Left(str.Find("."));
|
|
CString gamePath = str.Left(str.Find("content\\textures\\"));
|
|
if (str.Find("content\\textures\\")>=0)
|
|
str = str.Right(str.GetLength()-strlen(gamePath+"content\\textures\\"));
|
|
m_listTextures.AddTail(str);
|
|
icount++;
|
|
}
|
|
find.Close();
|
|
|
|
// Find all tga textures
|
|
bmore = find.FindFile(dir + "*.tga")?true:false;
|
|
while (bmore)
|
|
{
|
|
bmore = find.FindNextFile()?true:false;
|
|
CString str = find.GetFilePath();
|
|
str.MakeLower();
|
|
str = str.Left(str.Find("."));
|
|
CString gamePath = str.Left(str.Find("content\\textures\\"));
|
|
if (str.Find("content\\textures\\")>=0)
|
|
str = str.Right(str.GetLength()-strlen(gamePath+"content\\textures\\"));
|
|
if (!m_listTextures.Find(str))
|
|
{
|
|
m_listTextures.AddTail(str);
|
|
}
|
|
icount++;
|
|
}
|
|
find.Close();
|
|
|
|
// Look in sub directories if needed
|
|
if (!m_checkSearchSubDir.GetCheck())
|
|
return;
|
|
|
|
HANDLE hfl;
|
|
WIN32_FIND_DATA fd;
|
|
|
|
if(dir[dir.GetLength()-1]=='\\')
|
|
{
|
|
dir=dir.Left(dir.GetLength()-1);
|
|
}
|
|
|
|
fd.dwFileAttributes=NULL;
|
|
hfl=FindFirstFile(dir+"\\*.*",&fd);
|
|
|
|
if(INVALID_HANDLE_VALUE!=hfl)
|
|
{
|
|
do
|
|
{
|
|
if(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
if(strcmp(fd.cFileName,".") && strcmp(fd.cFileName,"..") )
|
|
{
|
|
FindTextures(dir+"\\"+fd.cFileName+"\\");
|
|
}
|
|
}
|
|
|
|
} while(FindNextFile(hfl,&fd));
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: FindAllTextures
|
|
/* description:
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::FindAllTextures()
|
|
{
|
|
m_listTextures.RemoveAll();
|
|
FindTextures("content\\textures\\");
|
|
UpdateUnusedList();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: ListExplicitMipmaps
|
|
/* description: List explicit mipmaps in the used list, ie,
|
|
/* mipmap0
|
|
/* mipmap1
|
|
/* mipmap2
|
|
/* mipmap3
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::ListExplicitMipmaps(CStringList* pMipmaps, int index)
|
|
{
|
|
bool bShowSeudo = m_checkShowSeudo.GetCheck()?true:false;
|
|
bool bShowSolid = m_checkShowSolid.GetCheck()?true:false;
|
|
bool bShowAlpha = m_checkShowAlpha.GetCheck()?true:false;
|
|
|
|
POSITION pos = pMipmaps->GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CString mipmapName = pMipmaps->GetNext(pos);
|
|
Stuff::Page *page = m_pNoteFile->FindPage(mipmapName);
|
|
if (page) {
|
|
|
|
const char* entry = NULL;
|
|
if (page->GetEntry("Resourcify",&entry))
|
|
{
|
|
// If a non-resourcified / seudo texture
|
|
if (!bShowSeudo && ::stricmp(entry, "false")==0)
|
|
continue;
|
|
}
|
|
|
|
if (page->GetEntry("Format",&entry))
|
|
{
|
|
// If a solid texture
|
|
if (::stricmp(entry, "solid")==0) {
|
|
if (!bShowSolid)
|
|
continue;
|
|
}
|
|
// Else if an alpha texture
|
|
else {
|
|
if (!bShowAlpha)
|
|
continue;
|
|
}
|
|
}
|
|
else {
|
|
if (!bShowSolid)
|
|
continue;
|
|
}
|
|
|
|
if (m_checkShowMipmap.GetCheck()) {
|
|
|
|
CString textureInfo = CString(" ")+mipmapName;
|
|
m_wndUsed.InsertString(++index, textureInfo);
|
|
Check_Object(page);
|
|
m_wndUsed.SetItemData(index,(DWORD)page);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: UpdateImageProp
|
|
/* description: Update image properties in under the preview window
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::UpdateImageProp(CListBox *pList, Image* pImage, Stuff::Page* pPage)
|
|
{
|
|
pList->ResetContent();
|
|
|
|
if (pImage)
|
|
{
|
|
//Fill in the image properties list
|
|
{
|
|
CString str;
|
|
char title[MAX_PATH];
|
|
char ext[MAX_PATH];
|
|
if (strlen(pImage->GetFileName())) {
|
|
_splitpath(pImage->GetFileName(),NULL,NULL,title,ext);
|
|
str.Format("Filename: %s%s",title,ext);
|
|
}
|
|
else if (pPage) {
|
|
str.Format("Filename: %s%s",pPage->GetName(),".png");
|
|
}
|
|
|
|
pList->AddString(str);
|
|
|
|
DWORD dwSize = pImage->GetWidth()*pImage->GetHeight()*pImage->GetBpp();
|
|
dwSize = dwSize>>3;
|
|
//DWORD dwSize = ::gos_FileSize(pImage->GetFileName());
|
|
str.Format("Size: %d bytes",dwSize);
|
|
pList->AddString(str);
|
|
|
|
str.Format("Res: %dx%dx%dbpp",pImage->GetWidth(),pImage->GetHeight(),pImage->GetBpp());
|
|
switch (pImage->GetIType())
|
|
{
|
|
case ITYPE_RGB:
|
|
{
|
|
str += " RGB";
|
|
break;
|
|
}
|
|
case ITYPE_INDEXED:
|
|
{
|
|
str += " INDEXED";
|
|
break;
|
|
}
|
|
}
|
|
pList->AddString(str);
|
|
|
|
str.Format("Has Alpha: %s",pImage->HasAlpha()?"true":"false");
|
|
pList->AddString(str);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
/* function name: UpdateImageBitmap
|
|
/* description: Update image bitmap for the preview window
|
|
/*******************************************************************************/
|
|
void CMultitronDlg::UpdateImageBitmap(CBitmap* pBitmap, Image* pImage, bool bPreviewAlpha)
|
|
{
|
|
if (!pImage || !pBitmap)
|
|
return;
|
|
|
|
RGBMask mask;
|
|
if(pImage->GetBpp()==32)
|
|
mask.Set(0x00ff0000,0x0000ff00,0x000000ff,0xff000000);
|
|
else
|
|
mask.Set(0x00ff0000,0x0000ff00,0x000000ff);
|
|
|
|
pImage->MaskTo(mask);
|
|
|
|
CDC memDC,*hfDC;
|
|
hfDC=GetDC();
|
|
|
|
pBitmap->DeleteObject();
|
|
BOOL bres;
|
|
bres=pBitmap->CreateCompatibleBitmap(hfDC,pImage->GetWidth(),pImage->GetHeight());
|
|
Verify(bres);
|
|
|
|
memDC.CreateCompatibleDC(hfDC);
|
|
memDC.SelectObject(pBitmap);
|
|
|
|
BITMAPINFOHEADER bhd;
|
|
BITMAPINFO binf;
|
|
bhd.biSize=sizeof(BITMAPINFOHEADER);
|
|
bhd.biWidth=pImage->GetWidth(); bhd.biHeight=-pImage->GetHeight();
|
|
bhd.biPlanes=1;
|
|
bhd.biBitCount=(unsigned short)pImage->GetBpp();
|
|
bhd.biCompression=BI_RGB;
|
|
bhd.biSizeImage=0;
|
|
bhd.biClrImportant=0;
|
|
binf.bmiHeader=bhd;
|
|
|
|
BYTE *imgdat=(BYTE *)(pImage->Lock());
|
|
|
|
// If this is an alpha image, and Preview Alpha is checked
|
|
// then write out RGB values with the alpha value, so that the
|
|
// bitmap becomes a gray-scale image show the alpha channel
|
|
if (pImage->GetBpp()==32 && bPreviewAlpha) {
|
|
for (int i=0; i<pImage->GetWidth()*pImage->GetHeight(); ++i)
|
|
{
|
|
*(imgdat+i*4+0) = *(imgdat+i*4+3);
|
|
*(imgdat+i*4+1) = *(imgdat+i*4+3);
|
|
*(imgdat+i*4+2) = *(imgdat+i*4+3);
|
|
}
|
|
}
|
|
|
|
SetDIBitsToDevice(memDC,
|
|
0,0,pImage->GetWidth(), pImage->GetHeight(),
|
|
0,0,0,pImage->GetHeight(),
|
|
imgdat, &binf,DIB_RGB_COLORS);
|
|
pImage->UnLock();
|
|
|
|
memDC.DeleteDC();
|
|
ReleaseDC(hfDC);
|
|
} |