Code:
void Clear(DWORD value=0)
{
DWORD *ptrMap=m_pMap;
DWORD dwSize=m_dwSize;
_asm {
mov edi,[ptrMap]
mov ecx,[dwSize]
mov eax,[value]
rep stosd
and ecx,03h
rep stosb
}
}
This code will clear a DWORD array of any size. If I don't use the and ecx,03h then on odd sized arrays or non-padded arrays (don't line up on right boundaries) it is possible to leave some bytes hanging.
The array type is DWORD *Array. However just clearing width*height does not clear the entire array. One DWORD is 4 bytes so the total size of a DWORD Array[width*height] is not width*height, but width*height*sizeof(DWORD).
It seems from a hex viewer that the number of layers being written to the disk is correct. So it seems the problem is prior to the loading code executes, which is where the maps are loaded. So it seems saving is ok.
Here is the Serialization code from CMapSystem.h
Note that CMapManager and CMap are not derived from CObject, but I can still use the CArchive::Write() and CArchive::Read() functions on any object regardless of whether or not it is derived from CObject.
Code:
void DoArchive(CArchive &ar)
{
if (ar.IsStoring())
{
MapHeader hdr;
hdr.dwHeight=m_dwHeight;
hdr.dwWidth=m_dwWidth;
hdr.dwSizeBytes=m_dwSize*sizeof(DWORD);
//CString text;
//text.Format("%u %u %u",hdr.dwHeight,hdr.dwWidth,hdr.dwSizeBytes);
//::MessageBox(0,text,0,0);
ar.Write(&hdr,sizeof(MapHeader));
ar.Write(m_pMap,hdr.dwSizeBytes);
}
else
{
MapHeader hdr;
ar.Read(&hdr,sizeof(MapHeader));
//CString text;
//text.Format("%u %u %u",hdr.dwHeight,hdr.dwWidth,hdr.dwSizeBytes);
//::MessageBox(0,text,0,0);
if (m_pMap) delete [] m_pMap;
m_pMap=new DWORD[hdr.dwWidth*hdr.dwHeight];
if (m_pMap)
{
m_dwWidth=hdr.dwWidth;
m_dwHeight=hdr.dwHeight;
m_dwSize=m_dwWidth*m_dwHeight;
Clear(0xFFFFFFFF);
ar.Read(m_pMap,hdr.dwSizeBytes);
}
}
}
This is the exact reverse of save and since save works, I dunno why load wouldn't as well.
Here is the MapManager code:
Code:
void DoArchiveForAll(CArchive &ar)
{
for (DWORD i=0;i<MapLayers.size();i++)
{
MapLayers[i]->DoArchive(ar);
}
}
Pretty straightforward. Iterate through the vector and have each map save itself. I thought this better than having the map manager being responsible for saving the map data. After all shouldn't a map object be able to load and save itself?
Please note that my graphical tile maps save perfect for all layers.
Maybe this is the problem. I'm creating a CArchive object but I never close it. Do I need to even create a CArchive object? Since I'm overloading OnFileSaveAs(), aren't I just doing what the framework call would do?
Code:
void CZeldaEditorDoc::OnFileSaveAs()
{
// TODO: Add your command handler code here
CFileDialog *dlg=new CFileDialog(false,
"*.EPJ",
NULL,
OFN_OVERWRITEPROMPT | OFN_CREATEPROMPT,
"Editor project files (.epj)|*.epj|");
int result=dlg->DoModal();
if (result==IDOK)
{
CFile file(dlg->GetPathName(), CFile::modeCreate | CFile::modeWrite);
CArchive ar(&file,CArchive::store);
CMainFrame *ptrFrame=(CMainFrame *)AfxGetMainWnd();
ptrFrame->Serialize(ar);
ptrFrame->SetWindowText(dlg->GetFileTitle()+".EPJ");
}
delete dlg;
}