Diff of /2DAEdit.cpp [0897cf] .. [e2d117]  Maximize  Restore

  Switch to side-by-side view

--- a/2DAEdit.cpp
+++ b/2DAEdit.cpp
@@ -1,1980 +1,1980 @@
-// 2DAEdit.cpp : implementation file
-//
-
-#include "stdafx.h"
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <mmsystem.h>
-#include "chitem.h"
-#include "2da.h"
-#include "2DAEdit.h"
-#include "StrRefDlg.h"
-#include "progressbar.h"
-#include "ColorPicker.h"
-#include "MyFileDialog.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-static void ResizeLastColumn(CListCtrl &lc, BOOL bSubtractScroll)
-{
-	CHeaderCtrl *pHeader = lc.GetHeaderCtrl();
-
-	int nCount = pHeader->GetItemCount();
-	if (!nCount)
-		return;
-
-	int nTotal = 0;
-	CRect rHeader;
-	pHeader->GetClientRect(&rHeader);
-	HDITEM hdi;
-	hdi.mask = HDI_WIDTH;
-
-	for(int i=0;i<nCount-1;i++)
-	{
-		pHeader->GetItem(i,&hdi);
-		if (hdi.mask & HDI_WIDTH)
-			nTotal += hdi.cxy;
-	}
-
-	hdi.cxy = rHeader.Width() - nTotal;
-	if (bSubtractScroll)
-		hdi.cxy -= ::GetSystemMetrics(SM_CXHSCROLL);
-
-	pHeader->SetItem(nCount-1,&hdi);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// C2DAEdit dialog
-
-C2DAEdit::C2DAEdit(CWnd* pParent /*=NULL*/)	: CDialog(C2DAEdit::IDD, pParent)
-{
-	//{{AFX_DATA_INIT(C2DAEdit)
-	m_integer = FALSE;
-	//}}AFX_DATA_INIT
-  m_inedit=0;
-  m_item=0;
-  m_subitem=0;
-}
-
-void C2DAEdit::DoDataExchange(CDataExchange* pDX)
-{
-	CDialog::DoDataExchange(pDX);
-	//{{AFX_DATA_MAP(C2DAEdit)
-	DDX_Control(pDX, IDC_2DA, m_2da_control);
-	DDX_Check(pDX, IDC_INT, m_integer);
-	//}}AFX_DATA_MAP
-  DDX_Text(pDX, IDC_DEFAULT, the_2da.defvalue);
-  if(the_2da.defvalue.IsEmpty())
-  {
-    if(m_integer) the_2da.defvalue="-1";
-    else the_2da.defvalue="*";
-  }
-}
-
-BEGIN_MESSAGE_MAP(C2DAEdit, CDialog)
-	//{{AFX_MSG_MAP(C2DAEdit)
-	ON_BN_CLICKED(IDC_LOAD, OnLoad)
-	ON_BN_CLICKED(IDC_LOADEX, OnLoadex)
-	ON_BN_CLICKED(IDC_SAVEAS, OnSaveas)
-	ON_BN_CLICKED(IDC_NEW, OnNew)
-	ON_BN_CLICKED(IDC_INT, OnInt)
-	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_2DA, OnEndlabeledit2da)
-	ON_NOTIFY(NM_CLICK, IDC_2DA, OnClick2da)
-	ON_NOTIFY(LVN_COLUMNCLICK, IDC_2DA, OnColumnclick2da)
-	ON_BN_CLICKED(IDC_ROW, OnRow)
-	ON_BN_CLICKED(IDC_COLUMN, OnColumn)
-	ON_BN_CLICKED(IDC_REMOVE, OnRemove)
-	ON_BN_CLICKED(IDC_REMOVE2, OnRemove2)
-	ON_NOTIFY(NM_RCLICK, IDC_2DA, OnRClick2da)
-	ON_BN_CLICKED(IDC_COPY2, OnCopy2)
-	ON_BN_CLICKED(IDC_COPY, OnCopy)
-	ON_BN_CLICKED(IDC_PASTE2, OnPaste2)
-	ON_BN_CLICKED(IDC_PASTE, OnPaste)
-	ON_BN_CLICKED(IDC_COLUMN2, OnColumn2)
-	ON_BN_CLICKED(IDC_ROW2, OnRow2)
-	ON_COMMAND(ID_FILE_SAVE, OnSave)
-	ON_COMMAND(ID_TOOLS_CAPITALIZEENTRIES, OnToolsCapitalize)
-	ON_COMMAND(ID_TOOLS_LOOKUPSTRREF, OnToolsLookupstrref)
-	ON_BN_CLICKED(IDC_ORDER, OnOrder)
-	ON_COMMAND(ID_TOOLS_ADDSPARKDATA, OnToolsAddsparkdata)
-	ON_EN_KILLFOCUS(IDC_DEFAULT, DefaultKillfocus)
-	ON_COMMAND(ID_FILE_NEW, OnNew)
-	ON_COMMAND(ID_FILE_LOAD, OnLoad)
-	ON_COMMAND(ID_FILE_LOADEXTERNALSCRIPT, OnLoadex)
-	ON_COMMAND(ID_FILE_SAVEAS, OnSaveas)
-	ON_COMMAND(ID_TOOLS_PLAYSOUND, OnToolsPlaysound)
-	//}}AFX_MSG_MAP
-  ON_EN_KILLFOCUS(IDC_EDITLINK,OnKillfocusEditlink)
-  ON_NOTIFY(NM_CUSTOMDRAW, IDC_2DA, OnCustomdrawMyList)
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// C2DAEdit message handlers
-
-void C2DAEdit::New2DA()
-{
-  CString *tmppoi;
-
-	the_2da.new_2da();
-  tmppoi=new CString[1];
-  if(!tmppoi) return;
-  tmppoi[0]="";
-  the_2da.collabels=tmppoi;
-	itemname="new 2da";
-}
-
-void C2DAEdit::OnLoad() 
-{
-	int res;
-	
-  if(IsWindow(m_edit)) return;
-  pickerdlg.m_restype=REF_2DA;
-  pickerdlg.m_picked=itemname;
-	res=pickerdlg.DoModal();
-	if(res==IDOK)
-	{
-		res=read_2da(pickerdlg.m_picked);
-    switch(res)
-    {
-    case 1:
-      MessageBox("2da loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
-  		itemname=pickerdlg.m_picked;
-      break;
-    case 0:
-  		itemname=pickerdlg.m_picked;
-      break;
-    default:
-      MessageBox("Cannot read 2da!","Error",MB_ICONSTOP|MB_OK);
-      New2DA();
-      break;
-    }
-	}
-  RefreshDialog();
-}
-
-static char BASED_CODE szFilter[] = "2DA files (*.2da)|*.2da|All files (*.*)|*.*||";
-
-void C2DAEdit::OnLoadex() 
-{
-  CString filepath;
-  int fhandle;
-  int res;
-  
-  res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER;
-  if(readonly) res|=OFN_READONLY;  
-  CMyFileDialog m_getfiledlg(TRUE, "2da", makeitemname(".2da",0), res, szFilter);
-
-restart:  
-  if( m_getfiledlg.DoModal() == IDOK )
-  {
-    filepath=m_getfiledlg.GetPathName();
-    fhandle=open(filepath, O_RDONLY|O_BINARY);
-    if(!fhandle)
-    {
-      MessageBox("Cannot open file!","Error",MB_ICONSTOP|MB_OK);
-      goto restart;
-    }
-    readonly=m_getfiledlg.GetReadOnlyPref();
-    res=the_2da.Read2DAFromFile(fhandle,-1);
-    close(fhandle);
-    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
-    switch(res)
-    {
-    case 1:
-      MessageBox("2da loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
-      itemname=m_getfiledlg.GetFileTitle();
-      itemname.MakeUpper();
-      break;
-    case 0:
-      itemname=m_getfiledlg.GetFileTitle();
-      itemname.MakeUpper();
-      break;
-    default:
-      MessageBox("Cannot read 2da!","Error",MB_ICONSTOP|MB_OK);
-      New2DA();
-      break;
-    }
-  }
-  RefreshDialog();
-}
-
-void C2DAEdit::OnSave() 
-{
-  SaveTable(1);
-}
-
-void C2DAEdit::OnSaveas() 
-{
-  SaveTable(0);
-}
-
-void C2DAEdit::SaveTable(int save) 
-{
-  CString filepath;
-  CString newname;
-  CString tmpstr;
-  int res;
-
-  if(readonly)
-  {
-    MessageBox("You opened it read only!","Warning",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-  res=OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_EXPLORER;
-  CMyFileDialog m_getfiledlg(FALSE, "2da", makeitemname(".2da",0), res, szFilter);
-
-  if(save)
-  {
-    newname=itemname;
-    filepath=makeitemname(".2da",0);
-    goto gotname;
-  }
-
-restart:  
-  if( m_getfiledlg.DoModal() == IDOK )
-  {
-    filepath=m_getfiledlg.GetPathName();
-    filepath.MakeLower();
-    if(filepath.Right(4)!=".2da")
-    {
-      filepath+=".2da";
-    }
-    newname=m_getfiledlg.GetFileName();
-    newname.MakeUpper();
-    if(newname.Right(4)==".2DA") newname=newname.Left(newname.GetLength()-4);
-gotname:
-    if(newname.GetLength()>8 || newname.GetLength()<1 || newname.Find(" ",0)!=-1)
-    {
-      tmpstr.Format("The resource name '%s' is bad, it should be 8 characters long and without spaces.",newname);
-      MessageBox(tmpstr,"Warning",MB_ICONEXCLAMATION|MB_OK);
-      goto restart;
-    }
-    if(newname!=itemname && file_exists(filepath) )
-    {
-      res=MessageBox("Do you want to overwrite "+newname+"?","Warning",MB_ICONQUESTION|MB_YESNO);
-      if(res==IDNO) goto restart;
-    }
-
-    res=write_2da(newname, filepath);
-    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
-    switch(res)
-    {
-    case 0:
-      itemname=newname;
-      break; //saved successfully
-    case -2:
-      MessageBox("Error while writing file!","Error",MB_ICONSTOP|MB_OK);
-      break;
-    default:
-      MessageBox("Unhandled error!","Error",MB_ICONSTOP|MB_OK);
-    }
-  }
-  RefreshDialog();
-}
-
-void C2DAEdit::OnNew() 
-{
-  New2DA();
-  RefreshDialog();
-}
-
-void C2DAEdit::RefreshDialog()
-{
-  POSITION pos;
-  CString *tmppoi;
-  int i,j;
-  int width, minwidth;
-
-  SetWindowText("Edit 2DA: "+itemname);
-  m_2da_control.DeleteAllItems();
-  while(m_2da_control.DeleteColumn(0));
-  m_2da_control.SetItemCount(the_2da.cols);
-  if (m_integer) minwidth = 50;
-  else minwidth = 100;
-  for(i=0;i<the_2da.cols;i++)
-  {
-    width=10*the_2da.collabels[i].GetLength();
-    if(width<minwidth) width=minwidth;
-    m_2da_control.InsertColumn(i,the_2da.collabels[i],LVCFMT_LEFT,width);
-  }
-  pos=the_2da.data->GetHeadPosition();
-  for(i=0;i<the_2da.rows;i++)
-  {
-    tmppoi=(CString *) the_2da.data->GetNext(pos);
-    m_2da_control.InsertItem(i, tmppoi[0]);
-    for(j=1;j<the_2da.cols;j++)
-    {
-      m_2da_control.SetItemText(i, j, tmppoi[j]);
-      if (tmppoi[j].Left(3)=="RGB")
-      {
-        the_2da.defvalue="RGB(0,0,0)";
-      }
-    }
-  }
-  m_integer=!invalidnumber(the_2da.defvalue);
-  UpdateData(UD_DISPLAY);
-}
-
-BOOL C2DAEdit::OnInitDialog() 
-{
-	CDialog::OnInitDialog();
-	RefreshDialog();
-
-  //tooltips
-  {
-    m_tooltip.Create(this,TTS_NOPREFIX);
-    m_tooltip.SetMaxTipWidth(200);
-    m_tooltip.SetTipBkColor(RGB(240,224,160));
-    
-    m_tooltip.AddTool(GetDlgItem(IDCANCEL), IDS_CANCEL);
-  }
-	return TRUE;  
-}
-
-void C2DAEdit::DefaultKillfocus() 
-{
-	UpdateData(UD_RETRIEVE);	
-	UpdateData(UD_DISPLAY);	
-}
-
-void C2DAEdit::OnInt() 
-{
-  m_integer=!m_integer;
-	UpdateData(UD_DISPLAY);	
-}
-
-void C2DAEdit::OnEndlabeledit2da(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  CString tmpstr;
-  CString *tmppoi;
-	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
-
-  if(pDispInfo->item.pszText)
-  {
-    tmpstr=pDispInfo->item.pszText;
-	  m_2da_control.SetItemText(pDispInfo->item.iItem, 0, tmpstr);
-    tmppoi=(CString *) the_2da.data->GetAt(the_2da.data->FindIndex(pDispInfo->item.iItem));
-    tmppoi[0]=tmpstr;
-  }
-	*pResult = 0;
-}
-
-void C2DAEdit::RClick()
-{
-  CString tmpstr;
-  CRect ref, ref2;
-
-  m_2da_control.GetSubItemRect(m_item,m_subitem,0,ref);
-  tmpstr=m_2da_control.GetItemText(m_item,m_subitem);
-  tmpstr=resolve_tlk_text(strtonum(tmpstr));
-  m_2da_control.GetWindowRect(ref2);
-  ScreenToClient(ref2);
-  ref.left+=ref2.left;
-  ref.top+=ref2.top;
-  ref.right+=ref2.left;
-  ref.bottom+=ref2.top+2;
-  if(ref.Width()/8<tmpstr.GetLength())
-  {
-    ref.right+=(tmpstr.GetLength()-5)*8;
-    if(ref.right>ref2.right) ref.right=ref2.right;
-  }
-  m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER |ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL,ref,this,IDC_EDITLINK);  
-  m_edit.SetWindowText(tmpstr);
-  m_inedit=3;
-  m_edit.SetFocus();
-}
-
-void C2DAEdit::Click(int flg)
-{
-  CString tmpstr;
-  CRect ref, ref2;
-  LVCOLUMN lvColumn;
-  char label[200];
-
-  if(!m_subitem)
-  {
-    m_2da_control.EditLabel(m_item);
-  }
-  else
-  {
-    m_2da_control.GetSubItemRect(m_item,m_subitem,LVIR_BOUNDS,ref);
-    if(m_item==-1)
-    {
-      if(m_subitem==-1) return;
-      lvColumn.mask=LVCF_TEXT;
-      lvColumn.pszText=label;
-      lvColumn.cchTextMax=200;
-      if(m_2da_control.GetColumn(m_subitem,&lvColumn))
-      {
-        tmpstr=lvColumn.pszText;
-      }
-    }
-    else
-    {
-      tmpstr=m_2da_control.GetItemText(m_item,m_subitem);
-    }
-    m_2da_control.GetWindowRect(ref2);
-    ScreenToClient(ref2);
-    ref.left+=ref2.left;
-    ref.top+=ref2.top;
-    ref.right+=ref2.left;
-    ref.bottom+=ref2.top+2;
-    m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER|ES_AUTOHSCROLL,ref,this,IDC_EDITLINK);
-    m_edit.SetWindowText(tmpstr);
-    m_edit.SetSel(0,-1);
-    m_inedit=flg;
-    m_edit.SetFocus();
-  }
-}
-
-void C2DAEdit::OnClick2da(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  LVHITTESTINFO htinfo;
-  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
-
-  if(IsWindow(m_edit)) m_edit.DestroyWindow();
-  htinfo.pt=pNMListView->ptAction;
-	m_item=m_2da_control.SubItemHitTest(&htinfo);
-  m_subitem=htinfo.iSubItem;
-  Click(1);
-	*pResult = 0;
-}
-
-void C2DAEdit::OnRClick2da(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  LVHITTESTINFO htinfo;
-  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
-
-  if(IsWindow(m_edit)) m_edit.DestroyWindow();
-  htinfo.pt=pNMListView->ptAction;
-	m_item=m_2da_control.SubItemHitTest(&htinfo);
-  m_subitem=htinfo.iSubItem;
-  if((m_subitem>=1) && (m_item>=0))
-  {
-    RClick();
-  }
-	*pResult = 0;
-}
-
-void C2DAEdit::OnColumnclick2da(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
-
-  OnKillfocusEditlink();
-  m_item=-1;
-  m_subitem=pNMListView->iSubItem;
-  Click(2);
-	*pResult = 0;
-}
-
-// original source of this piece of code:
-// http://www.codeproject.com/listctrl/lvcustomdraw.asp
-// Neat Stuff to do in List Controls Using Custom Draw
-// By Michael Dunn
-void C2DAEdit::OnCustomdrawMyList(NMHDR *pNMHDR, LRESULT *pResult)
-{
-  NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
-  
-  // Take the default processing unless we set this to something else below.
-  *pResult = CDRF_DODEFAULT;
-  
-  // First thing - check the draw stage. If it's the control's prepaint
-  // stage, then tell Windows we want messages for every item.
-  
-  if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
-  {
-    *pResult = CDRF_NOTIFYITEMDRAW;
-  }
-  else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
-  {
-    // This is the prepaint stage for an item. Here's where we set the
-    // item's text color. Our return value will tell Windows to draw the
-    // item itself, but it will use the new color we set here.
-    // We'll cycle the colors through red, green, and light blue.
-    
-    COLORREF crText;
-    
-    if(pLVCD->nmcd.dwItemSpec &1)
-    {
-      crText = RGB(240,240,240);
-    }
-    else
-    {
-      crText = RGB(255,255,255);
-    }
-    
-    // Store the color back in the NMLVCUSTOMDRAW struct.
-    pLVCD->clrTextBk = crText;
-    
-    // Tell Windows to paint the control itself.
-    *pResult = CDRF_DODEFAULT;
-  }
-}
-
-void C2DAEdit::OnKillfocusEditlink()
-{
-  POSITION pos;
-  CString tmpstr;
-  CString *row;
-  LVCOLUMN lvColumn;
-  int strref;
-
-	switch(m_inedit)
-  {
-  case 3:
-    m_inedit=0;
-    if(m_item>=the_2da.rows || m_subitem>=the_2da.cols)
-    {
-      goto escape;
-    }
-    if(m_item<0 || m_subitem<0)
-    {
-      goto escape;
-    }
-    m_edit.GetWindowText(tmpstr);
-    pos=the_2da.data->FindIndex(m_item);
-    if(!pos)
-    {
-      goto escape;
-    }
-    row=(CString *)the_2da.data->GetAt(pos);
-    if(!row)
-    {
-      goto escape;
-    }
-    strref=strtonum(row[m_subitem]);
-    if(!strref && !m_integer)
-    {
-      goto escape;
-    }
-    if(resolve_tlk_text(strref)==tmpstr)
-    {
-      goto escape;
-    }
-    strref=store_tlk_text(strref, tmpstr);
-    row[m_subitem].Format("%d",strref);
-    m_2da_control.SetItemText(m_item,m_subitem,row[m_subitem]);
-escape:
-    m_edit.ShowWindow(false);
-    break;
-  case 0:
-    m_edit.DestroyWindow();
-    break;
-  case 2:
-    m_inedit=1;
-    m_edit.SetFocus();
-    break;
-  case 1:
-    m_inedit=0;
-    if(m_item<the_2da.rows && m_subitem<the_2da.cols)
-    {
-      m_edit.GetWindowText(tmpstr);
-      if(m_item==-1)
-      {
-        if(m_subitem<0)
-        {
-          return;
-        }
-        the_2da.collabels[m_subitem]=tmpstr;
-        lvColumn.mask=LVCF_TEXT;
-        lvColumn.pszText=tmpstr.GetBuffer(0);
-        lvColumn.cchTextMax=tmpstr.GetLength();
-        m_2da_control.SetColumn(m_subitem, &lvColumn);
-      }
-      else
-      {
-        if(m_integer && invalidnumber(tmpstr) )
-        {
-          MessageBox("Enter a decimal or hexadecimal value!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-        }
-        else
-        {
-          pos=the_2da.data->FindIndex(m_item);
-          if(pos)
-          {
-            row=(CString *)the_2da.data->GetAt(pos);
-            if(row)
-            {
-              row[m_subitem]=tmpstr;
-              m_2da_control.SetItemText(m_item,m_subitem,tmpstr);
-            }
-          }
-        }
-      }
-    }
-    m_edit.DestroyWindow();
-  }
-}
-
-void C2DAEdit::RefreshSelection()
-{
-	m_2da_control.EnsureVisible(m_item, false);
-	m_2da_control.SetItemState(m_item, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
-}
-
-void C2DAEdit::OnRow2() 
-{
-  CString *row;
-  CString tmpstr;
-  POSITION pos;
-  int i;
-
-  if(m_item<0 || m_item>the_2da.rows) m_item=the_2da.rows;
-  tmpstr.Format("Row%d",m_item);
-  the_2da.AddRow(m_item, tmpstr, the_2da.defvalue);
-  pos=the_2da.data->FindIndex(m_item);
-  row=(CString *)the_2da.data->GetAt(pos);
-  m_2da_control.InsertItem(m_item, tmpstr);
-  for(i=0;i<the_2da.cols;i++)
-  {
-    m_2da_control.SetItemText(m_item,i, row[i]);
-  }
-  RefreshSelection();
-//  RefreshDialog();
-}
-
-void C2DAEdit::OnColumn() 
-{
-  CString tmpstr;
-  int column;
-
-  column=m_subitem+1;
-  if(column<1) column=1;
-  else if(column>the_2da.cols) column=the_2da.cols;
-  tmpstr.Format("Column%d",column);
-  the_2da.AddColumn(column,tmpstr,  the_2da.defvalue);
-  m_subitem=column;
-  RefreshDialog();
-}
-
-void C2DAEdit::OnRow() 
-{
-	m_item++;
-	OnRow2();
-}
-
-void C2DAEdit::OnColumn2() 
-{
-  m_subitem--;
-  OnColumn();
-}
-
-void C2DAEdit::OnRemove() 
-{
-  if(m_item<0)
-  {
-    MessageBox("Please select a row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	if(the_2da.RemoveRow(m_item))
-  {
-    m_2da_control.DeleteItem(m_item);
-    if(m_item>=the_2da.rows) m_item=the_2da.rows-1;
-    RefreshSelection();
-  }
-  else MessageBox("Cannot remove row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-}
-
-void C2DAEdit::OnRemove2() 
-{
-	if(m_subitem<1)
-  {
-    MessageBox("Please select a column (can't remove label column).","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	if(the_2da.RemoveColumn(m_subitem))
-  {
-    RefreshDialog();
-    m_subitem--;
-  }
-  else MessageBox("Cannot remove column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-}
-
-void C2DAEdit::OnCopy() 
-{
-	if(m_item<0)
-  {
-    MessageBox("Please select a row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	the_2da.CopyRow(m_item);
-}
-
-void C2DAEdit::OnCopy2() 
-{
-	if(m_subitem<0)
-  {
-    MessageBox("Please select a column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	the_2da.CopyColumn(m_subitem);
-}
-
-void C2DAEdit::OnPaste() 
-{
-	if(m_item<0)
-  {
-    MessageBox("Please select a row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	the_2da.PasteRow(m_item);
-  RefreshDialog();
-}
-
-void C2DAEdit::OnPaste2() 
-{
-	if(m_subitem<0)
-  {
-    MessageBox("Please select a column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	the_2da.PasteColumn(m_subitem);
-  RefreshDialog();
-}
-
-void C2DAEdit::OnOrder() 
-{
-	if(m_subitem<0)
-  {
-    MessageBox("Please select a column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	the_2da.OrderByColumn(m_subitem, m_integer);
-  RefreshDialog();
-}
-
-void C2DAEdit::OnToolsAddsparkdata() 
-{
-  CString *tmppoi;
-  CString tmpstr;
-  int i;
-  
-  if (m_item<0)
-  {
-    return;
-  }
-  if (the_2da.cols!=6)
-  {
-    return;
-  }
-  tmppoi=(CString *) the_2da.data->GetAt(the_2da.data->FindIndex(m_item));
-  if (!tmppoi)
-  {
-    return;
-  }
-  colordlg.m_picked=0;
-  if(colordlg.DoModal()==IDOK)
-  {
-    unsigned long colors[5];
-    
-    MakeGradientArray(colors, (unsigned char) colordlg.m_picked);
-    for (i=0;i<5;i++)
-    {
-      tmpstr.Format("RGB(%d,%d,%d)",((colors[i]>>16)&255),((colors[i]>>8)&255), (colors[i]&255));
-      tmppoi[i+1]=tmpstr;
-    }
-    RefreshDialog();
-  }
-}
-
-void C2DAEdit::OnToolsCapitalize() 
-{
-  POSITION pos;
-  int i,j;
-  CString *tmppoi;
-  
-  pos=the_2da.data->GetHeadPosition();
-  for(j=0;j<the_2da.cols;j++)
-  {
-    the_2da.collabels[j].MakeUpper();
-  }
-  for(i=0;i<the_2da.rows;i++)
-  {
-    tmppoi=(CString *) the_2da.data->GetNext(pos);
-    for(j=0;j<the_2da.cols;j++)
-    {
-      tmppoi[j].MakeUpper();
-    }
-  }
-  RefreshDialog();
-}
-
-void C2DAEdit::OnToolsLookupstrref() 
-{
-  CStrRefDlg dlg;
-  
-  if(IsWindow(m_edit)) m_edit.DestroyWindow();
-  dlg.DoModal();
-  RefreshDialog();
-}
-
-void C2DAEdit::OnToolsPlaysound() 
-{
-  CString tmpstr;
-
-  tmpstr=m_2da_control.GetItemText(m_item,m_subitem);
-  tmpstr.MakeUpper();
-  play_acm(tmpstr,false,false);
-}
-
-BOOL C2DAEdit::PreTranslateMessage(MSG* pMsg) 
-{
-	m_tooltip.RelayEvent(pMsg);
-	return CDialog::PreTranslateMessage(pMsg);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// CIDSEdit dialog
-
-CIDSEdit::CIDSEdit(CWnd* pParent /*=NULL*/)
-	: CDialog(CIDSEdit::IDD, pParent)
-{
-	//{{AFX_DATA_INIT(CIDSEdit)
-	m_hex = FALSE;
-	m_four = FALSE;
-	//}}AFX_DATA_INIT
-  m_inedit=false;
-  m_item=0;
-  m_subitem=0;
-	m_searchdlg=NULL;
-}
-
-void CIDSEdit::DoDataExchange(CDataExchange* pDX)
-{
-	CDialog::DoDataExchange(pDX);
-	//{{AFX_DATA_MAP(CIDSEdit)
-	DDX_Control(pDX, IDC_IDS, m_ids_control);
-	DDX_Check(pDX, IDC_INT, m_hex);
-	DDX_Check(pDX, IDC_FOUR, m_four);
-	//}}AFX_DATA_MAP
-}
-
-void CIDSEdit::NewIDS()
-{
-	the_ids.new_ids();
-	itemname="new identifiers";
-  m_hex=false;
-  m_four=false;
-}
-
-void CIDSEdit::SetHex()
-{
-  POSITION pos;
-  CString *tmppoi;
-  int i;
-
-  pos=the_ids.data->GetHeadPosition();
-  m_hex=false;
-  m_four=true;
-  for(i=0;i<the_ids.rows;i++)
-  {
-    tmppoi=(CString *) the_ids.data->GetNext(pos);
-    if(atoi(tmppoi[0])!=strtonum(tmppoi[0]) )
-    {
-      m_hex=true;
-      if(tmppoi[0].GetLength()!=6) m_four=false;
-    }
-    else
-    {
-      if(tmppoi[0].GetLength()<4) m_four=false;
-    }
-  }
-}
-
-void CIDSEdit::RefreshDialog()
-{
-  POSITION pos;
-  CString *tmppoi;
-  int i;
-  int val;
-
-  if(m_readonly)
-  {
-    SetWindowText("Browse IDS: "+itemname);
-  }
-  else
-  {
-    SetWindowText("Edit IDS: "+itemname);
-  }
-  m_ids_control.DeleteAllItems();
-  while(m_ids_control.DeleteColumn(0));
-  m_ids_control.SetItemCount(2);
-  m_ids_control.InsertColumn(0,"Value",LVCFMT_LEFT,80);
-  m_ids_control.InsertColumn(1,"Identifier",LVCFMT_LEFT,0);
-  ResizeLastColumn(m_ids_control,true);
-  pos=the_ids.data->GetHeadPosition();
-  for(i=0;i<the_ids.rows;i++)
-  {
-    tmppoi=(CString *) the_ids.data->GetNext(pos);
-    val=strtonum(tmppoi[0]);
-    if(m_four)
-    {
-      if(m_hex) tmppoi[0].Format("0x%04x",val);
-      else tmppoi[0].Format("%04d",val);
-    }
-    else
-    {
-      if(m_hex) tmppoi[0].Format("0x%x",val);
-      else tmppoi[0].Format("%d",val);
-    }
-
-    m_ids_control.InsertItem(i, tmppoi[0]);
-    m_ids_control.SetItemText(i, 1, tmppoi[1]);
-  }
-  UpdateData(UD_DISPLAY);
-}
-
-BOOL CIDSEdit::OnInitDialog() 
-{
-	CDialog::OnInitDialog();	
-	RefreshDialog();	
-  //tooltips
-  {
-    m_tooltip.Create(this,TTS_NOPREFIX);
-    m_tooltip.SetMaxTipWidth(200);
-    m_tooltip.SetTipBkColor(RGB(240,224,160));
-    
-    m_tooltip.AddTool(GetDlgItem(IDCANCEL), IDS_CANCEL);
-  }
-  if(m_readonly)
-  {
-    GetDlgItem(IDC_SAVEAS)->EnableWindow(false);
-  }
-  CMenu *menu=GetMenu();
-  if(menu) menu=menu->GetSubMenu(0);
-  if(menu)
-  {
-    menu->EnableMenuItem(ID_FILE_NEW,m_readonly?MF_GRAYED:MF_ENABLED);
-    menu->EnableMenuItem(ID_FILE_SAVE,m_readonly?MF_GRAYED:MF_ENABLED);
-    menu->EnableMenuItem(ID_FILE_SAVEAS,m_readonly?MF_GRAYED:MF_ENABLED);
-  }
-	return TRUE;
-}
-
-BEGIN_MESSAGE_MAP(CIDSEdit, CDialog)
-	//{{AFX_MSG_MAP(CIDSEdit)
-	ON_BN_CLICKED(IDC_LOAD, OnLoad)
-	ON_BN_CLICKED(IDC_LOADEX, OnLoadex)
-	ON_BN_CLICKED(IDC_NEW, OnNew)
-	ON_BN_CLICKED(IDC_SAVEAS, OnSaveas)
-	ON_BN_CLICKED(IDC_ROW, OnRow)
-	ON_NOTIFY(NM_CLICK, IDC_IDS, OnClickIds)
-	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_IDS, OnEndlabeleditIds)
-	ON_BN_CLICKED(IDC_INT, OnInt)
-	ON_BN_CLICKED(IDC_ORDER, OnOrder)
-	ON_BN_CLICKED(IDC_REMOVE, OnRemove)
-	ON_BN_CLICKED(IDC_FOUR, OnFour)
-	ON_COMMAND(ID_FILE_SAVE, OnSave)
-	ON_COMMAND(ID_FILE_NEW, OnNew)
-	ON_COMMAND(ID_FILE_LOAD, OnLoad)
-	ON_COMMAND(ID_FILE_LOADEXTERNALSCRIPT, OnLoadex)
-	ON_COMMAND(ID_INT, OnInt)
-	ON_COMMAND(ID_FOUR, OnFour)
-	ON_COMMAND(ID_REMOVE, OnRemove)
-	ON_COMMAND(ID_ORDER, OnOrder)
-	ON_COMMAND(ID_ADD, OnRow)
-	ON_COMMAND(ID_EDIT_FINDID, OnEditFindid)
-	//}}AFX_MSG_MAP
-  ON_EN_KILLFOCUS(IDC_EDITLINK,OnKillfocusEditlink)
-  ON_NOTIFY(NM_CUSTOMDRAW, IDC_IDS, OnCustomdrawMyList)
-	ON_REGISTERED_MESSAGE( WM_FINDREPLACE, OnFindReplace )
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// CIDSEdit message handlers
-
-void CIDSEdit::OnLoad() 
-{
-	int res;
-	
-  pickerdlg.m_restype=REF_IDS;
-  pickerdlg.m_picked=itemname;
-	res=pickerdlg.DoModal();
-	if(res==IDOK)
-	{
-		res=read_ids(pickerdlg.m_picked);
-    switch(res)
-    {
-    case 1:
-      MessageBox("Identifiers loaded with some errors.","Warning",MB_ICONEXCLAMATION|MB_OK);
-  		itemname=pickerdlg.m_picked;
-      break;
-    case 0:
-  		itemname=pickerdlg.m_picked;
-      break;
-    default:
-      MessageBox("Cannot read identifiers!","Error",MB_ICONSTOP|MB_OK);
-      NewIDS();
-      break;
-    }
-	}
-  SetHex();
-  RefreshDialog();
-}
-
-static char BASED_CODE szFilter2[] = "IDS files (*.ids)|*.ids|All files (*.*)|*.*||";
-
-void CIDSEdit::OnLoadex() 
-{
-  CString filepath;
-  int fhandle;
-  int res;
-  
-  res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER;
-  if(readonly) res|=OFN_READONLY;  
-  CMyFileDialog m_getfiledlg(TRUE, "ids", makeitemname(".ids",0), res, szFilter2);
-
-restart:  
-  if( m_getfiledlg.DoModal() == IDOK )
-  {
-    filepath=m_getfiledlg.GetPathName();
-    fhandle=open(filepath, O_RDONLY|O_BINARY);
-    if(!fhandle)
-    {
-      MessageBox("Cannot open file!","Error",MB_ICONSTOP|MB_OK);
-      goto restart;
-    }
-    readonly=m_getfiledlg.GetReadOnlyPref();
-    res=the_ids.ReadIDSFromFile(fhandle,-1);
-    close(fhandle);
-    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
-    switch(res)
-    {
-    case 1:
-      MessageBox("Identifiers loaded with some errors.","Warning",MB_ICONEXCLAMATION|MB_OK);
-      itemname=m_getfiledlg.GetFileTitle();
-      itemname.MakeUpper();
-      break;
-    case 0:
-      itemname=m_getfiledlg.GetFileTitle();
-      itemname.MakeUpper();
-      break;
-    default:
-      MessageBox("Cannot read identifiers!","Error",MB_ICONSTOP|MB_OK);
-      NewIDS();
-      break;
-    }
-  }
-  SetHex();
-  RefreshDialog();
-}
-
-void CIDSEdit::OnNew() 
-{
-  NewIDS();
-  RefreshDialog();
-}
-
-void CIDSEdit::OnSave() 
-{
-  SaveIDS(1);
-}
-
-void CIDSEdit::OnSaveas() 
-{
-  SaveIDS(0);
-}
-
-void CIDSEdit::SaveIDS(int save) 
-{
-  CString filepath;
-  CString newname;
-  CString tmpstr;
-  int fhandle;
-  int res;
-
-  if(readonly || m_readonly) //m_readonly is the local read only flag
-  {
-    MessageBox("You opened it read only!","Warning",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-  res=OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_EXPLORER;
-  CMyFileDialog m_getfiledlg(FALSE, "ids", makeitemname(".ids",0), res, szFilter2);
-
-  if(save)
-  {
-    newname=itemname;
-    filepath=makeitemname(".ids",0);
-    goto gotname;
-  }
-
-restart:  
-  if( m_getfiledlg.DoModal() == IDOK )
-  {
-    filepath=m_getfiledlg.GetPathName();
-    filepath.MakeLower();
-    if(filepath.Right(4)!=".ids")
-    {
-      filepath+=".ids";
-    }
-    newname=m_getfiledlg.GetFileName();
-    newname.MakeUpper();
-    if(newname.Right(4)==".IDS") newname=newname.Left(newname.GetLength()-4);
-gotname:
-    if(newname.GetLength()>8 || newname.GetLength()<1 || newname.Find(" ",0)!=-1)
-    {
-      tmpstr.Format("The resource name '%s' is bad, it should be 8 characters long and without spaces.",newname);
-      MessageBox(tmpstr,"Warning",MB_ICONEXCLAMATION|MB_OK);
-      goto restart;
-    }
-    if(newname!=itemname && file_exists(filepath) )
-    {
-      res=MessageBox("Do you want to overwrite "+newname+"?","Warning",MB_ICONQUESTION|MB_YESNO);
-      if(res==IDNO) goto restart;
-    }
-    fhandle=open(filepath, O_BINARY|O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
-    if(fhandle<1)
-    {
-      MessageBox("Can't write file!","Error",MB_ICONSTOP|MB_OK);
-      goto restart;
-    }
-    res=the_ids.WriteIDSToFile(fhandle);
-    close(fhandle);
-    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
-    switch(res)
-    {
-    case 0:
-      itemname=newname;
-      break; //saved successfully
-    case -2:
-      MessageBox("Error while writing file!","Error",MB_ICONSTOP|MB_OK);
-      break;
-    default:
-      MessageBox("Unhandled error!","Error",MB_ICONSTOP|MB_OK);
-    }
-  }
-  RefreshDialog();
-}
-
-void CIDSEdit::OnKillfocusEditlink()
-{
-  POSITION pos;
-  CString tmpstr;
-  CString *row;
-
-	if(m_inedit)
-  {
-    m_inedit=false;
-    if(m_item<the_ids.rows && m_subitem<2)
-    {
-      m_edit.GetWindowText(tmpstr);
-      if(m_item==-1)
-      {
-        //label
-      }
-      else
-      {
-        pos=the_ids.data->FindIndex(m_item);
-        if(pos)
-        {
-          row=(CString *)the_ids.data->GetAt(pos);
-          if(row)
-          {
-            row[m_subitem]=tmpstr;
-            m_ids_control.SetItemText(m_item,m_subitem,tmpstr);
-          }
-        }
-      }
-    }
-    m_edit.DestroyWindow();
-  }
-}
-
-bool CIDSEdit::perform_search(int idx, int match, CString srch)
-{
-	CString *row=(CString *)the_ids.data->GetAt(the_ids.data->FindIndex(idx));
-	if(row)
-	{
-		CString tmp2 = row[1];
-		
-		if(match&1) // case insensitive trick
-    {
-      tmp2.MakeLower();
-    }
-    if(match&2) // full word trick
-    {
-      tmp2=" "+tmp2+" "; //in this
-    }
-    if(tmp2.Find(srch) !=-1) return true;
-	}
-
-	return false;
-}
-
-void CIDSEdit::do_search(int direction, int match, CString search)
-{
-	int idx;
-	int start, end;
-
-	if (direction==0) direction=-1;
-
-	if (direction<0) end=-1;
-	else end=the_ids.rows;
-
-	if (direction<0) start=the_ids.rows-1;
-	else start=0;
-	for(idx=m_item+direction;idx!=end;idx+=direction)
-	{
-		if(perform_search(idx,match,search))
-		{
-			m_item=idx;
-			RefreshSelection();
-			return;
-		}
-	}
-	for(idx=start;idx!=m_item;idx+=direction)
-	{
-		if(perform_search(idx,match,search))
-		{
-			m_item=idx;
-			RefreshSelection();
-			return;
-		}
-	}
-
-}
-
-long CIDSEdit::OnFindReplace(WPARAM /*wParam*/, LPARAM /*lParam*/)
-{
-  int direction;
-  int match;
-  CString search;
-  CString replace;
-
-  if(!m_searchdlg) return 0;
-  if(m_searchdlg->IsTerminating() )
-  {
-    m_searchdlg=NULL;
-    return 0;
-  }
-  direction=m_searchdlg->SearchDown();
-  //matchcase is cheaper, therefore it is marked 0
-  match=!m_searchdlg->MatchCase()+(!!m_searchdlg->MatchWholeWord())*2; 
-  search=m_searchdlg->GetFindString();  
-
-  if(match&1) //we can do this here
-  {
-    search.MakeLower();
-  }
-  if(match&2) //this too
-  {
-    search=" "+search+" ";
-  }
-
-  do_search(direction,match,search);
-  return 0;
-}
-
-void CIDSEdit::OnEditFindid() 
-{
-	m_searchdlg=new CFindReplaceDialog;
-	m_searchdlg->Create(true,"",NULL, FR_DOWN, this);
-}
-
-void CIDSEdit::RefreshSelection()
-{
-	m_ids_control.EnsureVisible(m_item, false);
-	m_ids_control.SetItemState(m_item, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
-}
-
-void CIDSEdit::OnRemove() 
-{
-  if(m_item<0)
-  {
-    MessageBox("Please select an item to remove.","IDS editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	if(the_ids.RemoveRow(m_item))
-  {
-    m_ids_control.DeleteItem(m_item);
-    RefreshSelection();
-  }
-  else
-  {
-    MessageBox("Cannot remove item.","IDS editor",MB_ICONEXCLAMATION|MB_OK);
-  }
-  UpdateData(UD_DISPLAY);
-}
-
-void CIDSEdit::OnRow() 
-{
-  CString tmpstr, def;
-
-  if(m_four)
-  {
-    if(m_hex) def="0x0000";
-    else def="0000";
-  }
-  else
-  {
-    if(m_hex) def="0x0";
-    else def="0";
-  }
-  if(m_item<0) m_item=the_ids.rows;
-  tmpstr.Format("Identifier%d",m_item);
-  the_ids.AddRow(m_item,def,tmpstr);
-  m_ids_control.InsertItem(m_item, def);
-  m_ids_control.SetItemText(m_item, 1, tmpstr);
-  RefreshSelection();
-  UpdateData(UD_DISPLAY);
-}
-
-void CIDSEdit::OnClickIds(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  CString tmpstr;
-  CRect ref, ref2;
-  LVHITTESTINFO htinfo;
-  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
-
-  if(IsWindow(m_edit)) m_edit.DestroyWindow();
-  htinfo.pt=pNMListView->ptAction;
-	m_item=m_ids_control.SubItemHitTest(&htinfo);
-  if(m_item<0) return;
-  m_subitem=htinfo.iSubItem;
-  if(!m_subitem)
-  {
-    m_ids_control.EditLabel(m_item);
-  }
-  else
-  {
-    m_ids_control.GetSubItemRect(m_item,1,0,ref);
-    tmpstr=m_ids_control.GetItemText(m_item,1);
-    m_ids_control.GetWindowRect(ref2);
-    ScreenToClient(ref2);
-    ref.left+=ref2.left;
-    ref.top+=ref2.top;
-    ref.right+=ref2.left;
-    ref.bottom+=ref2.top+2;
-    m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER,ref,this,IDC_EDITLINK);
-    m_edit.SetWindowText(tmpstr);
-    m_edit.SetFocus();
-    m_edit.SetSel(0,-1);
-    m_inedit=true;
-  }
-	*pResult = 0;
-}
-
-void CIDSEdit::OnEndlabeleditIds(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  int val;
-  CString tmpstr;
-	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
-  CString *tmppoi;
-
-  if(pDispInfo->item.pszText)
-  {
-    val=strtonum(pDispInfo->item.pszText);
-    if(m_four)
-    {
-      if(m_hex) tmpstr.Format("0x%04X",val);
-      else tmpstr.Format("%04d",val);
-    }
-    else
-    {
-      if(m_hex) tmpstr.Format("0x%x",val);
-      else tmpstr.Format("%d",val);
-    }
-	  m_ids_control.SetItemText(pDispInfo->item.iItem, 0, tmpstr);
-    tmppoi=(CString *) the_ids.data->GetAt(the_ids.data->FindIndex(pDispInfo->item.iItem));
-    tmppoi[0]=tmpstr;
-  }
-	*pResult = 0;
-}
-
-void CIDSEdit::OnInt() 
-{
-  UpdateData(UD_RETRIEVE);
-  m_hex=!m_hex;
-	RefreshDialog();
-}
-
-void CIDSEdit::OnFour() 
-{
-  UpdateData(UD_RETRIEVE);
-  m_four=!m_four;
-	RefreshDialog();
-}
-
-void CIDSEdit::OnOrder() 
-{
-  CString *tmppoi, *tmppoi2;
-  POSITION pos, pos2, pos3;
-  CPtrList *data2;
-  int val;
-  int mask;
-
-  if(itemname=="TRIGGER") mask=0x3fff;
-  else mask=~0;
-  data2=new CPtrList;
-  if(!data2) return; //can't order it due to low memory
-  pos=the_ids.data->GetHeadPosition();
-  while(pos)
-  {
-    tmppoi=(CString *) the_ids.data->GetNext(pos);
-    val=strtonum(tmppoi[0])&mask;
-    pos2=data2->GetTailPosition();
-    do
-    {
-      pos3=pos2;
-      if(!pos2) break;
-      tmppoi2=(CString *) data2->GetPrev(pos2);
-    }
-    while((strtonum(tmppoi2[0])&mask)>val);
-    if(pos3) data2->InsertAfter(pos3,tmppoi);
-    else data2->AddHead(tmppoi);
-  }
-  delete the_ids.data; //we must not delete referenced data members
-	the_ids.data=data2;
-	RefreshDialog();
-}
-
-void CIDSEdit::OnCustomdrawMyList(NMHDR *pNMHDR, LRESULT *pResult)
-{
-  NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
-  
-  // Take the default processing unless we set this to something else below.
-  *pResult = CDRF_DODEFAULT;
-  
-  // First thing - check the draw stage. If it's the control's prepaint
-  // stage, then tell Windows we want messages for every item.
-  
-  if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
-  {
-    *pResult = CDRF_NOTIFYITEMDRAW;
-  }
-  else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
-  {
-    // This is the prepaint stage for an item. Here's where we set the
-    // item's text color. Our return value will tell Windows to draw the
-    // item itself, but it will use the new color we set here.
-    // We'll cycle the colors through red, green, and light blue.
-    
-    COLORREF crText;
-    
-    if(pLVCD->nmcd.dwItemSpec &1)
-    {
-      crText = RGB(240,240,240);
-    }
-    else
-    {
-      crText = RGB(255,255,255);
-    }
-    
-    // Store the color back in the NMLVCUSTOMDRAW struct.
-    pLVCD->clrTextBk = crText;
-    
-    // Tell Windows to paint the control itself.
-    *pResult = CDRF_DODEFAULT;
-  }
-}
-
-BOOL CIDSEdit::PreTranslateMessage(MSG* pMsg) 
-{
-	m_tooltip.RelayEvent(pMsg);
-	return CDialog::PreTranslateMessage(pMsg);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// CMUSEdit dialog
-
-void CMUSEdit::NewMUS()
-{
-	the_mus.new_mus();
-  the_mus.internal="";
-	itemname="new musiclist";
-}
-
-CMUSEdit::CMUSEdit(CWnd* pParent /*=NULL*/)
-	: CDialog(CMUSEdit::IDD, pParent)
-{
-	//{{AFX_DATA_INIT(CMUSEdit)
-		// NOTE: the ClassWizard will add member initialization here
-	//}}AFX_DATA_INIT
-  m_inedit=0;
-  m_item=0;
-  m_subitem=0;
-}
-
-void CMUSEdit::DoDataExchange(CDataExchange* pDX)
-{
-	CDialog::DoDataExchange(pDX);
-	//{{AFX_DATA_MAP(CMUSEdit)
-	DDX_Control(pDX, IDC_MUS, m_mus_control);
-	//}}AFX_DATA_MAP
-}
-
-BEGIN_MESSAGE_MAP(CMUSEdit, CDialog)
-	//{{AFX_MSG_MAP(CMUSEdit)
-	ON_BN_CLICKED(IDC_REMOVE, OnRemove)
-	ON_BN_CLICKED(IDC_ROW, OnRow)
-	ON_BN_CLICKED(IDC_LOAD, OnLoad)
-	ON_BN_CLICKED(IDC_LOADEX, OnLoadex)
-	ON_BN_CLICKED(IDC_SAVEAS, OnSaveas)
-	ON_BN_CLICKED(IDC_NEW, OnNew)
-	ON_NOTIFY(NM_CLICK, IDC_MUS, OnClickMus)
-	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_MUS, OnEndlabeleditMus)
-	ON_NOTIFY(NM_RCLICK, IDC_MUS, OnRClickMus)
-	ON_BN_CLICKED(IDC_PLAYWHOLE, OnPlaywhole)
-	ON_BN_CLICKED(IDC_PLAY, OnRClickCmd)
-	ON_COMMAND(ID_PLAY_PLAYWHOLE, OnPlaywhole)
-	ON_COMMAND(ID_PLAY_PLAYPART, OnRClickCmd)
-	ON_COMMAND(ID_ADD, OnRow)
-	ON_COMMAND(ID_REMOVE, OnRemove)
-	//}}AFX_MSG_MAP
-  ON_EN_KILLFOCUS(IDC_EDITLINK,OnKillfocusEditlink)
-  ON_NOTIFY(NM_CUSTOMDRAW, IDC_MUS, OnCustomdrawMyList)
-END_MESSAGE_MAP()
-
-/////////////////////////////////////////////////////////////////////////////
-// CMUSEdit message handlers
-void CMUSEdit::OnLoad() 
-{
-	int res;
-	
-  pickerdlg.m_restype=REF_MUS;
-  pickerdlg.m_picked=itemname;
-	res=pickerdlg.DoModal();
-	if(res==IDOK)
-	{
-		res=read_mus(pickerdlg.m_picked);
-    switch(res)
-    {
-    case 1:
-      MessageBox("Musiclist loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
-  		itemname=pickerdlg.m_picked;
-      break;
-    case 0:
-  		itemname=pickerdlg.m_picked;
-      break;
-    default:
-      MessageBox("Cannot read list!","Error",MB_ICONSTOP|MB_OK);
-      NewMUS();
-      break;
-    }
-	}
-  RefreshDialog();
-}
-
-static char BASED_CODE szFilter3[] = "Musiclists (*.mus)|*.mus|All files (*.*)|*.*||";
-
-void CMUSEdit::OnLoadex() 
-{
-  CString filepath;
-  int fhandle;
-  int res;
-  
-  res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER;
-  if(readonly) res|=OFN_READONLY;  
-  CMyFileDialog m_getfiledlg(TRUE, "mus", makeitemname(".mus",4), res, szFilter3);
-
-restart:  
-  if( m_getfiledlg.DoModal() == IDOK )
-  {
-    filepath=m_getfiledlg.GetPathName();
-    fhandle=open(filepath, O_RDONLY|O_BINARY);
-    if(!fhandle)
-    {
-      MessageBox("Cannot open file!","Error",MB_ICONSTOP|MB_OK);
-      goto restart;
-    }
-    readonly=m_getfiledlg.GetReadOnlyPref();
-    res=the_mus.ReadMusFromFile(fhandle,-1);
-    close(fhandle);
-    lastopenedmusic=filepath.Left(filepath.ReverseFind('\\'));
-    switch(res)
-    {
-    case 1:
-      MessageBox("Musiclist loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
-      itemname=m_getfiledlg.GetFileTitle();
-      itemname.MakeUpper();
-      break;
-    case 0:
-      itemname=m_getfiledlg.GetFileTitle();
-      itemname.MakeUpper();
-      break;
-    default:
-      MessageBox("Cannot read list!","Error",MB_ICONSTOP|MB_OK);
-      NewMUS();
-      break;
-    }
-  }
-  RefreshDialog();
-}
-
-void CMUSEdit::OnSaveas() 
-{
-  CString filepath;
-  CString newname;
-  CString tmpstr;
-  int fhandle;
-  int res;
-
-  if(readonly)
-  {
-    MessageBox("You opened it read only!","Warning",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-  res=OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_EXPLORER;
-  //CMyFileDialog m_getfiledlg(FALSE, "mus", bgfolder+"music\\"+itemname+".mus", res, szFilter3);
-  CMyFileDialog m_getfiledlg(FALSE, "mus", makeitemname(".mus",4), res, szFilter3);
-restart:  
-  if( m_getfiledlg.DoModal() == IDOK )
-  {
-    filepath=m_getfiledlg.GetPathName();
-    filepath.MakeLower();
-    if(filepath.Right(4)!=".mus")
-    {
-      filepath+=".mus";
-    }
-    newname=m_getfiledlg.GetFileName();
-    newname.MakeUpper();
-    if(newname.Right(4)==".MUS") newname=newname.Left(newname.GetLength()-4);
-    if(newname.GetLength()>8 || newname.GetLength()<1 || newname.Find(" ",0)!=-1)
-    {
-      tmpstr.Format("The resource name '%s' is bad, it should be 8 characters long and without spaces.",newname);
-      MessageBox(tmpstr,"Warning",MB_ICONEXCLAMATION|MB_OK);
-      goto restart;
-    }
-    if(newname!=itemname && file_exists(filepath) )
-    {
-      res=MessageBox("Do you want to overwrite "+newname+"?","Warning",MB_ICONQUESTION|MB_YESNO);
-      if(res==IDNO) goto restart;
-    }
-    fhandle=open(filepath, O_BINARY|O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
-    if(fhandle<1)
-    {
-      MessageBox("Can't write file!","Error",MB_ICONSTOP|MB_OK);
-      goto restart;
-    }
-    if(the_mus.internal.IsEmpty()) the_mus.internal=newname;
-    the_mus.internal.MakeUpper();
-
-    res=the_mus.WriteMusToFile(fhandle);
-    close(fhandle);
-    lastopenedmusic=filepath.Left(filepath.ReverseFind('\\'));
-    switch(res)
-    {
-    case 0:
-      itemname=newname;
-      break; //saved successfully
-    case -2:
-      MessageBox("Error while writing file!","Error",MB_ICONSTOP|MB_OK);
-      break;
-    default:
-      MessageBox("Unhandled error!","Error",MB_ICONSTOP|MB_OK);
-    }
-  }
-  RefreshDialog();
-}
-
-void CMUSEdit::OnNew() 
-{
-  NewMUS();
-  RefreshDialog();
-}
-
-void CMUSEdit::OnKillfocusEditlink()
-{
-  POSITION pos;
-  CString tmpstr;
-  CString *row;
-
-	switch(m_inedit)
-  {
-  case 0:
-    m_edit.DestroyWindow();
-    break;
-  case 1:
-    m_inedit=0;
-    if(m_item<the_mus.rows && m_subitem<MUSCOLUMN)
-    {
-      m_edit.GetWindowText(tmpstr);
-      tmpstr.MakeUpper();
-      pos=the_mus.data->FindIndex(m_item);
-      if(pos)
-      {
-        row=(CString *)the_mus.data->GetAt(pos);
-        if(row)
-        {
-          row[m_subitem]=tmpstr;
-          m_mus_control.SetItemText(m_item,m_subitem,tmpstr);
-        }
-      }
-    }
-    m_edit.DestroyWindow();
-  }
-}
-
-void CMUSEdit::OnRemove() 
-{
-  if(m_item<0)
-  {
-    MessageBox("Please select a row!","Musiclist editor",MB_ICONEXCLAMATION|MB_OK);
-    return;
-  }
-	if(the_mus.RemoveRow(m_item))
-  {
-    RefreshDialog();
-  }
-  else MessageBox("Cannot remove row!","Musiclist editor",MB_ICONEXCLAMATION|MB_OK);
-}
-
-void CMUSEdit::OnRow() 
-{
-  if(m_item<0) m_item=the_2da.rows;
-  the_mus.AddRow(m_item,"NEW","","");
-  RefreshDialog();
-}
-
-static CString muscolumns[MUSCOLUMN]={"Part suffix","Loop suffix","Tag suffix"};
-
-void CMUSEdit::RefreshDialog()
-{
-  POSITION pos;
-  CString *tmppoi;
-  int i,j;
-  int width;
-
-  SetWindowText("Edit musiclist: "+itemname);
-  m_mus_control.DeleteAllItems();
-  while(m_mus_control.DeleteColumn(0));
-  m_mus_control.SetItemCount(MUSCOLUMN);
-  for(i=0;i<MUSCOLUMN;i++) //3 
-  {
-    width=10*muscolumns[i].GetLength();
-    if(width<50) width=50;
-    m_mus_control.InsertColumn(i,muscolumns[i],LVCFMT_LEFT,width);
-  }
-  ResizeLastColumn(m_mus_control,true);
-  pos=the_mus.data->GetHeadPosition();
-  for(i=0;i<the_mus.rows;i++)
-  {
-    tmppoi=(CString *) the_mus.data->GetNext(pos);
-    m_mus_control.InsertItem(i, tmppoi[0]);
-    for(j=1;j<MUSCOLUMN;j++)
-    {
-      m_mus_control.SetItemText(i, j, tmppoi[j]);
-    }
-  }
-  UpdateData(UD_DISPLAY);
-}
-
-BOOL CMUSEdit::OnInitDialog() 
-{
-  CString tmpstr, tmpstr1, tmpstr2;
-
-	CDialog::OnInitDialog();
-	RefreshDialog();	
-  //tooltips
-  {
-    m_tooltip.Create(this,TTS_NOPREFIX);
-    m_tooltip.SetMaxTipWidth(200);
-    m_tooltip.SetTipBkColor(RGB(240,224,160));
-    
-    m_tooltip.AddTool(GetDlgItem(IDCANCEL), IDS_CANCEL);
-    tmpstr1.LoadString(IDS_LOAD);
-    tmpstr2.LoadString(IDS_MUS);
-    tmpstr.Format(tmpstr1, tmpstr2);
-    m_tooltip.AddTool(GetDlgItem(IDC_LOAD), tmpstr);
-    tmpstr1.LoadString(IDS_LOADEX);
-    tmpstr.Format(tmpstr1, tmpstr2);
-    m_tooltip.AddTool(GetDlgItem(IDC_LOADEX), tmpstr);
-    tmpstr1.LoadString(IDS_SAVE);
-    tmpstr.Format(tmpstr1, tmpstr2);
-    m_tooltip.AddTool(GetDlgItem(IDC_SAVEAS), tmpstr);
-    tmpstr1.LoadString(IDS_NEW);
-    tmpstr.Format(tmpstr1, tmpstr2);
-    m_tooltip.AddTool(GetDlgItem(IDC_NEW), tmpstr);
-  }	
-	return TRUE;
-}
-
-void CMUSEdit::Click()
-{
-  CString tmpstr;
-  CRect ref, ref2;
-
-  if(!m_subitem)
-  {
-    m_mus_control.EditLabel(m_item);
-  }
-  else
-  {
-    m_mus_control.GetSubItemRect(m_item,m_subitem,0,ref);
-    if(m_item==-1) return;
-    tmpstr=m_mus_control.GetItemText(m_item,m_subitem);
-    m_mus_control.GetWindowRect(ref2);
-    ScreenToClient(ref2);
-    ref.left+=ref2.left;
-    ref.top+=ref2.top;
-    ref.right+=ref2.left;
-    ref.bottom+=ref2.top+2;
-    m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER|ES_AUTOHSCROLL,ref,this,IDC_EDITLINK);
-    m_edit.SetWindowText(tmpstr);
-    m_edit.SetSel(0,-1);
-    m_inedit=1;
-    m_edit.SetFocus();
-  }
-}
-
-void CMUSEdit::OnClickMus(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  LVHITTESTINFO htinfo;
-  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
-
-  if(IsWindow(m_edit)) m_edit.DestroyWindow();
-  htinfo.pt=pNMListView->ptAction;
-	m_item=m_mus_control.SubItemHitTest(&htinfo);
-  m_subitem=htinfo.iSubItem;
-  Click();
-	*pResult = 0;
-}
-
-int CMUSEdit::RClick()
-{
-  CString filename;
-
-  filename=m_mus_control.GetItemText(m_item,m_subitem);
-  //these hacks are the same as in the engine code
-  return play_acm(convert_musiclist(filename, true), true, false);
-}
-
-void CMUSEdit::OnPlaywhole() 
-{
-  panicbutton dlg;
-  int poi;
-  int tmpitem=m_item;
-  int tmpsubitem=m_subitem;
-  void *memory1=NULL, *memory2=NULL;
-  CString filename;
-  int ret;
-
-  m_subitem=0;
-  filename=m_mus_control.GetItemText(m_item++,m_subitem);
-  poi=play_acm(convert_musiclist(filename, true), true, true);
-  if(poi<1 && poi>-10) goto endofquest;
-  memory1=(void *) poi;
-  
-	for(;m_item<the_mus.rows;m_item++)
-  {
-    if(memory1)
-    {
-      sndPlaySound((const char *) memory1,SND_MEMORY | SND_ASYNC);
-    }
-    filename=m_mus_control.GetItemText(m_item,m_subitem);
-    poi=play_acm(convert_musiclist(filename, true), true, true);
-    if(poi<1 && poi>-10) goto endofquest;
-    memory2=(void *) poi;
-    BringWindowToTop();//this is needed so there is no crash when the window was hidden (braindead Windows)
-    dlg.waitsound=true;
-    ret=dlg.DoModal();
-    sndPlaySound(NULL,SND_NODEFAULT);
-    if(memory1) delete memory1;
-    memory1=memory2;
-    if(ret==IDCANCEL) goto endofquest;
-  }
-  if(memory1)
-  {
-    sndPlaySound((const char *) memory1,SND_MEMORY | SND_ASYNC);
-  }
-  BringWindowToTop(); //this is needed so there is no crash when the window was hidden
-  dlg.waitsound=true;
-  dlg.DoModal();
-  sndPlaySound(NULL,SND_NODEFAULT);
-endofquest:
-  if(memory1)
-  {
-    delete memory1;
-  }
-  m_item=tmpitem;
-  m_subitem=tmpsubitem;
-}
-
-void CMUSEdit::OnRClickCmd()
-{
-  RClick();
-}
-
-void CMUSEdit::OnRClickMus(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  LVHITTESTINFO htinfo;
-  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
-
-  if(IsWindow(m_edit)) m_edit.DestroyWindow();
-  htinfo.pt=pNMListView->ptAction;
-	m_item=m_mus_control.SubItemHitTest(&htinfo);
-  m_subitem=htinfo.iSubItem;
-  if((m_subitem>=0) && (m_item>=0))
-  {
-    RClick();
-  }
-	*pResult = 0;
-}
-
-void CMUSEdit::OnEndlabeleditMus(NMHDR* pNMHDR, LRESULT* pResult) 
-{
-  CString tmpstr;
-  CString *tmppoi;
-	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
-
-  if(pDispInfo->item.pszText)
-  {
-    tmpstr=pDispInfo->item.pszText;
-	  m_mus_control.SetItemText(pDispInfo->item.iItem, 0, tmpstr);
-    tmppoi=(CString *) the_mus.data->GetAt(the_mus.data->FindIndex(pDispInfo->item.iItem));
-    tmppoi[0]=tmpstr;
-  }
-	*pResult = 0;
-}
-
-void CMUSEdit::OnCustomdrawMyList(NMHDR *pNMHDR, LRESULT *pResult)
-{
-  NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
-  
-  // Take the default processing unless we set this to something else below.
-  *pResult = CDRF_DODEFAULT;
-  
-  // First thing - check the draw stage. If it's the control's prepaint
-  // stage, then tell Windows we want messages for every item.
-  
-  if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
-  {
-    *pResult = CDRF_NOTIFYITEMDRAW;
-  }
-  else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
-  {
-    // This is the prepaint stage for an item. Here's where we set the
-    // item's text color. Our return value will tell Windows to draw the
-    // item itself, but it will use the new color we set here.
-    // We'll cycle the colors through red, green, and light blue.
-    
-    COLORREF crText;
-    
-    if(pLVCD->nmcd.dwItemSpec &1)
-    {
-      crText = RGB(240,240,240);
-    }
-    else
-    {
-      crText = RGB(255,255,255);
-    }
-    
-    // Store the color back in the NMLVCUSTOMDRAW struct.
-    pLVCD->clrTextBk = crText;
-    
-    // Tell Windows to paint the control itself.
-    *pResult = CDRF_DODEFAULT;
-  }
-}
-
-BOOL CMUSEdit::PreTranslateMessage(MSG* pMsg) 
-{
-  m_tooltip.RelayEvent(pMsg);
-	return CDialog::PreTranslateMessage(pMsg);
-}
-
+// 2DAEdit.cpp : implementation file
+//
+
+#include "stdafx.h"
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <mmsystem.h>
+#include "chitem.h"
+#include "2da.h"
+#include "2DAEdit.h"
+#include "StrRefDlg.h"
+#include "progressbar.h"
+#include "ColorPicker.h"
+#include "MyFileDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+static void ResizeLastColumn(CListCtrl &lc, BOOL bSubtractScroll)
+{
+	CHeaderCtrl *pHeader = lc.GetHeaderCtrl();
+
+	int nCount = pHeader->GetItemCount();
+	if (!nCount)
+		return;
+
+	int nTotal = 0;
+	CRect rHeader;
+	pHeader->GetClientRect(&rHeader);
+	HDITEM hdi;
+	hdi.mask = HDI_WIDTH;
+
+	for(int i=0;i<nCount-1;i++)
+	{
+		pHeader->GetItem(i,&hdi);
+		if (hdi.mask & HDI_WIDTH)
+			nTotal += hdi.cxy;
+	}
+
+	hdi.cxy = rHeader.Width() - nTotal;
+	if (bSubtractScroll)
+		hdi.cxy -= ::GetSystemMetrics(SM_CXHSCROLL);
+
+	pHeader->SetItem(nCount-1,&hdi);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// C2DAEdit dialog
+
+C2DAEdit::C2DAEdit(CWnd* pParent /*=NULL*/)	: CDialog(C2DAEdit::IDD, pParent)
+{
+	//{{AFX_DATA_INIT(C2DAEdit)
+	m_integer = FALSE;
+	//}}AFX_DATA_INIT
+  m_inedit=0;
+  m_item=0;
+  m_subitem=0;
+}
+
+void C2DAEdit::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(C2DAEdit)
+	DDX_Control(pDX, IDC_2DA, m_2da_control);
+	DDX_Check(pDX, IDC_INT, m_integer);
+	//}}AFX_DATA_MAP
+  DDX_Text(pDX, IDC_DEFAULT, the_2da.defvalue);
+  if(the_2da.defvalue.IsEmpty())
+  {
+    if(m_integer) the_2da.defvalue="-1";
+    else the_2da.defvalue="*";
+  }
+}
+
+BEGIN_MESSAGE_MAP(C2DAEdit, CDialog)
+	//{{AFX_MSG_MAP(C2DAEdit)
+	ON_BN_CLICKED(IDC_LOAD, OnLoad)
+	ON_BN_CLICKED(IDC_LOADEX, OnLoadex)
+	ON_BN_CLICKED(IDC_SAVEAS, OnSaveas)
+	ON_BN_CLICKED(IDC_NEW, OnNew)
+	ON_BN_CLICKED(IDC_INT, OnInt)
+	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_2DA, OnEndlabeledit2da)
+	ON_NOTIFY(NM_CLICK, IDC_2DA, OnClick2da)
+	ON_NOTIFY(LVN_COLUMNCLICK, IDC_2DA, OnColumnclick2da)
+	ON_BN_CLICKED(IDC_ROW, OnRow)
+	ON_BN_CLICKED(IDC_COLUMN, OnColumn)
+	ON_BN_CLICKED(IDC_REMOVE, OnRemove)
+	ON_BN_CLICKED(IDC_REMOVE2, OnRemove2)
+	ON_NOTIFY(NM_RCLICK, IDC_2DA, OnRClick2da)
+	ON_BN_CLICKED(IDC_COPY2, OnCopy2)
+	ON_BN_CLICKED(IDC_COPY, OnCopy)
+	ON_BN_CLICKED(IDC_PASTE2, OnPaste2)
+	ON_BN_CLICKED(IDC_PASTE, OnPaste)
+	ON_BN_CLICKED(IDC_COLUMN2, OnColumn2)
+	ON_BN_CLICKED(IDC_ROW2, OnRow2)
+	ON_COMMAND(ID_FILE_SAVE, OnSave)
+	ON_COMMAND(ID_TOOLS_CAPITALIZEENTRIES, OnToolsCapitalize)
+	ON_COMMAND(ID_TOOLS_LOOKUPSTRREF, OnToolsLookupstrref)
+	ON_BN_CLICKED(IDC_ORDER, OnOrder)
+	ON_COMMAND(ID_TOOLS_ADDSPARKDATA, OnToolsAddsparkdata)
+	ON_EN_KILLFOCUS(IDC_DEFAULT, DefaultKillfocus)
+	ON_COMMAND(ID_FILE_NEW, OnNew)
+	ON_COMMAND(ID_FILE_LOAD, OnLoad)
+	ON_COMMAND(ID_FILE_LOADEXTERNALSCRIPT, OnLoadex)
+	ON_COMMAND(ID_FILE_SAVEAS, OnSaveas)
+	ON_COMMAND(ID_TOOLS_PLAYSOUND, OnToolsPlaysound)
+	//}}AFX_MSG_MAP
+  ON_EN_KILLFOCUS(IDC_EDITLINK,OnKillfocusEditlink)
+  ON_NOTIFY(NM_CUSTOMDRAW, IDC_2DA, OnCustomdrawMyList)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// C2DAEdit message handlers
+
+void C2DAEdit::New2DA()
+{
+  CString *tmppoi;
+
+	the_2da.new_2da();
+  tmppoi=new CString[1];
+  if(!tmppoi) return;
+  tmppoi[0]="";
+  the_2da.collabels=tmppoi;
+	itemname="new 2da";
+}
+
+void C2DAEdit::OnLoad() 
+{
+	int res;
+	
+  if(IsWindow(m_edit)) return;
+  pickerdlg.m_restype=REF_2DA;
+  pickerdlg.m_picked=itemname;
+	res=pickerdlg.DoModal();
+	if(res==IDOK)
+	{
+		res=read_2da(pickerdlg.m_picked, the_2da);
+    switch(res)
+    {
+    case 1:
+      MessageBox("2da loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
+  		itemname=pickerdlg.m_picked;
+      break;
+    case 0:
+  		itemname=pickerdlg.m_picked;
+      break;
+    default:
+      MessageBox("Cannot read 2da!","Error",MB_ICONSTOP|MB_OK);
+      New2DA();
+      break;
+    }
+	}
+  RefreshDialog();
+}
+
+static char BASED_CODE szFilter[] = "2DA files (*.2da)|*.2da|All files (*.*)|*.*||";
+
+void C2DAEdit::OnLoadex() 
+{
+  CString filepath;
+  int fhandle;
+  int res;
+  
+  res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER;
+  if(readonly) res|=OFN_READONLY;  
+  CMyFileDialog m_getfiledlg(TRUE, "2da", makeitemname(".2da",0), res, szFilter);
+
+restart:  
+  if( m_getfiledlg.DoModal() == IDOK )
+  {
+    filepath=m_getfiledlg.GetPathName();
+    fhandle=open(filepath, O_RDONLY|O_BINARY);
+    if(!fhandle)
+    {
+      MessageBox("Cannot open file!","Error",MB_ICONSTOP|MB_OK);
+      goto restart;
+    }
+    readonly=m_getfiledlg.GetReadOnlyPref();
+    res=the_2da.Read2DAFromFile(fhandle,-1);
+    close(fhandle);
+    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
+    switch(res)
+    {
+    case 1:
+      MessageBox("2da loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
+      itemname=m_getfiledlg.GetFileTitle();
+      itemname.MakeUpper();
+      break;
+    case 0:
+      itemname=m_getfiledlg.GetFileTitle();
+      itemname.MakeUpper();
+      break;
+    default:
+      MessageBox("Cannot read 2da!","Error",MB_ICONSTOP|MB_OK);
+      New2DA();
+      break;
+    }
+  }
+  RefreshDialog();
+}
+
+void C2DAEdit::OnSave() 
+{
+  SaveTable(1);
+}
+
+void C2DAEdit::OnSaveas() 
+{
+  SaveTable(0);
+}
+
+void C2DAEdit::SaveTable(int save) 
+{
+  CString filepath;
+  CString newname;
+  CString tmpstr;
+  int res;
+
+  if(readonly)
+  {
+    MessageBox("You opened it read only!","Warning",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+  res=OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_EXPLORER;
+  CMyFileDialog m_getfiledlg(FALSE, "2da", makeitemname(".2da",0), res, szFilter);
+
+  if(save)
+  {
+    newname=itemname;
+    filepath=makeitemname(".2da",0);
+    goto gotname;
+  }
+
+restart:  
+  if( m_getfiledlg.DoModal() == IDOK )
+  {
+    filepath=m_getfiledlg.GetPathName();
+    filepath.MakeLower();
+    if(filepath.Right(4)!=".2da")
+    {
+      filepath+=".2da";
+    }
+    newname=m_getfiledlg.GetFileName();
+    newname.MakeUpper();
+    if(newname.Right(4)==".2DA") newname=newname.Left(newname.GetLength()-4);
+gotname:
+    if(newname.GetLength()>8 || newname.GetLength()<1 || newname.Find(" ",0)!=-1)
+    {
+      tmpstr.Format("The resource name '%s' is bad, it should be 8 characters long and without spaces.",newname);
+      MessageBox(tmpstr,"Warning",MB_ICONEXCLAMATION|MB_OK);
+      goto restart;
+    }
+    if(newname!=itemname && file_exists(filepath) )
+    {
+      res=MessageBox("Do you want to overwrite "+newname+"?","Warning",MB_ICONQUESTION|MB_YESNO);
+      if(res==IDNO) goto restart;
+    }
+
+    res=write_2da(newname, filepath);
+    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
+    switch(res)
+    {
+    case 0:
+      itemname=newname;
+      break; //saved successfully
+    case -2:
+      MessageBox("Error while writing file!","Error",MB_ICONSTOP|MB_OK);
+      break;
+    default:
+      MessageBox("Unhandled error!","Error",MB_ICONSTOP|MB_OK);
+    }
+  }
+  RefreshDialog();
+}
+
+void C2DAEdit::OnNew() 
+{
+  New2DA();
+  RefreshDialog();
+}
+
+void C2DAEdit::RefreshDialog()
+{
+  POSITION pos;
+  CString *tmppoi;
+  int i,j;
+  int width, minwidth;
+
+  SetWindowText("Edit 2DA: "+itemname);
+  m_2da_control.DeleteAllItems();
+  while(m_2da_control.DeleteColumn(0));
+  m_2da_control.SetItemCount(the_2da.cols);
+  if (m_integer) minwidth = 50;
+  else minwidth = 100;
+  for(i=0;i<the_2da.cols;i++)
+  {
+    width=10*the_2da.collabels[i].GetLength();
+    if(width<minwidth) width=minwidth;
+    m_2da_control.InsertColumn(i,the_2da.collabels[i],LVCFMT_LEFT,width);
+  }
+  pos=the_2da.data->GetHeadPosition();
+  for(i=0;i<the_2da.rows;i++)
+  {
+    tmppoi=(CString *) the_2da.data->GetNext(pos);
+    m_2da_control.InsertItem(i, tmppoi[0]);
+    for(j=1;j<the_2da.cols;j++)
+    {
+      m_2da_control.SetItemText(i, j, tmppoi[j]);
+      if (tmppoi[j].Left(3)=="RGB")
+      {
+        the_2da.defvalue="RGB(0,0,0)";
+      }
+    }
+  }
+  m_integer=!invalidnumber(the_2da.defvalue);
+  UpdateData(UD_DISPLAY);
+}
+
+BOOL C2DAEdit::OnInitDialog() 
+{
+	CDialog::OnInitDialog();
+	RefreshDialog();
+
+  //tooltips
+  {
+    m_tooltip.Create(this,TTS_NOPREFIX);
+    m_tooltip.SetMaxTipWidth(200);
+    m_tooltip.SetTipBkColor(RGB(240,224,160));
+    
+    m_tooltip.AddTool(GetDlgItem(IDCANCEL), IDS_CANCEL);
+  }
+	return TRUE;  
+}
+
+void C2DAEdit::DefaultKillfocus() 
+{
+	UpdateData(UD_RETRIEVE);	
+	UpdateData(UD_DISPLAY);	
+}
+
+void C2DAEdit::OnInt() 
+{
+  m_integer=!m_integer;
+	UpdateData(UD_DISPLAY);	
+}
+
+void C2DAEdit::OnEndlabeledit2da(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  CString tmpstr;
+  CString *tmppoi;
+	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+
+  if(pDispInfo->item.pszText)
+  {
+    tmpstr=pDispInfo->item.pszText;
+	  m_2da_control.SetItemText(pDispInfo->item.iItem, 0, tmpstr);
+    tmppoi=(CString *) the_2da.data->GetAt(the_2da.data->FindIndex(pDispInfo->item.iItem));
+    tmppoi[0]=tmpstr;
+  }
+	*pResult = 0;
+}
+
+void C2DAEdit::RClick()
+{
+  CString tmpstr;
+  CRect ref, ref2;
+
+  m_2da_control.GetSubItemRect(m_item,m_subitem,0,ref);
+  tmpstr=m_2da_control.GetItemText(m_item,m_subitem);
+  tmpstr=resolve_tlk_text(strtonum(tmpstr));
+  m_2da_control.GetWindowRect(ref2);
+  ScreenToClient(ref2);
+  ref.left+=ref2.left;
+  ref.top+=ref2.top;
+  ref.right+=ref2.left;
+  ref.bottom+=ref2.top+2;
+  if(ref.Width()/8<tmpstr.GetLength())
+  {
+    ref.right+=(tmpstr.GetLength()-5)*8;
+    if(ref.right>ref2.right) ref.right=ref2.right;
+  }
+  m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER |ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL,ref,this,IDC_EDITLINK);  
+  m_edit.SetWindowText(tmpstr);
+  m_inedit=3;
+  m_edit.SetFocus();
+}
+
+void C2DAEdit::Click(int flg)
+{
+  CString tmpstr;
+  CRect ref, ref2;
+  LVCOLUMN lvColumn;
+  char label[200];
+
+  if(!m_subitem)
+  {
+    m_2da_control.EditLabel(m_item);
+  }
+  else
+  {
+    m_2da_control.GetSubItemRect(m_item,m_subitem,LVIR_BOUNDS,ref);
+    if(m_item==-1)
+    {
+      if(m_subitem==-1) return;
+      lvColumn.mask=LVCF_TEXT;
+      lvColumn.pszText=label;
+      lvColumn.cchTextMax=200;
+      if(m_2da_control.GetColumn(m_subitem,&lvColumn))
+      {
+        tmpstr=lvColumn.pszText;
+      }
+    }
+    else
+    {
+      tmpstr=m_2da_control.GetItemText(m_item,m_subitem);
+    }
+    m_2da_control.GetWindowRect(ref2);
+    ScreenToClient(ref2);
+    ref.left+=ref2.left;
+    ref.top+=ref2.top;
+    ref.right+=ref2.left;
+    ref.bottom+=ref2.top+2;
+    m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER|ES_AUTOHSCROLL,ref,this,IDC_EDITLINK);
+    m_edit.SetWindowText(tmpstr);
+    m_edit.SetSel(0,-1);
+    m_inedit=flg;
+    m_edit.SetFocus();
+  }
+}
+
+void C2DAEdit::OnClick2da(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  LVHITTESTINFO htinfo;
+  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
+
+  if(IsWindow(m_edit)) m_edit.DestroyWindow();
+  htinfo.pt=pNMListView->ptAction;
+	m_item=m_2da_control.SubItemHitTest(&htinfo);
+  m_subitem=htinfo.iSubItem;
+  Click(1);
+	*pResult = 0;
+}
+
+void C2DAEdit::OnRClick2da(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  LVHITTESTINFO htinfo;
+  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
+
+  if(IsWindow(m_edit)) m_edit.DestroyWindow();
+  htinfo.pt=pNMListView->ptAction;
+	m_item=m_2da_control.SubItemHitTest(&htinfo);
+  m_subitem=htinfo.iSubItem;
+  if((m_subitem>=1) && (m_item>=0))
+  {
+    RClick();
+  }
+	*pResult = 0;
+}
+
+void C2DAEdit::OnColumnclick2da(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
+
+  OnKillfocusEditlink();
+  m_item=-1;
+  m_subitem=pNMListView->iSubItem;
+  Click(2);
+	*pResult = 0;
+}
+
+// original source of this piece of code:
+// http://www.codeproject.com/listctrl/lvcustomdraw.asp
+// Neat Stuff to do in List Controls Using Custom Draw
+// By Michael Dunn
+void C2DAEdit::OnCustomdrawMyList(NMHDR *pNMHDR, LRESULT *pResult)
+{
+  NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
+  
+  // Take the default processing unless we set this to something else below.
+  *pResult = CDRF_DODEFAULT;
+  
+  // First thing - check the draw stage. If it's the control's prepaint
+  // stage, then tell Windows we want messages for every item.
+  
+  if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
+  {
+    *pResult = CDRF_NOTIFYITEMDRAW;
+  }
+  else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
+  {
+    // This is the prepaint stage for an item. Here's where we set the
+    // item's text color. Our return value will tell Windows to draw the
+    // item itself, but it will use the new color we set here.
+    // We'll cycle the colors through red, green, and light blue.
+    
+    COLORREF crText;
+    
+    if(pLVCD->nmcd.dwItemSpec &1)
+    {
+      crText = RGB(240,240,240);
+    }
+    else
+    {
+      crText = RGB(255,255,255);
+    }
+    
+    // Store the color back in the NMLVCUSTOMDRAW struct.
+    pLVCD->clrTextBk = crText;
+    
+    // Tell Windows to paint the control itself.
+    *pResult = CDRF_DODEFAULT;
+  }
+}
+
+void C2DAEdit::OnKillfocusEditlink()
+{
+  POSITION pos;
+  CString tmpstr;
+  CString *row;
+  LVCOLUMN lvColumn;
+  int strref;
+
+	switch(m_inedit)
+  {
+  case 3:
+    m_inedit=0;
+    if(m_item>=the_2da.rows || m_subitem>=the_2da.cols)
+    {
+      goto escape;
+    }
+    if(m_item<0 || m_subitem<0)
+    {
+      goto escape;
+    }
+    m_edit.GetWindowText(tmpstr);
+    pos=the_2da.data->FindIndex(m_item);
+    if(!pos)
+    {
+      goto escape;
+    }
+    row=(CString *)the_2da.data->GetAt(pos);
+    if(!row)
+    {
+      goto escape;
+    }
+    strref=strtonum(row[m_subitem]);
+    if(!strref && !m_integer)
+    {
+      goto escape;
+    }
+    if(resolve_tlk_text(strref)==tmpstr)
+    {
+      goto escape;
+    }
+    strref=store_tlk_text(strref, tmpstr);
+    row[m_subitem].Format("%d",strref);
+    m_2da_control.SetItemText(m_item,m_subitem,row[m_subitem]);
+escape:
+    m_edit.ShowWindow(false);
+    break;
+  case 0:
+    m_edit.DestroyWindow();
+    break;
+  case 2:
+    m_inedit=1;
+    m_edit.SetFocus();
+    break;
+  case 1:
+    m_inedit=0;
+    if(m_item<the_2da.rows && m_subitem<the_2da.cols)
+    {
+      m_edit.GetWindowText(tmpstr);
+      if(m_item==-1)
+      {
+        if(m_subitem<0)
+        {
+          return;
+        }
+        the_2da.collabels[m_subitem]=tmpstr;
+        lvColumn.mask=LVCF_TEXT;
+        lvColumn.pszText=tmpstr.GetBuffer(0);
+        lvColumn.cchTextMax=tmpstr.GetLength();
+        m_2da_control.SetColumn(m_subitem, &lvColumn);
+      }
+      else
+      {
+        if(m_integer && invalidnumber(tmpstr) )
+        {
+          MessageBox("Enter a decimal or hexadecimal value!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+        }
+        else
+        {
+          pos=the_2da.data->FindIndex(m_item);
+          if(pos)
+          {
+            row=(CString *)the_2da.data->GetAt(pos);
+            if(row)
+            {
+              row[m_subitem]=tmpstr;
+              m_2da_control.SetItemText(m_item,m_subitem,tmpstr);
+            }
+          }
+        }
+      }
+    }
+    m_edit.DestroyWindow();
+  }
+}
+
+void C2DAEdit::RefreshSelection()
+{
+	m_2da_control.EnsureVisible(m_item, false);
+	m_2da_control.SetItemState(m_item, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
+}
+
+void C2DAEdit::OnRow2() 
+{
+  CString *row;
+  CString tmpstr;
+  POSITION pos;
+  int i;
+
+  if(m_item<0 || m_item>the_2da.rows) m_item=the_2da.rows;
+  tmpstr.Format("Row%d",m_item);
+  the_2da.AddRow(m_item, tmpstr, the_2da.defvalue);
+  pos=the_2da.data->FindIndex(m_item);
+  row=(CString *)the_2da.data->GetAt(pos);
+  m_2da_control.InsertItem(m_item, tmpstr);
+  for(i=0;i<the_2da.cols;i++)
+  {
+    m_2da_control.SetItemText(m_item,i, row[i]);
+  }
+  RefreshSelection();
+//  RefreshDialog();
+}
+
+void C2DAEdit::OnColumn() 
+{
+  CString tmpstr;
+  int column;
+
+  column=m_subitem+1;
+  if(column<1) column=1;
+  else if(column>the_2da.cols) column=the_2da.cols;
+  tmpstr.Format("Column%d",column);
+  the_2da.AddColumn(column,tmpstr,  the_2da.defvalue);
+  m_subitem=column;
+  RefreshDialog();
+}
+
+void C2DAEdit::OnRow() 
+{
+	m_item++;
+	OnRow2();
+}
+
+void C2DAEdit::OnColumn2() 
+{
+  m_subitem--;
+  OnColumn();
+}
+
+void C2DAEdit::OnRemove() 
+{
+  if(m_item<0)
+  {
+    MessageBox("Please select a row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	if(the_2da.RemoveRow(m_item))
+  {
+    m_2da_control.DeleteItem(m_item);
+    if(m_item>=the_2da.rows) m_item=the_2da.rows-1;
+    RefreshSelection();
+  }
+  else MessageBox("Cannot remove row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+}
+
+void C2DAEdit::OnRemove2() 
+{
+	if(m_subitem<1)
+  {
+    MessageBox("Please select a column (can't remove label column).","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	if(the_2da.RemoveColumn(m_subitem))
+  {
+    RefreshDialog();
+    m_subitem--;
+  }
+  else MessageBox("Cannot remove column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+}
+
+void C2DAEdit::OnCopy() 
+{
+	if(m_item<0)
+  {
+    MessageBox("Please select a row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	the_2da.CopyRow(m_item);
+}
+
+void C2DAEdit::OnCopy2() 
+{
+	if(m_subitem<0)
+  {
+    MessageBox("Please select a column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	the_2da.CopyColumn(m_subitem);
+}
+
+void C2DAEdit::OnPaste() 
+{
+	if(m_item<0)
+  {
+    MessageBox("Please select a row!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	the_2da.PasteRow(m_item);
+  RefreshDialog();
+}
+
+void C2DAEdit::OnPaste2() 
+{
+	if(m_subitem<0)
+  {
+    MessageBox("Please select a column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	the_2da.PasteColumn(m_subitem);
+  RefreshDialog();
+}
+
+void C2DAEdit::OnOrder() 
+{
+	if(m_subitem<0)
+  {
+    MessageBox("Please select a column!","2DA editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	the_2da.OrderByColumn(m_subitem, m_integer);
+  RefreshDialog();
+}
+
+void C2DAEdit::OnToolsAddsparkdata() 
+{
+  CString *tmppoi;
+  CString tmpstr;
+  int i;
+  
+  if (m_item<0)
+  {
+    return;
+  }
+  if (the_2da.cols!=6)
+  {
+    return;
+  }
+  tmppoi=(CString *) the_2da.data->GetAt(the_2da.data->FindIndex(m_item));
+  if (!tmppoi)
+  {
+    return;
+  }
+  colordlg.m_picked=0;
+  if(colordlg.DoModal()==IDOK)
+  {
+    unsigned long colors[5];
+    
+    MakeGradientArray(colors, (unsigned char) colordlg.m_picked);
+    for (i=0;i<5;i++)
+    {
+      tmpstr.Format("RGB(%d,%d,%d)",((colors[i]>>16)&255),((colors[i]>>8)&255), (colors[i]&255));
+      tmppoi[i+1]=tmpstr;
+    }
+    RefreshDialog();
+  }
+}
+
+void C2DAEdit::OnToolsCapitalize() 
+{
+  POSITION pos;
+  int i,j;
+  CString *tmppoi;
+  
+  pos=the_2da.data->GetHeadPosition();
+  for(j=0;j<the_2da.cols;j++)
+  {
+    the_2da.collabels[j].MakeUpper();
+  }
+  for(i=0;i<the_2da.rows;i++)
+  {
+    tmppoi=(CString *) the_2da.data->GetNext(pos);
+    for(j=0;j<the_2da.cols;j++)
+    {
+      tmppoi[j].MakeUpper();
+    }
+  }
+  RefreshDialog();
+}
+
+void C2DAEdit::OnToolsLookupstrref() 
+{
+  CStrRefDlg dlg;
+  
+  if(IsWindow(m_edit)) m_edit.DestroyWindow();
+  dlg.DoModal();
+  RefreshDialog();
+}
+
+void C2DAEdit::OnToolsPlaysound() 
+{
+  CString tmpstr;
+
+  tmpstr=m_2da_control.GetItemText(m_item,m_subitem);
+  tmpstr.MakeUpper();
+  play_acm(tmpstr,false,false);
+}
+
+BOOL C2DAEdit::PreTranslateMessage(MSG* pMsg) 
+{
+	m_tooltip.RelayEvent(pMsg);
+	return CDialog::PreTranslateMessage(pMsg);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CIDSEdit dialog
+
+CIDSEdit::CIDSEdit(CWnd* pParent /*=NULL*/)
+	: CDialog(CIDSEdit::IDD, pParent)
+{
+	//{{AFX_DATA_INIT(CIDSEdit)
+	m_hex = FALSE;
+	m_four = FALSE;
+	//}}AFX_DATA_INIT
+  m_inedit=false;
+  m_item=0;
+  m_subitem=0;
+	m_searchdlg=NULL;
+}
+
+void CIDSEdit::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CIDSEdit)
+	DDX_Control(pDX, IDC_IDS, m_ids_control);
+	DDX_Check(pDX, IDC_INT, m_hex);
+	DDX_Check(pDX, IDC_FOUR, m_four);
+	//}}AFX_DATA_MAP
+}
+
+void CIDSEdit::NewIDS()
+{
+	the_ids.new_ids();
+	itemname="new identifiers";
+  m_hex=false;
+  m_four=false;
+}
+
+void CIDSEdit::SetHex()
+{
+  POSITION pos;
+  CString *tmppoi;
+  int i;
+
+  pos=the_ids.data->GetHeadPosition();
+  m_hex=false;
+  m_four=true;
+  for(i=0;i<the_ids.rows;i++)
+  {
+    tmppoi=(CString *) the_ids.data->GetNext(pos);
+    if(atoi(tmppoi[0])!=strtonum(tmppoi[0]) )
+    {
+      m_hex=true;
+      if(tmppoi[0].GetLength()!=6) m_four=false;
+    }
+    else
+    {
+      if(tmppoi[0].GetLength()<4) m_four=false;
+    }
+  }
+}
+
+void CIDSEdit::RefreshDialog()
+{
+  POSITION pos;
+  CString *tmppoi;
+  int i;
+  int val;
+
+  if(m_readonly)
+  {
+    SetWindowText("Browse IDS: "+itemname);
+  }
+  else
+  {
+    SetWindowText("Edit IDS: "+itemname);
+  }
+  m_ids_control.DeleteAllItems();
+  while(m_ids_control.DeleteColumn(0));
+  m_ids_control.SetItemCount(2);
+  m_ids_control.InsertColumn(0,"Value",LVCFMT_LEFT,80);
+  m_ids_control.InsertColumn(1,"Identifier",LVCFMT_LEFT,0);
+  ResizeLastColumn(m_ids_control,true);
+  pos=the_ids.data->GetHeadPosition();
+  for(i=0;i<the_ids.rows;i++)
+  {
+    tmppoi=(CString *) the_ids.data->GetNext(pos);
+    val=strtonum(tmppoi[0]);
+    if(m_four)
+    {
+      if(m_hex) tmppoi[0].Format("0x%04x",val);
+      else tmppoi[0].Format("%04d",val);
+    }
+    else
+    {
+      if(m_hex) tmppoi[0].Format("0x%x",val);
+      else tmppoi[0].Format("%d",val);
+    }
+
+    m_ids_control.InsertItem(i, tmppoi[0]);
+    m_ids_control.SetItemText(i, 1, tmppoi[1]);
+  }
+  UpdateData(UD_DISPLAY);
+}
+
+BOOL CIDSEdit::OnInitDialog() 
+{
+	CDialog::OnInitDialog();	
+	RefreshDialog();	
+  //tooltips
+  {
+    m_tooltip.Create(this,TTS_NOPREFIX);
+    m_tooltip.SetMaxTipWidth(200);
+    m_tooltip.SetTipBkColor(RGB(240,224,160));
+    
+    m_tooltip.AddTool(GetDlgItem(IDCANCEL), IDS_CANCEL);
+  }
+  if(m_readonly)
+  {
+    GetDlgItem(IDC_SAVEAS)->EnableWindow(false);
+  }
+  CMenu *menu=GetMenu();
+  if(menu) menu=menu->GetSubMenu(0);
+  if(menu)
+  {
+    menu->EnableMenuItem(ID_FILE_NEW,m_readonly?MF_GRAYED:MF_ENABLED);
+    menu->EnableMenuItem(ID_FILE_SAVE,m_readonly?MF_GRAYED:MF_ENABLED);
+    menu->EnableMenuItem(ID_FILE_SAVEAS,m_readonly?MF_GRAYED:MF_ENABLED);
+  }
+	return TRUE;
+}
+
+BEGIN_MESSAGE_MAP(CIDSEdit, CDialog)
+	//{{AFX_MSG_MAP(CIDSEdit)
+	ON_BN_CLICKED(IDC_LOAD, OnLoad)
+	ON_BN_CLICKED(IDC_LOADEX, OnLoadex)
+	ON_BN_CLICKED(IDC_NEW, OnNew)
+	ON_BN_CLICKED(IDC_SAVEAS, OnSaveas)
+	ON_BN_CLICKED(IDC_ROW, OnRow)
+	ON_NOTIFY(NM_CLICK, IDC_IDS, OnClickIds)
+	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_IDS, OnEndlabeleditIds)
+	ON_BN_CLICKED(IDC_INT, OnInt)
+	ON_BN_CLICKED(IDC_ORDER, OnOrder)
+	ON_BN_CLICKED(IDC_REMOVE, OnRemove)
+	ON_BN_CLICKED(IDC_FOUR, OnFour)
+	ON_COMMAND(ID_FILE_SAVE, OnSave)
+	ON_COMMAND(ID_FILE_NEW, OnNew)
+	ON_COMMAND(ID_FILE_LOAD, OnLoad)
+	ON_COMMAND(ID_FILE_LOADEXTERNALSCRIPT, OnLoadex)
+	ON_COMMAND(ID_INT, OnInt)
+	ON_COMMAND(ID_FOUR, OnFour)
+	ON_COMMAND(ID_REMOVE, OnRemove)
+	ON_COMMAND(ID_ORDER, OnOrder)
+	ON_COMMAND(ID_ADD, OnRow)
+	ON_COMMAND(ID_EDIT_FINDID, OnEditFindid)
+	//}}AFX_MSG_MAP
+  ON_EN_KILLFOCUS(IDC_EDITLINK,OnKillfocusEditlink)
+  ON_NOTIFY(NM_CUSTOMDRAW, IDC_IDS, OnCustomdrawMyList)
+	ON_REGISTERED_MESSAGE( WM_FINDREPLACE, OnFindReplace )
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CIDSEdit message handlers
+
+void CIDSEdit::OnLoad() 
+{
+	int res;
+	
+  pickerdlg.m_restype=REF_IDS;
+  pickerdlg.m_picked=itemname;
+	res=pickerdlg.DoModal();
+	if(res==IDOK)
+	{
+		res=read_ids(pickerdlg.m_picked);
+    switch(res)
+    {
+    case 1:
+      MessageBox("Identifiers loaded with some errors.","Warning",MB_ICONEXCLAMATION|MB_OK);
+  		itemname=pickerdlg.m_picked;
+      break;
+    case 0:
+  		itemname=pickerdlg.m_picked;
+      break;
+    default:
+      MessageBox("Cannot read identifiers!","Error",MB_ICONSTOP|MB_OK);
+      NewIDS();
+      break;
+    }
+	}
+  SetHex();
+  RefreshDialog();
+}
+
+static char BASED_CODE szFilter2[] = "IDS files (*.ids)|*.ids|All files (*.*)|*.*||";
+
+void CIDSEdit::OnLoadex() 
+{
+  CString filepath;
+  int fhandle;
+  int res;
+  
+  res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER;
+  if(readonly) res|=OFN_READONLY;  
+  CMyFileDialog m_getfiledlg(TRUE, "ids", makeitemname(".ids",0), res, szFilter2);
+
+restart:  
+  if( m_getfiledlg.DoModal() == IDOK )
+  {
+    filepath=m_getfiledlg.GetPathName();
+    fhandle=open(filepath, O_RDONLY|O_BINARY);
+    if(!fhandle)
+    {
+      MessageBox("Cannot open file!","Error",MB_ICONSTOP|MB_OK);
+      goto restart;
+    }
+    readonly=m_getfiledlg.GetReadOnlyPref();
+    res=the_ids.ReadIDSFromFile(fhandle,-1);
+    close(fhandle);
+    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
+    switch(res)
+    {
+    case 1:
+      MessageBox("Identifiers loaded with some errors.","Warning",MB_ICONEXCLAMATION|MB_OK);
+      itemname=m_getfiledlg.GetFileTitle();
+      itemname.MakeUpper();
+      break;
+    case 0:
+      itemname=m_getfiledlg.GetFileTitle();
+      itemname.MakeUpper();
+      break;
+    default:
+      MessageBox("Cannot read identifiers!","Error",MB_ICONSTOP|MB_OK);
+      NewIDS();
+      break;
+    }
+  }
+  SetHex();
+  RefreshDialog();
+}
+
+void CIDSEdit::OnNew() 
+{
+  NewIDS();
+  RefreshDialog();
+}
+
+void CIDSEdit::OnSave() 
+{
+  SaveIDS(1);
+}
+
+void CIDSEdit::OnSaveas() 
+{
+  SaveIDS(0);
+}
+
+void CIDSEdit::SaveIDS(int save) 
+{
+  CString filepath;
+  CString newname;
+  CString tmpstr;
+  int fhandle;
+  int res;
+
+  if(readonly || m_readonly) //m_readonly is the local read only flag
+  {
+    MessageBox("You opened it read only!","Warning",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+  res=OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_EXPLORER;
+  CMyFileDialog m_getfiledlg(FALSE, "ids", makeitemname(".ids",0), res, szFilter2);
+
+  if(save)
+  {
+    newname=itemname;
+    filepath=makeitemname(".ids",0);
+    goto gotname;
+  }
+
+restart:  
+  if( m_getfiledlg.DoModal() == IDOK )
+  {
+    filepath=m_getfiledlg.GetPathName();
+    filepath.MakeLower();
+    if(filepath.Right(4)!=".ids")
+    {
+      filepath+=".ids";
+    }
+    newname=m_getfiledlg.GetFileName();
+    newname.MakeUpper();
+    if(newname.Right(4)==".IDS") newname=newname.Left(newname.GetLength()-4);
+gotname:
+    if(newname.GetLength()>8 || newname.GetLength()<1 || newname.Find(" ",0)!=-1)
+    {
+      tmpstr.Format("The resource name '%s' is bad, it should be 8 characters long and without spaces.",newname);
+      MessageBox(tmpstr,"Warning",MB_ICONEXCLAMATION|MB_OK);
+      goto restart;
+    }
+    if(newname!=itemname && file_exists(filepath) )
+    {
+      res=MessageBox("Do you want to overwrite "+newname+"?","Warning",MB_ICONQUESTION|MB_YESNO);
+      if(res==IDNO) goto restart;
+    }
+    fhandle=open(filepath, O_BINARY|O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
+    if(fhandle<1)
+    {
+      MessageBox("Can't write file!","Error",MB_ICONSTOP|MB_OK);
+      goto restart;
+    }
+    res=the_ids.WriteIDSToFile(fhandle);
+    close(fhandle);
+    lastopenedoverride=filepath.Left(filepath.ReverseFind('\\'));
+    switch(res)
+    {
+    case 0:
+      itemname=newname;
+      break; //saved successfully
+    case -2:
+      MessageBox("Error while writing file!","Error",MB_ICONSTOP|MB_OK);
+      break;
+    default:
+      MessageBox("Unhandled error!","Error",MB_ICONSTOP|MB_OK);
+    }
+  }
+  RefreshDialog();
+}
+
+void CIDSEdit::OnKillfocusEditlink()
+{
+  POSITION pos;
+  CString tmpstr;
+  CString *row;
+
+	if(m_inedit)
+  {
+    m_inedit=false;
+    if(m_item<the_ids.rows && m_subitem<2)
+    {
+      m_edit.GetWindowText(tmpstr);
+      if(m_item==-1)
+      {
+        //label
+      }
+      else
+      {
+        pos=the_ids.data->FindIndex(m_item);
+        if(pos)
+        {
+          row=(CString *)the_ids.data->GetAt(pos);
+          if(row)
+          {
+            row[m_subitem]=tmpstr;
+            m_ids_control.SetItemText(m_item,m_subitem,tmpstr);
+          }
+        }
+      }
+    }
+    m_edit.DestroyWindow();
+  }
+}
+
+bool CIDSEdit::perform_search(int idx, int match, CString srch)
+{
+	CString *row=(CString *)the_ids.data->GetAt(the_ids.data->FindIndex(idx));
+	if(row)
+	{
+		CString tmp2 = row[1];
+		
+		if(match&1) // case insensitive trick
+    {
+      tmp2.MakeLower();
+    }
+    if(match&2) // full word trick
+    {
+      tmp2=" "+tmp2+" "; //in this
+    }
+    if(tmp2.Find(srch) !=-1) return true;
+	}
+
+	return false;
+}
+
+void CIDSEdit::do_search(int direction, int match, CString search)
+{
+	int idx;
+	int start, end;
+
+	if (direction==0) direction=-1;
+
+	if (direction<0) end=-1;
+	else end=the_ids.rows;
+
+	if (direction<0) start=the_ids.rows-1;
+	else start=0;
+	for(idx=m_item+direction;idx!=end;idx+=direction)
+	{
+		if(perform_search(idx,match,search))
+		{
+			m_item=idx;
+			RefreshSelection();
+			return;
+		}
+	}
+	for(idx=start;idx!=m_item;idx+=direction)
+	{
+		if(perform_search(idx,match,search))
+		{
+			m_item=idx;
+			RefreshSelection();
+			return;
+		}
+	}
+
+}
+
+long CIDSEdit::OnFindReplace(WPARAM /*wParam*/, LPARAM /*lParam*/)
+{
+  int direction;
+  int match;
+  CString search;
+  CString replace;
+
+  if(!m_searchdlg) return 0;
+  if(m_searchdlg->IsTerminating() )
+  {
+    m_searchdlg=NULL;
+    return 0;
+  }
+  direction=m_searchdlg->SearchDown();
+  //matchcase is cheaper, therefore it is marked 0
+  match=!m_searchdlg->MatchCase()+(!!m_searchdlg->MatchWholeWord())*2; 
+  search=m_searchdlg->GetFindString();  
+
+  if(match&1) //we can do this here
+  {
+    search.MakeLower();
+  }
+  if(match&2) //this too
+  {
+    search=" "+search+" ";
+  }
+
+  do_search(direction,match,search);
+  return 0;
+}
+
+void CIDSEdit::OnEditFindid() 
+{
+	m_searchdlg=new CFindReplaceDialog;
+	m_searchdlg->Create(true,"",NULL, FR_DOWN, this);
+}
+
+void CIDSEdit::RefreshSelection()
+{
+	m_ids_control.EnsureVisible(m_item, false);
+	m_ids_control.SetItemState(m_item, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
+}
+
+void CIDSEdit::OnRemove() 
+{
+  if(m_item<0)
+  {
+    MessageBox("Please select an item to remove.","IDS editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	if(the_ids.RemoveRow(m_item))
+  {
+    m_ids_control.DeleteItem(m_item);
+    RefreshSelection();
+  }
+  else
+  {
+    MessageBox("Cannot remove item.","IDS editor",MB_ICONEXCLAMATION|MB_OK);
+  }
+  UpdateData(UD_DISPLAY);
+}
+
+void CIDSEdit::OnRow() 
+{
+  CString tmpstr, def;
+
+  if(m_four)
+  {
+    if(m_hex) def="0x0000";
+    else def="0000";
+  }
+  else
+  {
+    if(m_hex) def="0x0";
+    else def="0";
+  }
+  if(m_item<0) m_item=the_ids.rows;
+  tmpstr.Format("Identifier%d",m_item);
+  the_ids.AddRow(m_item,def,tmpstr);
+  m_ids_control.InsertItem(m_item, def);
+  m_ids_control.SetItemText(m_item, 1, tmpstr);
+  RefreshSelection();
+  UpdateData(UD_DISPLAY);
+}
+
+void CIDSEdit::OnClickIds(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  CString tmpstr;
+  CRect ref, ref2;
+  LVHITTESTINFO htinfo;
+  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
+
+  if(IsWindow(m_edit)) m_edit.DestroyWindow();
+  htinfo.pt=pNMListView->ptAction;
+	m_item=m_ids_control.SubItemHitTest(&htinfo);
+  if(m_item<0) return;
+  m_subitem=htinfo.iSubItem;
+  if(!m_subitem)
+  {
+    m_ids_control.EditLabel(m_item);
+  }
+  else
+  {
+    m_ids_control.GetSubItemRect(m_item,1,0,ref);
+    tmpstr=m_ids_control.GetItemText(m_item,1);
+    m_ids_control.GetWindowRect(ref2);
+    ScreenToClient(ref2);
+    ref.left+=ref2.left;
+    ref.top+=ref2.top;
+    ref.right+=ref2.left;
+    ref.bottom+=ref2.top+2;
+    m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER,ref,this,IDC_EDITLINK);
+    m_edit.SetWindowText(tmpstr);
+    m_edit.SetFocus();
+    m_edit.SetSel(0,-1);
+    m_inedit=true;
+  }
+	*pResult = 0;
+}
+
+void CIDSEdit::OnEndlabeleditIds(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  int val;
+  CString tmpstr;
+	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+  CString *tmppoi;
+
+  if(pDispInfo->item.pszText)
+  {
+    val=strtonum(pDispInfo->item.pszText);
+    if(m_four)
+    {
+      if(m_hex) tmpstr.Format("0x%04X",val);
+      else tmpstr.Format("%04d",val);
+    }
+    else
+    {
+      if(m_hex) tmpstr.Format("0x%x",val);
+      else tmpstr.Format("%d",val);
+    }
+	  m_ids_control.SetItemText(pDispInfo->item.iItem, 0, tmpstr);
+    tmppoi=(CString *) the_ids.data->GetAt(the_ids.data->FindIndex(pDispInfo->item.iItem));
+    tmppoi[0]=tmpstr;
+  }
+	*pResult = 0;
+}
+
+void CIDSEdit::OnInt() 
+{
+  UpdateData(UD_RETRIEVE);
+  m_hex=!m_hex;
+	RefreshDialog();
+}
+
+void CIDSEdit::OnFour() 
+{
+  UpdateData(UD_RETRIEVE);
+  m_four=!m_four;
+	RefreshDialog();
+}
+
+void CIDSEdit::OnOrder() 
+{
+  CString *tmppoi, *tmppoi2;
+  POSITION pos, pos2, pos3;
+  CPtrList *data2;
+  int val;
+  int mask;
+
+  if(itemname=="TRIGGER") mask=0x3fff;
+  else mask=~0;
+  data2=new CPtrList;
+  if(!data2) return; //can't order it due to low memory
+  pos=the_ids.data->GetHeadPosition();
+  while(pos)
+  {
+    tmppoi=(CString *) the_ids.data->GetNext(pos);
+    val=strtonum(tmppoi[0])&mask;
+    pos2=data2->GetTailPosition();
+    do
+    {
+      pos3=pos2;
+      if(!pos2) break;
+      tmppoi2=(CString *) data2->GetPrev(pos2);
+    }
+    while((strtonum(tmppoi2[0])&mask)>val);
+    if(pos3) data2->InsertAfter(pos3,tmppoi);
+    else data2->AddHead(tmppoi);
+  }
+  delete the_ids.data; //we must not delete referenced data members
+	the_ids.data=data2;
+	RefreshDialog();
+}
+
+void CIDSEdit::OnCustomdrawMyList(NMHDR *pNMHDR, LRESULT *pResult)
+{
+  NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
+  
+  // Take the default processing unless we set this to something else below.
+  *pResult = CDRF_DODEFAULT;
+  
+  // First thing - check the draw stage. If it's the control's prepaint
+  // stage, then tell Windows we want messages for every item.
+  
+  if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
+  {
+    *pResult = CDRF_NOTIFYITEMDRAW;
+  }
+  else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
+  {
+    // This is the prepaint stage for an item. Here's where we set the
+    // item's text color. Our return value will tell Windows to draw the
+    // item itself, but it will use the new color we set here.
+    // We'll cycle the colors through red, green, and light blue.
+    
+    COLORREF crText;
+    
+    if(pLVCD->nmcd.dwItemSpec &1)
+    {
+      crText = RGB(240,240,240);
+    }
+    else
+    {
+      crText = RGB(255,255,255);
+    }
+    
+    // Store the color back in the NMLVCUSTOMDRAW struct.
+    pLVCD->clrTextBk = crText;
+    
+    // Tell Windows to paint the control itself.
+    *pResult = CDRF_DODEFAULT;
+  }
+}
+
+BOOL CIDSEdit::PreTranslateMessage(MSG* pMsg) 
+{
+	m_tooltip.RelayEvent(pMsg);
+	return CDialog::PreTranslateMessage(pMsg);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMUSEdit dialog
+
+void CMUSEdit::NewMUS()
+{
+	the_mus.new_mus();
+  the_mus.internal="";
+	itemname="new musiclist";
+}
+
+CMUSEdit::CMUSEdit(CWnd* pParent /*=NULL*/)
+	: CDialog(CMUSEdit::IDD, pParent)
+{
+	//{{AFX_DATA_INIT(CMUSEdit)
+		// NOTE: the ClassWizard will add member initialization here
+	//}}AFX_DATA_INIT
+  m_inedit=0;
+  m_item=0;
+  m_subitem=0;
+}
+
+void CMUSEdit::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CMUSEdit)
+	DDX_Control(pDX, IDC_MUS, m_mus_control);
+	//}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CMUSEdit, CDialog)
+	//{{AFX_MSG_MAP(CMUSEdit)
+	ON_BN_CLICKED(IDC_REMOVE, OnRemove)
+	ON_BN_CLICKED(IDC_ROW, OnRow)
+	ON_BN_CLICKED(IDC_LOAD, OnLoad)
+	ON_BN_CLICKED(IDC_LOADEX, OnLoadex)
+	ON_BN_CLICKED(IDC_SAVEAS, OnSaveas)
+	ON_BN_CLICKED(IDC_NEW, OnNew)
+	ON_NOTIFY(NM_CLICK, IDC_MUS, OnClickMus)
+	ON_NOTIFY(LVN_ENDLABELEDIT, IDC_MUS, OnEndlabeleditMus)
+	ON_NOTIFY(NM_RCLICK, IDC_MUS, OnRClickMus)
+	ON_BN_CLICKED(IDC_PLAYWHOLE, OnPlaywhole)
+	ON_BN_CLICKED(IDC_PLAY, OnRClickCmd)
+	ON_COMMAND(ID_PLAY_PLAYWHOLE, OnPlaywhole)
+	ON_COMMAND(ID_PLAY_PLAYPART, OnRClickCmd)
+	ON_COMMAND(ID_ADD, OnRow)
+	ON_COMMAND(ID_REMOVE, OnRemove)
+	//}}AFX_MSG_MAP
+  ON_EN_KILLFOCUS(IDC_EDITLINK,OnKillfocusEditlink)
+  ON_NOTIFY(NM_CUSTOMDRAW, IDC_MUS, OnCustomdrawMyList)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMUSEdit message handlers
+void CMUSEdit::OnLoad() 
+{
+	int res;
+	
+  pickerdlg.m_restype=REF_MUS;
+  pickerdlg.m_picked=itemname;
+	res=pickerdlg.DoModal();
+	if(res==IDOK)
+	{
+		res=read_mus(pickerdlg.m_picked);
+    switch(res)
+    {
+    case 1:
+      MessageBox("Musiclist loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
+  		itemname=pickerdlg.m_picked;
+      break;
+    case 0:
+  		itemname=pickerdlg.m_picked;
+      break;
+    default:
+      MessageBox("Cannot read list!","Error",MB_ICONSTOP|MB_OK);
+      NewMUS();
+      break;
+    }
+	}
+  RefreshDialog();
+}
+
+static char BASED_CODE szFilter3[] = "Musiclists (*.mus)|*.mus|All files (*.*)|*.*||";
+
+void CMUSEdit::OnLoadex() 
+{
+  CString filepath;
+  int fhandle;
+  int res;
+  
+  res=OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_EXPLORER;
+  if(readonly) res|=OFN_READONLY;  
+  CMyFileDialog m_getfiledlg(TRUE, "mus", makeitemname(".mus",4), res, szFilter3);
+
+restart:  
+  if( m_getfiledlg.DoModal() == IDOK )
+  {
+    filepath=m_getfiledlg.GetPathName();
+    fhandle=open(filepath, O_RDONLY|O_BINARY);
+    if(!fhandle)
+    {
+      MessageBox("Cannot open file!","Error",MB_ICONSTOP|MB_OK);
+      goto restart;
+    }
+    readonly=m_getfiledlg.GetReadOnlyPref();
+    res=the_mus.ReadMusFromFile(fhandle,-1);
+    close(fhandle);
+    lastopenedmusic=filepath.Left(filepath.ReverseFind('\\'));
+    switch(res)
+    {
+    case 1:
+      MessageBox("Musiclist loaded with some errors (minor inconsistency).","Warning",MB_ICONEXCLAMATION|MB_OK);
+      itemname=m_getfiledlg.GetFileTitle();
+      itemname.MakeUpper();
+      break;
+    case 0:
+      itemname=m_getfiledlg.GetFileTitle();
+      itemname.MakeUpper();
+      break;
+    default:
+      MessageBox("Cannot read list!","Error",MB_ICONSTOP|MB_OK);
+      NewMUS();
+      break;
+    }
+  }
+  RefreshDialog();
+}
+
+void CMUSEdit::OnSaveas() 
+{
+  CString filepath;
+  CString newname;
+  CString tmpstr;
+  int fhandle;
+  int res;
+
+  if(readonly)
+  {
+    MessageBox("You opened it read only!","Warning",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+  res=OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_EXPLORER;
+  //CMyFileDialog m_getfiledlg(FALSE, "mus", bgfolder+"music\\"+itemname+".mus", res, szFilter3);
+  CMyFileDialog m_getfiledlg(FALSE, "mus", makeitemname(".mus",4), res, szFilter3);
+restart:  
+  if( m_getfiledlg.DoModal() == IDOK )
+  {
+    filepath=m_getfiledlg.GetPathName();
+    filepath.MakeLower();
+    if(filepath.Right(4)!=".mus")
+    {
+      filepath+=".mus";
+    }
+    newname=m_getfiledlg.GetFileName();
+    newname.MakeUpper();
+    if(newname.Right(4)==".MUS") newname=newname.Left(newname.GetLength()-4);
+    if(newname.GetLength()>8 || newname.GetLength()<1 || newname.Find(" ",0)!=-1)
+    {
+      tmpstr.Format("The resource name '%s' is bad, it should be 8 characters long and without spaces.",newname);
+      MessageBox(tmpstr,"Warning",MB_ICONEXCLAMATION|MB_OK);
+      goto restart;
+    }
+    if(newname!=itemname && file_exists(filepath) )
+    {
+      res=MessageBox("Do you want to overwrite "+newname+"?","Warning",MB_ICONQUESTION|MB_YESNO);
+      if(res==IDNO) goto restart;
+    }
+    fhandle=open(filepath, O_BINARY|O_RDWR|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE);
+    if(fhandle<1)
+    {
+      MessageBox("Can't write file!","Error",MB_ICONSTOP|MB_OK);
+      goto restart;
+    }
+    if(the_mus.internal.IsEmpty()) the_mus.internal=newname;
+    the_mus.internal.MakeUpper();
+
+    res=the_mus.WriteMusToFile(fhandle);
+    close(fhandle);
+    lastopenedmusic=filepath.Left(filepath.ReverseFind('\\'));
+    switch(res)
+    {
+    case 0:
+      itemname=newname;
+      break; //saved successfully
+    case -2:
+      MessageBox("Error while writing file!","Error",MB_ICONSTOP|MB_OK);
+      break;
+    default:
+      MessageBox("Unhandled error!","Error",MB_ICONSTOP|MB_OK);
+    }
+  }
+  RefreshDialog();
+}
+
+void CMUSEdit::OnNew() 
+{
+  NewMUS();
+  RefreshDialog();
+}
+
+void CMUSEdit::OnKillfocusEditlink()
+{
+  POSITION pos;
+  CString tmpstr;
+  CString *row;
+
+	switch(m_inedit)
+  {
+  case 0:
+    m_edit.DestroyWindow();
+    break;
+  case 1:
+    m_inedit=0;
+    if(m_item<the_mus.rows && m_subitem<MUSCOLUMN)
+    {
+      m_edit.GetWindowText(tmpstr);
+      tmpstr.MakeUpper();
+      pos=the_mus.data->FindIndex(m_item);
+      if(pos)
+      {
+        row=(CString *)the_mus.data->GetAt(pos);
+        if(row)
+        {
+          row[m_subitem]=tmpstr;
+          m_mus_control.SetItemText(m_item,m_subitem,tmpstr);
+        }
+      }
+    }
+    m_edit.DestroyWindow();
+  }
+}
+
+void CMUSEdit::OnRemove() 
+{
+  if(m_item<0)
+  {
+    MessageBox("Please select a row!","Musiclist editor",MB_ICONEXCLAMATION|MB_OK);
+    return;
+  }
+	if(the_mus.RemoveRow(m_item))
+  {
+    RefreshDialog();
+  }
+  else MessageBox("Cannot remove row!","Musiclist editor",MB_ICONEXCLAMATION|MB_OK);
+}
+
+void CMUSEdit::OnRow() 
+{
+  if(m_item<0) m_item=the_2da.rows;
+  the_mus.AddRow(m_item,"NEW","","");
+  RefreshDialog();
+}
+
+static CString muscolumns[MUSCOLUMN]={"Part suffix","Loop suffix","Tag suffix"};
+
+void CMUSEdit::RefreshDialog()
+{
+  POSITION pos;
+  CString *tmppoi;
+  int i,j;
+  int width;
+
+  SetWindowText("Edit musiclist: "+itemname);
+  m_mus_control.DeleteAllItems();
+  while(m_mus_control.DeleteColumn(0));
+  m_mus_control.SetItemCount(MUSCOLUMN);
+  for(i=0;i<MUSCOLUMN;i++) //3 
+  {
+    width=10*muscolumns[i].GetLength();
+    if(width<50) width=50;
+    m_mus_control.InsertColumn(i,muscolumns[i],LVCFMT_LEFT,width);
+  }
+  ResizeLastColumn(m_mus_control,true);
+  pos=the_mus.data->GetHeadPosition();
+  for(i=0;i<the_mus.rows;i++)
+  {
+    tmppoi=(CString *) the_mus.data->GetNext(pos);
+    m_mus_control.InsertItem(i, tmppoi[0]);
+    for(j=1;j<MUSCOLUMN;j++)
+    {
+      m_mus_control.SetItemText(i, j, tmppoi[j]);
+    }
+  }
+  UpdateData(UD_DISPLAY);
+}
+
+BOOL CMUSEdit::OnInitDialog() 
+{
+  CString tmpstr, tmpstr1, tmpstr2;
+
+	CDialog::OnInitDialog();
+	RefreshDialog();	
+  //tooltips
+  {
+    m_tooltip.Create(this,TTS_NOPREFIX);
+    m_tooltip.SetMaxTipWidth(200);
+    m_tooltip.SetTipBkColor(RGB(240,224,160));
+    
+    m_tooltip.AddTool(GetDlgItem(IDCANCEL), IDS_CANCEL);
+    tmpstr1.LoadString(IDS_LOAD);
+    tmpstr2.LoadString(IDS_MUS);
+    tmpstr.Format(tmpstr1, tmpstr2);
+    m_tooltip.AddTool(GetDlgItem(IDC_LOAD), tmpstr);
+    tmpstr1.LoadString(IDS_LOADEX);
+    tmpstr.Format(tmpstr1, tmpstr2);
+    m_tooltip.AddTool(GetDlgItem(IDC_LOADEX), tmpstr);
+    tmpstr1.LoadString(IDS_SAVE);
+    tmpstr.Format(tmpstr1, tmpstr2);
+    m_tooltip.AddTool(GetDlgItem(IDC_SAVEAS), tmpstr);
+    tmpstr1.LoadString(IDS_NEW);
+    tmpstr.Format(tmpstr1, tmpstr2);
+    m_tooltip.AddTool(GetDlgItem(IDC_NEW), tmpstr);
+  }	
+	return TRUE;
+}
+
+void CMUSEdit::Click()
+{
+  CString tmpstr;
+  CRect ref, ref2;
+
+  if(!m_subitem)
+  {
+    m_mus_control.EditLabel(m_item);
+  }
+  else
+  {
+    m_mus_control.GetSubItemRect(m_item,m_subitem,0,ref);
+    if(m_item==-1) return;
+    tmpstr=m_mus_control.GetItemText(m_item,m_subitem);
+    m_mus_control.GetWindowRect(ref2);
+    ScreenToClient(ref2);
+    ref.left+=ref2.left;
+    ref.top+=ref2.top;
+    ref.right+=ref2.left;
+    ref.bottom+=ref2.top+2;
+    m_edit.Create(DS_CONTROL | WS_CHILD | WS_VISIBLE |WS_BORDER|ES_AUTOHSCROLL,ref,this,IDC_EDITLINK);
+    m_edit.SetWindowText(tmpstr);
+    m_edit.SetSel(0,-1);
+    m_inedit=1;
+    m_edit.SetFocus();
+  }
+}
+
+void CMUSEdit::OnClickMus(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  LVHITTESTINFO htinfo;
+  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
+
+  if(IsWindow(m_edit)) m_edit.DestroyWindow();
+  htinfo.pt=pNMListView->ptAction;
+	m_item=m_mus_control.SubItemHitTest(&htinfo);
+  m_subitem=htinfo.iSubItem;
+  Click();
+	*pResult = 0;
+}
+
+int CMUSEdit::RClick()
+{
+  CString filename;
+
+  filename=m_mus_control.GetItemText(m_item,m_subitem);
+  //these hacks are the same as in the engine code
+  return play_acm(convert_musiclist(filename, true), true, false);
+}
+
+void CMUSEdit::OnPlaywhole() 
+{
+  panicbutton dlg;
+  int poi;
+  int tmpitem=m_item;
+  int tmpsubitem=m_subitem;
+  void *memory1=NULL, *memory2=NULL;
+  CString filename;
+  int ret;
+
+  m_subitem=0;
+  filename=m_mus_control.GetItemText(m_item++,m_subitem);
+  poi=play_acm(convert_musiclist(filename, true), true, true);
+  if(poi<1 && poi>-10) goto endofquest;
+  memory1=(void *) poi;
+  
+	for(;m_item<the_mus.rows;m_item++)
+  {
+    if(memory1)
+    {
+      sndPlaySound((const char *) memory1,SND_MEMORY | SND_ASYNC);
+    }
+    filename=m_mus_control.GetItemText(m_item,m_subitem);
+    poi=play_acm(convert_musiclist(filename, true), true, true);
+    if(poi<1 && poi>-10) goto endofquest;
+    memory2=(void *) poi;
+    BringWindowToTop();//this is needed so there is no crash when the window was hidden (braindead Windows)
+    dlg.waitsound=true;
+    ret=dlg.DoModal();
+    sndPlaySound(NULL,SND_NODEFAULT);
+    if(memory1) delete memory1;
+    memory1=memory2;
+    if(ret==IDCANCEL) goto endofquest;
+  }
+  if(memory1)
+  {
+    sndPlaySound((const char *) memory1,SND_MEMORY | SND_ASYNC);
+  }
+  BringWindowToTop(); //this is needed so there is no crash when the window was hidden
+  dlg.waitsound=true;
+  dlg.DoModal();
+  sndPlaySound(NULL,SND_NODEFAULT);
+endofquest:
+  if(memory1)
+  {
+    delete memory1;
+  }
+  m_item=tmpitem;
+  m_subitem=tmpsubitem;
+}
+
+void CMUSEdit::OnRClickCmd()
+{
+  RClick();
+}
+
+void CMUSEdit::OnRClickMus(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  LVHITTESTINFO htinfo;
+  NM_LISTVIEW *pNMListView = (NM_LISTVIEW*)pNMHDR;
+
+  if(IsWindow(m_edit)) m_edit.DestroyWindow();
+  htinfo.pt=pNMListView->ptAction;
+	m_item=m_mus_control.SubItemHitTest(&htinfo);
+  m_subitem=htinfo.iSubItem;
+  if((m_subitem>=0) && (m_item>=0))
+  {
+    RClick();
+  }
+	*pResult = 0;
+}
+
+void CMUSEdit::OnEndlabeleditMus(NMHDR* pNMHDR, LRESULT* pResult) 
+{
+  CString tmpstr;
+  CString *tmppoi;
+	LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
+
+  if(pDispInfo->item.pszText)
+  {
+    tmpstr=pDispInfo->item.pszText;
+	  m_mus_control.SetItemText(pDispInfo->item.iItem, 0, tmpstr);
+    tmppoi=(CString *) the_mus.data->GetAt(the_mus.data->FindIndex(pDispInfo->item.iItem));
+    tmppoi[0]=tmpstr;
+  }
+	*pResult = 0;
+}
+
+void CMUSEdit::OnCustomdrawMyList(NMHDR *pNMHDR, LRESULT *pResult)
+{
+  NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
+  
+  // Take the default processing unless we set this to something else below.
+  *pResult = CDRF_DODEFAULT;
+  
+  // First thing - check the draw stage. If it's the control's prepaint
+  // stage, then tell Windows we want messages for every item.
+  
+  if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
+  {
+    *pResult = CDRF_NOTIFYITEMDRAW;
+  }
+  else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
+  {
+    // This is the prepaint stage for an item. Here's where we set the
+    // item's text color. Our return value will tell Windows to draw the
+    // item itself, but it will use the new color we set here.
+    // We'll cycle the colors through red, green, and light blue.
+    
+    COLORREF crText;
+    
+    if(pLVCD->nmcd.dwItemSpec &1)
+    {
+      crText = RGB(240,240,240);
+    }
+    else
+    {
+      crText = RGB(255,255,255);
+    }
+    
+    // Store the color back in the NMLVCUSTOMDRAW struct.
+    pLVCD->clrTextBk = crText;
+    
+    // Tell Windows to paint the control itself.
+    *pResult = CDRF_DODEFAULT;
+  }
+}
+
+BOOL CMUSEdit::PreTranslateMessage(MSG* pMsg) 
+{
+  m_tooltip.RelayEvent(pMsg);
+	return CDialog::PreTranslateMessage(pMsg);
+}
+

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks