void menu_machine_select( int action ) { widget_select_t info; char **options, *buffer; size_t i; int error; libspectrum_machine new_machine; options = malloc( machine_count * sizeof( const char * ) ); if( !options ) { ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ ); return; } buffer = malloc( 40 * machine_count ); if( !buffer ) { ui_error( UI_ERROR_ERROR, "out of memory at %s:%d", __FILE__, __LINE__ ); free( options ); return; } for( i = 0; i < machine_count; i++ ) { options[i] = &buffer[ i * 40 ]; snprintf( options[i], 40, libspectrum_machine_name( machine_types[i]->machine ) ); if( machine_current->machine == machine_types[i]->machine ) info.current = i; } info.title = "Select machine"; info.options = (const char**)options; info.count = machine_count; error = widget_do( WIDGET_TYPE_SELECT, &info ); free( buffer ); free( options ); if( error ) return; if( info.result == -1 ) return; new_machine = machine_types[ info.result ]->machine; if( machine_current->machine != new_machine ) machine_select( new_machine ); }
/* Called by the menu when Machine/Select selected */ void menu_machine_select( int action ) { /* FIXME: choosing spectrum SE crashes Fuse sound_frame () at sound.c:477 "ay_change[f].ofs = ( ay_change[f].tstates * sfreq ) / cpufreq;" */ /* FIXME: choosing some Timexes crashes (win32) fuse as well */ int selected_machine; win32ui_select_info items; int i; /* Stop emulation */ fuse_emulation_pause(); /* Populate win32ui_select_info */ items.dialog_title = TEXT( "Fuse - Select Machine" ); items.labels = malloc( machine_count * sizeof( char * ) ); items.length = machine_count; for( i=0; i<machine_count; i++ ) { items.labels[i] = libspectrum_machine_name( machine_types[i]->machine ); if( machine_current == machine_types[i] ) { items.selected = i; } } /* start the machine select dialog box */ selected_machine = selector_dialog( &items ); if( selected_machine >= 0 && machine_types[ selected_machine ] != machine_current ) { machine_select( machine_types[ selected_machine ]->machine ); } free( items.labels ); /* Resume emulation */ fuse_emulation_unpause(); }
int machine_select( libspectrum_machine type ) { int i; int error; /* We don't want to have to deal with screen size changes in the movie code and recording movies where we change machines seems pretty obscure */ movie_stop(); for( i=0; i < machine_count; i++ ) { if( machine_types[i]->machine == type ) { machine_location = i; error = machine_select_machine( machine_types[i] ); if( !error ) return 0; /* If we couldn't select the new machine type, try falling back to plain old 48K */ if( type != LIBSPECTRUM_MACHINE_48 ) error = machine_select( LIBSPECTRUM_MACHINE_48 ); /* If that still didn't work, give up */ if( error ) { ui_error( UI_ERROR_ERROR, "can't select 48K machine. Giving up." ); fuse_abort(); } else { ui_error( UI_ERROR_INFO, "selecting 48K machine" ); return 0; } return 0; } } ui_error( UI_ERROR_ERROR, "machine type %d unknown", type ); return 1; }
/* Open `filename' and do something sensible with it; autoload tapes if `autoload' is true and return the type of file found in `type' */ int utils_open_file( const char *filename, int autoload, libspectrum_id_t *type_ptr) { utils_file file; libspectrum_id_t type; libspectrum_class_t class; int error; error = 0; if( rzx_recording ) error = rzx_stop_recording(); if( rzx_playback ) error = rzx_stop_playback( 1 ); if( error ) return error; /* Read the file into a buffer */ if( utils_read_file( filename, &file ) ) return 1; /* See if we can work out what it is */ if( libspectrum_identify_file_with_class( &type, &class, filename, file.buffer, file.length ) ) { utils_close_file( &file ); return 1; } switch( class ) { case LIBSPECTRUM_CLASS_UNKNOWN: ui_error( UI_ERROR_ERROR, "utils_open_file: couldn't identify `%s'", filename ); utils_close_file( &file ); return 1; case LIBSPECTRUM_CLASS_RECORDING: error = rzx_start_playback_from_buffer( file.buffer, file.length ); break; case LIBSPECTRUM_CLASS_SNAPSHOT: error = snapshot_read_buffer( file.buffer, file.length, type ); pokemem_find_pokfile( filename ); break; case LIBSPECTRUM_CLASS_TAPE: error = tape_read_buffer( file.buffer, file.length, type, filename, autoload ); pokemem_find_pokfile( filename ); break; case LIBSPECTRUM_CLASS_DISK_PLUS3: if( !( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_PLUS3_DISK ) ) { error = machine_select( LIBSPECTRUM_MACHINE_PLUS3 ); if( error ) break; } error = specplus3_disk_insert( SPECPLUS3_DRIVE_A, filename, autoload ); break; case LIBSPECTRUM_CLASS_DISK_DIDAKTIK: error = didaktik80_disk_insert( DIDAKTIK80_DRIVE_A, filename, autoload ); break; case LIBSPECTRUM_CLASS_DISK_PLUSD: if( periph_is_active( PERIPH_TYPE_DISCIPLE ) ) error = disciple_disk_insert( DISCIPLE_DRIVE_1, filename, autoload ); else error = plusd_disk_insert( PLUSD_DRIVE_1, filename, autoload ); break; case LIBSPECTRUM_CLASS_DISK_OPUS: error = opus_disk_insert( OPUS_DRIVE_1, filename, autoload ); break; case LIBSPECTRUM_CLASS_DISK_TRDOS: if( !( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TRDOS_DISK ) && !periph_is_active( PERIPH_TYPE_BETA128 ) ) { error = machine_select( LIBSPECTRUM_MACHINE_PENT ); if( error ) break; } /* Check that we actually got a Beta capable machine to insert the disk */ if( ( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TRDOS_DISK ) || periph_is_active( PERIPH_TYPE_BETA128 ) ) { error = beta_disk_insert( BETA_DRIVE_A, filename, autoload ); } break; case LIBSPECTRUM_CLASS_DISK_GENERIC: if( machine_current->machine == LIBSPECTRUM_MACHINE_PLUS3 || machine_current->machine == LIBSPECTRUM_MACHINE_PLUS2A ) error = specplus3_disk_insert( SPECPLUS3_DRIVE_A, filename, autoload ); else if( machine_current->machine == LIBSPECTRUM_MACHINE_PENT || machine_current->machine == LIBSPECTRUM_MACHINE_PENT512 || machine_current->machine == LIBSPECTRUM_MACHINE_PENT1024 || machine_current->machine == LIBSPECTRUM_MACHINE_SCORP ) error = beta_disk_insert( BETA_DRIVE_A, filename, autoload ); else if( periph_is_active( PERIPH_TYPE_BETA128 ) ) error = beta_disk_insert( BETA_DRIVE_A, filename, autoload ); else if( periph_is_active( PERIPH_TYPE_DISCIPLE ) ) error = disciple_disk_insert( DISCIPLE_DRIVE_1, filename, autoload ); else if( periph_is_active( PERIPH_TYPE_PLUSD ) ) error = plusd_disk_insert( PLUSD_DRIVE_1, filename, autoload ); break; case LIBSPECTRUM_CLASS_CARTRIDGE_IF2: error = if2_insert( filename ); break; case LIBSPECTRUM_CLASS_MICRODRIVE: error = if1_mdr_insert( -1, filename ); break; case LIBSPECTRUM_CLASS_CARTRIDGE_TIMEX: if( !( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { error = machine_select( LIBSPECTRUM_MACHINE_TC2068 ); if( error ) break; } /* Check that we actually got a Dock capable machine to insert the cart */ if( machine_current->capabilities & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) { error = dck_insert( filename ); } break; case LIBSPECTRUM_CLASS_HARDDISK: if( !settings_current.simpleide_active && !settings_current.zxatasp_active && !settings_current.divide_enabled && !settings_current.zxcf_active ) { settings_current.zxcf_active = 1; periph_update(); } if( settings_current.zxcf_active ) { error = zxcf_insert( filename ); } else if( settings_current.zxatasp_active ) { error = zxatasp_insert( filename, LIBSPECTRUM_IDE_MASTER ); } else if( settings_current.simpleide_active ) { error = simpleide_insert( filename, LIBSPECTRUM_IDE_MASTER ); } else { error = divide_insert( filename, LIBSPECTRUM_IDE_MASTER ); } if( error ) return error; break; case LIBSPECTRUM_CLASS_AUXILIARY: if( type == LIBSPECTRUM_ID_AUX_POK ) { ui_pokemem_selector( filename ); } break; default: ui_error( UI_ERROR_ERROR, "utils_open_file: unknown class %d", type ); error = 1; break; } if( error ) { utils_close_file( &file ); return error; } utils_close_file( &file ); if( type_ptr ) *type_ptr = type; return 0; }