1 /* menu.c: general menu callbacks
2 Copyright (c) 2004-2018 Philip Kendall and others
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 Author contact information:
19
20 Philip Kendall <philip-fuse@shadowmagic.org.uk>
21
22 */
23
24 #include <config.h>
25
26 #include <libspectrum.h>
27
28 #include "event.h"
29 #include "fuse.h"
30 #include "menu.h"
31 #include "movie.h"
32 #include "machines/specplus3.h"
33 #include "peripherals/dck.h"
34 #include "peripherals/disk/beta.h"
35 #include "peripherals/disk/didaktik.h"
36 #include "peripherals/disk/disciple.h"
37 #include "peripherals/disk/opus.h"
38 #include "peripherals/disk/plusd.h"
39 #include "peripherals/ide/divide.h"
40 #include "peripherals/ide/divmmc.h"
41 #include "peripherals/ide/simpleide.h"
42 #include "peripherals/ide/zxatasp.h"
43 #include "peripherals/ide/zxcf.h"
44 #include "peripherals/ide/zxmmc.h"
45 #include "peripherals/if1.h"
46 #include "peripherals/if2.h"
47 #include "peripherals/joystick.h"
48 #include "peripherals/multiface.h"
49 #include "peripherals/scld.h"
50 #include "profile.h"
51 #include "psg.h"
52 #include "rzx.h"
53 #include "screenshot.h"
54 #include "settings.h"
55 #include "snapshot.h"
56 #include "svg.h"
57 #include "tape.h"
58 #include "ui/scaler/scaler.h"
59 #include "ui/ui.h"
60 #include "ui/uimedia.h"
61 #include "utils.h"
62 #include "z80/z80.h"
63
64 static int menu_select_machine_roms( libspectrum_machine machine, size_t start,
65 size_t n );
66
67 static int menu_select_peripheral_roms( const char *peripheral_name,
68 size_t start, size_t n );
69
MENU_CALLBACK(menu_file_open)70 MENU_CALLBACK( menu_file_open )
71 {
72 char *filename;
73
74 fuse_emulation_pause();
75
76 filename = ui_get_open_filename( "Fuse - Open Spectrum File" );
77 if( !filename ) { fuse_emulation_unpause(); return; }
78
79 utils_open_file( filename, tape_can_autoload(), NULL );
80
81 libspectrum_free( filename );
82
83 display_refresh_all();
84
85 fuse_emulation_unpause();
86 }
87
MENU_CALLBACK(menu_file_recording_insertsnapshot)88 MENU_CALLBACK( menu_file_recording_insertsnapshot )
89 {
90 libspectrum_snap *snap;
91 libspectrum_error error;
92
93 if( !rzx_recording ) return;
94
95 ui_widget_finish();
96
97 libspectrum_rzx_stop_input( rzx );
98
99 snap = libspectrum_snap_alloc();
100
101 error = snapshot_copy_to( snap );
102 if( error ) { libspectrum_snap_free( snap ); return; }
103
104 libspectrum_rzx_add_snap( rzx, snap, 0 );
105
106 libspectrum_rzx_start_input( rzx, tstates );
107 }
108
MENU_CALLBACK(menu_file_recording_rollback)109 MENU_CALLBACK( menu_file_recording_rollback )
110 {
111 libspectrum_error error;
112
113 if( !rzx_recording ) return;
114
115 ui_widget_finish();
116
117 fuse_emulation_pause();
118
119 error = rzx_rollback();
120 if( error ) { fuse_emulation_unpause(); return; }
121
122 fuse_emulation_unpause();
123 }
124
MENU_CALLBACK(menu_file_recording_rollbackto)125 MENU_CALLBACK( menu_file_recording_rollbackto )
126 {
127 libspectrum_error error;
128
129 if( !rzx_recording ) return;
130
131 ui_widget_finish();
132
133 fuse_emulation_pause();
134
135 error = rzx_rollback_to();
136 if( error ) { fuse_emulation_unpause(); return; }
137
138 fuse_emulation_unpause();
139 }
140
MENU_CALLBACK(menu_file_recording_play)141 MENU_CALLBACK( menu_file_recording_play )
142 {
143 char *recording;
144
145 if( rzx_playback || rzx_recording ) return;
146
147 fuse_emulation_pause();
148
149 recording = ui_get_open_filename( "Fuse - Start Replay" );
150 if( !recording ) { fuse_emulation_unpause(); return; }
151
152 rzx_start_playback( recording, 1 );
153
154 libspectrum_free( recording );
155
156 display_refresh_all();
157
158 if( rzx_playback ) ui_menu_activate( UI_MENU_ITEM_RECORDING, 1 );
159
160 fuse_emulation_unpause();
161 }
162
MENU_CALLBACK(menu_file_recording_stop)163 MENU_CALLBACK( menu_file_recording_stop )
164 {
165 if( !( rzx_recording || rzx_playback ) ) return;
166
167 ui_widget_finish();
168
169 if( rzx_recording ) rzx_stop_recording();
170 if( rzx_playback ) rzx_stop_playback( 1 );
171 }
172
MENU_CALLBACK(menu_file_recording_finalise)173 MENU_CALLBACK( menu_file_recording_finalise )
174 {
175 char *rzx_filename;
176 int error;
177
178 if( rzx_playback || rzx_recording ) return;
179
180 fuse_emulation_pause();
181
182 rzx_filename = ui_get_open_filename( "Fuse - Finalise Recording" );
183 if( !rzx_filename ) { fuse_emulation_unpause(); return; }
184
185 error = rzx_finalise_recording( rzx_filename );
186
187 if( error == LIBSPECTRUM_ERROR_NONE ) {
188 ui_error( UI_ERROR_INFO, "RZX file finalised" );
189 } else {
190 ui_error( UI_ERROR_WARNING, "RZX file cannot be finalised" );
191 }
192
193 libspectrum_free( rzx_filename );
194
195 fuse_emulation_unpause();
196 }
197
MENU_CALLBACK(menu_file_aylogging_stop)198 MENU_CALLBACK( menu_file_aylogging_stop )
199 {
200 if ( !psg_recording ) return;
201
202 ui_widget_finish();
203
204 psg_stop_recording();
205 ui_menu_activate( UI_MENU_ITEM_AY_LOGGING, 0 );
206 }
207
MENU_CALLBACK(menu_file_screenshot_openscrscreenshot)208 MENU_CALLBACK( menu_file_screenshot_openscrscreenshot )
209 {
210 char *filename;
211
212 fuse_emulation_pause();
213
214 filename = ui_get_open_filename( "Fuse - Open SCR Screenshot" );
215 if( !filename ) { fuse_emulation_unpause(); return; }
216
217 screenshot_scr_read( filename );
218
219 libspectrum_free( filename );
220
221 fuse_emulation_unpause();
222 }
223
MENU_CALLBACK(menu_file_screenshot_openmltscreenshot)224 MENU_CALLBACK( menu_file_screenshot_openmltscreenshot )
225 {
226 char *filename;
227
228 fuse_emulation_pause();
229
230 filename = ui_get_open_filename( "Fuse - Open MLT Screenshot" );
231 if( !filename ) { fuse_emulation_unpause(); return; }
232
233 screenshot_mlt_read( filename );
234
235 libspectrum_free( filename );
236
237 fuse_emulation_unpause();
238 }
239
MENU_CALLBACK(menu_file_movie_stop)240 MENU_CALLBACK( menu_file_movie_stop )
241 {
242 ui_widget_finish();
243
244 movie_stop();
245 }
246
MENU_CALLBACK(menu_file_movie_pause)247 MENU_CALLBACK( menu_file_movie_pause )
248 {
249 ui_widget_finish();
250
251 movie_pause();
252 }
253
MENU_CALLBACK_WITH_ACTION(menu_options_selectroms_machine_select)254 MENU_CALLBACK_WITH_ACTION( menu_options_selectroms_machine_select )
255 {
256 switch( action ) {
257
258 case 1: menu_select_machine_roms( LIBSPECTRUM_MACHINE_16, 0, 1 ); return;
259 case 2: menu_select_machine_roms( LIBSPECTRUM_MACHINE_48, 1, 1 ); return;
260 case 3: menu_select_machine_roms( LIBSPECTRUM_MACHINE_128, 2, 2 ); return;
261 case 4: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PLUS2, 4, 2 ); return;
262 case 5: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PLUS2A, 6, 4 ); return;
263 case 6: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PLUS3, 10, 4 ); return;
264 case 7: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PLUS3E, 14, 4 ); return;
265 case 8: menu_select_machine_roms( LIBSPECTRUM_MACHINE_TC2048, 18, 1 ); return;
266 case 9: menu_select_machine_roms( LIBSPECTRUM_MACHINE_TC2068, 19, 2 ); return;
267 case 10: menu_select_machine_roms( LIBSPECTRUM_MACHINE_TS2068, 21, 2 ); return;
268 case 11: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PENT, 23, 3 ); return;
269 case 12: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PENT512, 26, 4 ); return;
270 case 13: menu_select_machine_roms( LIBSPECTRUM_MACHINE_PENT1024, 30, 4 ); return;
271 case 14: menu_select_machine_roms( LIBSPECTRUM_MACHINE_SCORP, 34, 4 ); return;
272 case 15: menu_select_machine_roms( LIBSPECTRUM_MACHINE_SE, 38, 2 ); return;
273
274 }
275
276 ui_error( UI_ERROR_ERROR,
277 "menu_options_selectroms_machine_select: unknown action %d", action );
278 fuse_abort();
279 }
280
MENU_CALLBACK_WITH_ACTION(menu_options_selectroms_peripheral_select)281 MENU_CALLBACK_WITH_ACTION( menu_options_selectroms_peripheral_select )
282 {
283 switch( action ) {
284
285 case 1: menu_select_peripheral_roms( "Interface 1", 0, 1 ); return;
286 case 2: menu_select_peripheral_roms( "Beta 128", 1, 1 ); return;
287 case 3: menu_select_peripheral_roms( "+D", 2, 1 ); return;
288 case 4: menu_select_peripheral_roms( "Didaktik 80", 3, 1 ); return;
289 case 5: menu_select_peripheral_roms( "DISCiPLE", 4, 1 ); return;
290 case 6: menu_select_peripheral_roms( "Multiface One", 5, 1 ); return;
291 case 7: menu_select_peripheral_roms( "Multiface 128", 6, 1 ); return;
292 case 8: menu_select_peripheral_roms( "Multiface 3", 7, 1 ); return;
293 case 9: menu_select_peripheral_roms( "Opus Discovery", 8, 1 ); return;
294 case 10: menu_select_peripheral_roms( "SpeccyBoot", 9, 1 ); return;
295 case 11: menu_select_peripheral_roms( "TTX2000S", 10, 1 ); return;
296 case 12: menu_select_peripheral_roms( "uSource", 11, 1 ); return;
297
298 }
299
300 ui_error( UI_ERROR_ERROR,
301 "menu_options_selectroms_peripheral_select: unknown action %d", action );
302 fuse_abort();
303 }
304
MENU_CALLBACK(menu_options_filter)305 MENU_CALLBACK( menu_options_filter )
306 {
307 scaler_type scaler;
308
309 /* Stop emulation */
310 fuse_emulation_pause();
311
312 scaler = menu_get_scaler( scaler_is_supported );
313 if( scaler != SCALER_NUM && scaler != current_scaler )
314 scaler_select_scaler( scaler );
315
316 /* Carry on with emulation again */
317 fuse_emulation_unpause();
318 }
319
MENU_CALLBACK(menu_options_fullscreen)320 MENU_CALLBACK( menu_options_fullscreen )
321 {
322 ui_widget_finish();
323 settings_current.full_screen = !settings_current.full_screen;
324 }
325
MENU_CALLBACK(menu_options_save)326 MENU_CALLBACK( menu_options_save )
327 {
328 ui_widget_finish();
329 settings_write_config( &settings_current );
330 }
331
MENU_CALLBACK(menu_machine_profiler_start)332 MENU_CALLBACK( menu_machine_profiler_start )
333 {
334 ui_widget_finish();
335 profile_start();
336 }
337
MENU_CALLBACK(menu_machine_profiler_stop)338 MENU_CALLBACK( menu_machine_profiler_stop )
339 {
340 char *filename;
341
342 fuse_emulation_pause();
343
344 filename = ui_get_save_filename( "Fuse - Save Profile Data" );
345 if( !filename ) { fuse_emulation_unpause(); return; }
346
347 profile_finish( filename );
348
349 libspectrum_free( filename );
350
351 fuse_emulation_unpause();
352 }
353
MENU_CALLBACK(menu_machine_nmi)354 MENU_CALLBACK( menu_machine_nmi )
355 {
356 ui_widget_finish();
357 event_add( 0, z80_nmi_event );
358 }
359
MENU_CALLBACK(menu_machine_multifaceredbutton)360 MENU_CALLBACK( menu_machine_multifaceredbutton )
361 {
362 ui_widget_finish();
363 multiface_red_button();
364 }
365
MENU_CALLBACK(menu_media_tape_open)366 MENU_CALLBACK( menu_media_tape_open )
367 {
368 char *filename;
369
370 fuse_emulation_pause();
371
372 filename = ui_get_open_filename( "Fuse - Open Tape" );
373 if( !filename ) { fuse_emulation_unpause(); return; }
374
375 tape_open( filename, 0 );
376
377 libspectrum_free( filename );
378
379 fuse_emulation_unpause();
380 }
381
MENU_CALLBACK(menu_media_tape_play)382 MENU_CALLBACK( menu_media_tape_play )
383 {
384 ui_widget_finish();
385 tape_toggle_play( 0 );
386 }
387
MENU_CALLBACK(menu_media_tape_rewind)388 MENU_CALLBACK( menu_media_tape_rewind )
389 {
390 ui_widget_finish();
391 tape_rewind();
392 }
393
MENU_CALLBACK(menu_media_tape_clear)394 MENU_CALLBACK( menu_media_tape_clear )
395 {
396 ui_widget_finish();
397 tape_close();
398 }
399
MENU_CALLBACK(menu_media_tape_write)400 MENU_CALLBACK( menu_media_tape_write )
401 {
402 ui_tape_write();
403 }
404
MENU_CALLBACK(menu_media_tape_recordstart)405 MENU_CALLBACK( menu_media_tape_recordstart )
406 {
407 ui_widget_finish();
408 tape_record_start();
409 }
410
MENU_CALLBACK(menu_media_tape_recordstop)411 MENU_CALLBACK( menu_media_tape_recordstop )
412 {
413 ui_widget_finish();
414 tape_record_stop();
415 }
416
MENU_CALLBACK_WITH_ACTION(menu_media_if1_rs232)417 MENU_CALLBACK_WITH_ACTION( menu_media_if1_rs232 )
418 {
419 char *filename;
420
421 fuse_emulation_pause();
422
423 if( action & 0xf0 ) {
424 ui_widget_finish();
425 if1_unplug( action & 0x0f );
426 } else {
427 filename = ui_get_open_filename( "Fuse - Select File for Communication" );
428 if( !filename ) { fuse_emulation_unpause(); return; }
429
430 if1_plug( filename, action );
431
432 libspectrum_free( filename );
433 }
434 fuse_emulation_unpause();
435
436 }
437
MENU_CALLBACK_WITH_ACTION(menu_media_insert_new)438 MENU_CALLBACK_WITH_ACTION( menu_media_insert_new )
439 {
440 int which, type;
441 ui_media_drive_info_t *drive;
442
443 ui_widget_finish();
444
445 action--;
446 which = action & 0x0f;
447 type = ( action & 0xf0 ) >> 4;
448
449 switch( type ) {
450 case 3:
451 if1_mdr_insert( which, NULL );
452 break;
453 default:
454 drive = ui_media_drive_find( type, which );
455 if( !drive )
456 return;
457 ui_media_drive_insert( drive, NULL, 0 );
458 break;
459 }
460 }
461
MENU_CALLBACK_WITH_ACTION(menu_media_insert)462 MENU_CALLBACK_WITH_ACTION( menu_media_insert )
463 {
464 char *filename;
465 char title[80];
466 int which, type;
467 ui_media_drive_info_t *drive = NULL;
468
469 action--;
470 which = action & 0x0f;
471 type = ( action & 0xf0 ) >> 4;
472
473 fuse_emulation_pause();
474
475 switch( type ) {
476 case 3:
477 snprintf( title, 80, "Fuse - Insert Microdrive Cartridge %i", which + 1 );
478 break;
479 default:
480 drive = ui_media_drive_find( type, which );
481 if( !drive )
482 return;
483 snprintf( title, sizeof(title), "Fuse - Insert %s", drive->name );
484 break;
485 }
486 filename = ui_get_open_filename( title );
487 if( !filename ) { fuse_emulation_unpause(); return; }
488
489 switch( type ) {
490 case 3:
491 if1_mdr_insert( which, filename );
492 break;
493 default:
494 ui_media_drive_insert( drive, filename, 0 );
495 break;
496 }
497
498 libspectrum_free( filename );
499
500 fuse_emulation_unpause();
501 }
502
MENU_CALLBACK_WITH_ACTION(menu_media_eject)503 MENU_CALLBACK_WITH_ACTION( menu_media_eject )
504 {
505 int which, type;
506
507 ui_widget_finish();
508
509 action--;
510 which = action & 0x00f;
511 type = ( action & 0x0f0 ) >> 4;
512
513 switch( type ) {
514 case 3:
515 if1_mdr_eject( which );
516 break;
517 default:
518 ui_media_drive_eject( type, which );
519 break;
520 }
521 }
522
MENU_CALLBACK_WITH_ACTION(menu_media_save)523 MENU_CALLBACK_WITH_ACTION( menu_media_save )
524 {
525 int which, saveas, type;
526
527 ui_widget_finish();
528
529 action--;
530 which = action & 0x00f;
531 type = ( action & 0x0f0 ) >> 4;
532 saveas = ( action & 0xf00 ) >> 8;
533
534 switch( type ) {
535 case 3:
536 if1_mdr_save( which, saveas );
537 break;
538 default:
539 ui_media_drive_save( type, which, saveas );
540 break;
541 }
542 }
543
MENU_CALLBACK_WITH_ACTION(menu_media_flip)544 MENU_CALLBACK_WITH_ACTION( menu_media_flip )
545 {
546 int which, type, flip;
547
548 ui_widget_finish();
549
550 action--;
551 which = action & 0x0f;
552 type = ( action & 0xf0 ) >> 4;
553 flip = !!( action & 0x100 );
554
555 switch( type ) {
556 /* No flip option for IF1 */
557 default:
558 ui_media_drive_flip( type, which, flip );
559 break;
560 }
561 }
562
MENU_CALLBACK_WITH_ACTION(menu_media_writeprotect)563 MENU_CALLBACK_WITH_ACTION( menu_media_writeprotect )
564 {
565 int which, wrprot, type;
566
567 ui_widget_finish();
568
569 action--;
570 which = action & 0x00f;
571 type = ( action & 0x0f0 ) >> 4;
572 wrprot = !!( action & 0x100 );
573
574 switch( type ) {
575 case 3:
576 if1_mdr_writeprotect( which, wrprot );
577 break;
578 default:
579 ui_media_drive_writeprotect( type, which, wrprot );
580 break;
581 }
582
583 }
584
MENU_CALLBACK(menu_media_cartridge_timexdock_insert)585 MENU_CALLBACK( menu_media_cartridge_timexdock_insert )
586 {
587 char *filename;
588
589 fuse_emulation_pause();
590
591 filename = ui_get_open_filename( "Fuse - Insert Timex Dock Cartridge" );
592 if( !filename ) { fuse_emulation_unpause(); return; }
593
594 dck_insert( filename );
595
596 libspectrum_free( filename );
597
598 fuse_emulation_unpause();
599 }
600
MENU_CALLBACK(menu_media_cartridge_timexdock_eject)601 MENU_CALLBACK( menu_media_cartridge_timexdock_eject )
602 {
603 ui_widget_finish();
604 dck_eject();
605 }
606
MENU_CALLBACK(menu_media_cartridge_interface2_insert)607 MENU_CALLBACK( menu_media_cartridge_interface2_insert )
608 {
609 char *filename;
610
611 fuse_emulation_pause();
612
613 filename = ui_get_open_filename( "Fuse - Insert Interface 2 Cartridge" );
614 if( !filename ) { fuse_emulation_unpause(); return; }
615
616 if2_insert( filename );
617
618 libspectrum_free( filename );
619
620 fuse_emulation_unpause();
621 }
622
MENU_CALLBACK(menu_media_cartridge_interface2_eject)623 MENU_CALLBACK( menu_media_cartridge_interface2_eject )
624 {
625 ui_widget_finish();
626 if2_eject();
627 }
628
MENU_CALLBACK_WITH_ACTION(menu_media_ide_insert)629 MENU_CALLBACK_WITH_ACTION( menu_media_ide_insert )
630 {
631 char *filename;
632
633 fuse_emulation_pause();
634
635 filename = ui_get_open_filename( "Fuse - Insert Hard Disk File" );
636 if( !filename ) { fuse_emulation_unpause(); return; }
637
638 switch( action ) {
639 case 1: simpleide_insert( filename, LIBSPECTRUM_IDE_MASTER ); break;
640 case 2: simpleide_insert( filename, LIBSPECTRUM_IDE_SLAVE ); break;
641 case 3: zxatasp_insert( filename, LIBSPECTRUM_IDE_MASTER ); break;
642 case 4: zxatasp_insert( filename, LIBSPECTRUM_IDE_SLAVE ); break;
643 case 5: zxcf_insert( filename ); break;
644 case 6: divide_insert( filename, LIBSPECTRUM_IDE_MASTER ); break;
645 case 7: divide_insert( filename, LIBSPECTRUM_IDE_SLAVE ); break;
646 case 8: divmmc_insert( filename ); break;
647 case 9: zxmmc_insert( filename ); break;
648 }
649
650 libspectrum_free( filename );
651
652 fuse_emulation_unpause();
653 }
654
MENU_CALLBACK_WITH_ACTION(menu_media_ide_commit)655 MENU_CALLBACK_WITH_ACTION( menu_media_ide_commit )
656 {
657 fuse_emulation_pause();
658
659 switch( action ) {
660 case 1: simpleide_commit( LIBSPECTRUM_IDE_MASTER ); break;
661 case 2: simpleide_commit( LIBSPECTRUM_IDE_SLAVE ); break;
662 case 3: zxatasp_commit( LIBSPECTRUM_IDE_MASTER ); break;
663 case 4: zxatasp_commit( LIBSPECTRUM_IDE_SLAVE ); break;
664 case 5: zxcf_commit(); break;
665 case 6: divide_commit( LIBSPECTRUM_IDE_MASTER ); break;
666 case 7: divide_commit( LIBSPECTRUM_IDE_SLAVE ); break;
667 case 8: divmmc_commit(); break;
668 case 9: zxmmc_commit(); break;
669 }
670
671 fuse_emulation_unpause();
672
673 ui_widget_finish();
674 }
675
MENU_CALLBACK_WITH_ACTION(menu_media_ide_eject)676 MENU_CALLBACK_WITH_ACTION( menu_media_ide_eject )
677 {
678 fuse_emulation_pause();
679
680 switch( action ) {
681 case 1: simpleide_eject( LIBSPECTRUM_IDE_MASTER ); break;
682 case 2: simpleide_eject( LIBSPECTRUM_IDE_SLAVE ); break;
683 case 3: zxatasp_eject( LIBSPECTRUM_IDE_MASTER ); break;
684 case 4: zxatasp_eject( LIBSPECTRUM_IDE_SLAVE ); break;
685 case 5: zxcf_eject(); break;
686 case 6: divide_eject( LIBSPECTRUM_IDE_MASTER ); break;
687 case 7: divide_eject( LIBSPECTRUM_IDE_SLAVE ); break;
688 case 8: divmmc_eject(); break;
689 }
690
691 fuse_emulation_unpause();
692
693 ui_widget_finish();
694 }
695
MENU_CALLBACK(menu_file_savesnapshot)696 MENU_CALLBACK( menu_file_savesnapshot )
697 {
698 char *filename;
699
700 ui_widget_finish();
701
702 fuse_emulation_pause();
703
704 filename = ui_get_save_filename( "Fuse - Save Snapshot" );
705 if( !filename ) { fuse_emulation_unpause(); return; }
706
707 snapshot_write( filename );
708
709 libspectrum_free( filename );
710
711 fuse_emulation_unpause();
712 }
713
MENU_CALLBACK(menu_file_screenshot_savescreenasscr)714 MENU_CALLBACK( menu_file_screenshot_savescreenasscr )
715 {
716 char *filename;
717
718 ui_widget_finish();
719
720 fuse_emulation_pause();
721
722 filename = ui_get_save_filename( "Fuse - Save Screenshot as SCR" );
723 if( !filename ) { fuse_emulation_unpause(); return; }
724
725 screenshot_scr_write( filename );
726
727 libspectrum_free( filename );
728
729 fuse_emulation_unpause();
730 }
731
MENU_CALLBACK(menu_file_screenshot_savescreenasmlt)732 MENU_CALLBACK( menu_file_screenshot_savescreenasmlt )
733 {
734 char *filename;
735
736 ui_widget_finish();
737
738 fuse_emulation_pause();
739
740 if( machine_current->timex && scld_last_dec.name.hires ) {
741 ui_error( UI_ERROR_ERROR,
742 "MLT format not supported for Timex hi-res screen mode" );
743 fuse_emulation_unpause();
744 return;
745 }
746
747 filename = ui_get_save_filename( "Fuse - Save Screenshot as MLT" );
748 if( !filename ) { fuse_emulation_unpause(); return; }
749
750 screenshot_mlt_write( filename );
751
752 libspectrum_free( filename );
753
754 fuse_emulation_unpause();
755 }
756
757 #ifdef USE_LIBPNG
758
MENU_CALLBACK(menu_file_screenshot_savescreenaspng)759 MENU_CALLBACK( menu_file_screenshot_savescreenaspng )
760 {
761 scaler_type scaler;
762 char *filename;
763
764 ui_widget_finish();
765
766 fuse_emulation_pause();
767
768 scaler = menu_get_scaler( screenshot_available_scalers );
769 if( scaler == SCALER_NUM ) {
770 fuse_emulation_unpause();
771 return;
772 }
773
774 filename =
775 ui_get_save_filename( "Fuse - Save Screenshot as PNG" );
776 if( !filename ) { fuse_emulation_unpause(); return; }
777
778 screenshot_write( filename, scaler );
779
780 libspectrum_free( filename );
781
782 fuse_emulation_unpause();
783 }
784
785 #endif
786
787 #ifdef HAVE_LIB_XML2
788
MENU_CALLBACK(menu_file_scalablevectorgraphics_startcaptureinlinemode)789 MENU_CALLBACK( menu_file_scalablevectorgraphics_startcaptureinlinemode )
790 {
791 char *filename;
792
793 ui_widget_finish();
794 if( !svg_capture_active ) {
795
796 fuse_emulation_pause();
797
798 filename = ui_get_save_filename( "Fuse - Capture to SVG File" );
799 if( !filename ) { fuse_emulation_unpause(); return; }
800
801 ui_menu_activate( UI_MENU_ITEM_FILE_SVG_CAPTURE, 1 );
802 svg_startcapture( filename, SVG_CAPTURE_LINES );
803
804 fuse_emulation_unpause();
805 }
806 }
807
MENU_CALLBACK(menu_file_scalablevectorgraphics_startcaptureindotmode)808 MENU_CALLBACK( menu_file_scalablevectorgraphics_startcaptureindotmode )
809 {
810 char *filename;
811
812 ui_widget_finish();
813 if( !svg_capture_active ) {
814
815 fuse_emulation_pause();
816
817 filename = ui_get_save_filename( "Fuse - Capture to SVG File" );
818 if( !filename ) { fuse_emulation_unpause(); return; }
819 ui_menu_activate( UI_MENU_ITEM_FILE_SVG_CAPTURE, 1 );
820
821 svg_startcapture( filename, SVG_CAPTURE_DOTS );
822
823 fuse_emulation_unpause();
824 }
825 }
826
MENU_CALLBACK(menu_file_scalablevectorgraphics_stopcapture)827 MENU_CALLBACK( menu_file_scalablevectorgraphics_stopcapture )
828 {
829 ui_widget_finish();
830 if( svg_capture_active ) {
831
832 fuse_emulation_pause();
833
834 svg_stopcapture();
835 ui_menu_activate( UI_MENU_ITEM_FILE_SVG_CAPTURE, 0 );
836
837 fuse_emulation_unpause();
838 }
839 }
840
841 #endif /* HAVE_LIB_XML2 */
842
843
MENU_CALLBACK(menu_file_movie_record)844 MENU_CALLBACK( menu_file_movie_record )
845 {
846 char *filename;
847
848 ui_widget_finish();
849
850 fuse_emulation_pause();
851
852 filename = ui_get_save_filename( "Fuse - Record Movie File" );
853 if( !filename ) { fuse_emulation_unpause(); return; }
854
855 movie_start( filename );
856 libspectrum_free( filename );
857
858 fuse_emulation_unpause();
859 }
860
MENU_CALLBACK(menu_file_movie_record_recordfromrzx)861 MENU_CALLBACK( menu_file_movie_record_recordfromrzx )
862 {
863 char *rzx_file, *fmf_file;
864
865 ui_widget_finish();
866
867 if( rzx_playback || rzx_recording || movie_recording ) return;
868
869 fuse_emulation_pause();
870
871 rzx_file = ui_get_open_filename( "Fuse - Load RZX" );
872 if( !rzx_file ) { fuse_emulation_unpause(); return; }
873
874 rzx_start_playback( rzx_file, 1 );
875 libspectrum_free( rzx_file );
876 display_refresh_all();
877
878 if( rzx_playback ) {
879 fmf_file = ui_get_save_filename( "Fuse - Record Movie File" );
880 if( !fmf_file ) {
881 rzx_stop_playback( 1 );
882 fuse_emulation_unpause();
883 return;
884 }
885
886 movie_start( fmf_file );
887 libspectrum_free( fmf_file );
888 ui_menu_activate( UI_MENU_ITEM_RECORDING, 1 );
889 }
890
891 fuse_emulation_unpause();
892 }
893
MENU_CALLBACK(menu_file_recording_record)894 MENU_CALLBACK( menu_file_recording_record )
895 {
896 char *recording;
897
898 if( rzx_playback || rzx_recording ) return;
899
900 fuse_emulation_pause();
901
902 recording = ui_get_save_filename( "Fuse - Start Recording" );
903 if( !recording ) { fuse_emulation_unpause(); return; }
904
905 rzx_start_recording( recording, 1 );
906
907 libspectrum_free( recording );
908
909 fuse_emulation_unpause();
910 }
911
MENU_CALLBACK(menu_file_recording_recordfromsnapshot)912 MENU_CALLBACK( menu_file_recording_recordfromsnapshot )
913 {
914 char *snap, *recording;
915
916 if( rzx_playback || rzx_recording ) return;
917
918 fuse_emulation_pause();
919
920 snap = ui_get_open_filename( "Fuse - Load Snapshot " );
921 if( !snap ) { fuse_emulation_unpause(); return; }
922
923 recording = ui_get_save_filename( "Fuse - Start Recording" );
924 if( !recording ) {
925 libspectrum_free( snap );
926 fuse_emulation_unpause();
927 return;
928 }
929
930 if( snapshot_read( snap ) ) {
931 libspectrum_free( snap );
932 libspectrum_free( recording );
933 fuse_emulation_unpause();
934 return;
935 }
936
937 rzx_start_recording( recording, settings_current.embed_snapshot );
938
939 libspectrum_free( recording );
940
941 display_refresh_all();
942
943 fuse_emulation_unpause();
944 }
945
MENU_CALLBACK(menu_file_recording_continuerecording)946 MENU_CALLBACK( menu_file_recording_continuerecording )
947 {
948 char *rzx_filename;
949 int error;
950
951 if( rzx_playback || rzx_recording ) return;
952
953 fuse_emulation_pause();
954
955 rzx_filename = ui_get_open_filename( "Fuse - Continue Recording" );
956 if( !rzx_filename ) { fuse_emulation_unpause(); return; }
957
958 error = rzx_continue_recording( rzx_filename );
959
960 if( error != LIBSPECTRUM_ERROR_NONE ) {
961 ui_error( UI_ERROR_WARNING, "RZX file cannot be continued" );
962 }
963
964 libspectrum_free( rzx_filename );
965
966 fuse_emulation_unpause();
967 }
968
MENU_CALLBACK(menu_file_aylogging_record)969 MENU_CALLBACK( menu_file_aylogging_record )
970 {
971 char *psgfile;
972
973 if( psg_recording ) return;
974
975 fuse_emulation_pause();
976
977 psgfile = ui_get_save_filename( "Fuse - Start AY Log" );
978 if( !psgfile ) { fuse_emulation_unpause(); return; }
979
980 psg_start_recording( psgfile );
981
982 libspectrum_free( psgfile );
983
984 display_refresh_all();
985
986 ui_menu_activate( UI_MENU_ITEM_AY_LOGGING, 1 );
987
988 fuse_emulation_unpause();
989 }
990
991 int
menu_check_media_changed(void)992 menu_check_media_changed( void )
993 {
994 int confirm, i;
995
996 confirm = tape_close(); if( confirm ) return 1;
997
998 confirm = ui_media_drive_eject_all();
999 if( confirm ) return 1;
1000
1001 for( i = 0; i < 8; i++ ) {
1002 confirm = if1_mdr_eject( i );
1003 if( confirm ) return 1;
1004 }
1005
1006 if( settings_current.simpleide_master_file ) {
1007 confirm = simpleide_eject( LIBSPECTRUM_IDE_MASTER );
1008 if( confirm ) return 1;
1009 }
1010
1011 if( settings_current.simpleide_slave_file ) {
1012 confirm = simpleide_eject( LIBSPECTRUM_IDE_SLAVE );
1013 if( confirm ) return 1;
1014 }
1015
1016 if( settings_current.zxatasp_master_file ) {
1017 confirm = zxatasp_eject( LIBSPECTRUM_IDE_MASTER );
1018 if( confirm ) return 1;
1019 }
1020
1021 if( settings_current.zxatasp_slave_file ) {
1022 confirm = zxatasp_eject( LIBSPECTRUM_IDE_SLAVE );
1023 if( confirm ) return 1;
1024 }
1025
1026 if( settings_current.zxcf_pri_file ) {
1027 confirm = zxcf_eject(); if( confirm ) return 1;
1028 }
1029
1030 if( settings_current.divide_master_file ) {
1031 confirm = divide_eject( LIBSPECTRUM_IDE_MASTER );
1032 if( confirm ) return 1;
1033 }
1034
1035 if( settings_current.divide_slave_file ) {
1036 confirm = divide_eject( LIBSPECTRUM_IDE_SLAVE );
1037 if( confirm ) return 1;
1038 }
1039
1040 if( settings_current.divmmc_file ) {
1041 confirm = divmmc_eject();
1042 if( confirm ) return 1;
1043 }
1044
1045 if( settings_current.zxmmc_file ) {
1046 confirm = zxmmc_eject();
1047 if( confirm ) return 1;
1048 }
1049
1050 return 0;
1051 }
1052
1053 static int
menu_select_machine_roms(libspectrum_machine machine,size_t start,size_t n)1054 menu_select_machine_roms( libspectrum_machine machine, size_t start, size_t n )
1055 {
1056 return menu_select_roms_with_title( libspectrum_machine_name( machine ),
1057 start, n, 0 );
1058 }
1059
1060 static int
menu_select_peripheral_roms(const char * peripheral_name,size_t start,size_t n)1061 menu_select_peripheral_roms( const char *peripheral_name, size_t start, size_t n )
1062 {
1063 return menu_select_roms_with_title( peripheral_name,
1064 start, n, 1 );
1065 }
1066
1067 const char*
menu_machine_detail(void)1068 menu_machine_detail( void )
1069 {
1070 return libspectrum_machine_name( machine_current->machine );
1071 }
1072
1073 const char*
menu_filter_detail(void)1074 menu_filter_detail( void )
1075 {
1076 return scaler_name(current_scaler);
1077 }
1078
1079 const char*
menu_keyboard_joystick_detail(void)1080 menu_keyboard_joystick_detail( void )
1081 {
1082 return joystick_name[ settings_current.joystick_keyboard_output ];
1083 }
1084
1085 const char*
menu_joystick_1_detail(void)1086 menu_joystick_1_detail( void )
1087 {
1088 return joystick_name[ settings_current.joystick_1_output ];
1089 }
1090
1091 const char*
menu_joystick_2_detail(void)1092 menu_joystick_2_detail( void )
1093 {
1094 return joystick_name[ settings_current.joystick_2_output ];
1095 }
1096
1097 const char*
menu_tape_detail(void)1098 menu_tape_detail( void )
1099 {
1100 if( !tape_present() ) return "Not inserted";
1101
1102 if( tape_is_playing() ) return "Playing";
1103 else return "Stopped";
1104 }
1105
1106 static const char * const disk_detail_str[] = {
1107 "Inserted",
1108 "Inserted WP",
1109 "Inserted UD",
1110 "Inserted WP,UD",
1111
1112 "*Inserted",
1113 "*Inserted WP",
1114 "*Inserted UD",
1115 "*Inserted WP,UD",
1116 "Not inserted",
1117 };
1118
1119 static const char*
menu_disk_detail(fdd_t * f)1120 menu_disk_detail( fdd_t *f )
1121 {
1122 int i = 0;
1123
1124 if( !f->loaded ) return disk_detail_str[8];
1125 if( f->wrprot ) i = 1;
1126 if( f->upsidedown ) i += 2;
1127 if( f->disk.dirty ) i += 4;
1128 return disk_detail_str[i];
1129 }
1130
1131 const char*
menu_plus3a_detail(void)1132 menu_plus3a_detail( void )
1133 {
1134 fdd_t *f = specplus3_get_fdd( SPECPLUS3_DRIVE_A );
1135
1136 return menu_disk_detail( f );
1137 }
1138
1139 const char*
menu_plus3b_detail(void)1140 menu_plus3b_detail( void )
1141 {
1142 fdd_t *f = specplus3_get_fdd( SPECPLUS3_DRIVE_B );
1143
1144 return menu_disk_detail( f );
1145 }
1146
1147 const char*
menu_beta128a_detail(void)1148 menu_beta128a_detail( void )
1149 {
1150 fdd_t *f = beta_get_fdd( BETA_DRIVE_A );
1151
1152 return menu_disk_detail( f );
1153 }
1154
1155 const char*
menu_beta128b_detail(void)1156 menu_beta128b_detail( void )
1157 {
1158 fdd_t *f = beta_get_fdd( BETA_DRIVE_B );
1159
1160 return menu_disk_detail( f );
1161 }
1162
1163 const char*
menu_beta128c_detail(void)1164 menu_beta128c_detail( void )
1165 {
1166 fdd_t *f = beta_get_fdd( BETA_DRIVE_C );
1167
1168 return menu_disk_detail( f );
1169 }
1170
1171 const char*
menu_beta128d_detail(void)1172 menu_beta128d_detail( void )
1173 {
1174 fdd_t *f = beta_get_fdd( BETA_DRIVE_D );
1175
1176 return menu_disk_detail( f );
1177 }
1178
1179 const char*
menu_opus1_detail(void)1180 menu_opus1_detail( void )
1181 {
1182 fdd_t *f = opus_get_fdd( OPUS_DRIVE_1 );
1183
1184 return menu_disk_detail( f );
1185 }
1186
1187 const char*
menu_opus2_detail(void)1188 menu_opus2_detail( void )
1189 {
1190 fdd_t *f = opus_get_fdd( OPUS_DRIVE_2 );
1191
1192 return menu_disk_detail( f );
1193 }
1194
1195 const char*
menu_plusd1_detail(void)1196 menu_plusd1_detail( void )
1197 {
1198 fdd_t *f = plusd_get_fdd( PLUSD_DRIVE_1 );
1199
1200 return menu_disk_detail( f );
1201 }
1202
1203 const char*
menu_plusd2_detail(void)1204 menu_plusd2_detail( void )
1205 {
1206 fdd_t *f = plusd_get_fdd( PLUSD_DRIVE_2 );
1207
1208 return menu_disk_detail( f );
1209 }
1210
1211 const char*
menu_didaktik_a_detail(void)1212 menu_didaktik_a_detail( void )
1213 {
1214 fdd_t *f = didaktik80_get_fdd( DIDAKTIK80_DRIVE_A );
1215
1216 return menu_disk_detail( f );
1217 }
1218
1219 const char*
menu_didaktik_b_detail(void)1220 menu_didaktik_b_detail( void )
1221 {
1222 fdd_t *f = didaktik80_get_fdd( DIDAKTIK80_DRIVE_B );
1223
1224 return menu_disk_detail( f );
1225 }
1226
1227 const char*
menu_disciple1_detail(void)1228 menu_disciple1_detail( void )
1229 {
1230 fdd_t *f = disciple_get_fdd( DISCIPLE_DRIVE_1 );
1231
1232 return menu_disk_detail( f );
1233 }
1234
1235 const char*
menu_disciple2_detail(void)1236 menu_disciple2_detail( void )
1237 {
1238 fdd_t *f = disciple_get_fdd( DISCIPLE_DRIVE_2 );
1239
1240 return menu_disk_detail( f );
1241 }
1242
MENU_CALLBACK(menu_machine_didaktiksnap)1243 MENU_CALLBACK( menu_machine_didaktiksnap )
1244 {
1245 ui_widget_finish();
1246 didaktik80_snap = 1;
1247 event_add( 0, z80_nmi_event );
1248 }
1249