comparison src/win32/MainWndTools.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
comparison
equal deleted inserted replaced
0:8ced16adf2e1 1:f9f4f1b99eed
1 #include "stdafx.h"
2 #include <cassert>
3 #include "resource.h"
4 #include "MainWnd.h"
5 #include "AccelEditor.h"
6 #include "AVIWrite.h"
7 #include "Disassemble.h"
8 #include "FileDlg.h"
9 #include "GBDisassemble.h"
10 #include "GBMapView.h"
11 #include "GBMemoryViewerDlg.h"
12 #include "GBOamView.h"
13 #include "GBPaletteView.h"
14 #include "GBTileView.h"
15 #include "GDBConnection.h"
16 #include "IOViewer.h"
17 #include "MapView.h"
18 #include "MemoryViewerDlg.h"
19 #include "MovieOpen.h"
20 #include "MovieCreate.h"
21 #include "OamView.h"
22 #include "PaletteView.h"
23 #include "Reg.h"
24 #include "TileView.h"
25 #include "WavWriter.h"
26 #include "WinResUtil.h"
27 #include "WinMiscUtil.h"
28 #include "VBA.h"
29
30 #include "../gba/GBA.h"
31 #include "../gba/GBAGlobals.h"
32 #include "../gb/GB.h"
33
34 extern int32 gbBorderOn;
35 extern int32 soundQuality;
36
37 extern bool debugger;
38 extern int emulating;
39 extern int remoteSocket;
40
41 extern void remoteCleanUp();
42 extern void remoteSetSockets(SOCKET, SOCKET);
43 extern void toolsLogging();
44
45 void MainWnd::OnToolsDisassemble()
46 {
47 if (systemCartridgeType == 0)
48 {
49 Disassemble *dlg = new Disassemble();
50 dlg->Create(IDD_DISASSEMBLE, this);
51 dlg->ShowWindow(SW_SHOW);
52 }
53 else
54 {
55 GBDisassemble *dlg = new GBDisassemble();
56 dlg->Create(IDD_GB_DISASSEMBLE, this);
57 dlg->ShowWindow(SW_SHOW);
58 }
59 }
60
61 void MainWnd::OnUpdateToolsDisassemble(CCmdUI *pCmdUI)
62 {
63 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
64 }
65
66 void MainWnd::OnToolsLogging()
67 {
68 toolsLogging();
69 }
70
71 void MainWnd::OnUpdateToolsLogging(CCmdUI *pCmdUI)
72 {
73 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
74 }
75
76 void MainWnd::OnToolsIoviewer()
77 {
78 IOViewer *dlg = new IOViewer;
79 dlg->Create(IDD_IO_VIEWER, this);
80 dlg->ShowWindow(SW_SHOW);
81 }
82
83 void MainWnd::OnUpdateToolsIoviewer(CCmdUI *pCmdUI)
84 {
85 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X && systemCartridgeType == 0);
86 }
87
88 void MainWnd::OnToolsMapview()
89 {
90 if (systemCartridgeType == 0)
91 {
92 MapView *dlg = new MapView;
93 dlg->Create(IDD_MAP_VIEW, this);
94 dlg->ShowWindow(SW_SHOW);
95 }
96 else
97 {
98 GBMapView *dlg = new GBMapView;
99 dlg->Create(IDD_GB_MAP_VIEW, this);
100 dlg->ShowWindow(SW_SHOW);
101 }
102 }
103
104 void MainWnd::OnUpdateToolsMapview(CCmdUI *pCmdUI)
105 {
106 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
107 }
108
109 void MainWnd::OnToolsMemoryviewer()
110 {
111 if (systemCartridgeType == 0)
112 {
113 MemoryViewerDlg *dlg = new MemoryViewerDlg;
114 dlg->Create(IDD_MEM_VIEWER, this);
115 dlg->ShowWindow(SW_SHOW);
116 }
117 else
118 {
119 GBMemoryViewerDlg *dlg = new GBMemoryViewerDlg;
120 dlg->Create(IDD_MEM_VIEWER, this);
121 dlg->ShowWindow(SW_SHOW);
122 }
123 }
124
125 void MainWnd::OnUpdateToolsMemoryviewer(CCmdUI *pCmdUI)
126 {
127 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
128 }
129
130 void MainWnd::OnToolsOamviewer()
131 {
132 if (systemCartridgeType == 0)
133 {
134 OamView *dlg = new OamView;
135 dlg->Create(IDD_OAM_VIEW, this);
136 dlg->ShowWindow(SW_SHOW);
137 }
138 else
139 {
140 GBOamView *dlg = new GBOamView;
141 dlg->Create(IDD_GB_OAM_VIEW, this);
142 dlg->ShowWindow(SW_SHOW);
143 }
144 }
145
146 void MainWnd::OnUpdateToolsOamviewer(CCmdUI *pCmdUI)
147 {
148 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
149 }
150
151 void MainWnd::OnToolsPaletteview()
152 {
153 if (systemCartridgeType == 0)
154 {
155 PaletteView *dlg = new PaletteView;
156 dlg->Create(IDD_PALETTE_VIEW, this);
157 dlg->ShowWindow(SW_SHOW);
158 }
159 else
160 {
161 GBPaletteView *dlg = new GBPaletteView;
162 dlg->Create(IDD_GB_PALETTE_VIEW, this);
163 dlg->ShowWindow(SW_SHOW);
164 }
165 }
166
167 void MainWnd::OnUpdateToolsPaletteview(CCmdUI *pCmdUI)
168 {
169 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
170 }
171
172 void MainWnd::OnToolsTileviewer()
173 {
174 if (systemCartridgeType == 0)
175 {
176 TileView *dlg = new TileView;
177 dlg->Create(IDD_TILE_VIEWER, this);
178 dlg->ShowWindow(SW_SHOW);
179 }
180 else
181 {
182 GBTileView *dlg = new GBTileView;
183 dlg->Create(IDD_GB_TILE_VIEWER, this);
184 dlg->ShowWindow(SW_SHOW);
185 }
186 }
187
188 void MainWnd::OnUpdateToolsTileviewer(CCmdUI *pCmdUI)
189 {
190 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X);
191 }
192
193 void MainWnd::OnDebugNextframe()
194 {
195 systemSetPause(false);
196 theApp.winPauseNextFrame = true;
197 }
198
199 void MainWnd::OnUpdateDebugNextframe(CCmdUI *pCmdUI)
200 {
201 pCmdUI->Enable(emulating);
202 }
203
204 void MainWnd::OnDebugNextframeAccountForLag()
205 {
206 theApp.nextframeAccountForLag = !theApp.nextframeAccountForLag;
207 }
208
209 void MainWnd::OnUpdateDebugNextframeAccountForLag(CCmdUI *pCmdUI)
210 {
211 pCmdUI->SetCheck(theApp.nextframeAccountForLag);
212 }
213
214 void MainWnd::OnDebugFramesearch()
215 {
216 extern u16 currentButtons [4]; // from System.cpp
217 extern SMovie Movie;
218 if (!theApp.frameSearching)
219 {
220 // starting a new search
221 theApp.frameSearching = true;
222 theApp.frameSearchStart = (Movie.state == MOVIE_STATE_NONE) ? systemCounters.frameCount : Movie.currentFrame;
223 theApp.frameSearchLength = 0;
224 theApp.frameSearchLoadValid = false;
225 theApp.emulator.emuWriteMemState(&theApp.frameSearchMemory[REWIND_SIZE * 0], REWIND_SIZE); // 0 is start state, 1 is
226 // intermediate state (for
227 // speedup when going
228 // forward),
229 // 2 is end state
230 theApp.emulator.emuWriteMemState(&theApp.frameSearchMemory[REWIND_SIZE * 1], REWIND_SIZE);
231
232 // store old buttons from frame before the search
233 for (int i = 0; i < 4; i++)
234 theApp.frameSearchOldInput[i] = currentButtons[i];
235 }
236 else
237 {
238 // advance forward 1 step in the search
239 theApp.frameSearchLength++;
240
241 // try it
242 theApp.emulator.emuReadMemState(&theApp.frameSearchMemory[REWIND_SIZE * 1], REWIND_SIZE);
243 }
244
245 char str [32];
246 sprintf(str, "%d frame search", theApp.frameSearchLength);
247 systemScreenMessage(str, 0);
248
249 theApp.frameSearchSkipping = true;
250
251 // make sure the display updates at least 1 frame to show the new message
252 theApp.frameSearchFirstStep = true;
253
254 if (theApp.paused)
255 theApp.paused = false;
256 }
257
258 void MainWnd::OnUpdateDebugFramesearch(CCmdUI *pCmdUI)
259 {
260 extern SMovie Movie;
261 pCmdUI->Enable(emulating && Movie.state != MOVIE_STATE_PLAY);
262 pCmdUI->SetCheck(theApp.frameSearching);
263 }
264
265 void MainWnd::OnDebugFramesearchPrev()
266 {
267 if (theApp.frameSearching)
268 {
269 if (theApp.frameSearchLength > 0)
270 {
271 // rewind 1 step in the search
272 theApp.frameSearchLength--;
273 }
274
275 // try it
276 theApp.emulator.emuReadMemState(&theApp.frameSearchMemory[REWIND_SIZE * 0], REWIND_SIZE);
277
278 char str[32];
279 sprintf(str, "%d frame search", theApp.frameSearchLength);
280 systemScreenMessage(str, 0);
281
282 theApp.frameSearchSkipping = true;
283
284 // make sure the display updates at least 1 frame to show the new message
285 theApp.frameSearchFirstStep = true;
286
287 if (theApp.paused)
288 theApp.paused = false;
289 }
290 }
291
292 void MainWnd::OnUpdateDebugFramesearchPrev(CCmdUI *pCmdUI)
293 {
294 extern SMovie Movie;
295 pCmdUI->Enable(emulating && theApp.frameSearching && Movie.state != MOVIE_STATE_PLAY);
296 }
297
298 void MainWnd::OnDebugFramesearchLoad()
299 {
300 if (theApp.frameSearchLoadValid)
301 {
302 theApp.emulator.emuReadMemState(&theApp.frameSearchMemory[REWIND_SIZE * 2], REWIND_SIZE);
303 theApp.paused = true;
304
305 if (theApp.frameSearching)
306 systemScreenMessage("end frame search", 0);
307 else
308 systemScreenMessage("restore search end", 0);
309 }
310 theApp.frameSearching = false;
311 theApp.frameSearchSkipping = false;
312 }
313
314 void MainWnd::OnUpdateDebugFramesearchLoad(CCmdUI *pCmdUI)
315 {
316 extern SMovie Movie;
317 pCmdUI->Enable(emulating && Movie.state != MOVIE_STATE_PLAY);
318 }
319
320 void MainWnd::OnToolsFrameCounter()
321 {
322 theApp.frameCounter = !theApp.frameCounter;
323 extern void VBAUpdateFrameCountDisplay(); VBAUpdateFrameCountDisplay();
324 }
325
326 void MainWnd::OnUpdateToolsFrameCounter(CCmdUI *pCmdUI)
327 {
328 pCmdUI->SetCheck(theApp.frameCounter);
329 }
330
331 void MainWnd::OnToolsLagCounter()
332 {
333 theApp.lagCounter = !theApp.lagCounter;
334 extern void VBAUpdateFrameCountDisplay(); VBAUpdateFrameCountDisplay();
335 }
336
337 void MainWnd::OnUpdateToolsLagCounter(CCmdUI *pCmdUI)
338 {
339 pCmdUI->SetCheck(theApp.lagCounter);
340 }
341
342 void MainWnd::OnToolsExtraCounter()
343 {
344 theApp.extraCounter = !theApp.extraCounter;
345 extern void VBAUpdateFrameCountDisplay(); VBAUpdateFrameCountDisplay();
346 }
347
348 void MainWnd::OnUpdateToolsExtraCounter(CCmdUI *pCmdUI)
349 {
350 pCmdUI->SetCheck(theApp.extraCounter);
351 }
352
353 void MainWnd::OnToolsExtraCounterReset()
354 {
355 systemCounters.extraCount = systemCounters.frameCount;
356 }
357
358 void MainWnd::OnToolsInputDisplay()
359 {
360 theApp.inputDisplay = !theApp.inputDisplay;
361 systemScreenMessage(theApp.inputDisplay ? "Input Display On" : "Input Display Off");
362 extern void VBAUpdateButtonPressDisplay(); VBAUpdateButtonPressDisplay();
363 }
364
365 void MainWnd::OnUpdateToolsInputDisplay(CCmdUI *pCmdUI)
366 {
367 pCmdUI->SetCheck(theApp.inputDisplay);
368 }
369
370 void MainWnd::OnToolsDebugGdb()
371 {
372 theApp.winCheckFullscreen();
373 GDBPortDlg dlg;
374
375 if (dlg.DoModal())
376 {
377 GDBWaitingDlg wait(dlg.getSocket(), dlg.getPort());
378 if (wait.DoModal())
379 {
380 remoteSetSockets(wait.getListenSocket(), wait.getSocket());
381 debugger = true;
382 emulating = 1;
383 systemCartridgeType = 0;
384 theApp.gameFilename = "\\gnu_stub";
385 rom = (u8 *)malloc(0x2000000 + 4);
386 workRAM = (u8 *)calloc(1, 0x40000 + 4);
387 bios = (u8 *)calloc(1, 0x4000 + 4);
388 internalRAM = (u8 *)calloc(1, 0x8000 + 4);
389 paletteRAM = (u8 *)calloc(1, 0x400 + 4);
390 vram = (u8 *)calloc(1, 0x20000 + 4);
391 oam = (u8 *)calloc(1, 0x400 + 4);
392 pix = (u8 *)calloc(1, 4 * 240 * 160);
393 ioMem = (u8 *)calloc(1, 0x400 + 4);
394
395 theApp.emulator = GBASystem;
396
397 CPUInit();
398 CPULoadBios(theApp.biosFileName, theApp.useBiosFile ? true : false);
399 CPUReset();
400 }
401 }
402 }
403
404 void MainWnd::OnUpdateToolsDebugGdb(CCmdUI *pCmdUI)
405 {
406 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X && remoteSocket == -1);
407 }
408
409 void MainWnd::OnToolsDebugLoadandwait()
410 {
411 theApp.winCheckFullscreen();
412 if (winFileOpenSelect(0))
413 {
414 if (winFileRun())
415 {
416 if (systemCartridgeType != 0)
417 {
418 systemMessage(IDS_ERROR_NOT_GBA_IMAGE, "Error: not a GBA image");
419 OnFileClose();
420 return;
421 }
422 GDBPortDlg dlg;
423
424 if (dlg.DoModal())
425 {
426 GDBWaitingDlg wait(dlg.getSocket(), dlg.getPort());
427 if (wait.DoModal())
428 {
429 remoteSetSockets(wait.getListenSocket(), wait.getSocket());
430 debugger = true;
431 emulating = 1;
432 }
433 }
434 }
435 }
436 }
437
438 void MainWnd::OnUpdateToolsDebugLoadandwait(CCmdUI *pCmdUI)
439 {
440 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X && remoteSocket == -1);
441 }
442
443 void MainWnd::OnToolsDebugBreak()
444 {
445 if (armState)
446 {
447 armNextPC -= 4;
448 reg[15].I -= 4;
449 }
450 else
451 {
452 armNextPC -= 2;
453 reg[15].I -= 2;
454 }
455 debugger = true;
456 }
457
458 void MainWnd::OnUpdateToolsDebugBreak(CCmdUI *pCmdUI)
459 {
460 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X && remoteSocket != -1);
461 }
462
463 void MainWnd::OnToolsDebugDisconnect()
464 {
465 remoteCleanUp();
466 debugger = false;
467 }
468
469 void MainWnd::OnUpdateToolsDebugDisconnect(CCmdUI *pCmdUI)
470 {
471 pCmdUI->Enable(theApp.videoOption <= VIDEO_4X && remoteSocket != -1);
472 }
473
474 void MainWnd::OnToolsSoundRecording()
475 {
476 if (!theApp.soundRecording)
477 OnToolsSoundStartrecording();
478 else
479 OnToolsSoundStoprecording();
480 }
481
482 void MainWnd::OnToolsSoundStartrecording()
483 {
484 theApp.winCheckFullscreen();
485
486 CString wavName = theApp.gameFilename;
487
488 if (VBAMovieActive())
489 {
490 extern SMovie Movie;
491 wavName = Movie.filename;
492 int index = wavName.ReverseFind('.');
493 if (index != -1)
494 wavName = wavName.Left(index);
495 }
496
497 LPCTSTR exts[] = { ".wav", NULL };
498
499 CString filter = winResLoadFilter(IDS_FILTER_WAV);
500 CString title = winResLoadString(IDS_SELECT_WAV_NAME);
501
502 wavName = winGetDestFilename(wavName, IDS_WAV_DIR, exts[0]);
503 CString wavDir = winGetDestDir(IDS_WAV_DIR);
504
505 FileDlg dlg(this, wavName, filter, 1, "WAV", exts, wavDir, title, true);
506
507 if (dlg.DoModal() == IDCANCEL)
508 {
509 return;
510 }
511
512 theApp.soundRecordName = dlg.GetPathName();
513 theApp.soundRecording = true;
514 }
515
516 void MainWnd::OnToolsSoundStoprecording()
517 {
518 if (theApp.soundRecorder)
519 {
520 delete theApp.soundRecorder;
521 theApp.soundRecorder = NULL;
522 }
523 theApp.soundRecording = false;
524 }
525
526 void MainWnd::OnUpdateToolsSoundRecording(CCmdUI *pCmdUI)
527 {
528 if (pCmdUI->m_pMenu != NULL)
529 {
530 if (!theApp.soundRecording)
531 pCmdUI->SetText(winResLoadString(IDS_STARTSOUNDRECORDING));
532 else
533 pCmdUI->SetText(winResLoadString(IDS_STOPSOUNDRECORDING));
534
535 theApp.winAccelMgr.UpdateMenu(pCmdUI->m_pMenu->GetSafeHmenu());
536 }
537
538 pCmdUI->Enable(emulating);
539 }
540
541 void MainWnd::OnToolsAVIRecording()
542 {
543 if (!theApp.aviRecording)
544 OnToolsStartAVIRecording();
545 else
546 OnToolsStopAVIRecording();
547 }
548
549 void MainWnd::OnToolsStartAVIRecording()
550 {
551 theApp.winCheckFullscreen();
552
553 CString aviName = theApp.gameFilename;
554
555 if (VBAMovieActive())
556 {
557 extern SMovie Movie;
558 aviName = Movie.filename;
559 int index = aviName.ReverseFind('.');
560 if (index != -1)
561 aviName = aviName.Left(index);
562 }
563
564 LPCTSTR exts[] = { ".avi", NULL };
565
566 CString filter = winResLoadFilter(IDS_FILTER_AVI);
567 CString title = winResLoadString(IDS_SELECT_AVI_NAME);
568
569 aviName = winGetDestFilename(aviName, IDS_AVI_DIR, exts[0]);
570 CString aviDir = winGetDestDir(IDS_AVI_DIR);
571
572 FileDlg dlg(this, aviName, filter, 1, "AVI", exts, aviDir, title, true);
573
574 if (dlg.DoModal() == IDCANCEL)
575 {
576 return;
577 }
578
579 theApp.aviRecordName = theApp.soundRecordName = dlg.GetPathName();
580 theApp.aviRecording = true;
581
582 /// extern long linearFrameCount; linearFrameCount = 0;
583 /// extern long linearSoundByteCount; linearSoundByteCount = 0;
584
585 if (theApp.aviRecorder == NULL)
586 {
587 int width = 240;
588 int height = 160;
589 switch (systemCartridgeType)
590 {
591 case 0:
592 width = 240;
593 height = 160;
594 break;
595 case 1:
596 if (gbBorderOn)
597 {
598 width = 256;
599 height = 224;
600 }
601 else
602 {
603 width = 160;
604 height = 144;
605 }
606 break;
607 }
608
609 theApp.aviRecorder = new AVIWrite();
610
611 theApp.aviRecorder->SetFPS(60);
612
613 BITMAPINFOHEADER bi;
614 memset(&bi, 0, sizeof(bi));
615 bi.biSize = 0x28;
616 bi.biPlanes = 1;
617 bi.biBitCount = 24;
618 bi.biWidth = width;
619 bi.biHeight = height;
620 bi.biSizeImage = 3 * width * height;
621 theApp.aviRecorder->SetVideoFormat(&bi);
622 if (!theApp.aviRecorder->Open(theApp.aviRecordName))
623 {
624 delete theApp.aviRecorder;
625 theApp.aviRecorder = NULL;
626 theApp.aviRecording = false;
627 }
628
629 if (theApp.aviRecorder)
630 {
631 WAVEFORMATEX wfx;
632 memset(&wfx, 0, sizeof(wfx));
633 wfx.wFormatTag = WAVE_FORMAT_PCM;
634 wfx.nChannels = 2;
635 wfx.nSamplesPerSec = 44100 / soundQuality;
636 wfx.wBitsPerSample = 16;
637 wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels;
638 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
639 wfx.cbSize = 0;
640 theApp.aviRecorder->SetSoundFormat(&wfx);
641 }
642 }
643 }
644
645 void MainWnd::OnToolsPauseAVIRecording()
646 {
647 theApp.aviRecorder->Pause(!theApp.aviRecorder->IsPaused());
648 }
649
650 void MainWnd::OnToolsStopAVIRecording()
651 {
652 if (theApp.aviRecorder != NULL)
653 {
654 delete theApp.aviRecorder;
655 theApp.aviRecorder = NULL;
656 }
657 theApp.aviRecording = false;
658 }
659
660 void MainWnd::OnUpdateToolsAVIRecording(CCmdUI *pCmdUI)
661 {
662 if (pCmdUI->m_pMenu != NULL)
663 {
664 if (!theApp.aviRecording)
665 pCmdUI->SetText(winResLoadString(IDS_STARTAVIRECORDING));
666 else
667 pCmdUI->SetText(winResLoadString(IDS_STOPAVIRECORDING));
668
669 theApp.winAccelMgr.UpdateMenu(pCmdUI->m_pMenu->GetSafeHmenu());
670 }
671
672 pCmdUI->Enable(emulating);
673 }
674
675 void MainWnd::OnUpdateToolsPauseAVIRecording(CCmdUI *pCmdUI)
676 {
677 if (pCmdUI->m_pMenu != NULL)
678 {
679 if (!theApp.aviRecording)
680 {
681 pCmdUI->SetText(winResLoadString(IDS_PAUSEAVIRECORDING));
682 theApp.winAccelMgr.UpdateMenu(pCmdUI->m_pMenu->GetSafeHmenu());
683 pCmdUI->Enable(false);
684 }
685 else
686 {
687 if (!theApp.aviRecorder->IsPaused())
688 pCmdUI->SetText(winResLoadString(IDS_PAUSEAVIRECORDING));
689 else
690 pCmdUI->SetText(winResLoadString(IDS_RESUMEAVIRECORDING));
691
692 theApp.winAccelMgr.UpdateMenu(pCmdUI->m_pMenu->GetSafeHmenu());
693 pCmdUI->Enable(emulating);
694 }
695 }
696 }
697
698 void MainWnd::OnToolsRecordMovie()
699 {
700 MovieCreate dlg;
701 dlg.DoModal();
702 }
703
704 void MainWnd::OnUpdateToolsRecordMovie(CCmdUI *pCmdUI)
705 {
706 pCmdUI->Enable(emulating);
707 }
708
709 void MainWnd::OnToolsStopMovie()
710 {
711 VBAMovieStop(false);
712 }
713
714 void MainWnd::OnUpdateToolsStopMovie(CCmdUI *pCmdUI)
715 {
716 pCmdUI->Enable(emulating && VBAMovieActive());
717 }
718
719 void MainWnd::OnToolsPlayMovie()
720 {
721 MovieOpen dlg;
722 dlg.DoModal();
723 }
724
725 void MainWnd::OnUpdateToolsPlayMovie(CCmdUI *pCmdUI)
726 {
727 pCmdUI->Enable(emulating);
728 }
729
730 void MainWnd::OnToolsPlayReadOnly()
731 {
732 if (!VBAMovieActive())
733 {
734 theApp.movieReadOnly = !theApp.movieReadOnly;
735 systemScreenMessage(theApp.movieReadOnly ? "Movie now read-only" : "Movie now editable");
736 }
737 else
738 VBAMovieToggleReadOnly();
739 }
740
741 void MainWnd::OnUpdateToolsPlayReadOnly(CCmdUI *pCmdUI)
742 {
743 /// pCmdUI->Enable(VBAMovieActive()); // FIXME: this is right, but disabling menu items screws up accelerators until you view
744 // the menu!
745 /// pCmdUI->SetCheck(VBAMovieReadOnly());
746 pCmdUI->Enable(TRUE); // TEMP
747 pCmdUI->SetCheck(VBAMovieActive() ? VBAMovieReadOnly() : theApp.movieReadOnly);
748 }
749
750 void MainWnd::OnAsscWithSaveState()
751 {
752 theApp.AsscWithSaveState = !theApp.AsscWithSaveState;
753 }
754
755 void MainWnd::OnUpdateAsscWithSaveState(CCmdUI *pCmdUI)
756 {
757 pCmdUI->Enable(TRUE); // TEMP
758 pCmdUI->SetCheck(theApp.AsscWithSaveState);
759 }
760
761 void MainWnd::OnToolsResumeRecord()
762 {
763 // toggle playing/recording
764 if (VBAMovieRecording())
765 {
766 if (!VBAMovieSwitchToPlaying())
767 systemScreenMessage("Cannot continue playing");
768 }
769 else
770 {
771 if (!VBAMovieSwitchToRecording())
772 systemScreenMessage("Cannot resume recording now");
773 }
774 }
775
776 void MainWnd::OnUpdateToolsResumeRecord(CCmdUI *pCmdUI)
777 {
778 pCmdUI->Enable(VBAMovieActive());
779 }
780
781 void MainWnd::OnToolsPlayRestart()
782 {
783 VBAMovieRestart();
784 }
785
786 void MainWnd::OnUpdateToolsPlayRestart(CCmdUI *pCmdUI)
787 {
788 pCmdUI->Enable(VBAMovieActive());
789 }
790
791 void MainWnd::OnToolsOnMovieEndPause()
792 {
793 theApp.movieOnEndPause = !theApp.movieOnEndPause;
794 }
795
796 void MainWnd::OnUpdateToolsOnMovieEndPause(CCmdUI *pCmdUI)
797 {
798 pCmdUI->SetCheck(theApp.movieOnEndPause);
799 }
800
801 void MainWnd::OnToolsOnMovieEndStop()
802 {
803 theApp.movieOnEndBehavior = 0;
804 }
805
806 void MainWnd::OnUpdateToolsOnMovieEndStop(CCmdUI *pCmdUI)
807 {
808 pCmdUI->SetRadio(theApp.movieOnEndBehavior == 0);
809 }
810
811 void MainWnd::OnToolsOnMovieEndRestart()
812 {
813 theApp.movieOnEndBehavior = 1;
814 }
815
816 void MainWnd::OnUpdateToolsOnMovieEndRestart(CCmdUI *pCmdUI)
817 {
818 pCmdUI->SetRadio(theApp.movieOnEndBehavior == 1);
819 }
820
821 void MainWnd::OnToolsOnMovieEndAppend()
822 {
823 theApp.movieOnEndBehavior = 2;
824 }
825
826 void MainWnd::OnUpdateToolsOnMovieEndAppend(CCmdUI *pCmdUI)
827 {
828 pCmdUI->SetRadio(theApp.movieOnEndBehavior == 2);
829 }
830
831 void MainWnd::OnToolsOnMovieEndKeep()
832 {
833 theApp.movieOnEndBehavior = 3;
834 }
835
836 void MainWnd::OnUpdateToolsOnMovieEndKeep(CCmdUI *pCmdUI)
837 {
838 pCmdUI->SetRadio(theApp.movieOnEndBehavior == 3);
839 }
840
841 /////////////////////////////////
842
843 void MainWnd::OnToolsMovieSetPauseAt()
844 {
845 // TODO
846 VBAMovieSetPauseAt(-1);
847 }
848
849 void MainWnd::OnUpdateToolsSetMoviePauseAt(CCmdUI *pCmdUI)
850 {
851 // TODO
852 pCmdUI->SetCheck(VBAMovieGetPauseAt() >= 0);
853 pCmdUI->Enable(FALSE && VBAMovieActive());
854 }
855
856 void MainWnd::OnToolsMovieConvertCurrent()
857 {
858 // temporary
859 int result = VBAMovieConvertCurrent();
860 switch (result)
861 {
862 case MOVIE_SUCCESS:
863 systemScreenMessage("Movie converted");
864 break;
865 case MOVIE_WRONG_VERSION:
866 systemMessage(0, "Cannot convert from VBM revision %u", VBAMovieGetMinorVersion());
867 break;
868 default:
869 systemScreenMessage("Nothing to convert");
870 break;
871 }
872 }
873
874 void MainWnd::OnUpdateToolsMovieConvertCurrent(CCmdUI *pCmdUI)
875 {
876 pCmdUI->Enable(VBAMovieActive());
877 }
878
879 void MainWnd::OnToolsMovieAutoConvert()
880 {
881 extern bool autoConvertMovieWhenPlaying; // from movie.cpp
882 autoConvertMovieWhenPlaying = !autoConvertMovieWhenPlaying;
883 if (autoConvertMovieWhenPlaying)
884 {
885 int result = VBAMovieConvertCurrent();
886 switch (result)
887 {
888 case MOVIE_SUCCESS:
889 systemScreenMessage("Movie converted");
890 break;
891 case MOVIE_WRONG_VERSION:
892 systemMessage(0, "Cannot convert from VBM revision %u", VBAMovieGetMinorVersion());
893 break;
894 default:
895 systemScreenMessage("Auto movie conversion enabled");
896 break;
897 }
898 }
899 }
900
901 void MainWnd::OnUpdateToolsMovieAutoConvert(CCmdUI *pCmdUI)
902 {
903 extern bool autoConvertMovieWhenPlaying; // from movie.cpp
904 pCmdUI->SetCheck(autoConvertMovieWhenPlaying);
905 }
906
907 void MainWnd::OnToolsMovieTruncateAtCurrent()
908 {
909 if (VBAMovieReadOnly())
910 systemScreenMessage("Cannot truncate movie in this mode");
911 else
912 VBAMovieTuncateAtCurrentFrame();
913 }
914
915 void MainWnd::OnUpdateToolsMovieTruncateAtCurrent(CCmdUI *pCmdUI)
916 {
917 pCmdUI->Enable(VBAMovieActive());
918 }
919
920 void MainWnd::OnToolsMovieFixHeader()
921 {
922 VBAMovieFixHeader();
923 }
924
925 void MainWnd::OnUpdateToolsMovieFixHeader(CCmdUI *pCmdUI)
926 {
927 pCmdUI->Enable(VBAMovieActive());
928 }
929
930 // TODO
931 void MainWnd::OnToolsMovieExtractFromSavegame()
932 {
933 // Currently, snapshots taken from a movie don't contain the initial SRAM or savestate of the movie,
934 // even if the movie was recorded from either of them. If a snapshot was taken at the first frame
935 // i.e. Frame 0, it can be safely assumed that the snapshot reflects the initial state of such a movie.
936 // However, if it was taken after the first frame, the SRAM contained might either be still the same
937 // as the original (usually true if no write operations on the SRAM occured) or have been modified,
938 // while the exact original state could hardly, if not impossibly, be safely worked out.
939
940 // TODO
941 }
942
943 void MainWnd::OnUpdateToolsMovieExtractFromSavegame(CCmdUI *pCmdUI)
944 {
945 pCmdUI->Enable(FALSE);
946 }
947
948 ///////////////////////////////////////////////////////////
949
950 void MainWnd::OnToolsRewind()
951 {
952 assert(theApp.rewindTimer > 0 && theApp.rewindSlots > 0);
953 if (emulating && theApp.emulator.emuReadMemState && theApp.rewindMemory && theApp.rewindCount)
954 {
955 assert(theApp.rewindPos >= 0 && theApp.rewindPos < theApp.rewindSlots);
956 theApp.rewindPos = (--theApp.rewindPos + theApp.rewindSlots) % theApp.rewindSlots;
957 assert(theApp.rewindPos >= 0 && theApp.rewindPos < theApp.rewindSlots);
958 theApp.emulator.emuReadMemState(&theApp.rewindMemory[REWIND_SIZE * theApp.rewindPos], REWIND_SIZE);
959 theApp.rewindCount--;
960 if (theApp.rewindCount > 0)
961 theApp.rewindCounter = 0;
962 else
963 {
964 theApp.rewindCounter = theApp.rewindTimer;
965 theApp.rewindSaveNeeded = true;
966
967 // immediately save state to avoid eroding away the earliest you can rewind to
968 theApp.saveRewindStateIfNecessary();
969
970 theApp.rewindSaveNeeded = false;
971 }
972 }
973 }
974
975 void MainWnd::OnUpdateToolsRewind(CCmdUI *pCmdUI)
976 {
977 pCmdUI->Enable(theApp.rewindMemory != NULL && emulating && theApp.rewindCount);
978 }
979
980 void MainWnd::OnToolsCustomize()
981 {
982 theApp.recreateMenuBar();
983
984 AccelEditor dlg(this, &theApp.m_menu, &theApp.winAccelMgr);
985 dlg.DoModal();
986 if (dlg.IsModified())
987 {
988 theApp.winAccelMgr = dlg.GetResultMangager();
989 theApp.winAccelMgr.UpdateWndTable();
990 theApp.winAccelMgr.Write();
991 }
992
993 theApp.winAccelMgr.UpdateMenu(theApp.menu); // we should always do this since the menu has been reloaded
994 }
995
996 void MainWnd::OnUpdateToolsCustomize(CCmdUI *pCmdUI)
997 {
998 pCmdUI->Enable(theApp.videoOption != VIDEO_320x240);
999 }
1000