/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // briefinglocalizerDlg.cpp : implementation file // #include "stdafx.h" #include "briefinglocalizer.h" #include "briefinglocalizerDlg.h" #include "crossplat.h" #include #include #include #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define TITLE_TAG "$title \"" #define TITLE_TAG_LENGTH strlen(TITLE_TAG) #define TEXT_START_TAG "$text" #define TEXT_START_TAG_LEN strlen(TEXT_START_TAG) #define TEXT_SHOW_TAG "show" #define TEXT_SHOW_TAG_LEN strlen(TEXT_SHOW_TAG) #define TEXT_END_TAG "$endtext" #define TEXT_END_TAG_TAG_LEN strlen(TEXT_END_TAG) #define FIND_NEXT_LINE(a, b) \ do { \ while (((b[a] == 0x0a) || (b[a] == 0x0d)) && (a < (b).GetLength())) \ a++; \ } while (0) // a = (b).FindOneOf("\x0a\x0d"); if(a!=-1) ///////////////////////////////////////////////////////////////////////////// // CBriefinglocalizerDlg dialog CBriefinglocalizerDlg::CBriefinglocalizerDlg(CWnd *pParent /*=NULL*/) : CDialog(CBriefinglocalizerDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBriefinglocalizerDlg) m_Title = _T(""); m_Text = _T(""); //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_FileChanged = false; m_CurTextLeft = 0; m_CurTextRight = 0; m_BigStringTextLower.Empty(); m_BigTextString.Empty(); } void CBriefinglocalizerDlg::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBriefinglocalizerDlg) DDX_Control(pDX, IDC_TEXT, m_RichText); DDX_Text(pDX, IDC_TITLE, m_Title); DDX_Text(pDX, IDC_TEXT, m_Text); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CBriefinglocalizerDlg, CDialog) //{{AFX_MSG_MAP(CBriefinglocalizerDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_NEXT, OnNext) ON_BN_CLICKED(IDC_PREV, OnPrev) ON_BN_CLICKED(IDC_QUIT, OnQuit) ON_BN_CLICKED(IDC_SAVE, OnSave) ON_EN_KILLFOCUS(IDC_TITLE, OnKillfocusTitle) ON_EN_CHANGE(IDC_TEXT, OnChangeText) ON_EN_CHANGE(IDC_TITLE, OnChangeTitle) ON_NOTIFY(NM_KILLFOCUS, IDC_TEXT, OnKillfocusText) ON_NOTIFY(EN_KILLFOCUS, IDC_TEXT, OnKillfocusText) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBriefinglocalizerDlg message handlers BOOL CBriefinglocalizerDlg::OnInitDialog() { static char sztemppath[_MAX_PATH * 2] = "."; static char sztempfile[_MAX_PATH * 2] = "tempfile.tmp"; char path[_MAX_PATH * 2]; char drive[10]; CString savepath; CString DefaultPath; CDialog::OnInitDialog(); m_RichText.SetEventMask(ENM_CHANGE); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon CFileDialog *fd; DefaultPath = AfxGetApp()->GetProfileString("Defaults", "LastDir", ""); static char szFilter[] = "Descent 3 Briefing (*.br?)|*.br?|All Files (*.*)|*.*||"; _chdir(DefaultPath); fd = new CFileDialog(true, ".brf", NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilter); if (fd->DoModal() == IDCANCEL) { delete fd; CDialog::OnCancel(); return FALSE; } GetTempPath(_MAX_PATH * 2, sztemppath); m_RealFileName = fd->GetPathName(); _splitpath(m_RealFileName, drive, path, NULL, NULL); savepath = drive; savepath += path; AfxGetApp()->WriteProfileString("Defaults", "LastDir", savepath); GetTempFileName(sztemppath, "d3brf", 0x42, sztempfile); m_TempFileName = sztempfile; delete fd; fd = NULL; FILE *infile; struct _stat buf; int result = _stat(m_RealFileName, &buf); if (result != 0) { AfxMessageBox("Error: Cannot determine file size!", MB_OK | MB_ICONSTOP); goto do_error; } infile = fopen(m_RealFileName, "rt"); if (infile) { CString newtitle; newtitle.Format("Outrage Briefing file localizer -- %s", m_RealFileName); SetWindowText(newtitle); char *szbuf; szbuf = (char *)malloc(buf.st_size); fread(szbuf, buf.st_size, 1, infile); fclose(infile); m_BigTextString = szbuf; m_BigStringTextLower = m_BigTextString; m_BigStringTextLower.MakeLower(); delete szbuf; m_TitleLeft = m_BigStringTextLower.Find(TITLE_TAG); if (m_TitleLeft != -1) { m_TitleRight = m_BigStringTextLower.Find("\"", m_TitleLeft + TITLE_TAG_LENGTH); m_Title = m_BigTextString.Mid(TITLE_TAG_LENGTH + m_TitleLeft, (m_TitleRight - (m_TitleLeft + TITLE_TAG_LENGTH))); } else { AfxMessageBox("Warning: There is no title in this briefing file!", MB_OK); GetDlgItem(IDC_TITLE)->EnableWindow(false); } // Now I need to find the first text item! m_CurTextLeft = m_BigStringTextLower.Find(TEXT_START_TAG); if (m_CurTextLeft != -1) { m_CurTextLeft = m_BigStringTextLower.Find(TEXT_SHOW_TAG, m_CurTextLeft); if (m_CurTextLeft != -1) { m_CurTextRight = m_BigStringTextLower.Find(TEXT_END_TAG, m_CurTextLeft + TEXT_SHOW_TAG_LEN); m_CurTextLeft += TEXT_SHOW_TAG_LEN; FIND_NEXT_LINE(m_CurTextLeft, m_BigTextString); m_Text = m_BigTextString.Mid(m_CurTextLeft, (m_CurTextRight - (m_CurTextLeft)-1)); } } else { AfxMessageBox("Warning: There is no text in this briefing file!", MB_OK); GetDlgItem(IDC_NEXT)->EnableWindow(false); GetDlgItem(IDC_PREV)->EnableWindow(false); GetDlgItem(IDC_TEXT)->EnableWindow(false); } m_CurrentText = 1; // Disable the previous button GetDlgItem(IDC_PREV)->EnableWindow(false); UpdateData(false); return TRUE; // return TRUE unless you set the focus to a control } do_error: AfxMessageBox("Error: Cannot open specified file!", MB_OK | MB_ICONSTOP); CDialog::OnCancel(); return TRUE; } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CBriefinglocalizerDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CBriefinglocalizerDlg::OnQueryDragIcon() { return (HCURSOR)m_hIcon; } void CBriefinglocalizerDlg::OnNext() { // Get the text out of the dialog... UpdateData(true); CString left, right; left = m_BigTextString.Left(m_CurTextLeft); right = m_BigTextString.Right(m_BigTextString.GetLength() - m_CurTextRight); m_BigTextString = left + m_Text + "\n" + right; m_BigStringTextLower = m_BigTextString; m_BigStringTextLower.MakeLower(); m_CurTextRight = m_CurTextLeft + m_Text.GetLength(); int saveleft = m_CurTextLeft; // Now I need to find the next text item! m_CurTextLeft = m_BigStringTextLower.Find(TEXT_START_TAG, m_CurTextRight); if (m_CurTextLeft != -1) { m_CurTextLeft = m_BigStringTextLower.Find(TEXT_SHOW_TAG, m_CurTextLeft); if (m_CurTextLeft != -1) { m_CurTextRight = m_BigStringTextLower.Find(TEXT_END_TAG, m_CurTextLeft + TEXT_SHOW_TAG_LEN); m_CurTextLeft += TEXT_SHOW_TAG_LEN; FIND_NEXT_LINE(m_CurTextLeft, m_BigTextString); m_Text = m_BigTextString.Mid(m_CurTextLeft, (m_CurTextRight - (m_CurTextLeft)-1)); GetDlgItem(IDC_PREV)->EnableWindow(true); m_CurrentText++; } } else { m_CurTextLeft = saveleft; GetDlgItem(IDC_NEXT)->EnableWindow(false); } UpdateData(false); } void CBriefinglocalizerDlg::OnPrev() { UpdateData(true); CString left, right; left = m_BigTextString.Left(m_CurTextLeft); right = m_BigTextString.Right(m_BigTextString.GetLength() - m_CurTextRight); m_BigTextString = left + m_Text + "\n" + right; m_BigStringTextLower = m_BigTextString; m_BigStringTextLower.MakeLower(); m_CurTextRight = 0; m_CurTextLeft = 0; m_CurrentText--; int count = 0; // Rewind to the previous item while (count != m_CurrentText) { m_CurTextLeft = m_BigStringTextLower.Find(TEXT_START_TAG, m_CurTextRight); if (m_CurTextLeft != -1) { m_CurTextLeft = m_BigStringTextLower.Find(TEXT_SHOW_TAG, m_CurTextLeft); if (m_CurTextLeft != -1) { m_CurTextRight = m_BigStringTextLower.Find(TEXT_END_TAG, m_CurTextLeft + TEXT_SHOW_TAG_LEN); m_CurTextLeft += TEXT_SHOW_TAG_LEN; FIND_NEXT_LINE(m_CurTextLeft, m_BigTextString); } } count++; } m_Text = m_BigTextString.Mid(m_CurTextLeft, (m_CurTextRight - (m_CurTextLeft))); GetDlgItem(IDC_NEXT)->EnableWindow(true); if (m_CurrentText <= 1) { // Disable the previous button GetDlgItem(IDC_PREV)->EnableWindow(false); } UpdateData(false); } void CBriefinglocalizerDlg::OnQuit() { // See if the file has changed since it was last saved if (m_FileChanged) { int res = AfxMessageBox("Briefing has changed, would you like to save your changes?", MB_YESNOCANCEL); switch (res) { case IDYES: // Prompt to save if it has OnSave(); break; case IDNO: break; case IDCANCEL: return; default: return; } } CDialog::OnCancel(); } void CBriefinglocalizerDlg::OnSave() { // Update the big string CString testfile; FILE *outfile; testfile = m_RealFileName; // + ".test"; outfile = fopen(testfile, "wt"); if (outfile) { fwrite(LPCSTR(m_BigTextString), m_BigTextString.GetLength(), 1, outfile); m_FileChanged = false; fclose(outfile); } else { AfxMessageBox("Error: Unable to write to file!", MB_OK); } } void CBriefinglocalizerDlg::OnKillfocusTitle() { CString oldtitle = m_Title; UpdateData(true); int titlelendelta = m_Title.GetLength() - oldtitle.GetLength(); int titleleft = 0; int titleright = 0; CString left, right; titleleft = m_BigStringTextLower.Find(TITLE_TAG); if (titleleft != -1) { titleright = m_BigStringTextLower.Find("\"", titleleft + TITLE_TAG_LENGTH); left = m_BigTextString.Left(titleleft + TITLE_TAG_LENGTH); right = m_BigTextString.Right(m_BigTextString.GetLength() - (titleright + 1)); m_BigTextString = left + m_Title + "\"" + right; m_BigStringTextLower = m_BigTextString; m_BigStringTextLower.MakeLower(); m_CurTextLeft += titlelendelta; m_CurTextRight += titlelendelta; } } void CBriefinglocalizerDlg::OnCancel() { // do nothing... we want to use OnQuit() // CDialog::OnCancel(); } void CBriefinglocalizerDlg::OnChangeText() { m_FileChanged = true; UpdateData(true); CString left, right; left = m_BigTextString.Left(m_CurTextLeft); right = m_BigTextString.Right(m_BigTextString.GetLength() - m_CurTextRight); m_BigTextString = left + m_Text + "\n" + right; m_BigStringTextLower = m_BigTextString; m_BigStringTextLower.MakeLower(); m_CurTextRight = m_CurTextLeft + m_Text.GetLength(); } void CBriefinglocalizerDlg::OnChangeTitle() { m_FileChanged = true; } void CBriefinglocalizerDlg::OnKillfocusText(NMHDR *pNMHDR, LRESULT *pResult) { UpdateData(true); CString left, right; left = m_BigTextString.Left(m_CurTextLeft); right = m_BigTextString.Right(m_BigTextString.GetLength() - m_CurTextRight); m_BigTextString = left + m_Text + "\n" + right; m_BigStringTextLower = m_BigTextString; m_BigStringTextLower.MakeLower(); m_CurTextRight = m_CurTextLeft + m_Text.GetLength(); *pResult = 0; }