1 // CampaignEditorDlg.cpp : implementation file
7 #include "campaigneditordlg.h"
8 #include "campaigntreeview.h"
9 #include "campaigntreewnd.h"
10 #include "management.h"
13 #include "missiongoals.h"
18 static char THIS_FILE[] = __FILE__;
21 int Cur_campaign_mission = -1;
22 int Cur_campaign_link = -1;
24 // determine the node number that would be allocated without actually allocating it yet.
25 int campaign_sexp_tree::get_new_node_position()
29 for (i=0; i<MAX_SEXP_TREE_SIZE; i++){
30 if (nodes[i].type == SEXPT_UNUSED){
38 // construct tree nodes for an sexp, adding them to the list and returning first node
39 int campaign_sexp_tree::load_sub_tree(int index)
44 cur = allocate_node(-1);
45 set_node(cur, (SEXPT_OPERATOR | SEXPT_VALID), "do-nothing"); // setup a default tree if none
49 // assumption: first token is an operator. I require this because it would cause problems
50 // with child/parent relations otherwise, and it should be this way anyway, since the
51 // return type of the whole sexp is boolean, and only operators can satisfy this.
52 Assert(Sexp_nodes[index].subtype == SEXP_ATOM_OPERATOR);
53 cur = get_new_node_position();
54 load_branch(index, -1);
58 /////////////////////////////////////////////////////////////////////////////
61 IMPLEMENT_DYNCREATE(campaign_editor, CFormView)
63 campaign_editor *Campaign_tree_formp;
65 campaign_editor::campaign_editor()
66 : CFormView(campaign_editor::IDD)
68 //{{AFX_DATA_INIT(campaign_editor)
71 m_num_players = _T("");
74 m_loop_brief_anim = _T("");
75 m_loop_brief_sound = _T("");
78 m_tree.m_mode = MODE_CAMPAIGN;
80 m_tree.link_modified(&Campaign_modified);
84 campaign_editor::~campaign_editor()
88 void campaign_editor::DoDataExchange(CDataExchange* pDX)
90 CFormView::DoDataExchange(pDX);
91 //{{AFX_DATA_MAP(campaign_editor)
92 DDX_Control(pDX, IDC_SEXP_TREE, m_tree);
93 DDX_Control(pDX, IDC_FILELIST, m_filelist);
94 DDX_Text(pDX, IDC_NAME, m_name);
95 DDX_CBIndex(pDX, IDC_CAMPAIGN_TYPE, m_type);
96 DDX_Text(pDX, IDC_NUM_PLAYERS, m_num_players);
97 DDX_Text(pDX, IDC_DESC2, m_desc);
98 DDX_Text(pDX, IDC_MISSISON_LOOP_DESC, m_loop_desc);
99 DDX_Text(pDX, IDC_LOOP_BRIEF_ANIM, m_loop_brief_anim);
100 DDX_Text(pDX, IDC_LOOP_BRIEF_SOUND, m_loop_brief_sound);
103 DDV_MaxChars(pDX, m_desc, MISSION_DESC_LENGTH - 1);
104 DDV_MaxChars(pDX, m_loop_desc, MISSION_DESC_LENGTH - 1);
107 BEGIN_MESSAGE_MAP(campaign_editor, CFormView)
108 //{{AFX_MSG_MAP(campaign_editor)
109 ON_BN_CLICKED(ID_LOAD, OnLoad)
110 ON_BN_CLICKED(IDC_ALIGN, OnAlign)
111 ON_BN_CLICKED(ID_CPGN_CLOSE, OnCpgnClose)
112 ON_NOTIFY(NM_RCLICK, IDC_SEXP_TREE, OnRclickTree)
113 ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_SEXP_TREE, OnBeginlabeleditSexpTree)
114 ON_NOTIFY(TVN_ENDLABELEDIT, IDC_SEXP_TREE, OnEndlabeleditSexpTree)
115 ON_NOTIFY(TVN_SELCHANGED, IDC_SEXP_TREE, OnSelchangedSexpTree)
116 ON_BN_CLICKED(IDC_MOVE_UP, OnMoveUp)
117 ON_BN_CLICKED(IDC_MOVE_DOWN, OnMoveDown)
118 ON_COMMAND(ID_END_EDIT, OnEndEdit)
119 ON_EN_CHANGE(IDC_BRIEFING_CUTSCENE, OnChangeBriefingCutscene)
120 ON_CBN_SELCHANGE(IDC_CAMPAIGN_TYPE, OnSelchangeType)
121 ON_BN_CLICKED(IDC_GALATEA, OnGalatea)
122 ON_BN_CLICKED(IDC_BASTION, OnBastion)
123 ON_BN_CLICKED(IDC_TOGGLE_LOOP, OnToggleLoop)
124 ON_BN_CLICKED(IDC_LOOP_BRIEF_BROWSE, OnBrowseLoopAni)
125 ON_BN_CLICKED(IDC_LOOP_BRIEF_SOUND_BROWSE, OnBrowseLoopSound)
129 /////////////////////////////////////////////////////////////////////////////
130 // campaign_editor diagnostics
133 void campaign_editor::AssertValid() const
135 CFormView::AssertValid();
138 void campaign_editor::Dump(CDumpContext& dc) const
144 /////////////////////////////////////////////////////////////////////////////
145 // campaign_editor message handlers
147 void campaign_editor::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
152 void campaign_editor::OnLoad()
156 if (Cur_campaign_mission < 0){
160 if (Campaign_modified){
161 if (Campaign_wnd->save_modified()){
166 GetCurrentDirectory(512, buf);
168 strcat(buf, Campaign.missions[Cur_campaign_mission].name);
169 FREDDoc_ptr->SetPathName(buf);
170 Campaign_wnd->DestroyWindow();
172 // if (FREDDoc_ptr->OnOpenDocument(Campaign.missions[Cur_campaign_mission].name)) {
173 // Bypass_clear_mission = 1;
174 // Campaign_wnd->DestroyWindow();
177 // MessageBox("Failed to load mission!", "Error");
181 BOOL campaign_editor::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
187 r = CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
189 box = (CComboBox *) GetDlgItem(IDC_CAMPAIGN_TYPE);
191 for (i=0; i<MAX_CAMPAIGN_TYPES; i++){
192 box->AddString(campaign_types[i]);
199 void campaign_editor::load_campaign()
201 Cur_campaign_mission = Cur_campaign_link = -1;
204 if (!strlen(Campaign.filename))
205 strcpy(Campaign.filename, BUILTIN_CAMPAIGN);
207 if (mission_campaign_load(Campaign.filename, 0)) {
208 MessageBox("Couldn't open Campaign file!", "Error");
209 Campaign_wnd->OnCpgnFileNew();
213 Campaign_modified = 0;
214 Campaign_tree_viewp->construct_tree();
218 void campaign_editor::OnAlign()
220 Campaign_tree_viewp->sort_elements();
221 Campaign_tree_viewp->realign_tree();
222 Campaign_tree_viewp->Invalidate();
225 void campaign_editor::initialize( int init_files )
227 Cur_campaign_mission = Cur_campaign_link = -1;
228 m_tree.setup((CEdit *) GetDlgItem(IDC_HELP_BOX));
230 Campaign_tree_viewp->initialize();
232 // only initialize the file dialog box when the parameter says to. This should
233 // only happen when a campaign type changes
235 m_filelist.initialize();
238 m_name = Campaign.name;
239 m_type = Campaign.type;
240 m_num_players.Format("%d", Campaign.num_players);
243 m_desc = convert_multiline_string(Campaign.desc);
248 m_loop_desc = _T("");
250 m_loop_brief_anim = _T("");
251 m_loop_brief_sound = _T("");
253 // single player should hide the two dialog items about number of players allowed
254 if ( m_type == CAMPAIGN_TYPE_SINGLE ) {
255 GetDlgItem(IDC_NUM_PLAYERS)->ShowWindow( SW_HIDE );
256 GetDlgItem(IDC_PLAYERS_LABEL)->ShowWindow( SW_HIDE );
258 GetDlgItem(IDC_NUM_PLAYERS)->ShowWindow( SW_SHOW );
259 GetDlgItem(IDC_PLAYERS_LABEL)->ShowWindow( SW_SHOW );
265 void campaign_editor::mission_selected(int num)
269 bc_dialog = (CEdit *) GetDlgItem(IDC_BRIEFING_CUTSCENE);
271 // clear out the text for the briefing cutscene, and put in new text if specified
272 bc_dialog->SetWindowText("");
273 if ( strlen(Campaign.missions[num].briefing_cutscene) )
274 bc_dialog->SetWindowText(Campaign.missions[num].briefing_cutscene);
276 if (Campaign.missions[num].flags & CMISSION_FLAG_BASTION) {
277 ((CButton *) GetDlgItem(IDC_GALATEA)) -> SetCheck(0);
278 ((CButton *) GetDlgItem(IDC_BASTION)) -> SetCheck(1);
281 ((CButton *) GetDlgItem(IDC_GALATEA)) -> SetCheck(1);
282 ((CButton *) GetDlgItem(IDC_BASTION)) -> SetCheck(0);
286 void campaign_editor::update()
288 char buf[MISSION_DESC_LENGTH];
290 // get data from dlog box
293 // update campaign name
294 string_copy(Campaign.name, m_name, NAME_LENGTH);
295 Campaign.type = m_type;
297 // update campaign desc
298 deconvert_multiline_string(buf, m_desc, MISSION_DESC_LENGTH);
303 Campaign.desc = NULL;
305 Campaign.desc = strdup(buf);
308 // maybe update mission loop text
309 save_loop_desc_window();
311 // set the number of players in a multiplayer mission equal to the number of players in the first mission
312 if ( Campaign.type != CAMPAIGN_TYPE_SINGLE ) {
313 if ( Campaign.num_missions == 0 ) {
314 Campaign.num_players = 0;
318 get_mission_info(Campaign.missions[0].name, &a_mission);
319 Campaign.num_players = a_mission.num_players;
324 void campaign_editor::OnCpgnClose()
326 Campaign_wnd->OnClose();
329 void campaign_editor::load_tree(int save_first)
339 m_tree.DeleteAllItems();
342 update_loop_desc_window();
344 m_last_mission = Cur_campaign_mission;
345 if (Cur_campaign_mission < 0) {
346 GetDlgItem(IDC_SEXP_TREE)->EnableWindow(FALSE);
347 GetDlgItem(IDC_BRIEFING_CUTSCENE)->EnableWindow(FALSE);
351 GetDlgItem(IDC_SEXP_TREE)->EnableWindow(TRUE);
352 GetDlgItem(IDC_BRIEFING_CUTSCENE)->EnableWindow(TRUE);
354 GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(FALSE);
355 GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(FALSE);
356 GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(FALSE);
357 GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(FALSE);
358 GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(FALSE);
360 for (i=0; i<Total_links; i++) {
361 if (Links[i].from == Cur_campaign_mission) {
362 Links[i].node = m_tree.load_sub_tree(Links[i].sexp);
365 if (Links[i].from == Links[i].to) {
366 strcpy(text, "Repeat mission");
367 } else if ( (Links[i].to == -1) && (Links[i].from != -1) ) {
368 strcpy(text, "End of Campaign");
370 sprintf(text, "Branch to %s", Campaign.missions[Links[i].to].name);
373 // insert item into tree
374 int image, sel_image;
375 if (Links[i].mission_loop) {
376 image = BITMAP_BLUE_DOT;
377 sel_image = BITMAP_GREEN_DOT;
379 image = BITMAP_BLACK_DOT;
380 sel_image = BITMAP_RED_DOT;
383 h = m_tree.insert(text, image, sel_image);
385 m_tree.SetItemData(h, Links[i].node);
386 m_tree.add_sub_tree(Links[i].node, h);
391 void campaign_editor::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult)
393 m_tree.right_clicked(MODE_CAMPAIGN);
397 void campaign_editor::OnBeginlabeleditSexpTree(NMHDR* pNMHDR, LRESULT* pResult)
399 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
401 if (m_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
403 Campaign_modified = 1;
409 void campaign_editor::OnEndlabeleditSexpTree(NMHDR* pNMHDR, LRESULT* pResult)
411 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
413 *pResult = m_tree.end_label_edit(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);
416 int campaign_editor::handler(int code, int node, char *str)
422 for (i=0; i<Total_links; i++){
423 if ((Links[i].from == Cur_campaign_mission) && (Links[i].node == node)){
428 Campaign_tree_viewp->delete_link(i);
439 void campaign_editor::save_tree(int clear)
443 if (m_last_mission < 0){
444 return; // nothing to save
447 for (i=0; i<Total_links; i++){
448 if (Links[i].from == m_last_mission) {
449 sexp_unmark_persistent(Links[i].sexp);
450 free_sexp2(Links[i].sexp);
451 Links[i].sexp = m_tree.save_tree(Links[i].node);
452 sexp_mark_persistent(Links[i].sexp);
461 void campaign_editor::OnSelchangedSexpTree(NMHDR* pNMHDR, LRESULT* pResult)
466 // get handle of selected item
467 NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
468 h = pNMTreeView->itemNew.hItem;
471 // update help on sexp
472 m_tree.update_help(h);
474 // get handle of parent
475 while ((h2 = m_tree.GetParentItem(h))>0){
479 // get identifier of parent
480 node = m_tree.GetItemData(h);
481 for (i=0; i<Total_links; i++){
482 if ((Links[i].from == Cur_campaign_mission) && (Links[i].node == node)){
487 if (i == Total_links) {
488 Cur_campaign_link = -1;
492 // update mission loop text
494 save_loop_desc_window();
496 Cur_campaign_link = i;
497 update_loop_desc_window();
498 Campaign_tree_viewp->Invalidate();
502 void campaign_editor::OnMoveUp()
505 campaign_tree_link temp;
508 if (Cur_campaign_link >= 0) {
510 for (i=0; i<Total_links; i++){
511 if (Links[i].from == Cur_campaign_mission) {
512 if (i == Cur_campaign_link){
520 if ((last != -1) && (i < Total_links)) {
521 h1 = m_tree.GetParentItem(m_tree.handle(Links[i].node));
522 h2 = m_tree.GetParentItem(m_tree.handle(Links[last].node));
523 m_tree.swap_roots(h1, h2);
524 m_tree.SelectItem(m_tree.GetParentItem(m_tree.handle(Links[i].node)));
527 Links[last] = Links[i];
529 Cur_campaign_link = last;
533 GetDlgItem(IDC_SEXP_TREE)->SetFocus();
536 void campaign_editor::OnMoveDown()
539 campaign_tree_link temp;
542 if (Cur_campaign_link >= 0) {
544 for (i=0; i<Total_links; i++)
545 if (Links[i].from == Cur_campaign_mission)
546 if (i == Cur_campaign_link)
549 for (j=i+1; j<Total_links; j++)
550 if (Links[j].from == Cur_campaign_mission)
553 if (j < Total_links) {
554 h1 = m_tree.GetParentItem(m_tree.handle(Links[i].node));
555 h2 = m_tree.GetParentItem(m_tree.handle(Links[j].node));
556 m_tree.swap_roots(h1, h2);
557 m_tree.SelectItem(m_tree.GetParentItem(m_tree.handle(Links[i].node)));
562 Cur_campaign_link = j;
566 GetDlgItem(IDC_SEXP_TREE)->SetFocus();
569 void campaign_editor::swap_handler(int node1, int node2)
572 campaign_tree_link temp;
574 for (index1=0; index1<Total_links; index1++){
575 if ((Links[index1].from == Cur_campaign_mission) && (Links[index1].node == node1)){
580 Assert(index1 < Total_links);
581 for (index2=0; index2<Total_links; index2++){
582 if ((Links[index2].from == Cur_campaign_mission) && (Links[index2].node == node2)){
587 Assert(index2 < Total_links);
588 temp = Links[index1];
589 // Links[index1] = Links[index2];
590 while (index1 < index2) {
591 Links[index1] = Links[index1 + 1];
595 while (index1 > index2 + 1) {
596 Links[index1] = Links[index1 - 1];
600 // update Cur_campaign_link
601 Cur_campaign_link = index1;
603 Links[index1] = temp;
606 void campaign_editor::insert_handler(int old, int node)
610 for (i=0; i<Total_links; i++){
611 if ((Links[i].from == Cur_campaign_mission) && (Links[i].node == old)){
616 Assert(i < Total_links);
617 Links[i].node = node;
621 void campaign_editor::OnEndEdit()
629 GetDlgItem(IDC_SEXP_TREE)->SetFocus();
634 void campaign_editor::OnChangeBriefingCutscene()
638 bc_dialog = (CEdit *) GetDlgItem(IDC_BRIEFING_CUTSCENE);
640 // maybe save off the current cutscene names.
641 if ( Cur_campaign_mission != -1 ) {
643 // see if the contents of the edit box have changed. Luckily, this returns 0 when the edit box is
645 if ( bc_dialog->GetModify() ) {
646 bc_dialog->GetWindowText( Campaign.missions[Cur_campaign_mission].briefing_cutscene, NAME_LENGTH );
647 Campaign_modified = 1;
653 // what to do when changing campaign type
654 void campaign_editor::OnSelchangeType()
656 // if campaign type is single player, then disable the multiplayer items
659 Campaign_modified = 1;
663 void campaign_editor::OnGalatea()
665 if (Cur_campaign_mission >= 0){
666 Campaign.missions[Cur_campaign_mission].flags &= ~CMISSION_FLAG_BASTION;
670 void campaign_editor::OnBastion()
672 if (Cur_campaign_mission >= 0){
673 Campaign.missions[Cur_campaign_mission].flags |= CMISSION_FLAG_BASTION;
677 // update the loop mission text
678 void campaign_editor::save_loop_desc_window()
680 char buffer[MISSION_DESC_LENGTH];
682 // update only if active link and there is a mission has mission loop
683 if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop ) {
684 deconvert_multiline_string(buffer, m_loop_desc, MISSION_DESC_LENGTH);
685 if (Links[Cur_campaign_link].mission_loop_txt) {
686 free(Links[Cur_campaign_link].mission_loop_txt);
688 if (Links[Cur_campaign_link].mission_loop_brief_anim) {
689 free(Links[Cur_campaign_link].mission_loop_brief_anim);
691 if (Links[Cur_campaign_link].mission_loop_brief_sound) {
692 free(Links[Cur_campaign_link].mission_loop_brief_sound);
695 if (strlen(buffer)) {
696 Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
698 Links[Cur_campaign_link].mission_loop_txt = NULL;
701 deconvert_multiline_string(buffer, m_loop_brief_anim, MAX_FILENAME_LEN);
703 Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
705 Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
708 deconvert_multiline_string(buffer, m_loop_brief_sound, MAX_FILENAME_LEN);
710 Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
712 Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
717 void campaign_editor::update_loop_desc_window()
719 bool enable_loop_desc_window;
721 enable_loop_desc_window = false;
722 if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop) {
723 enable_loop_desc_window = true;
726 // maybe enable description window
727 GetDlgItem(IDC_MISSISON_LOOP_DESC)->EnableWindow(enable_loop_desc_window);
728 GetDlgItem(IDC_LOOP_BRIEF_ANIM)->EnableWindow(enable_loop_desc_window);
729 GetDlgItem(IDC_LOOP_BRIEF_SOUND)->EnableWindow(enable_loop_desc_window);
730 GetDlgItem(IDC_LOOP_BRIEF_BROWSE)->EnableWindow(enable_loop_desc_window);
731 GetDlgItem(IDC_LOOP_BRIEF_SOUND_BROWSE)->EnableWindow(enable_loop_desc_window);
734 if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_txt && enable_loop_desc_window) {
735 m_loop_desc = convert_multiline_string(Links[Cur_campaign_link].mission_loop_txt);
737 m_loop_desc = _T("");
741 if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_brief_anim && enable_loop_desc_window) {
742 m_loop_brief_anim = convert_multiline_string(Links[Cur_campaign_link].mission_loop_brief_anim);
744 m_loop_brief_anim = _T("");
748 if ((Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop_brief_sound && enable_loop_desc_window) {
749 m_loop_brief_sound = convert_multiline_string(Links[Cur_campaign_link].mission_loop_brief_sound);
751 m_loop_brief_sound = _T("");
758 void campaign_editor::OnToggleLoop()
760 // check if branch selected
761 if (Cur_campaign_link == -1) {
765 // store mission looop text
768 if ( (Cur_campaign_link >= 0) && Links[Cur_campaign_link].mission_loop ) {
769 if (Links[Cur_campaign_link].mission_loop_txt) {
770 free(Links[Cur_campaign_link].mission_loop_txt);
773 if (Links[Cur_campaign_link].mission_loop_brief_anim) {
774 free(Links[Cur_campaign_link].mission_loop_brief_anim);
777 if (Links[Cur_campaign_link].mission_loop_brief_sound) {
778 free(Links[Cur_campaign_link].mission_loop_brief_sound);
781 char buffer[MISSION_DESC_LENGTH];
783 deconvert_multiline_string(buffer, m_loop_desc, MISSION_DESC_LENGTH);
784 if (m_loop_desc && strlen(buffer)) {
785 Links[Cur_campaign_link].mission_loop_txt = strdup(buffer);
787 Links[Cur_campaign_link].mission_loop_txt = NULL;
790 deconvert_multiline_string(buffer, m_loop_brief_anim, MISSION_DESC_LENGTH);
791 if (m_loop_brief_anim && strlen(buffer)) {
792 Links[Cur_campaign_link].mission_loop_brief_anim = strdup(buffer);
794 Links[Cur_campaign_link].mission_loop_brief_anim = NULL;
797 deconvert_multiline_string(buffer, m_loop_brief_sound, MISSION_DESC_LENGTH);
798 if (m_loop_brief_sound && strlen(buffer)) {
799 Links[Cur_campaign_link].mission_loop_brief_sound = strdup(buffer);
801 Links[Cur_campaign_link].mission_loop_brief_sound = NULL;
805 // toggle to mission_loop setting
806 Links[Cur_campaign_link].mission_loop = !Links[Cur_campaign_link].mission_loop;
808 // reset loop desc window (gray if inactive)
809 update_loop_desc_window();
812 int bitmap1, bitmap2;
813 if (Links[Cur_campaign_link].mission_loop) {
814 bitmap2 = BITMAP_GREEN_DOT;
815 bitmap1 = BITMAP_BLUE_DOT;
817 bitmap1 = BITMAP_BLACK_DOT;
818 bitmap2 = BITMAP_RED_DOT;
821 // Search for item and update bitmap
822 HTREEITEM h = m_tree.GetRootItem();
824 if ((int) m_tree.GetItemData(h) == Links[Cur_campaign_link].node) {
825 m_tree.SetItemImage(h, bitmap1, bitmap2);
829 h = m_tree.GetNextSiblingItem(h);
833 Campaign_tree_viewp->Invalidate();
836 void campaign_editor::OnBrowseLoopAni()
842 // switch directories
843 pushed_dir = cfile_push_chdir(CF_TYPE_INTERFACE);
844 CFileDialog dlg(TRUE, "ani", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Ani Files (*.ani)|*.ani");
846 if (dlg.DoModal() == IDOK) {
847 m_loop_brief_anim = dlg.GetFileName();
851 // move back to the proper directory
857 void campaign_editor::OnBrowseLoopSound()
863 // switch directories
864 pushed_dir = cfile_push_chdir(CF_TYPE_VOICE_CMD_BRIEF);
865 CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR, "Wave Files (*.wav)|*.wav||");
867 if (dlg.DoModal() == IDOK) {
868 m_loop_brief_sound = dlg.GetFileName();
872 // move back to the proper directory