/* ** AreaEditor - a program for editing SMAUG and ROM area files. ** Author: Nick Gammon ** http://www.gammon.com.au/ ** See Copyright Notice at the end of AreaEditor.h */ #include "stdafx.h" #include "AreaEditor.h" #include "MainFrm.h" #include "AreaEditorDoc.h" // ======================================================================== void CFileRead::Init (const char * sMessage, CArchive * ar) { m_ar = ar; m_nLine = 0; m_strLastLineRead.Empty (); m_strPartialLine.Empty (); m_bProgressBar = false; if (strlen (sMessage) > 0) { Frame.CreateProgressBar (sMessage, ar->GetFile ()->GetLength ()); m_bProgressBar = true; } } // end of CFileRead::Init void CFileRead::Wrapup (void) { if (m_bProgressBar) Frame.RemoveProgressBar (); m_ar = NULL; m_bProgressBar = false; } // end of CFileRead::Wrapup void CFileRead::fread_getnonblankline (const bool bLeftJustify) { // read another line if necessary while (m_strPartialLine.IsEmpty ()) { // find file position of this line if (!m_ar->ReadString (m_strPartialLine)) ThrowErrorException ("Unexpected end of file"); else { // removing leading spaces moves us further into the file if (bLeftJustify) m_strPartialLine.TrimLeft (); m_strPartialLine.TrimRight (); // save line details in case of exception m_strLastLineRead = m_strPartialLine; m_nLine++; if (m_bProgressBar) if (m_nLine % 32 == 0) Frame.UpdateProgressBar (m_ar->GetFile ()->GetPosition ()); if (!bLeftJustify) break; // keep blank lines for left-justification } } // end of read loop // removing leading spaces moves us further into the file if (bLeftJustify) m_strPartialLine.TrimLeft (); } // end of fread_getnonblankline char CFileRead::fread_letter (void) { fread_getnonblankline (); char c = m_strPartialLine [0]; m_strPartialLine = m_strPartialLine.Mid (1); return c; } // end of fread_letter CString CFileRead::fread_to_eol (void) { // we will return the rest of the line - it might be a comment CString strResult = m_strPartialLine; strResult.TrimRight (); m_strPartialLine.Empty (); return strResult; } // end of fread_to_eol CString CFileRead::fread_word (void) { fread_getnonblankline (); int iStart, iEnd; char cEnd = m_strPartialLine [0]; if (cEnd == '\'' || cEnd == '"') iStart = 1; else { cEnd = ' '; iStart = 0; } for (iEnd = iStart; iEnd < m_strPartialLine.GetLength (); iEnd++) if (cEnd == ' ' ? isspace(m_strPartialLine [iEnd]) : m_strPartialLine [iEnd]== cEnd ) break; CString strResult = m_strPartialLine.Mid (iStart, iEnd - iStart); if (iEnd >= m_strPartialLine.GetLength ()) m_strPartialLine.Empty (); else m_strPartialLine = m_strPartialLine.Mid (iEnd + 1); return strResult; } // end of fread_word CString CFileRead::fread_string (const bool bLeftJustify) { CString strResult; int iEnd; char c; while (true) { fread_getnonblankline (bLeftJustify); for (iEnd = 0; iEnd < m_strPartialLine.GetLength (); iEnd++) if ((c = m_strPartialLine [iEnd]) == '~') break; strResult += m_strPartialLine.Left (iEnd); if (iEnd >= m_strPartialLine.GetLength ()) m_strPartialLine.Empty (); else m_strPartialLine = m_strPartialLine.Mid (iEnd + 1); if (c == '~') break; strResult += ENDLINE; } // end of looping until we get a ~ return strResult; } // end of fread_string CString CFileRead::fread_line (void) { CString strResult; fread_getnonblankline (); strResult = m_strPartialLine; m_strPartialLine.Empty (); return strResult; } // end of fread_line long CFileRead::fread_number (const bool bFlag) { long number = 0; int iPos; bool negative = false; char c; fread_getnonblankline (); iPos = 0; // find the leading sign, if any if (m_strPartialLine [0] == '+') iPos++; else if (m_strPartialLine [0] == '-') { iPos++; negative = true; } // must start with a digit if (!isdigit (m_strPartialLine[iPos])) if (bFlag) { while (iPos < m_strPartialLine.GetLength () && isalpha (c = m_strPartialLine[iPos])) { number += flag_convert(c); iPos++; } } else ThrowErrorException ("Expected a number"); while (iPos < m_strPartialLine.GetLength () && isdigit (c = m_strPartialLine[iPos])) { number = number * 10 + c - '0'; iPos++; } if (negative) number = 0 - number; m_strPartialLine = m_strPartialLine.Mid (iPos); if (c == '|') { m_strPartialLine = m_strPartialLine.Mid (1); // skip the "|" symbol number += fread_number (); } return number; } // end of fread_number EXT_BV CFileRead::fread_bitvector (const bool bFlag) { EXT_BV ret = 0; char c; EXT_BV num = 0; for (int i = 0; i < 2; i++) { num = (unsigned int) fread_number (bFlag); if (i == 1) num <<= 32; ret |= num; // extended bitvectors should appear on a single line if (m_strPartialLine.IsEmpty ()) break; c = m_strPartialLine [0]; if (c != '&') break; m_strPartialLine = m_strPartialLine.Mid (1); } // end of reading each number in the bitvector return ret; } // end of fread_bitvector long CFileRead::flag_convert (const char letter) { long bitsum = 0; char i; if ('A' <= letter && letter <= 'Z') { bitsum = 1; for (i = letter; i > 'A'; i--) bitsum *= 2; } else if ('a' <= letter && letter <= 'z') { bitsum = 67108864; /* 2^26 */ for (i = letter; i > 'a'; i --) bitsum *= 2; } return bitsum; } // ======================================================================== void CFileWrite::Init (const char * sMessage, CArchive * ar, long iItems) { m_ar = ar; m_nLine = 0; m_iSaveMilestone = 0; m_bProgressBar = false; if (strlen (sMessage) > 0) { Frame.CreateProgressBar (sMessage, iItems); m_bProgressBar = true; } } // end of CFileWrite::Init void CFileWrite::Wrapup (void) { if (m_bProgressBar) Frame.RemoveProgressBar (); m_ar = NULL; m_bProgressBar = false; } // end of CFileWrite::Wrapup void CFileWrite::DoSaveMilestone (void) { if (m_bProgressBar) if (m_iSaveMilestone++ % 32 == 0) Frame.UpdateProgressBar (m_iSaveMilestone); } void CFileWrite::fwrite_string (const char * s) { m_ar->WriteString (CFormat ("%s" ENDLINE, s)); } // end of CFileWrite::fwrite_string #if 0 /* * Extended Bitvector Routines -Thoric */ /* check to see if the extended bitvector is completely empty */ bool ext_is_empty( EXT_BV *bits ) { int x; for ( x = 0; x < XBI; x++ ) if ( bits->bits[x] != 0 ) return FALSE; return TRUE; } void ext_clear_bits( EXT_BV *bits ) { int x; for ( x = 0; x < XBI; x++ ) bits->bits[x] = 0; } /* for use by xHAS_BITS() -- works like IS_SET() */ int ext_has_bits( EXT_BV *var, EXT_BV *bits ) { int x, bit; for ( x = 0; x < XBI; x++ ) if ( (bit=(var->bits[x] & bits->bits[x])) != 0 ) return bit; return 0; } /* for use by xSAME_BITS() -- works like == */ bool ext_same_bits( EXT_BV *var, EXT_BV *bits ) { int x; for ( x = 0; x < XBI; x++ ) if ( var->bits[x] != bits->bits[x] ) return FALSE; return TRUE; } /* for use by xSET_BITS() -- works like SET_BIT() */ void ext_set_bits( EXT_BV *var, EXT_BV *bits ) { int x; for ( x = 0; x < XBI; x++ ) var->bits[x] |= bits->bits[x]; } /* for use by xREMOVE_BITS() -- works like REMOVE_BIT() */ void ext_remove_bits( EXT_BV *var, EXT_BV *bits ) { int x; for ( x = 0; x < XBI; x++ ) var->bits[x] &= ~(bits->bits[x]); } /* for use by xTOGGLE_BITS() -- works like TOGGLE_BIT() */ void ext_toggle_bits( EXT_BV *var, EXT_BV *bits ) { int x; for ( x = 0; x < XBI; x++ ) var->bits[x] ^= bits->bits[x]; } #endif /* return a string for writing a bitvector to a file */ CString print_bitvector (const EXT_BV & bits) { CString strResult; LARGE_INTEGER number; number.QuadPart = bits; if (number.HighPart == 0) strResult = CFormat ("%d", number.LowPart); else strResult = CFormat ("%d&%d", number.LowPart, number.HighPart); return strResult; } /* * Write an extended bitvector to a file -Thoric */ void CFileWrite::fwrite_bitvector (const EXT_BV & bits) { m_ar->WriteString (CFormat ("%s" ENDLINE, (LPCTSTR) print_bitvector (bits))); } // end of CFileWrite::fwrite_bitvector