Streamline Callbacks and Ensure MediaType (#78)

* Separate drive speeds; better ensuring of media type

This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD.
This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes

* Multiple medium

* Add more drive speed prototyping

* Strip out redundant calls

* Separate drive speeds; better ensuring of media type

This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD.
This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes

* Multiple medium

* Add more drive speed prototyping

* Strip out redundant calls

* Streamline merge

* Comment patrol; keep BluRay a first-class citizen

* HD-DVD is supported?!
This commit is contained in:
Matt Nadareski
2018-06-27 23:21:52 -07:00
committed by GitHub
parent 4176f22d79
commit c1bd30e008
4 changed files with 99 additions and 76 deletions

View File

@@ -14,11 +14,17 @@ namespace DICUI.Data
public const string StopDumping = "Stop Dumping";
public const string FloppyDriveString = "<<FLOPPY>>";
// Private lists of known drive speed ranges
private static IReadOnlyList<int> AllowedDriveSpeedsForCD { get; } = new List<int> { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 };
private static IReadOnlyList<int> AllowedDriveSpeedsForDVD { get; } = AllowedDriveSpeedsForCD.Where(s => s <= 24).ToList();
private static IReadOnlyList<int> AllowedDriveSpeedsForBD { get; } = AllowedDriveSpeedsForCD.Where(s => s <= 16).ToList();
private static IReadOnlyList<int> AllowedDriveSpeedsForUnknownType { get; } = AllowedDriveSpeedsForCD; /*TODO: all or maybe just 1? eg new List<int> { 1 };*/
private static IReadOnlyList<int> AllowedDriveSpeedsForUnknownType { get; } = AllowedDriveSpeedsForCD; // TODO: All or {1}? Maybe null?
/// <summary>
/// Get list of all drive speeds for a given MediaType
/// </summary>
/// <param name="type">MediaType? that represents the current item</param>
/// <returns>Read-only list of drive speeds</returns>
public static IReadOnlyList<int> GetAllowedDriveSpeedsForMediaType(MediaType? type)
{
switch (type)
@@ -32,19 +38,19 @@ namespace DICUI.Data
case MediaType.WiiOpticalDisc:
case MediaType.WiiUOpticalDisc:
return AllowedDriveSpeedsForDVD;
//TODO: we should return them all since DIC doens't support them in any case
case MediaType.BluRay:
return AllowedDriveSpeedsForBD;
default:
return AllowedDriveSpeedsForUnknownType;
return AllowedDriveSpeedsForUnknownType;
}
}
public static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList<int> list)
=> new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
// Create collections for UI based on known drive speeds
public static DoubleCollection AllowedDriveSpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForCD);
public static DoubleCollection AllowedDriveSpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForDVD);
public static DoubleCollection AllowedDriveSpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(AllowedDriveSpeedsForBD);
private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList<int> list)
=> new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
}
/// <summary>

View File

@@ -39,10 +39,6 @@ namespace DICUI
// Populate the list of drives
PopulateDrives();
// Populate the list of drive speeds
PopulateDriveSpeeds();
SetSupportedDriveSpeed();
}
#region Events
@@ -74,32 +70,31 @@ namespace DICUI
private void btn_Search_Click(object sender, RoutedEventArgs e)
{
PopulateDrives();
SetCurrentDiscType();
SetSupportedDriveSpeed();
EnsureDiscInformation();
}
private void cmb_SystemType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PopulateMediaTypeAccordingToChosenSystem();
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_MediaType_SelectionChanged(object sencder, SelectionChangedEventArgs e)
private void cmb_MediaType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Only change the media type if the selection and not the list has changed
if (e.RemovedItems.Count == 1 && e.AddedItems.Count == 1)
{
_currentMediaType = cmb_MediaType.SelectedItem as MediaType?;
}
// TODO: This is giving people the benefit of the doubt that their change is valid
_currentMediaType = cmb_MediaType.SelectedItem as MediaType?;
SetSupportedDriveSpeed();
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_DriveLetter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetCurrentDiscType();
SetSupportedDriveSpeed();
GetOutputNames();
EnsureDiscInformation();
SetSupportedDriveSpeed();
}
private void cmb_DriveSpeed_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -158,7 +153,7 @@ namespace DICUI
cmb_MediaType.ItemsSource = _mediaTypes;
cmb_MediaType.IsEnabled = _mediaTypes.Count > 1;
cmb_MediaType.SelectedIndex = 0;
cmb_MediaType.SelectedIndex = (_mediaTypes.IndexOf(_currentMediaType) >= 0 ? _mediaTypes.IndexOf(_currentMediaType) : 0);
}
else
{
@@ -199,27 +194,17 @@ namespace DICUI
if (cmb_DriveLetter.Items.Count > 0)
{
cmb_DriveLetter.SelectedIndex = 0;
lbl_Status.Content = "Valid optical disc found! Choose your Disc Type";
lbl_Status.Content = "Valid media found! Choose your Media Type";
btn_StartStop.IsEnabled = true;
}
else
{
cmb_DriveLetter.SelectedIndex = -1;
lbl_Status.Content = "No valid optical disc found!";
lbl_Status.Content = "No valid media found!";
btn_StartStop.IsEnabled = false;
}
}
/// <summary>
/// Get a complete list of (possible) disc drive speeds, and fill the combo box
/// </summary>
private void PopulateDriveSpeeds()
{
var values = UIElements.GetAllowedDriveSpeedsForMediaType(_currentMediaType);
cmb_DriveSpeed.ItemsSource = values;
cmb_DriveSpeed.SelectedIndex = values.Count / 2;
}
/// <summary>
/// Browse for an output folder
/// </summary>
@@ -349,7 +334,7 @@ namespace DICUI
&& selectedSystem != KnownSystem.MicrosoftXBOX
&& selectedSystem != KnownSystem.MicrosoftXBOX360XDG2
&& selectedSystem != KnownSystem.MicrosoftXBOX360XDG3
? (int)cmb_DriveSpeed.SelectedItem + " " : "")
? (int?)cmb_DriveSpeed.SelectedItem + " " : "")
+ string.Join(" ", defaultParams);
}
}
@@ -370,21 +355,11 @@ namespace DICUI
// If we're on an unsupported type, update the status accordingly
switch (type)
{
case MediaType.NONE:
return Result.Failure("Please select a valid disc type");
case MediaType.GameCubeGameDisc:
case MediaType.GDROM:
return Result.Success("{0} discs are partially supported by DIC", type.Name());
// Fully supported types
case MediaType.CD:
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.LaserDisc:
case MediaType.CED:
case MediaType.UMD:
case MediaType.WiiOpticalDisc:
case MediaType.WiiUOpticalDisc:
case MediaType.Cartridge:
case MediaType.Cassette:
return Result.Failure("{0} discs are not currently supported by DIC", type.Name());
default:
case MediaType.BluRay:
if (system == KnownSystem.MicrosoftXBOX360XDG3)
{
return Result.Failure("{0} discs are not currently supported by DIC", type.Name());
@@ -405,15 +380,32 @@ namespace DICUI
}
else
{
return Result.Success("Disc of type {0} found, but the current system does not support it!", type.Name());
return Result.Success("Disc of type {0} found, but the current system does not support it!", _currentMediaType.Name());
}
}
}
break;
}
return Result.Success("{0} ready to dump", type.Name());
return Result.Success("{0} ready to dump", type.Name());
// Partially supported types
case MediaType.GDROM:
case MediaType.GameCubeGameDisc:
case MediaType.WiiOpticalDisc:
case MediaType.WiiUOpticalDisc:
return Result.Success("{0} discs are partially supported by DIC", type.Name());
// Undumpable but recognized types
case MediaType.LaserDisc:
case MediaType.CED:
case MediaType.UMD:
case MediaType.Cartridge:
case MediaType.Cassette:
return Result.Failure("{0} discs are not currently supported by DIC", type.Name());
// Invalid or unknown types
case MediaType.NONE:
default:
return Result.Failure("Please select a valid disc type");
}
}
/// <summary>
@@ -446,8 +438,10 @@ namespace DICUI
/// </summary>
private void SetSupportedDriveSpeed()
{
// Set generic drive speed just in case
cmb_DriveSpeed.SelectedItem = 8;
// Set the drive speed list that's appropriate
var values = UIElements.GetAllowedDriveSpeedsForMediaType(_currentMediaType);
cmb_DriveSpeed.ItemsSource = values;
cmb_DriveSpeed.SelectedIndex = values.Count / 2;
// Get the drive letter from the selected item
var selected = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
@@ -457,7 +451,7 @@ namespace DICUI
}
//Validators.GetDriveSpeed((char)selected?.Key);
//Validators.GetDriveSpeedEx((char)selected?.Key, MediaType.CD);
//Validators.GetDriveSpeedEx((char)selected?.Key, _currentMediaType);
// Validate that the required program exists and it's not DICUI itself
if (!File.Exists(_options.dicPath) ||

View File

@@ -262,7 +262,7 @@ namespace DICUI.Utilities
case MediaType.GDROM:
return DICCommands.GDROM;
case MediaType.HDDVD:
return null;
return DICCommands.DigitalVideoDisc;
case MediaType.BluRay:
return DICCommands.BluRay;
@@ -331,6 +331,7 @@ namespace DICUI.Utilities
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
break;
case MediaType.HDDVD:
// Currently no defaults set
break;
case MediaType.BluRay:
// Currently no defaults set

View File

@@ -52,7 +52,6 @@ namespace DICUI.Utilities
case KnownSystem.MicrosoftXBOX360XDG3:
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
types.Add(MediaType.HDDVD);
break;
case KnownSystem.MicrosoftXBOXOne:
types.Add(MediaType.BluRay);
@@ -546,6 +545,7 @@ namespace DICUI.Utilities
/// See if SCSI_MODE_SENSE can be used here
/// Currently, the calculations get something that is technically accurate, but is different than the advertisised
/// capabilities of the drives (according to QPXTool)
/// TransferRate appears to be the CURRENT transfer rate, not the maximum... basically making that flag useless
/// </remarks>
public static int GetDriveSpeed(char driveLetter)
{
@@ -561,19 +561,17 @@ namespace DICUI.Utilities
transferRate = (double?)queryObj["TransferRate"];
}
// Transfer Rates (bps)
double cdTransfer = 150 * 1024;
double dvdTransfer = 1353 * 1024;
// Transfer Rates (kBps)
double cdTransfer = 153.6;
double dvdTransfer = 1385;
double cdTransferTest = ((transferRate ?? -1) * 1024) / cdTransfer;
double cdTransferTestKilo = ((transferRate ?? -1) * 1000) / cdTransfer;
double dvdTransferTest = ((transferRate ?? -1) * 1024) / dvdTransfer;
double dvdTransferTestKilo = ((transferRate ?? -1) * 1000) / dvdTransfer;
double cdTransferTest = ((transferRate ?? -1)) / cdTransfer;
double dvdTransferTest = ((transferRate ?? -1)) / dvdTransfer;
return 0;
}
public static int GetDriveSpeedEx(char driveLetter, MediaType? mediaType)
public unsafe static int GetDriveSpeedEx(char driveLetter, MediaType? mediaType)
{
// Get the DeviceID from the current drive letter
string deviceId = null;
@@ -646,25 +644,49 @@ namespace DICUI.Utilities
return -1;
}
// Ones that haven't worked:
// recorderEx.GetAdapterDescriptor
// recorderEx.GetDeviceDescriptor
// recorderEx.GetDiscInformation
// recorderEx.GetTrackInformation
// Now we get the requested feature page
// TODO: Figure out structure of returned data
IntPtr featureData = Marshal.AllocHGlobal(32 * sizeof(byte));
recorderEx.GetFeaturePage(
ifpt,
(sbyte)0,
featureData,
out uint byteSize);
byte[] outFeatureArray = new byte[byteSize];
Marshal.Copy(featureData, outFeatureArray, 0, (int)byteSize);
// Now we get the requested mode data
// TODO: Figure out structure of returned data
IntPtr modeData = Marshal.AllocHGlobal(256 * sizeof(byte));
recorderEx.GetModePage(
IMAPI_MODE_PAGE_TYPE.IMAPI_MODE_PAGE_TYPE_LEGACY_CAPABILITIES,
(IMAPI_MODE_PAGE_TYPE)0x2A,
IMAPI_MODE_PAGE_REQUEST_TYPE.IMAPI_MODE_PAGE_REQUEST_TYPE_CURRENT_VALUES,
modeData,
out uint modeDataSize);
byte[] outModeArray = new byte[modeDataSize];
Marshal.Copy(modeData, outModeArray, 0, (int)modeDataSize);
// Now we get the requested feature page
IntPtr featureData = Marshal.AllocHGlobal(32 * sizeof(byte));
recorderEx.GetFeaturePage(
ifpt,
(sbyte)1,
featureData,
out uint byteSize);
byte[] outArray = new byte[byteSize];
Marshal.Copy(featureData, outArray, 0, (int)byteSize);
// Now we send the command to get sense data from the device
// TODO: This seems like the best option, but how is this data structured properly?
byte[] cdbArray = new byte[] { 0x5a, 0x0, 0x2a, 0x00, 0xff, 0x0 };
byte[] senseBuffer = new byte[256];
byte[] buffer = new byte[256];
uint bufferSize = 256;
recorderEx.SendCommandGetDataFromDevice(
ref cdbArray[0],
(uint)6,
senseBuffer,
(uint)60,
out buffer[0],
bufferSize,
out uint BufferFetched);
return -1;
}