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.
1813 lines
40 KiB
C++
1813 lines
40 KiB
C++
// ImageGrinderDoc.cpp : implementation of the CImageGrinderDoc class
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "ImageGrinder.h"
|
|
#include "NewGridDlg.h"
|
|
#include "ImageGrinderDoc.h"
|
|
#include "BackGroundProps.h"
|
|
#include "DepthDiag.h"
|
|
#include "ImageCache.h"
|
|
|
|
#include <Compost\TexturePool.hpp>
|
|
#include <Stuff\StuffHeaders.hpp>
|
|
#include <GameOS\ToolOS.hpp>
|
|
|
|
#define MAXDOCS 256
|
|
CImageGrinderDoc *DocList[MAXDOCS];
|
|
int DocCount=0;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CImageGrinderDoc
|
|
|
|
IMPLEMENT_DYNCREATE(CImageGrinderDoc, CDocument)
|
|
|
|
BEGIN_MESSAGE_MAP(CImageGrinderDoc, CDocument)
|
|
//{{AFX_MSG_MAP(CImageGrinderDoc)
|
|
ON_COMMAND(ID_FILE_EXPORT_TGAFILES, OnFileExportTgafiles)
|
|
ON_COMMAND(ID_FILE_EXPORT_IMAGEDATA, OnFileExportImagedata)
|
|
ON_COMMAND(ID_FILE_EXPORT_SINGLETGA, OnFileExportSingletga)
|
|
ON_COMMAND(ID_FILE_MERGEFEATURES, OnFileMergefeatures)
|
|
ON_COMMAND(ID_FILE_EXPORT_USEDIMAGELIST, OnFileExportUsedimagelist)
|
|
ON_COMMAND(ID_FILE_EXPORT_MATERIALMAP, OnFileExportMaterialmap)
|
|
ON_COMMAND(ID_FILE_EXPORT_SINGLEMATERIALMAP, OnFileExportSinglematerialmap)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CImageGrinderDoc construction/destruction
|
|
|
|
|
|
|
|
|
|
CImageGrinderDoc::CImageGrinderDoc()
|
|
{
|
|
CurSelFet=NULL;
|
|
DocList[DocCount++]=this;
|
|
|
|
Verify(DocCount<MAXDOCS);
|
|
FPool = NULL;
|
|
FGrid = NULL;
|
|
UpdateList=NULL;
|
|
ManualUpdate=false;
|
|
// SelectionCount=0;
|
|
// HLCount=0;
|
|
// LockCount=0;
|
|
SnapMask = 4;
|
|
|
|
}
|
|
|
|
CImageGrinderDoc::~CImageGrinderDoc()
|
|
{
|
|
int i,didx;
|
|
for(didx=0;didx<DocCount && DocList[didx]!=this;didx++);
|
|
Verify(didx<DocCount);
|
|
for(i=didx;i<(DocCount-1);i++) DocList[i]=DocList[i+1];
|
|
DocCount--;
|
|
|
|
if(UpdateList)
|
|
{
|
|
delete UpdateList;
|
|
}
|
|
|
|
if(FGrid)
|
|
{
|
|
Unregister_Pointer(FGrid);
|
|
delete FGrid;
|
|
}
|
|
|
|
if(FPool)
|
|
{
|
|
Unregister_Pointer(FPool);
|
|
delete FPool;
|
|
}
|
|
}
|
|
|
|
BOOL CImageGrinderDoc::OnNewDocument()
|
|
{
|
|
CNewGridDlg ngd;
|
|
if(ngd.DoModal()==IDOK)
|
|
{
|
|
|
|
if (!CDocument::OnNewDocument())
|
|
return FALSE;
|
|
|
|
FPool = new Compost::FeaturePool();
|
|
Register_Pointer(FPool);
|
|
|
|
if(ngd.m_hires==TRUE)
|
|
{
|
|
FGrid = new Compost::FeatureGrid(8*ngd.m_XZones, 8*ngd.m_YZones, FPool, true);
|
|
}
|
|
else
|
|
{
|
|
FGrid = new Compost::FeatureGrid(8*ngd.m_XZones, 8*ngd.m_YZones, FPool);
|
|
}
|
|
|
|
Register_Pointer(FGrid);
|
|
|
|
UpdateList=new bool[FGrid->GetRows()*FGrid->GetColumns()];
|
|
ClearSelection();
|
|
|
|
CBackGroundProps dlg;
|
|
|
|
Compost::Tool_Feature *TmpFet = new Compost::Tool_Feature;
|
|
Register_Pointer(TmpFet);
|
|
TmpFet->SetName((LPCSTR)"BackGround");
|
|
TmpFet->SetFeatureHeight(FGrid->GetRows()*FGrid->GetGridSize());
|
|
TmpFet->SetFeatureWidth(FGrid->GetColumns()*FGrid->GetGridSize());
|
|
|
|
dlg.DoModal(TmpFet);
|
|
if(dlg.m_stretch)
|
|
{
|
|
TmpFet->SetBlendMode(Compost::Feature::Blend_Mode::StretchPaste);
|
|
TmpFet->SetFeatureMask0(TmpFet->GetFeatureTexture());
|
|
}
|
|
else
|
|
TmpFet->SetBlendMode(Compost::Feature::Blend_Mode::Paste);
|
|
|
|
FPool->Add(TmpFet);
|
|
FGrid->Add(TmpFet, 0, 0);
|
|
SetDrawFlags();
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
// (SDI documents will reuse this document)
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CImageGrinderDoc serialization
|
|
|
|
void CImageGrinderDoc::Serialize(CArchive& ar)
|
|
{
|
|
if (ar.IsStoring())
|
|
{
|
|
// TODO: add storing code here
|
|
}
|
|
else
|
|
{
|
|
// TODO: add loading code here
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CImageGrinderDoc diagnostics
|
|
|
|
#ifdef _DEBUG
|
|
void CImageGrinderDoc::AssertValid() const
|
|
{
|
|
CDocument::AssertValid();
|
|
}
|
|
|
|
void CImageGrinderDoc::Dump(CDumpContext& dc) const
|
|
{
|
|
CDocument::Dump(dc);
|
|
}
|
|
#endif //_DEBUG
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CImageGrinderDoc commands
|
|
|
|
void CImageGrinderDoc::AddFeature(Compost::Feature *fet, int x, int y)
|
|
{
|
|
if(x<0)
|
|
{
|
|
x = 0;
|
|
}
|
|
if(y<0)
|
|
{
|
|
y = 0;
|
|
}
|
|
if(x + fet->GetFeatureWidth()>FGrid->GetColumns()*FGrid->GetGridSize())
|
|
{
|
|
x -= (x+fet->GetFeatureWidth()) - (FGrid->GetColumns()*FGrid->GetGridSize());
|
|
}
|
|
if(y+fet->GetFeatureHeight()>FGrid->GetRows()*FGrid->GetGridSize())
|
|
{
|
|
y-=(y+fet->GetFeatureHeight())-(FGrid->GetRows()*FGrid->GetGridSize());
|
|
}
|
|
if(x<0)
|
|
{
|
|
x = 0;
|
|
}
|
|
if(y<0)
|
|
{
|
|
y = 0;
|
|
}
|
|
|
|
ClearSelection();
|
|
Compost::FeatureInstance *fetint;
|
|
fetint=FGrid->Add(fet, x & ~(SnapMask-1), y & ~(SnapMask-1)); // & ~(SnapMask-1));
|
|
|
|
fetint->StatFlags|=FIF_SELECTED;
|
|
AddCommand *addcom=new AddCommand(fetint,this);
|
|
UndoMan.AddCommand(addcom);
|
|
SetDrawFlags(fetint);
|
|
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
void CImageGrinderDoc::AddFeature(Compost::Feature *fet)
|
|
{
|
|
AddFeature(fet,NewPlacePoint.x,NewPlacePoint.y);
|
|
CPoint offset;
|
|
|
|
offset.x=(int)((rand()*20)/RAND_MAX)-10;
|
|
offset.y=(int)((rand()*20)/RAND_MAX)-10;
|
|
|
|
NewPlacePoint+=offset;
|
|
}
|
|
|
|
void CImageGrinderDoc::OffsetSelection(int xp, int yp)
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
{
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
int x,y,tx,ty;
|
|
x=(*FList)[CurFet]->feature_x_pos;
|
|
y=(*FList)[CurFet]->feature_z_pos;
|
|
x+=xp;
|
|
y+=yp;
|
|
tx=(*FList)[CurFet]->texture_x_pos;
|
|
ty=(*FList)[CurFet]->texture_z_pos;
|
|
tx-=xp;
|
|
ty-=yp;
|
|
|
|
Compost::Feature *fet=(*FList)[CurFet]->feature;
|
|
|
|
if(x<0) x=0;
|
|
if(y<0) y=0;
|
|
if(x+fet->GetFeatureWidth()>FGrid->GetColumns()*FGrid->GetGridSize())
|
|
{
|
|
x-=(x+fet->GetFeatureWidth())-(FGrid->GetColumns()*FGrid->GetGridSize());
|
|
tx+=(x+fet->GetFeatureWidth())-(FGrid->GetColumns()*FGrid->GetGridSize());
|
|
}
|
|
|
|
if(y+fet->GetFeatureHeight()>FGrid->GetRows()*FGrid->GetGridSize())
|
|
{
|
|
y-=(y+fet->GetFeatureHeight())-(FGrid->GetRows()*FGrid->GetGridSize());
|
|
ty+=(y+fet->GetFeatureHeight())-(FGrid->GetRows()*FGrid->GetGridSize());
|
|
}
|
|
|
|
int nx,ny,dx,dy;
|
|
nx=(x + (SnapMask>>1)) & ~(SnapMask-1);
|
|
dx=nx-x;
|
|
x=nx;
|
|
tx-=dx;
|
|
|
|
ny=(y + (SnapMask>>1)) & ~(SnapMask-1);
|
|
dy=ny-y;
|
|
y=ny;
|
|
ty-=dy;
|
|
|
|
|
|
(*FList)[CurFet]->feature_x_pos = x;
|
|
(*FList)[CurFet]->feature_z_pos = y;
|
|
|
|
if((*FList)[CurFet]->StatFlags&FIF_WSTEXTURE)
|
|
{
|
|
(*FList)[CurFet]->texture_x_pos = tx;
|
|
(*FList)[CurFet]->texture_z_pos = ty;
|
|
}
|
|
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
}
|
|
FGrid->LoadGridFromUnique();
|
|
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
|
|
|
|
|
|
void CImageGrinderDoc::NewSelection(Compost::FeatureInstance *fet)
|
|
{
|
|
if(IsLocked(fet)) return;
|
|
ClearSelection();
|
|
AddSelection(fet);
|
|
UpdateAllViews(NULL);
|
|
}
|
|
|
|
void CImageGrinderDoc::AddSelection(Compost::FeatureInstance *fet)
|
|
{
|
|
if(IsLocked(fet)) return;
|
|
fet->StatFlags|=FIF_SELECTED;
|
|
((Compost::Tool_Feature *)fet->feature)->StatFlags|=FF_HIGHLIGHTED;
|
|
SelectGroupMembers(fet);
|
|
}
|
|
|
|
void CImageGrinderDoc::SubSelection(Compost::FeatureInstance *fet)
|
|
{
|
|
fet->StatFlags&=~FIF_SELECTED;
|
|
DeSelectGroupMembers(fet);
|
|
}
|
|
|
|
void CImageGrinderDoc::NewSelection(CRect &rct)
|
|
{
|
|
ClearSelection();
|
|
AddSelection(rct);
|
|
}
|
|
|
|
void CImageGrinderDoc::AddSelection(CRect &rct)
|
|
{
|
|
int i;
|
|
Stuff::DynamicArrayOf<Compost::FeatureInstance*> list;
|
|
|
|
FGrid->ShootRectangle(list,(unsigned short)rct.left,(unsigned short)rct.top,rct.Width(),rct.Height());
|
|
|
|
|
|
for(i=0;i<list.GetLength();i++)
|
|
AddSelection(list[i]);
|
|
}
|
|
|
|
void CImageGrinderDoc::SubSelection(CRect &rct)
|
|
{
|
|
int i;
|
|
Stuff::DynamicArrayOf<Compost::FeatureInstance*> list;
|
|
|
|
FGrid->ShootRectangle(list,(unsigned short)rct.left,(unsigned short)rct.top,rct.Width(),rct.Height());
|
|
|
|
|
|
for(i=0;i<list.GetLength();i++)
|
|
SubSelection(list[i]);
|
|
}
|
|
|
|
void CImageGrinderDoc::NewSelection(CPoint &pnt)
|
|
{
|
|
ClearSelection();
|
|
ClearHL();
|
|
AddSelection(pnt);
|
|
}
|
|
|
|
void CImageGrinderDoc::AddSelection(CPoint &pnt)
|
|
{
|
|
|
|
int i,depth;
|
|
depth=FGrid->ShootRay((unsigned short)pnt.x,(unsigned short)pnt.y);
|
|
if(depth<=1) return;
|
|
|
|
for(i=depth-1;
|
|
i>0 && (IsSelected(FGrid->GetCollectedNr(i)) ||
|
|
!(FGrid->GetCollectedNr(i)->feature->GetFeatureWidth()<FGrid->GetColumns()*FGrid->GetGridSize() &&
|
|
FGrid->GetCollectedNr(i)->feature->GetFeatureHeight()<FGrid->GetRows()*FGrid->GetGridSize()))
|
|
;i--);
|
|
|
|
if(i>0)
|
|
{
|
|
AddSelection(FGrid->GetCollectedNr(i));
|
|
}
|
|
}
|
|
|
|
void CImageGrinderDoc::SubSelection(CPoint &pnt)
|
|
{
|
|
|
|
int selfet,depth;
|
|
depth=FGrid->ShootRay((unsigned short)pnt.x,(unsigned short)pnt.y);
|
|
if(depth<=1) return;
|
|
|
|
for(selfet=1;selfet<depth && !IsSelected(FGrid->GetCollectedNr(selfet));selfet++);
|
|
|
|
if(selfet<depth)
|
|
{
|
|
SubSelection(FGrid->GetCollectedNr(selfet));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void CImageGrinderDoc::SelectionByList(CPoint &pnt)
|
|
{
|
|
if(FGrid->ShootRay((unsigned short)pnt.x,(unsigned short)pnt.y)<=1) return;
|
|
CDepthDiag dlg;
|
|
|
|
dlg.DoModal(this,pnt);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CImageGrinderDoc::SetDrawFlags(Compost::Feature *fet)
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->feature==fet)
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
}
|
|
|
|
void CImageGrinderDoc::SetDrawFlags(Compost::FeatureInstance *fetI)
|
|
{
|
|
|
|
int xl,yl,r,c,w,h;
|
|
int x,y;
|
|
x=fetI->feature_x_pos;
|
|
y=fetI->feature_z_pos;
|
|
Compost::Feature *fet=fetI->feature;
|
|
w=fet->GetFeatureWidth();
|
|
h=fet->GetFeatureHeight();
|
|
|
|
for(yl=y;yl<=y+h;yl+=FGrid->GetGridSize()<h?FGrid->GetGridSize():h)
|
|
for(xl=x;xl<=x+w;xl+=FGrid->GetGridSize()<w?FGrid->GetGridSize():w)
|
|
{
|
|
r=yl>>FGrid->GetGridShift(); c=xl>>FGrid->GetGridShift();
|
|
if(c<FGrid->GetColumns() && r<FGrid->GetRows())
|
|
{
|
|
UpdateList[FGrid->GetColumns()*r+c]=true;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::SetDrawFlags()
|
|
{
|
|
int gsqu=FGrid->GetRows()*FGrid->GetColumns();
|
|
for(int i=0;i<gsqu;i++) UpdateList[i]=true;
|
|
}
|
|
|
|
void CImageGrinderDoc::DeleteSelected()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count, CurFet;
|
|
UndoCommand *cmd=NULL;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
do
|
|
{
|
|
for(CurFet=0;CurFet<count && !((*FList)[CurFet]->StatFlags&FIF_SELECTED);CurFet++);
|
|
|
|
if(CurFet<count)
|
|
{
|
|
if(FPool->GetFeaturePosition((*FList)[CurFet]->feature)==0) return;
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
DeleteCommand *dcom=new DeleteCommand((*FList)[CurFet],this);
|
|
if(cmd==NULL) cmd=dcom; else cmd->Attach(dcom);
|
|
FGrid->Remove((*FList)[CurFet]);
|
|
}
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
}
|
|
while(CurFet<count);
|
|
|
|
if(cmd)
|
|
{
|
|
UndoMan.Clear();
|
|
UndoMan.AddCommand(cmd);
|
|
}
|
|
FGrid->RedoFeaturePosition();
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
BOOL CImageGrinderDoc::OnOpenDocument(LPCTSTR lpszPathName)
|
|
{
|
|
/*
|
|
if (!CDocument::OnOpenDocument(lpszPathName))
|
|
return FALSE;
|
|
*/
|
|
CloseCurrent();
|
|
OpenText(lpszPathName);
|
|
PostLoadInit();
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CImageGrinderDoc::OnSaveDocument(LPCTSTR lpszPathName)
|
|
{
|
|
SaveAs(lpszPathName);
|
|
SetModifiedFlag(FALSE);
|
|
// return CDocument::OnSaveDocument(lpszPathName);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool CImageGrinderDoc::InSelectedRegion(CPoint &pnt)
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
{
|
|
CRect rct;
|
|
rct.left=(*FList)[CurFet]->feature_x_pos;
|
|
rct.top=(*FList)[CurFet]->feature_z_pos;
|
|
rct.right=(*FList)[CurFet]->feature_x_pos+(*FList)[CurFet]->feature->GetFeatureWidth();
|
|
rct.bottom=(*FList)[CurFet]->feature_z_pos+(*FList)[CurFet]->feature->GetFeatureHeight();
|
|
|
|
if(rct.PtInRect(pnt)==TRUE)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
void CImageGrinderDoc::OnFileExportTgafiles()
|
|
{
|
|
CString ImgName, BaseName, GridName;
|
|
GridName=GetTitle();
|
|
BaseName=GridName.Left(GridName.ReverseFind('.'));
|
|
|
|
|
|
Verify((FGrid->GetRows()%8)==0);
|
|
Verify((FGrid->GetColumns()%8)==0);
|
|
int ZoneCountX = FGrid->GetColumns()/8;
|
|
int ZoneCountY = FGrid->GetRows()/8;
|
|
|
|
|
|
|
|
CString DirName = Compost::TexturePool::Instance->GetTexturePath();
|
|
DirName=DirName.Left(DirName.ReverseFind('\\'));
|
|
DirName+="\\Maps\\";
|
|
DirName+=BaseName;
|
|
|
|
if(!gos_DoesFileExist(DirName))
|
|
gos_CreateDirectory(DirName);
|
|
|
|
Image imgseg,totimg,savimg;
|
|
|
|
imgseg.CreateBlank(FGrid->GetGridSize(),FGrid->GetGridSize(), ITYPE_RGB, 32);
|
|
imgseg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
totimg.CreateBlank(FGrid->GetColumns()*FGrid->GetGridSize(), FGrid->GetRows()*FGrid->GetGridSize(), ITYPE_RGB, 32);
|
|
totimg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
// GridName=dlg.GetPathName();
|
|
// BaseName=GridName.Left(GridName.ReverseFind('.'));
|
|
|
|
int zrow, zcol;
|
|
|
|
for(zrow=0;zrow<ZoneCountY;zrow++)
|
|
{
|
|
for(zcol=0;zcol<ZoneCountX;zcol++)
|
|
{
|
|
CString subDirName;
|
|
|
|
subDirName.Format("%s\\%c%c", DirName, 'A'+ZoneCountY-zrow-1, 'A'+ZoneCountX-zcol-1);
|
|
|
|
if(!gos_DoesFileExist(subDirName))
|
|
{
|
|
gos_CreateDirectory(subDirName);
|
|
}
|
|
int row, col;
|
|
|
|
for(row=0;row<8;row++)
|
|
{
|
|
for(col=0;col<8;col++)
|
|
{
|
|
|
|
BYTE *imgdat=imgseg.Lock();
|
|
|
|
if(!FGrid->ComposeGrid(row+zrow*8, col+zcol*8, imgdat))
|
|
{
|
|
for(int i=0;i<FGrid->GetGridSize()*FGrid->GetGridSize()*4;i++)
|
|
{
|
|
imgdat[i]=i%FGrid->GetGridSize();
|
|
}
|
|
}
|
|
|
|
imgseg.UnLock();
|
|
totimg.Blt(
|
|
imgseg,
|
|
(col+zcol*8)*FGrid->GetGridSize(),
|
|
(row+zrow*8)*FGrid->GetGridSize(),
|
|
CRect(0,0,FGrid->GetGridSize(),FGrid->GetGridSize())
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
{
|
|
int iw = totimg.GetWidth()/(2*ZoneCountX);
|
|
int ih = totimg.GetHeight()/(2*ZoneCountY);
|
|
int i, j;
|
|
|
|
for(j=0;j<2;j++)
|
|
{
|
|
for(i=0;i<2;i++)
|
|
{
|
|
imgseg.Blt(
|
|
totimg,
|
|
CRect(
|
|
0,
|
|
0,
|
|
imgseg.GetWidth(),
|
|
imgseg.GetHeight()
|
|
),
|
|
CRect(
|
|
zcol*8*FGrid->GetGridSize()+i*iw,
|
|
zrow*8*FGrid->GetGridSize()+j*ih,
|
|
zcol*8*FGrid->GetGridSize()+(i+1)*iw,
|
|
zrow*8*FGrid->GetGridSize()+(j+1)*ih
|
|
)
|
|
);
|
|
|
|
ImgName.Format("%s\\%c%c\\%s_%c%c_1_%02X%02X.tga",
|
|
DirName,
|
|
'A'+ZoneCountY-zrow-1,
|
|
'A'+ZoneCountX-zcol-1,
|
|
BaseName,
|
|
'A'+ZoneCountY-zrow-1,
|
|
'A'+ZoneCountX-zcol-1,
|
|
i,
|
|
j
|
|
);
|
|
|
|
savimg=imgseg;
|
|
savimg.MakeRGB24();
|
|
savimg.SaveTga((char *)(LPCSTR)ImgName);
|
|
}
|
|
}
|
|
}
|
|
|
|
imgseg.Blt(
|
|
totimg,
|
|
CRect(
|
|
0,
|
|
0,
|
|
imgseg.GetWidth(),
|
|
imgseg.GetHeight()
|
|
),
|
|
CRect(
|
|
zcol*8*FGrid->GetGridSize(),
|
|
zrow*8*FGrid->GetGridSize(),
|
|
zcol*8*FGrid->GetGridSize() + (totimg.GetWidth()/ZoneCountX),
|
|
zrow*8*FGrid->GetGridSize() + (totimg.GetHeight()/ZoneCountY)
|
|
)
|
|
);
|
|
|
|
ImgName.Format("%s\\%c%c\\%s_%c%c_0_0000.Tga",
|
|
DirName,
|
|
'A'+ZoneCountY-zrow-1,
|
|
'A'+ZoneCountX-zcol-1,
|
|
BaseName,
|
|
'A'+ZoneCountY-zrow-1,
|
|
'A'+ZoneCountX-zcol-1
|
|
);
|
|
|
|
savimg=imgseg;
|
|
savimg.MakeRGB24();
|
|
savimg.SaveTga((char *)(LPCSTR)ImgName);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::OnFileExportImagedata()
|
|
{
|
|
Compost::Feature_Texture *FTexture;
|
|
Stuff::TableIteratorOf<Compost::Feature_Texture*, int> imageTableIterator(Compost::TexturePool::Instance->GetImageTable());
|
|
|
|
CString tgaFileName, bidFileName;
|
|
while(NULL!=(FTexture = imageTableIterator.ReadAndNext()))
|
|
{
|
|
if(FTexture->GetName() && (FTexture->dataSize > 0))
|
|
{
|
|
tgaFileName = Compost::TexturePool::Instance->GetTexturePath();
|
|
tgaFileName += "\\";
|
|
tgaFileName += *(FTexture->GetName());
|
|
tgaFileName += ".tga";
|
|
|
|
bidFileName = Compost::TexturePool::Instance->GetTexturePath();
|
|
bidFileName += "\\";
|
|
bidFileName += *(FTexture->GetName());
|
|
bidFileName += ".bid";
|
|
|
|
HGOSFILE hfile;
|
|
gos_OpenFile(&hfile, bidFileName, READWRITE);
|
|
gos_WriteFile(hfile, FTexture->data, FTexture->dataSize);
|
|
gos_CloseFile(hfile);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CImageGrinderDoc::OnFileExportSingletga()
|
|
{
|
|
CString ImgName,BaseName,GridName;
|
|
GridName=GetTitle();
|
|
BaseName=GridName.Left(GridName.ReverseFind('.'));
|
|
|
|
CFileDialog dlg(FALSE,"Tga",BaseName+".tga",NULL,"Targa Images (*.tga)|*.tga||",NULL);
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
Image imgseg,totimg;
|
|
|
|
|
|
imgseg.CreateBlank(FGrid->GetGridSize(),FGrid->GetGridSize(),ITYPE_RGB,32);
|
|
imgseg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
totimg.CreateBlank(FGrid->GetRows()*FGrid->GetGridSize(),FGrid->GetColumns()*FGrid->GetGridSize(),ITYPE_RGB,24);
|
|
totimg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
|
|
int row,col;
|
|
for(row=0;row<FGrid->GetRows();row++)
|
|
for(col=0;col<FGrid->GetColumns();col++)
|
|
{
|
|
BYTE *imgdat=imgseg.Lock();
|
|
|
|
if(!FGrid->ComposeGrid(row,col,imgdat))
|
|
for(int i=0;i<FGrid->GetGridSize()*FGrid->GetGridSize()*3;i++) imgdat[i]=i%FGrid->GetGridSize();
|
|
|
|
imgseg.UnLock();
|
|
totimg.Blt(imgseg,col*FGrid->GetGridSize(),row*FGrid->GetGridSize(),CRect(0,0,FGrid->GetGridSize(),FGrid->GetGridSize()));
|
|
}
|
|
|
|
|
|
imgseg.Blt(totimg, CRect(0,0,imgseg.GetWidth(),imgseg.GetHeight()) ,
|
|
CRect(0,0,totimg.GetWidth(),totimg.GetHeight()));
|
|
|
|
totimg.SaveTga((char *)(LPCSTR)dlg.GetPathName());
|
|
}
|
|
|
|
}
|
|
|
|
bool CImageGrinderDoc::IsSelected(Compost::FeatureInstance *fetint)
|
|
{
|
|
return fetint->StatFlags&FIF_SELECTED?true:false;
|
|
|
|
}
|
|
|
|
bool CImageGrinderDoc::IsSelected(Compost::Tool_Feature *fet)
|
|
{
|
|
if(fet==NULL) return false;
|
|
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED && (*FList)[CurFet]->feature==fet)
|
|
return true;
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
Compost::FeatureInstance *CImageGrinderDoc::GetTopFeature(CPoint &pnt)
|
|
{
|
|
|
|
int selfet,depth;
|
|
depth=FGrid->ShootRay((unsigned short)pnt.x,(unsigned short)pnt.y);
|
|
if(depth<=1) return NULL;
|
|
|
|
for(selfet=1;selfet<depth && !IsSelected(FGrid->GetCollectedNr(selfet)) && !IsLocked(FGrid->GetCollectedNr(selfet));selfet++);
|
|
|
|
return FGrid->GetCollectedNr(depth-1);
|
|
}
|
|
|
|
Compost::FeatureInstance *CImageGrinderDoc::GetTopSelected(CPoint &pnt)
|
|
{
|
|
|
|
int selfet,depth;
|
|
depth=FGrid->ShootRay((unsigned short)pnt.x,(unsigned short)pnt.y);
|
|
if(depth<=1) return NULL;
|
|
|
|
for(selfet=1;selfet<depth && !IsSelected(FGrid->GetCollectedNr(selfet)) && !IsLocked(FGrid->GetCollectedNr(selfet));selfet++);
|
|
|
|
if(selfet<depth)
|
|
{
|
|
return FGrid->GetCollectedNr(selfet);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
DWORD CImageGrinderDoc::IsOnScaleHandle(CPoint &pnt,Compost::FeatureInstance *fetint)
|
|
{
|
|
if(!fetint)
|
|
return HF_NONE;
|
|
if(pnt.x<fetint->feature_x_pos || pnt.y<fetint->feature_z_pos ||
|
|
pnt.x>=(fetint->feature->GetFeatureWidth()+fetint->feature_x_pos) ||
|
|
pnt.y>=(fetint->feature->GetFeatureHeight()+fetint->feature_z_pos) )
|
|
return HF_NONE;
|
|
|
|
DWORD flg=HF_NONE;
|
|
|
|
if((pnt.x-fetint->feature_x_pos)<HANDLESIZE)
|
|
flg|=HF_LEFT;
|
|
else
|
|
if(((fetint->feature->GetFeatureWidth()+fetint->feature_x_pos)-pnt.x)<HANDLESIZE)
|
|
flg|=HF_RIGHT;
|
|
|
|
if((pnt.y-fetint->feature_z_pos)<HANDLESIZE)
|
|
flg|=HF_TOP;
|
|
else
|
|
if(((fetint->feature->GetFeatureHeight()+fetint->feature_z_pos)-pnt.y)<HANDLESIZE)
|
|
flg|=HF_BOTTOM;
|
|
|
|
return flg;
|
|
}
|
|
|
|
bool CImageGrinderDoc::IsOnSelectHandle(CPoint &pnt,Compost::FeatureInstance *fetint)
|
|
{
|
|
if(!fetint)
|
|
return false;
|
|
|
|
if(pnt.x<fetint->feature_x_pos || pnt.y<fetint->feature_z_pos ||
|
|
pnt.x>=(fetint->feature->GetFeatureWidth()+fetint->feature_x_pos) ||
|
|
pnt.y>=(fetint->feature->GetFeatureHeight()+fetint->feature_z_pos) )
|
|
return false;
|
|
|
|
DWORD flg=HF_NONE;
|
|
CRect rct(-HANDLESIZE/2,-HANDLESIZE/2,HANDLESIZE/2,HANDLESIZE/2);
|
|
CPoint ct(fetint->feature_x_pos+fetint->feature->GetFeatureWidth()/2,fetint->feature_z_pos+fetint->feature->GetFeatureHeight()/2);
|
|
rct.OffsetRect(ct);
|
|
return rct.PtInRect(pnt)?true:false;
|
|
}
|
|
|
|
bool CImageGrinderDoc::IsOnSelectHandle(CPoint &pnt)
|
|
{
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED && IsOnSelectHandle(pnt,(*FList)[CurFet]))
|
|
{
|
|
NewSelection((*FList)[CurFet]);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
void CImageGrinderDoc::MakeSelectedUnique()
|
|
{
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
MakeUnique((*FList)[CurFet]);
|
|
|
|
}
|
|
|
|
CString CImageGrinderDoc::MakeNameUnique(CString &istr)
|
|
{
|
|
|
|
|
|
if(!InList(istr))
|
|
{
|
|
return istr;
|
|
}
|
|
else
|
|
{
|
|
CString bstr;
|
|
|
|
if(istr.FindOneOf("0123456789")==-1)
|
|
bstr=istr;
|
|
else
|
|
bstr=istr.Left(istr.FindOneOf("0123456789"));
|
|
|
|
int num=0;
|
|
CString fstr;
|
|
do
|
|
{
|
|
fstr.Format("%s%04i",bstr,num);
|
|
num++;
|
|
}
|
|
while(InList(fstr));
|
|
|
|
return fstr;
|
|
}
|
|
}
|
|
|
|
bool CImageGrinderDoc::InList(CString &str)
|
|
{
|
|
|
|
ASSERT(FPool!=NULL && FGrid!=NULL);
|
|
|
|
Compost::Feature *Fet;
|
|
|
|
int itmtot=FPool->GetNumberOfFeatures();
|
|
for(int i=1;i<itmtot;i++)
|
|
{
|
|
Fet=FPool->GetFeatureNumber(i);
|
|
CString tstr((char *)(*(Fet->GetName())));
|
|
if(tstr.CompareNoCase(str)==0) return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CImageGrinderDoc::MakeUnique(Compost::FeatureInstance *fetint)
|
|
{
|
|
|
|
if(FGrid->CountFeature(fetint->feature)>1)
|
|
{
|
|
|
|
Compost::Tool_Feature *TmpFet=new Compost::Tool_Feature;
|
|
Register_Pointer(TmpFet);
|
|
*TmpFet=*((Compost::Tool_Feature *)fetint->feature);
|
|
|
|
TmpFet->SetName((LPCSTR)MakeNameUnique(CString(*(fetint->feature->GetName()))));
|
|
FPool->Add(TmpFet);
|
|
|
|
FGrid->Add(TmpFet, fetint->feature_x_pos,fetint->feature_z_pos);
|
|
FGrid->Remove(fetint);
|
|
|
|
SetModifiedFlag(TRUE);
|
|
UpdateAllViews(NULL);
|
|
}
|
|
}
|
|
|
|
void CImageGrinderDoc::CloneSelection()
|
|
{
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
{
|
|
Clone((*FList)[CurFet]);
|
|
}
|
|
|
|
}
|
|
|
|
Compost::FeatureInstance *CImageGrinderDoc::Clone(Compost::FeatureInstance *fetint)
|
|
{
|
|
Compost::FeatureInstance *newfet;
|
|
newfet=FGrid->Add(fetint->feature, fetint->feature_x_pos,fetint->feature_z_pos);
|
|
SetModifiedFlag(TRUE);
|
|
|
|
|
|
return newfet;
|
|
}
|
|
|
|
bool CImageGrinderDoc::IsHLFeature(Compost::FeatureInstance *fetint)
|
|
{
|
|
return ((Compost::Tool_Feature *)fetint->feature)->StatFlags&FF_HIGHLIGHTED?true:false;
|
|
}
|
|
|
|
void CImageGrinderDoc::AddHLFeature(Compost::Tool_Feature *fet)
|
|
{
|
|
fet->StatFlags|=FF_HIGHLIGHTED;
|
|
}
|
|
|
|
void CImageGrinderDoc::SubHLFeature(Compost::Tool_Feature *fet)
|
|
{
|
|
fet->StatFlags&=~FF_HIGHLIGHTED;
|
|
}
|
|
|
|
void CImageGrinderDoc::LockFeature(Compost::FeatureInstance *fet)
|
|
{
|
|
fet->StatFlags|=FIF_LOCKED;
|
|
fet->StatFlags&=~FIF_SELECTED;
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::LockSelection()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
LockFeature((*FList)[CurFet]);
|
|
|
|
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::UnLockFeature(Compost::FeatureInstance *fet)
|
|
{
|
|
fet->StatFlags&=~FIF_LOCKED;
|
|
|
|
}
|
|
|
|
bool CImageGrinderDoc::IsLocked(Compost::FeatureInstance *fet)
|
|
{
|
|
if(fet->StatFlags&FIF_LOCKED)
|
|
return true;
|
|
else
|
|
return false;
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::ClearHL()
|
|
{
|
|
int count;
|
|
int CurFet;
|
|
|
|
|
|
count=FPool->GetNumberOfFeatures();
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
{
|
|
Compost::Tool_Feature *temfet=((Compost::Tool_Feature *)FPool->GetFeatureNumber(CurFet));
|
|
temfet->StatFlags&=~FF_HIGHLIGHTED;
|
|
}
|
|
}
|
|
|
|
void CImageGrinderDoc::UnLockAll()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
int CurFet;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
UnLockFeature((*FList)[CurFet]);
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::ClearSelection()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
int CurFet;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
SubSelection((*FList)[CurFet]);
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::MakeWorldSpaceTexture(Compost::FeatureInstance *fet)
|
|
{
|
|
fet->StatFlags|=FIF_WSTEXTURE;
|
|
}
|
|
|
|
void CImageGrinderDoc::MakeLocalTexture(Compost::FeatureInstance *fet)
|
|
{
|
|
fet->StatFlags&=~FIF_WSTEXTURE;
|
|
}
|
|
|
|
void CImageGrinderDoc::SetFlagOnSelection(UINT flg)
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
(*FList)[CurFet]->StatFlags|=flg;
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::ClearFlagOnSelection(UINT flg)
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
(*FList)[CurFet]->StatFlags&=~flg;
|
|
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::GroupSelection()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
int NewTag=GetAvailableTag();
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
(*FList)[CurFet]->Tag=NewTag;
|
|
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::UnGroupSelection()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
(*FList)[CurFet]->Tag=0;
|
|
|
|
}
|
|
|
|
int CImageGrinderDoc::GetAvailableTag()
|
|
{
|
|
int Tag;
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
Tag=0;
|
|
do
|
|
{
|
|
Tag++;
|
|
for(CurFet=0;CurFet<count && (*FList)[CurFet]->Tag!=Tag;CurFet++);
|
|
}
|
|
while(CurFet<count);
|
|
|
|
if(Tag>=256) return 0;
|
|
else
|
|
return Tag;
|
|
}
|
|
|
|
void CImageGrinderDoc::SelectGroupMembers(Compost::FeatureInstance *fet)
|
|
{
|
|
if(fet->Tag==0) return;
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if(fet->Tag==(*FList)[CurFet]->Tag)
|
|
{
|
|
(*FList)[CurFet]->StatFlags|=FIF_SELECTED;
|
|
((Compost::Tool_Feature *)(*FList)[CurFet]->feature)->StatFlags|=FF_HIGHLIGHTED;
|
|
}
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::DeSelectGroupMembers(Compost::FeatureInstance *fet)
|
|
{
|
|
if(fet->Tag==0) return;
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if(fet->Tag==(*FList)[CurFet]->Tag)
|
|
(*FList)[CurFet]->StatFlags&=~FIF_SELECTED;
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::OnFileMergefeatures()
|
|
{
|
|
CFileDialog dlg(TRUE,NULL,NULL,NULL,"Image Gringer files (*.fgd)|*.fgd||");
|
|
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
Compost::FeaturePool *TmpFPool;
|
|
|
|
|
|
TmpFPool = new Compost::FeaturePool();
|
|
Register_Pointer(TmpFPool);
|
|
|
|
|
|
Check_Object(Stuff::FileStreamManager::Instance);
|
|
Stuff::FileStream *fstr=new Stuff::FileStream;
|
|
Register_Object(fstr);
|
|
fstr->Open(dlg.GetPathName(),Stuff::FileStream::ReadOnly);
|
|
TmpFPool->LoadIndex(fstr);
|
|
// fstr->Close();
|
|
Unregister_Object(fstr);
|
|
delete fstr;
|
|
|
|
int i, fettot=TmpFPool->GetNumberOfFeatures();
|
|
|
|
for(i=0;i<fettot;i++)
|
|
{
|
|
Compost::Tool_Feature *TmpFet=new Compost::Tool_Feature;
|
|
Register_Pointer(TmpFet);
|
|
|
|
*TmpFet=*((Compost::Tool_Feature *)TmpFPool->GetFeatureNumber(i));
|
|
FPool->Add(TmpFet);
|
|
}
|
|
|
|
Unregister_Pointer(TmpFPool);
|
|
delete TmpFPool;
|
|
|
|
UpdateAllViews(NULL);
|
|
SetModifiedFlag(TRUE);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::RemoveFeature(Compost::Tool_Feature *fet)
|
|
{
|
|
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
|
|
int CurFet;
|
|
|
|
do
|
|
{
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
for(CurFet=0;CurFet<count && ((*FList)[CurFet]->feature!=fet);CurFet++);
|
|
|
|
if(CurFet<count)
|
|
{
|
|
if(FPool->GetFeaturePosition((*FList)[CurFet]->feature)==0) return;
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
FGrid->Remove((*FList)[CurFet]);
|
|
}
|
|
|
|
}
|
|
while(CurFet<count);
|
|
|
|
FGrid->RedoFeaturePosition();
|
|
|
|
|
|
|
|
|
|
FPool->Remove(fet);
|
|
delete fet;
|
|
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
|
|
|
|
void CImageGrinderDoc::MakeSelectionWorldSpaceTexture()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED && !((*FList)[CurFet]->StatFlags&FIF_WSTEXTURE))
|
|
{
|
|
MakeWorldSpaceTexture((*FList)[CurFet]);
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
}
|
|
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
void CImageGrinderDoc::MakeSelectionLocalTexture()
|
|
{
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED && (*FList)[CurFet]->StatFlags&FIF_WSTEXTURE)
|
|
{
|
|
MakeLocalTexture((*FList)[CurFet]);
|
|
SetDrawFlags((*FList)[CurFet]);
|
|
}
|
|
SetModifiedFlag();
|
|
}
|
|
|
|
int CStringCompare( const void *arg1, const void *arg2 )
|
|
{
|
|
|
|
return ((CString *)arg1)->CompareNoCase(*((CString *)arg2));
|
|
}
|
|
|
|
void CImageGrinderDoc::OnFileExportUsedimagelist()
|
|
{
|
|
CString *name_list;
|
|
int *used_count;
|
|
int image_count;
|
|
|
|
Compost::Feature_Texture *FTexture;
|
|
Stuff::TableIteratorOf<Compost::Feature_Texture*, int> imageTableIterator(Compost::TexturePool::Instance->GetImageTable());
|
|
|
|
image_count=imageTableIterator.GetSize();
|
|
name_list=new CString[image_count];
|
|
used_count=new int[image_count];
|
|
|
|
imageTableIterator.First();
|
|
{
|
|
int cpos=0;
|
|
while(NULL!=(FTexture=imageTableIterator.ReadAndNext()))
|
|
{
|
|
name_list[cpos]=(char *)(*(FTexture->GetName()));
|
|
used_count[cpos]=0;
|
|
cpos++;
|
|
}
|
|
|
|
Verify(cpos==image_count);
|
|
}
|
|
|
|
qsort(name_list,image_count,sizeof(CString),CStringCompare);
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
int CurFet;
|
|
Stuff::MString *mstr;
|
|
Compost::Tool_Feature *feature = NULL;
|
|
Compost::Feature_Texture *fTexture = NULL;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
{
|
|
feature=((Compost::Tool_Feature *)(*FList)[CurFet]->feature);
|
|
Check_Pointer(feature);
|
|
fTexture = feature->GetFeatureTexture();
|
|
Check_Object(fTexture);
|
|
|
|
int tpos;
|
|
|
|
mstr = fTexture->GetName();
|
|
for(tpos=0;tpos<image_count && name_list[tpos].CompareNoCase((char *)*mstr);tpos++);
|
|
if(tpos>=image_count) PAUSE(("Texture Count Problem"));
|
|
used_count[tpos]++;
|
|
|
|
fTexture = feature->GetFeatureMask0();
|
|
if(fTexture != NULL)
|
|
{
|
|
mstr = fTexture->GetName();
|
|
for(tpos=0;tpos<image_count && name_list[tpos].CompareNoCase((char *)*mstr);tpos++);
|
|
if(tpos>=image_count) PAUSE(("Texture Count Problem"));
|
|
used_count[tpos]++;
|
|
}
|
|
|
|
fTexture = feature->GetFeatureMask1();
|
|
if(fTexture != NULL)
|
|
{
|
|
mstr = fTexture->GetName();
|
|
for(tpos=0;tpos<image_count && name_list[tpos].CompareNoCase((char *)*mstr);tpos++);
|
|
if(tpos>=image_count) PAUSE(("Texture Count Problem"));
|
|
used_count[tpos]++;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
CString BaseName, GridName;
|
|
GridName=GetTitle();
|
|
BaseName=GridName.Left(GridName.ReverseFind('.'));
|
|
|
|
CFileDialog dlg(FALSE,"bat",BaseName+"BidCopy.bat",NULL,"batch files (*.bat)|*.bat||",NULL);
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
FILE *fl;
|
|
fl=fopen(dlg.GetPathName(),"w");
|
|
Verify(fl);
|
|
if(fl)
|
|
{
|
|
for(int i=0;i<image_count;i++)
|
|
if(used_count[i]>0)
|
|
{
|
|
fprintf(fl,"copy %s.bid %%1 /y\n",name_list[i]);
|
|
fprintf(fl,"copy %s.tga %%2 /y\n",name_list[i]);
|
|
}
|
|
fclose(fl);
|
|
}
|
|
}
|
|
delete used_count;
|
|
// delete name_list;
|
|
}
|
|
|
|
void CImageGrinderDoc::SaveAs(LPCTSTR lpszPathName,int xoffset,int zoffset)
|
|
{
|
|
SaveText(lpszPathName,xoffset,zoffset);
|
|
|
|
CString ImgName, BaseName, GridName;
|
|
GridName=lpszPathName;
|
|
BaseName=GridName.Left(GridName.ReverseFind('.'));
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::ExportMaterialMap(CString &path)
|
|
{
|
|
CString ImgName,DirName=path;
|
|
|
|
|
|
Verify((FGrid->GetRows()%8)==0);
|
|
Verify((FGrid->GetColumns()%8)==0);
|
|
int ZoneCountX = FGrid->GetColumns()/8;
|
|
int ZoneCountY = FGrid->GetRows()/8;
|
|
|
|
|
|
Image imgseg,totimg,savimg;
|
|
|
|
imgseg.CreateBlank(256,256,ITYPE_RGB,32);
|
|
imgseg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
totimg.CreateBlank(8*256,8*256,ITYPE_RGB,32);
|
|
totimg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
savimg.CreateBlank(256,256,ITYPE_INDEXED,8);
|
|
savimg.MakeGrayscalePalette();
|
|
|
|
|
|
int zrow, zcol;
|
|
|
|
for(zrow=0;zrow<ZoneCountY;zrow++)
|
|
{
|
|
for(zcol=0;zcol<ZoneCountX;zcol++)
|
|
{
|
|
|
|
int row, col;
|
|
|
|
for(row=0;row<8;row++)
|
|
{
|
|
for(col=0;col<8;col++)
|
|
{
|
|
|
|
BYTE *imgdat=imgseg.Lock();
|
|
|
|
if(!FGrid->ComposeGrid(row+zrow*8, col+zcol*8, imgdat, 0, 2))
|
|
{
|
|
for(int i=0;i<FGrid->GetGridSize()*FGrid->GetGridSize()*4;i++)
|
|
{
|
|
imgdat[i]=i%FGrid->GetGridSize();
|
|
}
|
|
}
|
|
|
|
// imgseg.SaveTga("C:\\temp\\SourceMat1.tga");
|
|
imgseg.UnLock();
|
|
totimg.Blt(
|
|
imgseg,
|
|
(col*256),
|
|
(row*256),
|
|
CRect(0,0,256,256)
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
imgseg.BltDominantColor(
|
|
totimg,
|
|
CRect(
|
|
0,
|
|
0,
|
|
imgseg.GetWidth(),
|
|
imgseg.GetHeight()
|
|
),
|
|
CRect(
|
|
0,
|
|
0,
|
|
totimg.GetWidth(),
|
|
totimg.GetHeight()
|
|
)
|
|
);
|
|
|
|
|
|
|
|
|
|
DWORD *srcptr=(DWORD *)imgseg.Lock();
|
|
BYTE *dstptr=savimg.Lock();
|
|
int xps,yps;
|
|
BYTE colidx;
|
|
DWORD tcol;
|
|
for(yps=0;yps<imgseg.GetHeight();yps++)
|
|
for(xps=0;xps<imgseg.GetWidth();xps++)
|
|
{
|
|
tcol=srcptr[xps+yps*savimg.GetWidth()];
|
|
|
|
for(colidx=0;colidx<Compost::MaterialEntriesCount;colidx++)
|
|
{
|
|
if(Compost::MaterialEntries[colidx].color==tcol)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
Verify(colidx<Compost::MaterialEntriesCount);
|
|
|
|
dstptr[xps+yps*savimg.GetWidth()]=colidx;
|
|
}
|
|
|
|
imgseg.UnLock();
|
|
savimg.UnLock();
|
|
|
|
ImgName.Format("%s\\%c%c.Material",
|
|
DirName,
|
|
'A'+ZoneCountY-zrow-1,
|
|
'A'+ZoneCountX-zcol-1
|
|
);
|
|
|
|
savimg.SaveRaw((char *)(LPCSTR)ImgName);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
void CImageGrinderDoc::ExportSingleMaterialMap(CString &path)
|
|
{
|
|
CString ImgName,DirName=path;
|
|
|
|
|
|
Verify((FGrid->GetRows()%8)==0);
|
|
Verify((FGrid->GetColumns()%8)==0);
|
|
int ZoneCountX = FGrid->GetColumns()/8;
|
|
int ZoneCountY = FGrid->GetRows()/8;
|
|
|
|
|
|
Image imgseg,totimg;
|
|
|
|
imgseg.CreateBlank(256,256,ITYPE_RGB,32);
|
|
imgseg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
totimg.CreateBlank(1024*ZoneCountX,1024*ZoneCountY,ITYPE_RGB,32);
|
|
totimg.MaskTo(RGBMask(0xff0000,0x00ff00,0x0000ff));
|
|
|
|
int zrow, zcol;
|
|
|
|
for(zrow=0;zrow<ZoneCountY;zrow++)
|
|
{
|
|
for(zcol=0;zcol<ZoneCountX;zcol++)
|
|
{
|
|
|
|
int row, col;
|
|
|
|
for(row=0;row<8;row++)
|
|
{
|
|
for(col=0;col<8;col++)
|
|
{
|
|
|
|
BYTE *imgdat=imgseg.Lock();
|
|
|
|
if(!FGrid->ComposeGrid(row+zrow*8, col+zcol*8, imgdat, 0, 2))
|
|
{
|
|
for(int i=0;i<FGrid->GetGridSize()*FGrid->GetGridSize()*4;i++)
|
|
{
|
|
imgdat[i]=i%FGrid->GetGridSize();
|
|
}
|
|
}
|
|
|
|
// imgseg.SaveTga("C:\\temp\\SourceMat1.tga");
|
|
imgseg.UnLock();
|
|
totimg.BltDominantColor(
|
|
imgseg,
|
|
CRect(
|
|
zcol*1024+col*128,
|
|
zrow*1024+row*128,
|
|
zcol*1024+col*128+128,
|
|
zrow*1024+row*128+128
|
|
),
|
|
CRect(0,0,256,256)
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
totimg.SaveTga((char *)(LPCSTR)path);
|
|
|
|
|
|
}
|
|
|
|
|
|
CString CImageGrinderDoc::MapPath()
|
|
{
|
|
CString path = Compost::TexturePool::Instance->GetTexturePath();
|
|
path=path.Left(path.ReverseFind('\\'));
|
|
path=path.Left(path.ReverseFind('\\'));
|
|
path+="\\Maps\\";
|
|
path+=GetTitle();
|
|
path=path.Left(path.ReverseFind('.'));
|
|
return path;
|
|
}
|
|
|
|
void CImageGrinderDoc::OnFileExportMaterialmap()
|
|
{
|
|
CString path = MapPath();
|
|
|
|
if(!gos_DoesFileExist(path))
|
|
gos_CreateDirectory(path);
|
|
|
|
ExportMaterialMap(path);
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::SavePosForUndo()
|
|
{
|
|
|
|
UndoCommand *com=NULL;
|
|
|
|
|
|
const Stuff::DynamicArrayOf<Compost::FeatureInstance*> *FList;
|
|
int count;
|
|
|
|
FList=FGrid->GetUniqueFeatureInstances(count);
|
|
|
|
int CurFet;
|
|
|
|
|
|
for(CurFet=0;CurFet<count;CurFet++)
|
|
if((*FList)[CurFet]->StatFlags&FIF_SELECTED)
|
|
{
|
|
MoveCommand *mcom=new MoveCommand((*FList)[CurFet],this);
|
|
if(com==NULL) com=mcom; else com->Attach(mcom);
|
|
}
|
|
|
|
if(com!=NULL) UndoMan.AddCommand(com);
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::SaveToGame()
|
|
{
|
|
CString bname=GetTitle();
|
|
bname=bname.Left(bname.ReverseFind('.'));
|
|
SaveFgd(MapPath()+"\\"+bname+".fgd");
|
|
}
|
|
|
|
void CImageGrinderDoc::SaveIGDataToGame()
|
|
{
|
|
CString bname=GetTitle();
|
|
bname=bname.Left(bname.ReverseFind('.'));
|
|
SaveText(MapPath()+"\\"+bname+".IGData");
|
|
}
|
|
|
|
|
|
void CImageGrinderDoc::SaveFgd(LPCTSTR lpszPathName,int xoffset,int zoffset)
|
|
{
|
|
|
|
Check_Object(Stuff::FileStreamManager::Instance);
|
|
Stuff::FileStream *fstr=new Stuff::FileStream;
|
|
Register_Object(fstr);
|
|
fstr->Open(lpszPathName,Stuff::FileStream::WriteOnly);
|
|
FPool->SaveIndex(fstr);
|
|
FGrid->SaveGrid(fstr,xoffset,zoffset);
|
|
|
|
Unregister_Object(fstr);
|
|
delete fstr;
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::SaveText(LPCTSTR lpszPathName,int xoffset,int zoffset)
|
|
{
|
|
|
|
Check_Object(Stuff::FileStreamManager::Instance);
|
|
Stuff::NotationFile note_file(lpszPathName);
|
|
note_file.DeleteAllPages();
|
|
Stuff::Page *page=note_file.SetPage(NULL);
|
|
Check_Object(page);
|
|
page->SetEntry("!concatenate","no");
|
|
|
|
FPool->SaveIndex(¬e_file);
|
|
FGrid->SaveGrid(¬e_file,xoffset,zoffset);
|
|
note_file.Save();
|
|
}
|
|
|
|
void CImageGrinderDoc::CloseCurrent()
|
|
{
|
|
if(FPool)
|
|
{
|
|
Unregister_Pointer(FPool);
|
|
delete FPool;
|
|
}
|
|
|
|
if(FGrid)
|
|
{
|
|
Unregister_Pointer(FGrid);
|
|
delete FGrid;
|
|
}
|
|
|
|
CurSelFet=NULL;
|
|
|
|
if(UpdateList) delete UpdateList;
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::OpenFgd(LPCTSTR lpszPathName)
|
|
{
|
|
|
|
FPool = new Compost::FeaturePool();
|
|
Register_Pointer(FPool);
|
|
|
|
Check_Object(Stuff::FileStreamManager::Instance);
|
|
Stuff::FileStream *fstr=new Stuff::FileStream;
|
|
Register_Object(fstr);
|
|
fstr->Open(lpszPathName,Stuff::FileStream::ReadOnly);
|
|
FPool->LoadIndex(fstr);
|
|
FGrid = new Compost::FeatureGrid(fstr, FPool);
|
|
Register_Pointer(FGrid);
|
|
Unregister_Object(fstr);
|
|
delete fstr;
|
|
|
|
ClearSelection();
|
|
}
|
|
|
|
void CImageGrinderDoc::OpenText(LPCTSTR lpszPathName)
|
|
{
|
|
|
|
|
|
FPool = new Compost::FeaturePool();
|
|
Register_Pointer(FPool);
|
|
|
|
|
|
Check_Object(Stuff::FileStreamManager::Instance);
|
|
Stuff::NotationFile note_file(lpszPathName);
|
|
FPool->LoadIndex(¬e_file);
|
|
FGrid = new Compost::FeatureGrid(¬e_file, FPool);
|
|
Register_Pointer(FGrid);
|
|
ClearSelection();
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::PostLoadInit()
|
|
{
|
|
if(Compost::TexturePool::Instance->IsChanged()==true)
|
|
{
|
|
Compost::TexturePool::Instance->SaveIndex(NULL);
|
|
}
|
|
|
|
|
|
UpdateList=new bool[FGrid->GetRows()*FGrid->GetColumns()];
|
|
SetDrawFlags();
|
|
|
|
}
|
|
|
|
void CImageGrinderDoc::OnFileExportSinglematerialmap()
|
|
{
|
|
CString ImgName,BaseName,GridName;
|
|
GridName=GetTitle();
|
|
BaseName=GridName.Left(GridName.ReverseFind('.'));
|
|
CString path = MapPath();
|
|
|
|
if(!gos_DoesFileExist(path))
|
|
gos_CreateDirectory(path);
|
|
|
|
CFileDialog dlg(FALSE,"Tga",BaseName+"Material.tga",NULL,"Targa Images (*.tga)|*.tga||",NULL);
|
|
if(dlg.DoModal()==IDOK)
|
|
{
|
|
ExportSingleMaterialMap(dlg.GetPathName());
|
|
}
|
|
|
|
}
|