Files
firestorm/Gameleap/code/mw4/Tools/Megatron/DlgCreateMegatexture.cpp
T
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

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();
}