www.pudn.com > uoth_src.zip > Region.cpp
//----------------------------------------------------------------------------- // // @doc // // @module Region.cpp - region information class | // // This module contains the region information class. // // Copyright (c) 2002 - Descartes Systems Sciences, Inc. // // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // 2. Neither the name of Descartes Systems Sciences, Inc nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // @end // // $History: Cnf.cpp $ // //----------------------------------------------------------------------------- #include "stdafx.h" #include "Level.h" #include "DataParser.h" #include "Filter.h" // // Debug NEW // #if defined (_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // // Class globals // CAtlArrayCRegion::gm_vRegions; // // Externals // extern TCHAR g_szAppName []; // // String constants // extern LPCTSTR g_pszWorldOverlayName; //----------------------------------------------------------------------------- // // @mfunc constructor. // // @rdesc None. // //----------------------------------------------------------------------------- CRegion::CRegion () { Init (true); } //----------------------------------------------------------------------------- // // @mfunc destructor. // // @rdesc None. // //----------------------------------------------------------------------------- CRegion::~CRegion () { if (m_paucPixels) free (m_paucPixels); } //----------------------------------------------------------------------------- // // @mfunc Initialize the object // // @parm bool | fConstruct | If true, we are being called from the // the constructor // // @rdesc None. // //----------------------------------------------------------------------------- void CRegion::Init (bool fConstruct) { m_nIndex = 0; m_x = 0; m_y = 0; m_fInRect = false; m_strName .Empty (); m_strComment .Empty (); m_rect = CRect (0, 0, 0, 0); if (!fConstruct) { if (m_paucPixels) free (m_paucPixels); } m_paucPixels = NULL; m_nWidthBytes = 0; } //----------------------------------------------------------------------------- // // @mfunc Begin the processing of a region // // @parm CDataParser * | pParser | Current parser // // @parm const XML_Char ** | papszAttrs | Attributes // // @rdesc None. // //----------------------------------------------------------------------------- void CRegion::OnStart (CDataParser *pParser, const XML_Char **papszAttrs) { // // The only allowed attribute is Index and // it is required // if (papszAttrs [0] == NULL || strcmp (papszAttrs [0], "Index") != 0 || papszAttrs [2] != NULL) { pParser ->SetError (IDS_ERR_XML_ONLY_INDEX); return; } // // Get the index number // int nIndex = atol (papszAttrs [1]); // // Validate the region range // if (nIndex <= 0 || nIndex > Max_Region) { pParser ->SetError (IDS_ERR_XML_INDEX_RANGE); return; } // // Initialize the region // Init (false); m_nIndex = nIndex; // // Move to the new state // pParser ->SetState (CDataParser::InRegion); return; } //----------------------------------------------------------------------------- // // @mfunc Begin the processing of an XML element // // @parm CDataParser * | pParser | Current parser // // @parm const XML_Char * | pszName | Name of the element // // @parm const XML_Char ** | papszAttrs | Attributes // // @rdesc None. // //----------------------------------------------------------------------------- void CRegion::OnStartElement (CDataParser *pParser, const XML_Char *pszName, const XML_Char **papszAttrs) { // // Get the element // _Element nElement = GetElement (pszName); if (nElement == Unknown) { pParser ->SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } // // No attributes are allowed // if (papszAttrs [0] != NULL) { pParser ->SetError (IDS_ERR_XML_NO_ATTRS); return; } return; } //----------------------------------------------------------------------------- // // @mfunc End an XML element // // @parm CDataParser * | pParser | Current parser // // @parm const XML_Char * | pszName | Name of the element // // @rdesc None. // //----------------------------------------------------------------------------- void CRegion::OnEndElement (CDataParser *pParser, const XML_Char *pszName) { // // Get the element // _Element nElement = GetElement (pszName); if (nElement == Unknown) { pParser ->SetError (IDS_ERR_XML_UNEXPECTED_ELEMENT); return; } // // Switch based on the element // switch (nElement) { // // If we are ending the level // case Region: pParser ->SetState (CDataParser::InData); gm_vRegions .SetAtGrow (m_nIndex, *this); break; // // If this is the name // case Name: m_strName = pParser ->GetText (false); break; // // If this is the mask offset // case MaskOffset: pParser ->GetCoord (&m_x, &m_y); break; // // If this is the mask hit test // case MaskHitTest: m_fInRect = atol (pParser ->GetText (false)) != 0; break; // // If this is the comment // case Comment: m_strComment = pParser ->GetText (true); break; } return; } //----------------------------------------------------------------------------- // // @mfunc Get the element number // // @parm const XML_Char * | pszName | Element name // // @rdesc Element id. // //----------------------------------------------------------------------------- CRegion::_Element CRegion::GetElement (const XML_Char *pszName) { if (stricmp (pszName, "Region") == 0) return Region; else if (stricmp (pszName, "Name") == 0) return Name; else if (stricmp (pszName, "MaskOffset") == 0) return MaskOffset; else if (stricmp (pszName, "MaskHitTest") == 0) return MaskHitTest; else if (stricmp (pszName, "Comment") == 0) return Comment; else return Unknown; } //----------------------------------------------------------------------------- // // @mfunc Get the next valid region // // @parm int | nTreasure | Current position // // @parm bool | fForward | If true, move forward // // @parm CFilter * | pFilter | Filter to use for test // // @rdesc New region number or zero if there are no more // //----------------------------------------------------------------------------- int CRegion::GetNext (int nRegion, bool fForward, CFilter *pFilter) { // // Get the additive // int nAdd = fForward ? 1 : -1; // // Look for the region // while (true) { nRegion += nAdd; if (nRegion <= 0 || nRegion >= gm_vRegions .GetCount ()) return 0; if (!gm_vRegions [nRegion] .IsValid ()) continue; if (pFilter) { if (pFilter ->IsMineFilterEnabled () && !pFilter ->DoesRegionHaveMap (nRegion)) continue; } return nRegion; } } //----------------------------------------------------------------------------- // // @mfunc Get the region information // // @parm bool | fTerse | If true, only provide limited data // // @rdesc String containing the text // //----------------------------------------------------------------------------- CString CRegion::GetInformation (bool fTerse) { CString str; // // Set the basics // str .Format (IDS_INF_REGION, m_nIndex, (LPCTSTR) m_strName); // // Append the comment // if (!fTerse) { if (!m_strComment .IsEmpty ()) { str += CString (_T ( "\r\n")) + m_strComment + _T ( "\r\n"); } } return str; } //----------------------------------------------------------------------------- // // @mfunc Load the region masks // // @parm unzFile | fpZip | Zip file containing data // // @rdesc Overall status // //----------------------------------------------------------------------------- bool CRegion::LoadMasks (unzFile fpZip) { // // Load the region masks // for (int ir = 0; ir < CRegion::gm_vRegions .GetCount (); ++ir) { CRegion *pRegion = &CRegion::gm_vRegions [ir]; if (!pRegion ->IsValid ()) continue; // // Load the bitmap // TCHAR szName [64]; _sntprintf (szName, _countof (szName), g_pszWorldOverlayName, pRegion ->m_nIndex); HBITMAP hbm = LoadBitmapFromZip (fpZip, szName); if (hbm == NULL) { CString str; str .Format (IDS_ERR_LOAD_FROM_ZIP, szName); ::MessageBox (NULL, str, g_szAppName, MB_OK); return false; } if (!IsBitmapMonochrome (hbm)) { CString str; str .Format (IDS_ERR_MONOCHROME, szName); ::MessageBox (NULL, str, g_szAppName, MB_OK); return false; } // // Convert the bitmap // BITMAP bmo; ::GetObject (hbm, sizeof (bmo), &bmo); CSize szBitmap (bmo .bmWidth, bmo .bmHeight); _ASSERTE (bmo .bmBitsPixel == 1); int nSize = bmo .bmHeight * bmo .bmWidthBytes; unsigned char *pauchSrc = (unsigned char *) malloc (nSize); ::GetBitmapBits (hbm, nSize, pauchSrc); ::DeleteObject (hbm); // // Save the size // pRegion ->m_rect = CRect (CPoint (pRegion ->m_x, pRegion ->m_y), szBitmap); pRegion ->m_paucPixels = pauchSrc; pRegion ->m_nWidthBytes = bmo .bmWidthBytes; } // // Success // return true; }