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.
626 lines
13 KiB
C++
626 lines
13 KiB
C++
// DlgCreateMegatexture.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "Megatron.h"
|
|
#include "DlgCreateMegatexture.h"
|
|
|
|
#include <elementrenderer\elementrendererheaders.hpp>
|
|
#include "Proxies\ProxyHeaders.hpp"
|
|
#include "ElementProxies\ElementProxies.hpp"
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
//#include <proxies\ArrangeMegaTextures.hpp>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgCreateMegatexture dialog
|
|
|
|
|
|
CDlgCreateMegatexture::CDlgCreateMegatexture(CWnd* pParent /*=NULL*/)
|
|
: CDialog(CDlgCreateMegatexture::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(CDlgCreateMegatexture)
|
|
//}}AFX_DATA_INIT
|
|
m_pList = NULL;
|
|
m_pCell = NULL;
|
|
m_pImage = NULL;
|
|
m_pNoteFile = NULL;
|
|
}
|
|
|
|
CDlgCreateMegatexture::~CDlgCreateMegatexture()
|
|
{
|
|
if (m_pCell)
|
|
delete m_pCell;
|
|
if (m_pImage)
|
|
delete m_pImage;
|
|
}
|
|
|
|
void CDlgCreateMegatexture::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CDlgCreateMegatexture)
|
|
DDX_Control(pDX, IDC_NAME, m_wndName);
|
|
DDX_Control(pDX, IDC_MEGAPREVIEW, m_wndMegaPreview);
|
|
DDX_Control(pDX, IDC_LIST, m_wndList);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDlgCreateMegatexture, CDialog)
|
|
//{{AFX_MSG_MAP(CDlgCreateMegatexture)
|
|
ON_LBN_SELCHANGE(IDC_LIST, OnSelchangeList)
|
|
ON_WM_DRAWITEM()
|
|
ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
|
|
ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CDlgCreateMegatexture message handlers
|
|
|
|
BOOL CDlgCreateMegatexture::OnInitDialog()
|
|
{
|
|
CDialog::OnInitDialog();
|
|
|
|
CWnd *pWnd = GetDlgItem(IDC_RADIO2);
|
|
((CButton *)pWnd)->SetCheck(true);
|
|
OnRadio2();
|
|
|
|
CPtrList *poslist = NULL;
|
|
if (m_pList)
|
|
{
|
|
POSITION pos = m_pList->GetHeadPosition();
|
|
if (pos)
|
|
{
|
|
poslist = (CPtrList *)m_pList->GetNext(pos);
|
|
}
|
|
while (pos)
|
|
{
|
|
bool bsel = false;
|
|
if (POSITION pos1 = poslist->Find((LPVOID)pos))
|
|
{
|
|
poslist->RemoveAt(pos1);
|
|
bsel = true;
|
|
}
|
|
|
|
Stuff::Page *page = (Stuff::Page *)m_pList->GetNext(pos);
|
|
Check_Object(page);
|
|
int index = m_wndList.AddString(page->GetName());
|
|
m_wndList.SetItemData(index,(DWORD)page);
|
|
if (bsel)
|
|
{
|
|
m_wndList.SetSel(index,true);
|
|
}
|
|
}
|
|
}
|
|
OnSelchangeList();
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
static CDWordArray arrVerts;
|
|
|
|
CCell::CCell()
|
|
{
|
|
bSplit = false;
|
|
for (int x=0;x<4;x++)
|
|
m_arrChildren[x] = NULL;
|
|
m_image = NULL;
|
|
state = 0;
|
|
}
|
|
|
|
CCell::~CCell()
|
|
{
|
|
for (int x=0;x<4;x++)
|
|
if (m_arrChildren[x])
|
|
delete m_arrChildren[x];
|
|
}
|
|
|
|
CPoint CCell::GetPoint1()
|
|
{
|
|
DWORD dw = arrVerts[V1];
|
|
CPoint pt(LOWORD(dw),HIWORD(dw));
|
|
return pt;
|
|
}
|
|
|
|
int CCell::AddVert(int x,int y)
|
|
{
|
|
DWORD dw = MAKELONG(x,y);
|
|
return arrVerts.Add(dw);
|
|
}
|
|
|
|
int CCell::GetXDim()
|
|
{
|
|
DWORD dw1 = arrVerts[V1];
|
|
WORD x1 = LOWORD(dw1);
|
|
|
|
DWORD dw2 = arrVerts[V2];
|
|
WORD x2 = LOWORD(dw2);
|
|
return (x2-x1);
|
|
}
|
|
|
|
int CCell::GetYDim()
|
|
{
|
|
DWORD dw1 = arrVerts[V1];
|
|
WORD y1 = HIWORD(dw1);
|
|
|
|
DWORD dw2 = arrVerts[V2];
|
|
WORD y2 = HIWORD(dw2);
|
|
return (y2-y1);
|
|
}
|
|
|
|
int CCell::GetV1()
|
|
{
|
|
return V1;
|
|
}
|
|
|
|
int CCell::GetV2()
|
|
{
|
|
return V2;
|
|
}
|
|
|
|
int CCell::SetVerts(int a,int b)
|
|
{
|
|
V1 = a;
|
|
V2 = b;
|
|
return 1;
|
|
}
|
|
|
|
int CCell::CreateCell(int xSize,int ySize)
|
|
{
|
|
V1 = AddVert(0,0);
|
|
V2 = AddVert(xSize,ySize);
|
|
state = 0; // Empty
|
|
return 1;
|
|
}
|
|
|
|
CCell *CCell::FillCell(Image *image)
|
|
{
|
|
if (2==state)
|
|
return NULL;
|
|
int xSize = image->GetWidth();
|
|
int ySize = image->GetHeight();
|
|
|
|
int xdim = GetXDim();
|
|
int ydim = GetYDim();
|
|
|
|
if ((xSize==xdim)&&(ySize==ydim)&&(0==state))
|
|
{
|
|
// use this cell, fill it up totally
|
|
m_image = image;
|
|
name = image->GetFileName();
|
|
state = 2;
|
|
return this;
|
|
}
|
|
else
|
|
{
|
|
if ((xSize<=xdim) && (ySize<=ydim))
|
|
{
|
|
SplitCell(xSize,ySize);
|
|
BYTE flags = 0;
|
|
for (int x=0;x<4;x++)
|
|
{
|
|
CCell *cell = m_arrChildren[x]->FillCell(image);
|
|
flags |= (2==m_arrChildren[x]->state) << x;
|
|
if (cell)
|
|
{
|
|
if (15==flags)
|
|
state = 2;
|
|
else
|
|
state = 1;
|
|
return cell;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// Cannot fill this cell with something this big, unless I union with neighbors
|
|
return NULL;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int CCell::SplitCell(int xSize,int ySize)
|
|
{
|
|
if (!bSplit)
|
|
{
|
|
CPoint pt1 = GetPoint1();
|
|
int xdim = GetXDim();
|
|
int ydim = GetYDim();
|
|
|
|
int topleft = GetV1();
|
|
int bottomright = GetV2();
|
|
int middle = AddVert(pt1.x+xSize,pt1.y+ySize);
|
|
int middletop = AddVert(pt1.x+xSize,pt1.y);
|
|
int middleleft = AddVert(pt1.x,pt1.y+ySize);
|
|
int middlebottom = AddVert(pt1.x+xSize,pt1.y+ydim);
|
|
int middleright = AddVert(pt1.x+xdim,pt1.y+ySize);
|
|
|
|
CCell *cell = m_arrChildren[0] = new CCell;
|
|
cell->SetVerts(topleft,middle);
|
|
|
|
cell = m_arrChildren[1] = new CCell;
|
|
cell->SetVerts(middletop,middleright);
|
|
|
|
cell = m_arrChildren[2] = new CCell;
|
|
cell->SetVerts(middleleft,middlebottom);
|
|
|
|
cell = m_arrChildren[3] = new CCell;
|
|
cell->SetVerts(middle,bottomright);
|
|
|
|
bSplit = true;
|
|
}
|
|
return 4;
|
|
}
|
|
|
|
int BuildMegaTexture(CCell *pCell,Image *pImage)
|
|
{
|
|
if (pCell)
|
|
{
|
|
if (pCell->m_image)
|
|
{
|
|
CPoint pt = pCell->GetPoint1();
|
|
pImage->Blt(*(pCell->m_image),pt.x,pt.y);
|
|
}
|
|
for (int x=0;x<4;x++)
|
|
BuildMegaTexture(pCell->m_arrChildren[x],pImage);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
CCell *ArrangeTextures(Stuff::NotationFile *pMega_file,CString mega_name,int xSize,int ySize,CMapStringToPtr *pMapImages,Image *mega_image)
|
|
{
|
|
Stuff::Page *mega_page = pMega_file->AddPage(mega_name);
|
|
CString str;
|
|
str.Format("%d %d",xSize,ySize);
|
|
mega_page->AppendEntry("PageSize",str);
|
|
|
|
CCell *pCell = new CCell;
|
|
pCell->CreateCell(xSize,ySize);
|
|
|
|
POSITION pos = pMapImages->GetStartPosition();
|
|
while (pos)
|
|
{
|
|
CString imagename;
|
|
LPVOID lpvoid;
|
|
pMapImages->GetNextAssoc(pos,imagename,lpvoid);
|
|
Image *pImage = (Image *)lpvoid;
|
|
|
|
CCell *cell = pCell->FillCell(pImage);
|
|
if (NULL == cell)
|
|
{
|
|
CString str;
|
|
str.Format("Could not fit texture %s",imagename);
|
|
MessageBox(NULL,str,"Fill Cell",MB_OK);
|
|
}
|
|
}
|
|
|
|
BuildMegaTexture(pCell,mega_image);
|
|
return pCell;
|
|
}
|
|
|
|
void CDlgCreateMegatexture::OnSelchangeList()
|
|
{
|
|
CString mega_name = "MegaTexture";
|
|
|
|
int iCount = m_wndList.GetSelCount();
|
|
int *items = new int[iCount];
|
|
m_wndList.GetSelItems(iCount,items);
|
|
|
|
CMapStringToPtr mapImages;
|
|
for (int x=0;x<iCount;x++)
|
|
{
|
|
Stuff::Page *page = (Stuff::Page *)m_wndList.GetItemData(items[x]);
|
|
|
|
CString imagename = page->GetName();
|
|
const char *entry;
|
|
if (page->GetEntry("Alias",&entry))
|
|
{
|
|
imagename = entry;
|
|
}
|
|
|
|
CString path = "content\\textures\\"+imagename;
|
|
|
|
Image *image = new Image;
|
|
|
|
CString fullname = path+".tga";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
image->Load((char *)(LPCTSTR)fullname);
|
|
}
|
|
else
|
|
{
|
|
fullname = path+".png";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
image->Load((char *)(LPCTSTR)fullname);
|
|
}
|
|
}
|
|
if(image->GetBpp()==32)
|
|
image->MaskTo(RGBMask(0x00ff0000,0x0000ff00,0x000000ff,0xff000000));
|
|
else
|
|
image->MaskTo(RGBMask(0x00ff0000,0x0000ff00,0x000000ff));
|
|
|
|
|
|
mapImages[imagename] = image;
|
|
|
|
|
|
/* m_BackBuffer.DeleteObject();
|
|
m_wndMegaPreview.Invalidate();
|
|
|
|
CDC memDC,*hfDC;
|
|
hfDC=GetDC();
|
|
|
|
BOOL bres;
|
|
bres=m_BackBuffer.CreateCompatibleBitmap(hfDC,image.GetWidth(),image.GetHeight());
|
|
Verify(bres);
|
|
|
|
memDC.CreateCompatibleDC(hfDC);
|
|
memDC.SelectObject(&m_BackBuffer);
|
|
|
|
BITMAPINFOHEADER bhd;
|
|
BITMAPINFO binf;
|
|
bhd.biSize=sizeof(BITMAPINFOHEADER);
|
|
bhd.biWidth=image.GetWidth(); bhd.biHeight=-image.GetHeight();
|
|
bhd.biPlanes=1;
|
|
bhd.biBitCount=image.GetBpp();
|
|
bhd.biCompression=BI_RGB;
|
|
bhd.biSizeImage=0;
|
|
bhd.biClrImportant=0;
|
|
binf.bmiHeader=bhd;
|
|
|
|
BYTE *imgdat=(BYTE *)(image.Lock());
|
|
|
|
SetDIBitsToDevice(memDC,0,0,image.GetWidth(),
|
|
image.GetHeight(),0,0,0,image.GetWidth(),imgdat,
|
|
&binf,DIB_RGB_COLORS);
|
|
|
|
image.UnLock();
|
|
|
|
memDC.DeleteDC();
|
|
ReleaseDC(hfDC);*/
|
|
}
|
|
delete items;
|
|
|
|
|
|
Stuff::NotationFile mega_file;
|
|
if (m_pCell)
|
|
delete m_pCell;
|
|
if (m_pImage)
|
|
delete m_pImage;
|
|
|
|
m_pImage = new Image;
|
|
m_pImage->CreateSolid(pagesize,pagesize,ImgRGBColor(0xff,0xff,0xff,0xff),ITYPE_RGB,32);
|
|
|
|
m_pCell = ArrangeTextures(&mega_file,mega_name,pagesize,pagesize,&mapImages,m_pImage);
|
|
|
|
|
|
POSITION pos = mapImages.GetStartPosition();
|
|
while (pos)
|
|
{
|
|
CString imagename;
|
|
LPVOID lpvoid;
|
|
mapImages.GetNextAssoc(pos,imagename,lpvoid);
|
|
Image *pImage = (Image *)lpvoid;
|
|
|
|
delete pImage;
|
|
}
|
|
mapImages.RemoveAll();
|
|
|
|
|
|
|
|
|
|
|
|
//mega_page->AppendEntry("Texture",imagename);
|
|
|
|
|
|
// Create the scene stuff
|
|
/* ElementRenderer::GroupElement *root = new ElementRenderer::GroupElement;
|
|
Check_Object(root);
|
|
|
|
ElementProxies::ElementSceneProxy *element_scene =
|
|
ElementProxies::ElementSceneProxy::MakeProxy(
|
|
root,
|
|
"content\\textures\\"
|
|
);
|
|
Check_Object(element_scene);
|
|
|
|
ElementProxies::MLRStatePoolProxy *state_library = Cast_Object(ElementProxies::MLRStatePoolProxy *,element_scene->GetStateLibrary());
|
|
Check_Object(state_library);
|
|
|
|
Proxies::TextureLibrary *texture_library = state_library->GetTextureLibrary();
|
|
Check_Object(texture_library);
|
|
|
|
|
|
// do the arranging
|
|
|
|
Proxies::ArrangeMegatexturesProcess arrange_process(&mega_file);
|
|
texture_library->ArrangeMegatextures(&arrange_process);
|
|
/*
|
|
Proxies::BuildMegatexturesProcess build_process(&mega_file);
|
|
texture_library->BuildMegatextures(&build_process);
|
|
*/
|
|
// Recycle the texture library
|
|
//
|
|
//delete texture_library;
|
|
//delete state_library;
|
|
|
|
/* element_scene->Destroy();
|
|
|
|
if (ElementProxies::MLRTexturePoolProxy::Instance)
|
|
{
|
|
ElementProxies::MLRTexturePoolProxy::Instance->CloseLibrary(true);
|
|
}
|
|
//delete root;
|
|
|
|
|
|
/*CString targa_name = "content\\textures\\";
|
|
targa_name+=mega_name+".tga";
|
|
|
|
Proxies::TextureProxy *texture_proxy = texture_library->UseTextureProxy(mega_name);
|
|
texture_proxy->SaveAsTarga(targa_name);
|
|
|
|
*/
|
|
{
|
|
/* CString path = "content\\textures\\"+mega_name;
|
|
|
|
Image image;
|
|
|
|
CString fullname = path+".tga";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
image.Load((char *)(LPCTSTR)fullname);
|
|
}
|
|
/*else
|
|
{
|
|
fullname = path+".png";
|
|
if (gos_DoesFileExist(fullname))
|
|
{
|
|
image.Load((char *)(LPCTSTR)fullname);
|
|
}
|
|
}*/
|
|
|
|
m_BackBuffer.DeleteObject();
|
|
m_wndMegaPreview.Invalidate();
|
|
|
|
CDC memDC,*hfDC;
|
|
hfDC=GetDC();
|
|
|
|
BOOL bres;
|
|
bres=m_BackBuffer.CreateCompatibleBitmap(hfDC,m_pImage->GetWidth(),m_pImage->GetHeight());
|
|
Verify(bres);
|
|
|
|
memDC.CreateCompatibleDC(hfDC);
|
|
memDC.SelectObject(&m_BackBuffer);
|
|
|
|
BITMAPINFOHEADER bhd;
|
|
BITMAPINFO binf;
|
|
bhd.biSize=sizeof(BITMAPINFOHEADER);
|
|
bhd.biWidth=m_pImage->GetWidth(); bhd.biHeight=-m_pImage->GetHeight();
|
|
bhd.biPlanes=1;
|
|
bhd.biBitCount=m_pImage->GetBpp();
|
|
bhd.biCompression=BI_RGB;
|
|
bhd.biSizeImage=0;
|
|
bhd.biClrImportant=0;
|
|
binf.bmiHeader=bhd;
|
|
|
|
BYTE *imgdat=(BYTE *)(m_pImage->Lock());
|
|
|
|
SetDIBitsToDevice(memDC,0,0,m_pImage->GetWidth(),
|
|
m_pImage->GetHeight(),0,0,0,m_pImage->GetWidth(),imgdat,
|
|
&binf,DIB_RGB_COLORS);
|
|
|
|
m_pImage->UnLock();
|
|
|
|
memDC.DeleteDC();
|
|
ReleaseDC(hfDC);
|
|
}
|
|
|
|
mega_file.IgnoreChanges();
|
|
}
|
|
|
|
void CDlgCreateMegatexture::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
|
|
{
|
|
switch (lpDrawItemStruct->CtlID)
|
|
{
|
|
case IDC_MEGAPREVIEW:
|
|
{
|
|
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
|
|
|
|
HBITMAP hBitmap = m_BackBuffer;
|
|
if (hBitmap)
|
|
{
|
|
CDC memDC;
|
|
int res;
|
|
|
|
BITMAP bmp;
|
|
res=m_BackBuffer.GetBitmap(&bmp);
|
|
Verify(res);
|
|
|
|
BOOL bres;
|
|
bres=memDC.CreateCompatibleDC(pDC);
|
|
Verify(bres);
|
|
memDC.SelectObject(&m_BackBuffer);
|
|
CRect hfrct;
|
|
GetClientRect(&hfrct);
|
|
//pDC->SetStretchBltMode(COLORONCOLOR);
|
|
bres=pDC->BitBlt(0,0,hfrct.Width(),hfrct.Height(),&memDC,0,0,SRCCOPY);
|
|
Verify(bres);
|
|
memDC.DeleteDC();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);
|
|
}
|
|
|
|
int ConstructPage(CCell *pCell,Stuff::Page *page)
|
|
{
|
|
if (NULL == pCell)
|
|
return 0;
|
|
if (pCell->m_image)
|
|
// Acutally m_image is already deleted by now so I can't use it
|
|
{
|
|
char name[MAX_PATH];
|
|
_splitpath(pCell->name,NULL,NULL,name,NULL);
|
|
CString str;
|
|
CPoint pt = pCell->GetPoint1();
|
|
str.Format("%d %d",pt.x,pt.y);
|
|
page->AppendEntry(name,str);
|
|
}
|
|
int count = 1;
|
|
for (int x=0;x<4;x++)
|
|
{
|
|
count += ConstructPage(pCell->m_arrChildren[x],page);
|
|
}
|
|
return count;
|
|
}
|
|
|
|
void CDlgCreateMegatexture::OnOK()
|
|
{
|
|
CString str;
|
|
m_wndName.GetWindowText(str);
|
|
if (str.GetLength()==0)
|
|
{
|
|
MessageBox("Must give new Megatexture a name");
|
|
return;
|
|
}
|
|
if (NULL == m_pImage)
|
|
{
|
|
MessageBox("Must select at least one image to create Megatexture");
|
|
return;
|
|
}
|
|
|
|
Stuff::Page *page = m_pNoteFile->AddPage(str);
|
|
CString str1;
|
|
str1.Format("%d %d",pagesize,pagesize);
|
|
page->AppendEntry("PageSize",str1);
|
|
ConstructPage(m_pCell,page);
|
|
|
|
str = "content\\textures\\"+str+".tga";
|
|
m_pImage->SaveTga((char *)(LPCTSTR)str);
|
|
|
|
CDialog::OnOK();
|
|
}
|
|
|
|
void CDlgCreateMegatexture::OnRadio1()
|
|
{
|
|
pagesize = 256;
|
|
OnSelchangeList();
|
|
}
|
|
|
|
void CDlgCreateMegatexture::OnRadio2()
|
|
{
|
|
pagesize = 512;
|
|
OnSelchangeList();
|
|
}
|