Compare commits

..

28 Commits
1.04b ... 1.07

Author SHA1 Message Date
Matt Nadareski
1e16e952cf Update for 1.07 2018-06-27 10:35:40 -07:00
Matt Nadareski
9f493ae27a One last fix for drive speed finding
DIC can sometimes report that a drive has a 0x speed, causing this automatic finder to fail in those cases
2018-06-27 10:35:29 -07:00
Matt Nadareski
2021230836 Quick fix to account for possibly odd speeds 2018-06-27 00:21:53 -07:00
Matt Nadareski
12ba5702fd Minor updates
This mostly takes care of adding a ton of comments and descriptions. Other minor changes include:
- Removing last remnants of psxt001z
- Capitalizing public variables
- Fixing the build that I stupidly broke
- Ensuring whitespace-named discs are handled
- Simplified DumpEnvironment init
2018-06-26 21:08:26 -07:00
Jacopo Santoni
2cf083eb89 Refactor of dump procedure into smaller components (#76)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* created Tasks file\nmoved some methods there, created DumpEnvironment to manage are arguments

* moved additional methods to Tasks to make it more modular

* changed StartDumping flow to avoid returning if extra tools are not found

* moved main dump workflow into Tasks class

* created specific DumpResult class for better error reporting/management

* fixes

* continued refactor
- split EnsureDiscInformation into an additional EnsureCorrectInformationForSystemAndMediaType
- proof of concept of using custom extensions to enum types to give better functionality (and encapsulation)
- changed cmb_MediaType to keep a List<MediaType?> and got rid of Tuple<string, MediaType?>

* restored GetDiscType functionality

* fixed btn_StartStop enabled on EnsureCorrect... error

* fixed whitespace

* fixed indentation

* fixes for PR
2018-06-26 20:18:37 -07:00
Matt Nadareski
c1f22d47dc Remove Redundant Calls and PSX Automation (#75)
* Work with callbacks to increase perf

* Make EDC field for PSX automatic

* Make AntiMod field for PSX automatic

* Make LibCrypt field for PSX automatic

* Remove psxt001z

Now that we have confirmed that DIC outputs the required information for libcrypt, we no longer need the external call to psxt001z to confirm (output was unused anyway)

* We need the subIntention data for LibCrypt

* Let's avoid null for now

* Set default speed in case of error

* Check the layerbreak better

* Remove extraneous header checking

* Add SubIntention field if it exists, always

* Add LibCrypt flag by default for PSX

* SubIntention needs a newline
2018-06-26 10:35:58 -07:00
Matt Nadareski
11287d081d Add system requirements (fixes #72) 2018-06-25 10:18:06 -07:00
Matt Nadareski
8652af5697 Usability Updates (#73)
* Checkpoint

* Add notes

* Rename Validation -> Validators

* Move data to Data folder

* Get current disk type

* Automatically detect disc type

* Comment out WIP code

* Add more prototype

The hope is that having this unhooked prototype code will get either myself or another contributor the right inspiration to get it going properly
2018-06-25 10:00:06 -07:00
Matt Nadareski
69561cb1a0 Bits and Pieces (#70)
* DiscType -> MediaType

* Fix bulk find/replace

* Add OrderedDictionary

* Stage 1 of moving off of Tuples

* Add CHANGELIST.md

* Stage 2 of Tuple removal

* String replacement for output paths

* Stage 3 of Tuple removal

* Slight reordering
2018-06-21 11:46:14 -07:00
Matt Nadareski
d587d2b4b3 Add system and media type to output submission info (#65)
* Add new constants to the template

* Slight reordering

* Add new fields to the output

* Whitespace!

* Minor formatting cleanup

* Add TODO

* Whitepace, 2.0
2018-06-20 22:00:26 -07:00
Matt Nadareski
a19418e46f Remove sg-raw (#64)
* Remove sg-raw from OptionsWindow.xaml.cs

* Remove sg-raw from OptionsWindow.xaml

* Remove sg-raw from Options.cs

* Remove sg-raw from MainWindow.xaml.cs

* Missed the other rows

* Remove sg-raw from App.config
2018-06-20 12:44:39 -07:00
Jacopo Santoni
de22ead07c Enhancement of options management (#63)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* added OptionsFrame that will manage all applicaton settings and implemented path browse buttons

* removed old properties code, added Options to manage all the program options, implemented interactions with OptionsWindow

* fixed margins automatically inserted by MSVS

* fixed margins automatically inserted by MSVS

* removed empty method placed by XAML designer

* added closed callback for OptionsWindows, tweaks

* fixed button in toolbar
2018-06-20 12:30:31 -07:00
Matt Nadareski
f777869103 Formats and Types (#58)
* Combine single/dual-layer disc types

* Add silly formats

* Minor tweaks to disc type population

* Make codepath slightly less complex

* Fix null error on dump

* Update strings that looked wrong in output
2018-06-20 11:38:12 -07:00
reignstumble
aec1131271 Update README.md 2018-06-20 12:23:01 -04:00
Jacopo Santoni
308fad3ed2 Separated of System and Disc Type (#56)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox
2018-06-18 12:43:07 -07:00
Matt Nadareski
61ce45667b Update for 1.06 2018-06-15 20:27:34 -07:00
Matt Nadareski
ababfdd2ed XBOX/360 Fixes (#50)
* Better creation of parameters (fixes Xbox/360)

* Split X360 into XDG2/3

* Don't enable drive speed if we're not supposed to

* Add first attempt at Xbox info extraction

* Trim or it never matches
2018-06-15 20:24:43 -07:00
Matt Nadareski
9683074197 Only eject when told 2018-06-14 20:18:01 -07:00
Matt Nadareski
ab2bc8f50c Worst typo ever 2018-06-14 20:11:49 -07:00
reignstumble
aa86ddaf47 Fix incorrectly enabled button 2018-06-14 20:40:41 -04:00
Matt Nadareski
68afebace4 Update for 1.05a 2018-06-14 16:37:43 -07:00
Matt Nadareski
bebe3ab8a0 Add specialty checking for PS1, PS2, and Saturn (#47)
* Setup upcoming work

* Add EXE date checking for PS1/PS2

* Add PS2 version checking

* Add Saturn header reading, fix validation again

* Get all Saturn build info
2018-06-14 16:33:40 -07:00
Matt Nadareski
1f314df8c1 Update for 1.05 2018-06-14 14:14:25 -07:00
Matt Nadareski
38c3638f21 Update Commands for new DIC Version (#46)
* Split constants further

* Fix TODOs in the dump information

* Add TODO for sg-raw

* Use DIC flags, add XBOX command

* Add .dat output for floppy disks, add note

* Better custom parameter checking

* Remove postfix from commands, add /74 flag

* Update DIC flag constant names

* Add descripion for Template constants

* Add description for UIElements

* New utilities namespace

* Add XBOX-specific information

* Add more disc-based arcade systems

* Add special check for PSX discs
2018-06-14 14:06:10 -07:00
Matt Nadareski
cde4b671fc Parameter Checking updates (#44)
* Fix custom parameter parsing, rename to just "parameters"

* Consolodate and fix param checking code
2018-06-13 22:15:53 -07:00
Matt Nadareski
578854cd3b Fixes and Floppies (#43)
* Fix button appearance on Settings window

* Add notes for floppy dumping later

* Support floppy disk reading (fixes #12)
2018-06-13 20:14:25 -07:00
Matt Nadareski
1cd7885194 More fixes (#42)
* Make custom parameters react to filename/directory changes

* Add subdump for Saturn (fixes #20)

* Add disc eject, fix minor issue (fixes #17)

* Fix spacing issue
2018-06-13 18:02:45 -07:00
Matt Nadareski
c0de39c229 Miscellaneous Fixes (#41)
* Make error count more accurate

* Extract dump information to separate file

* Remove TODO

* Add subIntention field check to other formats

* Correct Wii and WiiU disc types

* Nuon correction (hard to base on the limited releases)

* Update Sega Lindbergh

* Add two Sega arcade platforms

* Clearer TODO

* Validate "swap" command

* Remove hanging comma from TODO

* Remove TODO
This one I'm removing because technically, the "gd" command is the correct way of dumping via DIC. The "swap" command is a stopgap for drives that only support GD-ROM dumping via hacked TOC discs
2018-06-13 17:07:55 -07:00
20 changed files with 4478 additions and 2524 deletions

View File

@@ -2,8 +2,7 @@
<configuration>
<appSettings>
<add key="dicPath" value="Programs\DiscImageCreator.exe"/>
<add key="psxt001zPath" value="psxt001z.exe"/>
<add key="sgRawPath" value="sg_raw.exe"/>
<add key="subdumpPath" value="subdump.exe"/>
<add key="defaultOutputPath" value="ISO"/>
</appSettings>
</configuration>
</configuration>

72
CHANGELIST.md Normal file
View File

@@ -0,0 +1,72 @@
### 1.07 (2018-06-27)
- Separated system and media type for easier navigation
- Combined instances of single- and dual-layer discs
- Removed reliance on **sg-raw** and **psxt001z**
- Added system and disc type to the submission info
- First attempt at getting current disc type
- Made the three PSX-specific fields (**EDC**, **Anti-modchip**, and **LibCrypt**) automatically filled in, when possible
- Many, many, many behind the scenes updates for speed, future features, and stability
### 1.06 (2018-06-15)
- Fixed not being able to use the `/c2` flag properly
- Fixed times when the ability to start dumping was improperly allowed
- Added full support for XBOX and XBOX360 (XDG1, XDG2) dumping through DIC (using a Kreon, or presumably a 0800)
### 1.05a (2018-06-14)
- Fixed some ordering and nullability issues
- Added automatic fields for PS1, PS2, Saturn
### 1.05 (2018-06-14)
- Miscellaneous fixes around custom parameter validation, dump information accuracy, settings window, and TODO cleanup
- Add many more supported platforms, mostly arcade (based on publicly available information)
- Add floppy disk dumping support
- Add optional disc eject on completion
- Add subdump for Sega Saturn
- Fully support newest version of DIC including all new flags and commands
- PlayStation and Saturn discs still don't have all internal information automatically generated
### 1.04b (2018-06-13)
- Added subIntention reading
- Fixed extra extensions being appended
- Fixed internationalization error (number formatting)
- Fixed "Custom Input" not working
### 1.04a (2018-06-13)
- Fixed issue with empty trays
- Added settings dialog
### 1.04 (2018-06-13)
- Behind-the-scenes fixes and formatting
- Better checks for external programs
- Automatically changing disc information
- Custom parameters (and parameter validation)
- Automatic drive speed selection
- Automatic submission information creation
- Add ability to stop a dump from the UI
### 1.03 (2018-06-08)
- edccchk now run on all CD-Roms
- Discs unsupported by Windows are now regonized
- Extra \ when accepting default save has been removed.
### 1.02b (2018-05-18)
- Added missing DLL
### 1.02 (2018-05-18)
- Fixed XBOX One and PS4 Drive Speed issue.
- Started implementing DiscImageCreator Path selection.
- Conforming my naming for objects and variable
### 1.01d (2018-05-18)
-Combine IBM PC-CD options, misc fixes.

View File

@@ -1,102 +0,0 @@
namespace DICUI
{
public static class UIElements
{
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
}
public static class DICCommands
{
// Commands
public const string CompactDiscCommand = "cd";
public const string DataCommand = "data";
public const string AudioCommand = "audio";
public const string GDROMCommand = "gd";
public const string GDROMSwapCommand = "swap";
public const string DVDCommand = "dvd";
public const string BDCommand = "bd";
public const string FloppyCommand = "fd";
public const string StopCommand = "stop";
public const string StartCommand = "start";
public const string EjectCommand = "eject";
public const string CloseCommand = "close";
public const string ResetCommand = "reset";
public const string SubCommand = "sub";
public const string MDSCommand = "mds";
public const string DriveSpeedCommand = "ls"; // Unlisted in help text
// DIC Flags
public const string ForceUnitAccessFlag = "/f";
public const string DisableBeepFlag = "/q";
public const string CDAddOffsetFlag = "/a";
public const string CDBEOpcodeFlag = "/be";
public const string CDD8OpcodeFlag = "/d8";
public const string CDC2OpcodeFlag = "/c2";
public const string CDMCNFlag = "/m";
public const string CDAMSFFlag = "/p";
public const string CDReverseFlag = "/r";
public const string CDMultiSessionFlag = "/ms";
public const string CDScanFileProtectFlag = "/sf";
public const string CDScanSectorProtectFlag = "/ss";
public const string CDScanAnitModFlag = "/am";
public const string CDNoFixSubPFlag = "/np";
public const string CDNoFixSubQFlag = "/nq";
public const string CDNoFixSubRtoWFlag = "/nr";
public const string CDNoFixSubQLibCryptFlag = "/nl";
public const string CDNoFixSubQSecuROMFlag = "/ns";
public const string CDSubchannelReadLevelFlag = "/s";
public const string DVDCMIFlag = "/c";
public const string DVDRawFlag = "/raw";
}
public static class Template
{
// Manual information
public const string TitleField = "Title";
public const string DiscNumberField = "Disc Number / Letter";
public const string DiscTitleField = "Disc Title";
public const string CategoryField = "Category";
public const string RegionField = "Region";
public const string LanguagesField = "Languages";
public const string DiscSerialField = "Disc Serial";
public const string BarcodeField = "Barcode";
public const string ISBNField = "ISBN";
public const string CommentsField = "Comments";
public const string ContentsField = "Contents";
public const string VersionField = "Version";
public const string EditionField = "Edition/Release";
public const string CopyProtectionField = "Copy Protection";
public const string MasteringRingField = "Mastering Ring";
public const string MasteringSIDField = "Mastering SID Code";
public const string MouldSIDField = "Mould SID Code";
public const string AdditionalMouldField = "Additional Mould";
public const string ToolstampField = "Toolstamp or Mastering Code";
// Automatic Information
public const string PVDField = "Primary Volume Descriptor (PVD)";
public const string DATField = "DAT";
public const string ErrorCountField = "Error Count";
public const string CuesheetField = "Cuesheet";
public const string SubIntentionField = "SubIntention (SecuROM)";
public const string WriteOffsetField = "WriteOffset";
public const string LayerbreakField = "Layerbreak";
public const string PlaystationEXEDateField = "EXE Date"; // TODO: Not automatic yet
public const string PlayStationEDCField = "EDC"; // TODO: Not automatic yet
public const string PlayStationAntiModchipField = "Anti-modchip"; // TODO: Not automatic yet
public const string PlayStationLibCryptField = "LibCrypt"; // TODO: Not automatic yet
public const string SaturnHeaderField = "Header"; // TODO: Not automatic yet
public const string SaturnBuildDateField = "Build Date"; // TODO: Not automatic yet
// Default values
public const string RequiredValue = "(REQUIRED)";
public const string RequiredIfExistsValue = "(REQUIRED, IF EXISTS)";
public const string OptionalValue = "(OPTIONAL)";
public const string YesNoValue = "Yes/No";
}
}

View File

@@ -39,6 +39,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -69,6 +70,8 @@
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Management" />
<Reference Include="System.Management.Instrumentation" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
@@ -88,8 +91,17 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Constants.cs" />
<Compile Include="Utilities.cs" />
<Compile Include="Data\Constants.cs" />
<Compile Include="External\OrderedDictionary.cs" />
<Compile Include="External\IOrderedDictionary.cs" />
<Compile Include="Options.cs" />
<Compile Include="Tasks.cs" />
<Compile Include="Utilities\DumpInformation.cs" />
<Compile Include="Utilities\Validators.cs" />
<Compile Include="Utilities\Converters.cs" />
<Compile Include="OptionsWindow.xaml.cs">
<DependentUpon>OptionsWindow.xaml</DependentUpon>
</Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -98,11 +110,15 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Enumerations.cs" />
<Compile Include="Data\Enumerations.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="OptionsWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -127,5 +143,25 @@
<ItemGroup>
<Resource Include="Icon.ico" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="IMAPI2FS">
<Guid>{2C941FD0-975B-59BE-A960-9A2A262853A5}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

122
Data/Constants.cs Normal file
View File

@@ -0,0 +1,122 @@
namespace DICUI.Data
{
/// <summary>
/// Text for UI elements
/// </summary>
public static class UIElements
{
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
public const string FloppyDriveString = "<<FLOPPY>>";
}
/// <summary>
/// Top-level commands for DiscImageCreator
/// </summary>
public static class DICCommands
{
public const string Audio = "audio";
public const string BluRay = "bd";
public const string Close = "close";
public const string CompactDisc = "cd";
public const string Data = "data";
public const string DigitalVideoDisc = "dvd";
public const string DriveSpeed = "ls";
public const string Eject = "eject";
public const string Floppy = "fd";
public const string GDROM = "gd";
public const string MDS = "mds";
public const string Reset = "reset";
public const string Start = "start";
public const string Stop = "stop";
public const string Sub = "sub";
public const string Swap = "swap";
public const string XBOX = "xbox";
}
/// <summary>
/// Dumping flags for DiscImageCreator
/// </summary>
public static class DICFlags
{
public const string AddOffset = "/a";
public const string AMSF = "/p";
public const string BEOpcode = "/be";
public const string C2Opcode = "/c2";
public const string CMI = "/c";
public const string D8Opcode = "/d8";
public const string DisableBeep = "/q";
public const string ForceUnitAccess = "/f";
public const string MCN = "/m";
public const string MultiSession = "/ms";
public const string NoFixSubP = "/np";
public const string NoFixSubQ = "/nq";
public const string NoFixSubQLibCrypt = "/nl";
public const string NoFixSubQSecuROM = "/ns";
public const string NoFixSubRtoW = "/nr";
public const string Raw = "/raw";
public const string Reverse = "/r";
public const string ScanAntiMod = "/am";
public const string ScanFileProtect = "/sf";
public const string ScanSectorProtect = "/ss";
public const string SeventyFour = "/74";
public const string SubchannelReadLevel = "/s";
}
/// <summary>
/// Template field values for submission info
/// </summary>
public static class Template
{
// Manual information
public const string TitleField = "Title";
public const string DiscNumberField = "Disc Number / Letter";
public const string DiscTitleField = "Disc Title";
public const string SystemField = "System";
public const string MediaTypeField = "Media Type";
public const string CategoryField = "Category";
public const string RegionField = "Region";
public const string LanguagesField = "Languages";
public const string DiscSerialField = "Disc Serial";
public const string BarcodeField = "Barcode";
public const string ISBNField = "ISBN";
public const string CommentsField = "Comments";
public const string ContentsField = "Contents";
public const string VersionField = "Version";
public const string EditionField = "Edition/Release";
public const string CopyProtectionField = "Copy Protection";
public const string MasteringRingField = "Mastering Ring";
public const string MasteringSIDField = "Mastering SID Code";
public const string MouldSIDField = "Mould SID Code";
public const string AdditionalMouldField = "Additional Mould";
public const string ToolstampField = "Toolstamp or Mastering Code";
// Automatic Information
public const string PVDField = "Primary Volume Descriptor (PVD)";
public const string DATField = "DAT";
public const string ErrorCountField = "Error Count";
public const string CuesheetField = "Cuesheet";
public const string SubIntentionField = "SubIntention Data (SecuROM/LibCrypt)";
public const string WriteOffsetField = "Write Offset";
public const string LayerbreakField = "Layerbreak";
public const string PlaystationEXEDateField = "EXE Date";
public const string PlayStationEDCField = "EDC";
public const string PlayStationAntiModchipField = "Anti-modchip";
public const string PlayStationLibCryptField = "LibCrypt";
public const string SaturnHeaderField = "Header";
public const string SaturnBuildDateField = "Build Date";
public const string XBOXDMIHash = "DMI.bin Hashes";
public const string XBOXPFIHash = "PFI.bin Hashes";
public const string XBOXSSHash = "SS.bin Hashes";
public const string XBOXSSRanges = "Security Sector Ranges";
// Default values
public const string RequiredValue = "(REQUIRED)";
public const string RequiredIfExistsValue = "(REQUIRED, IF EXISTS)";
public const string OptionalValue = "(OPTIONAL)";
public const string YesNoValue = "Yes/No";
}
}

View File

@@ -1,27 +1,5 @@
namespace DICUI
namespace DICUI.Data
{
/// <summary>
/// Known disc types
/// </summary>
public enum DiscType
{
NONE = 0,
CD,
DVD5,
DVD9,
GDROM,
HDDVD,
BD25,
BD50,
// Special Formats
GameCubeGameDisc,
UMD,
// Keeping this separate since it's currently unsupported in the UI
Floppy = 99,
}
/// <summary>
/// Known systems
/// </summary>
@@ -38,7 +16,8 @@
CommodoreAmigaCDTV,
MattelHyperscan,
MicrosoftXBOX,
MicrosoftXBOX360,
MicrosoftXBOX360XDG2,
MicrosoftXBOX360XDG3,
MicrosoftXBOXOne,
NECPCEngineTurboGrafxCD,
NECPCFX,
@@ -77,14 +56,59 @@
#region Arcade
AmigaCUBOCD32,
AmericanLaserGames3DO,
Atari3DO,
Atronic,
AUSCOMSystem1,
BallyGameMagic,
CapcomCPSystemIII,
GlobalVRVarious,
GlobalVRVortek,
GlobalVRVortekV3,
ICEPCHardware,
IncredibleTechnologiesEagle,
IncredibleTechnologiesVarious,
KonamiFirebeat,
KonamiGVSystem,
KonamiM2,
KonamiPython,
KonamiPython2,
KonamiSystem573,
KonamiTwinkle,
KonamiVarious,
MeritIndustriesBoardwalk,
MeritIndustriesMegaTouchAurora,
MeritIndustriesMegaTouchForce,
MeritIndustriesMegaTouchION,
MeritIndustriesMegaTouchMaxx,
MeritIndustriesMegaTouchXL,
NamcoCapcomSystem256,
NamcoCapcomTaitoSystem246,
NamcoSegaNintendoTriforce,
NamcoSystem246,
NamcoSystem12,
NamcoSystem357,
NewJatreCDi,
NichibutsuHighRateSystem,
NichibutsuSuperCD,
NichibutsuXRateSystem,
PhotoPlayVarious,
RawThrillsVarious,
SegaChihiro,
SegaEuropaR,
SegaLindbergh,
SegaNaomi,
SegaNaomi2,
SegaNu,
SegaRingEdge,
SegaRingEdge2,
SegaRingWide,
SegaSTV,
SegaSystem32,
SeibuCATSSystem,
TABAustriaQuizard,
TandyMemorexVisualInformationSystem,
TsunamiTsuMoMultiGameMotionSystem,
#endregion
@@ -94,6 +118,7 @@
BDVideo,
DVDVideo,
EnhancedCD,
HDDVDVideo,
PalmOS,
PhilipsCDiDigitalVideo,
PhotoCD,
@@ -103,5 +128,34 @@
VideoCD,
#endregion
Custom = -1
}
/// <summary>
/// Known media types
/// </summary>
public enum MediaType
{
// Generic Optical Formats
NONE = 0,
CD,
DVD,
GDROM,
HDDVD,
BluRay,
LaserDisc,
// Special Optical Formats
GameCubeGameDisc,
WiiOpticalDisc,
WiiUOpticalDisc,
UMD,
// Non-Optical Formats
Floppy,
Cartridge,
Cassette,
CED,
}
}

10
External/IOrderedDictionary.cs vendored Normal file
View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;
using System.Collections.Specialized;
namespace DICUI.External
{
// Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO
public interface IOrderedDictionary<TKey, TValue> : IOrderedDictionary, IDictionary<TKey, TValue>
{
}
}

326
External/OrderedDictionary.cs vendored Normal file
View File

@@ -0,0 +1,326 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace DICUI.External
{
// Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO
public class OrderedDictionary<TKey, TValue> : IOrderedDictionary<TKey, TValue>
{
private List<KeyValuePair<TKey, TValue>> _list;
private Dictionary<TKey, TValue> _dictionary;
#region Interface properties
public int Count { get; }
int ICollection.Count => Count;
int ICollection<KeyValuePair<TKey, TValue>>.Count => Count;
ICollection IDictionary.Keys => _dictionary.Keys;
ICollection<TKey> IDictionary<TKey, TValue>.Keys => _dictionary.Keys;
ICollection IDictionary.Values => _dictionary.Values;
ICollection<TValue> IDictionary<TKey, TValue>.Values => _dictionary.Values;
bool IDictionary.IsReadOnly => false;
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
bool IDictionary.IsFixedSize => false;
object ICollection.SyncRoot => new object();
bool ICollection.IsSynchronized => true;
public TValue this[int index]
{
get
{
return _list[index].Value;
}
set
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than" +
" the size of the collection");
TKey key = _list[index].Key;
_list[index] = new KeyValuePair<TKey, TValue>(key, value);
_dictionary[key] = value;
}
}
object IOrderedDictionary.this[int index]
{
get
{
return _list[index].Value;
}
set
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than" +
" the size of the collection");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
TKey key = _list[index].Key;
_list[index] = new KeyValuePair<TKey, TValue>(key, valueObj);
_dictionary[key] = valueObj;
}
}
object IDictionary.this[object key]
{
get
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
return _dictionary[keyObj];
}
set
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
if (_dictionary.ContainsKey(keyObj))
{
_dictionary[keyObj] = valueObj;
_list[IndexOfKey(keyObj)] = new KeyValuePair<TKey, TValue>(keyObj, valueObj);
}
else
{
Add(keyObj, valueObj);
}
}
}
TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
return _dictionary[key];
}
set
{
if (_dictionary.ContainsKey(key))
{
_dictionary[key] = value;
_list[IndexOfKey(key)] = new KeyValuePair<TKey, TValue>(key, value);
}
else
{
Add(key, value);
}
}
}
#endregion
public OrderedDictionary()
{
_list = new List<KeyValuePair<TKey, TValue>>();
_dictionary = new Dictionary<TKey, TValue>();
Count = 0;
}
public int Add(TKey key, TValue value)
{
_dictionary.Add(key, value);
_list.Add(new KeyValuePair<TKey, TValue>(key, value));
return Count - 1;
}
public void Insert(int index, TKey key, TValue value)
{
if (index > Count || index < 0)
throw new ArgumentOutOfRangeException("index");
_dictionary.Add(key, value);
_list.Insert(index, new KeyValuePair<TKey, TValue>(key, value));
}
void IOrderedDictionary.RemoveAt(int index)
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than " +
"the size of the collection");
TKey key = _list[index].Key;
_list.RemoveAt(index);
_dictionary.Remove(key);
}
public bool Remove(TKey key)
{
if (null == key)
throw new ArgumentNullException("key");
int index = IndexOfKey(key);
if (index >= 0)
{
if (_dictionary.Remove(key))
{
_list.RemoveAt(index);
return true;
}
}
return false;
}
public bool ContainsKey(TKey key)
{
return _dictionary.ContainsKey(key);
}
private int IndexOfKey(TKey key)
{
return _list.FindIndex(kvp => kvp.Key.Equals(key));
}
#region Interface methods
IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
void IOrderedDictionary.Insert(int index, object key, object value)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
Insert(index, keyObj, valueObj);
}
bool IDictionary.Contains(object key)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
return _dictionary.ContainsKey(keyObj);
}
void IDictionary.Add(object key, object value)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
Add(keyObj, valueObj);
}
void IDictionary.Clear()
{
_dictionary.Clear();
_list.Clear();
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
void IDictionary.Remove(object key)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
Remove(keyObj);
}
void ICollection.CopyTo(Array array, int index)
{
var arrayObj = array as KeyValuePair<TKey, TValue>[];
if (arrayObj == null)
throw new ArgumentException($"Key must be of type {typeof(KeyValuePair<TKey, TValue>[])}");
_list.CopyTo(arrayObj, index);
}
bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
{
return ContainsKey(key);
}
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
Add(key, value);
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
return Remove(key);
}
bool IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)
{
return _dictionary.TryGetValue(key, out value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
_dictionary.Clear();
_list.Clear();
}
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
return _list.Contains(item);
}
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
return Remove(item.Key);
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _list.GetEnumerator();
}
#endregion
}
}

View File

@@ -4,9 +4,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
xmlns:utilities="clr-namespace:DICUI.Utilities"
mc:Ignorable="d"
Title="Disc Image Creator GUI" Height="450" Width="600">
<Window.Resources>
<utilities:EnumDescriptionConverter x:Key="enumConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
@@ -21,7 +26,7 @@
<ToolBarTray Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Height="30" HorizontalAlignment="Stretch" IsLocked="True">
<ToolBar>
<Button x:Name="tbr_Properties" Content="Properties" Command="Properties" Click="tbr_Properties_Click" CommandManager.CanExecute="tbr_Properties_CanExecute"/>
<Button x:Name="tbr_Options" Content="Options" Click="tbr_Options_Click" />
</ToolBar>
</ToolBarTray>
<GroupBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" HorizontalAlignment="Stretch" Header="Settings"/>
@@ -42,30 +47,38 @@
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center">Disc Type</Label>
<ComboBox x:Name="cmb_DiscType" Grid.Row="0" Grid.Column="1" Height="22" SelectionChanged="cmb_DiscType_SelectionChanged" />
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
<ComboBox x:Name="cmb_SystemType" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="left" SelectionChanged="cmb_SystemType_SelectionChanged" />
<ComboBox x:Name="cmb_MediaType" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="right" SelectionChanged="cmb_MediaType_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center">Output Filename</Label>
<TextBox x:Name="txt_OutputFilename" Grid.Row="1" Grid.Column="1" Height="22"></TextBox>
<TextBox x:Name="txt_OutputFilename" Grid.Row="1" Grid.Column="1" Height="22" TextChanged="txt_OutputFilename_TextChanged" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
<TextBox x:Name="txt_OutputDirectory" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="left" Text="ISO" />
<TextBox x:Name="txt_OutputDirectory" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="left" TextChanged="txt_OutputDirectory_TextChanged" />
<Button x:Name="btn_OutputDirectoryBrowse" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="btn_OutputDirectoryBrowse_Click"/>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
<ComboBox x:Name="cmb_DriveLetter" Grid.Row="3" Grid.Column="1" Height="22" Width="397" HorizontalAlignment="left" SelectionChanged="cmb_DriveLetter_SelectionChanged"/>
<ComboBox x:Name="cmb_DriveLetter" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveLetter_SelectionChanged" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
<ComboBox x:Name="cmb_DriveSpeed" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveSpeed_SelectionChanged"/>
<ComboBox x:Name="cmb_DriveSpeed" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveSpeed_SelectionChanged" />
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Custom Parameters</Label>
<TextBox x:Name="txt_CustomParameters" Grid.Row="5" Grid.Column="1" Height="22" Width="397" HorizontalAlignment="left" IsEnabled="False" />
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Parameters</Label>
<TextBox x:Name="txt_Parameters" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" IsEnabled="False" />
</Grid>
<Grid Grid.Row="2" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
@@ -73,6 +86,7 @@
<Button x:Name="btn_StartStop" Grid.Row="0" Grid.Column="0" Height="22" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Start Dumping" Click="btn_StartStop_Click" IsEnabled="False" />
<Button x:Name="btn_Search" Grid.Row="0" Grid.Column="1" Height="22" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks" Click="btn_Search_Click" />
<CheckBox x:Name="chk_EjectWhenDone" Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Eject When Done" IsChecked="False" />
</Grid>
<Grid Grid.Row="3" Grid.Column="0" Margin="15,20.2,15.2,9.8" Grid.ColumnSpan="2">

View File

@@ -1,37 +1,39 @@
using System;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using WinForms = System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
public partial class MainWindow : Window
{
// Private paths
private string defaultOutputPath;
private string dicPath;
private string psxtPath;
private string sgRawPath;
// Private UI-related variables
private List<Tuple<char, string>> _drives { get; set; }
private List<KeyValuePair<char, string>> _drives { get; set; }
private MediaType? _currentMediaType { get; set; }
private List<int> _driveSpeeds { get { return new List<int> { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 }; } }
private List<Tuple<string, KnownSystem?, DiscType?>> _systems { get; set; }
private Process childProcess { get; set; }
private Window childWindow { get; set; }
private List<KeyValuePair<string, KnownSystem?>> _systems { get; set; }
private List<MediaType?> _mediaTypes { get; set; }
private DumpEnvironment _env;
// Option related
private Options _options;
private OptionsWindow _optionsWindow;
public MainWindow()
{
InitializeComponent();
// Get all settings
GetSettings();
// Initializes and load Options object
_options = new Options();
_options.Load();
// Populate the list of systems
PopulateSystems();
@@ -48,13 +50,19 @@ namespace DICUI
private void btn_StartStop_Click(object sender, RoutedEventArgs e)
{
// Dump or stop the dump
if ((string)btn_StartStop.Content == UIElements.StartDumping)
{
StartDumping();
}
else if ((string)btn_StartStop.Content == UIElements.StopDumping)
{
CancelDumping();
Tasks.CancelDumping(_env);
if (chk_EjectWhenDone.IsChecked == true)
{
Tasks.EjectDisc(_env);
}
}
}
@@ -67,18 +75,29 @@ namespace DICUI
private void btn_Search_Click(object sender, RoutedEventArgs e)
{
PopulateDrives();
SetCurrentDiscType();
SetSupportedDriveSpeed();
EnsureDiscInformation();
}
private void cmb_DiscType_SelectionChanged(object sender, SelectionChangedEventArgs e)
private void cmb_SystemType_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
PopulateMediaTypeAccordingToChosenSystem();
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_MediaType_SelectionChanged(object sencder, SelectionChangedEventArgs e)
{
// TODO: This is giving people the benefit of the doubt that their change is valid
_currentMediaType = cmb_MediaType.SelectedItem as MediaType?;
GetOutputNames();
EnsureDiscInformation();
}
private void cmb_DriveLetter_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetCurrentDiscType();
SetSupportedDriveSpeed();
GetOutputNames();
EnsureDiscInformation();
@@ -89,42 +108,72 @@ namespace DICUI
EnsureDiscInformation();
}
private void tbr_Properties_Click(object sender, RoutedEventArgs e)
private void tbr_Options_Click(object sender, RoutedEventArgs e)
{
ShowSettings();
// lazy initialization
if (_optionsWindow == null)
{
_optionsWindow = new OptionsWindow(_options);
_optionsWindow.Closed += delegate
{
_optionsWindow = null;
};
}
_optionsWindow.Owner = this;
_optionsWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_optionsWindow.Refresh();
_optionsWindow.Show();
}
private void tbr_Properties_CanExecute(object sender, System.Windows.Input.CanExecuteRoutedEventArgs e)
private void txt_OutputFilename_TextChanged(object sender, TextChangedEventArgs e)
{
e.CanExecute = true;
EnsureDiscInformation();
}
private void btn_Settings_Accept_Click(object sender, RoutedEventArgs e)
private void txt_OutputDirectory_TextChanged(object sender, TextChangedEventArgs e)
{
SaveSettings();
childWindow.Close();
GetSettings();
}
private void btn_Settings_Cancel_Click(object sender, RoutedEventArgs e)
{
childWindow.Close();
EnsureDiscInformation();
}
#endregion
#region Helpers
/// <summary>
/// Populate disc type according to system type
/// </summary>
private void PopulateMediaTypeAccordingToChosenSystem()
{
var currentSystem = cmb_SystemType.SelectedItem as KeyValuePair<string, KnownSystem?>?;
if (currentSystem != null)
{
_mediaTypes = Validators.GetValidMediaTypes(currentSystem?.Value).ToList();
cmb_MediaType.ItemsSource = _mediaTypes;
cmb_MediaType.IsEnabled = _mediaTypes.Count > 1;
cmb_MediaType.SelectedIndex = 0;
}
else
{
cmb_MediaType.IsEnabled = false;
cmb_MediaType.ItemsSource = null;
cmb_MediaType.SelectedIndex = -1;
}
}
/// <summary>
/// Get a complete list of supported systems and fill the combo box
/// </summary>
private void PopulateSystems()
{
_systems = Utilities.CreateListOfSystems();
cmb_DiscType.ItemsSource = _systems;
cmb_DiscType.DisplayMemberPath = "Item1";
cmb_DiscType.SelectedIndex = 0;
cmb_DiscType_SelectionChanged(null, null);
_systems = Validators.CreateListOfSystems()
.Select(i => new KeyValuePair<string, KnownSystem?>(i.Key, i.Value))
.ToList();
cmb_SystemType.ItemsSource = _systems;
cmb_SystemType.DisplayMemberPath = "Key";
cmb_SystemType.SelectedIndex = 0;
btn_StartStop.IsEnabled = false;
}
@@ -136,19 +185,21 @@ namespace DICUI
private void PopulateDrives()
{
// Populate the list of drives and add it to the combo box
_drives = Utilities.CreateListOfDrives();
_drives = Validators.CreateListOfDrives()
.Select(i => new KeyValuePair<char, string>(i.Key, i.Value))
.ToList();
cmb_DriveLetter.ItemsSource = _drives;
cmb_DriveLetter.DisplayMemberPath = "Item1";
cmb_DriveLetter.SelectedIndex = 0;
cmb_DriveLetter_SelectionChanged(null, null);
cmb_DriveLetter.DisplayMemberPath = "Key";
if (cmb_DriveLetter.Items.Count > 0)
{
cmb_DriveLetter.SelectedIndex = 0;
lbl_Status.Content = "Valid optical disc found! Choose your Disc Type";
btn_StartStop.IsEnabled = true;
}
else
{
cmb_DriveLetter.SelectedIndex = -1;
lbl_Status.Content = "No valid optical disc found!";
btn_StartStop.IsEnabled = false;
}
@@ -177,161 +228,54 @@ namespace DICUI
}
}
/// <summary>
/// Create a DumpEnvironment with all current settings
/// </summary>
/// <returns>Filled DumpEnvironment instance</returns>
private DumpEnvironment DetermineEnvironment()
{
// Populate all KVPs
var driveKvp = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
var systemKvp = cmb_SystemType.SelectedValue as KeyValuePair<string, KnownSystem?>?;
return new DumpEnvironment()
{
// Paths to tools
SubdumpPath = _options.subdumpPath,
DICPath = _options.dicPath,
OutputDirectory = txt_OutputDirectory.Text,
OutputFilename = txt_OutputFilename.Text,
// Get the currently selected options
DriveLetter = (char)driveKvp?.Key,
IsFloppy = (driveKvp?.Value == UIElements.FloppyDriveString),
DICParameters = txt_Parameters.Text,
System = systemKvp?.Value,
Type = cmb_MediaType.SelectedItem as MediaType?
};
}
/// <summary>
/// Begin the dumping process using the given inputs
/// </summary>
private async void StartDumping()
{
// Local variables
string driveLetter = cmb_DriveLetter.Text;
string outputDirectory = txt_OutputDirectory.Text;
string outputFilename = txt_OutputFilename.Text;
_env = DetermineEnvironment();
btn_StartStop.Content = UIElements.StopDumping;
// Get the currently selected item
var selected = cmb_DiscType.SelectedValue as Tuple<string, KnownSystem?, DiscType?>;
// Validate that everything is good
if (string.IsNullOrWhiteSpace(txt_CustomParameters.Text)
|| !Utilities.ValidateParameters(txt_CustomParameters.Text))
{
lbl_Status.Content = "Error! Current configuration is not supported!";
btn_StartStop.Content = UIElements.StartDumping;
return;
}
// Validate that the required program exits
if (!File.Exists(dicPath))
{
lbl_Status.Content = "Error! Could not find DiscImageCreator!";
btn_StartStop.Content = UIElements.StartDumping;
return;
}
// If a complete dump already exists
if (Utilities.FoundAllFiles(outputDirectory, outputFilename, selected.Item3))
{
MessageBoxResult result = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
{
lbl_Status.Content = "Dumping aborted!";
btn_StartStop.Content = UIElements.StartDumping;
return;
}
}
lbl_Status.Content = "Beginning dumping process";
string parameters = txt_CustomParameters.Text;
await Task.Run(
() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = dicPath,
Arguments = parameters,
},
};
childProcess.Start();
childProcess.WaitForExit();
});
// Special cases
switch (selected.Item2)
{
case KnownSystem.MicrosoftXBOXOne:
case KnownSystem.SonyPlayStation4:
if (!File.Exists(sgRawPath))
{
lbl_Status.Content = "Error! Could not find sg-raw!";
break;
}
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = sgRawPath,
Arguments = "-v -r 4100 -R " + driveLetter + ": " + "ad 01 00 00 00 00 00 00 10 04 00 00 -o \"PIC.bin\""
},
};
childProcess.Start();
childProcess.WaitForExit();
break;
case KnownSystem.SonyPlayStation:
if (!File.Exists(psxtPath))
{
lbl_Status.Content = "Error! Could not find psxt001z!";
break;
}
// Invoke the program with all 3 configurations
// TODO: Use these outputs for PSX information
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = psxtPath,
Arguments = "\"" + Utilities.GetFirstTrack(outputDirectory, outputFilename) + "\" > " + "\"" + Path.Combine(outputDirectory, "psxt001z.txt"),
},
};
childProcess.Start();
childProcess.WaitForExit();
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = psxtPath,
Arguments = "--libcrypt " + "\"" + Path.Combine(outputDirectory, outputFilename + ".sub") + "\" > " + "\"" + Path.Combine(outputDirectory, "libcrypt.txt"),
},
};
childProcess.Start();
childProcess.WaitForExit();
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = psxtPath,
Arguments = "--libcryptdrvfast " + driveLetter + " > " + "\"" + Path.Combine(outputDirectory, "libcryptdrv.log"),
},
};
childProcess.Start();
childProcess.WaitForExit();
break;
}
// Check to make sure that the output had all the correct files
if (!Utilities.FoundAllFiles(outputDirectory, outputFilename, selected.Item3))
{
lbl_Status.Content = "Error! Please check output directory as dump may be incomplete!";
btn_StartStop.Content = UIElements.StartDumping;
return;
}
lbl_Status.Content = "Dumping complete!";
Dictionary<string, string> templateValues = Utilities.ExtractOutputInformation(outputDirectory, outputFilename, selected.Item2, selected.Item3);
List<string> formattedValues = Utilities.FormatOutputData(templateValues, selected.Item2, selected.Item3);
bool success = Utilities.WriteOutputData(outputDirectory, outputFilename, formattedValues);
var task = Tasks.StartDumping(_env);
Result result = await task;
lbl_Status.Content = result ? "Dumping complete!" : result.message;
btn_StartStop.Content = UIElements.StartDumping;
}
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
private void CancelDumping()
{
try
{
childProcess.Kill();
}
catch
{ }
if (chk_EjectWhenDone.IsChecked == true)
Tasks.EjectDisc(_env);
}
/// <summary>
@@ -339,101 +283,154 @@ namespace DICUI
/// </summary>
private void EnsureDiscInformation()
{
// If we're on a separator, go to the next item
var tuple = cmb_DiscType.SelectedItem as Tuple<string, KnownSystem?, DiscType?>;
if (tuple.Item2 == null && tuple.Item3 == null)
var systemKvp = cmb_SystemType.SelectedItem as KeyValuePair<string, KnownSystem?>?;
// If we're on a separator, go to the next item and return
if (systemKvp?.Value == null)
{
cmb_DiscType.SelectedIndex++;
tuple = cmb_DiscType.SelectedItem as Tuple<string, KnownSystem?, DiscType?>;
cmb_SystemType.SelectedIndex++;
return;
}
// If we're on an unsupported type, update the status accordingly
switch (tuple.Item3)
{
case DiscType.NONE:
lbl_Status.Content = "Please select a valid disc type";
btn_StartStop.IsEnabled = false;
break;
case DiscType.GameCubeGameDisc:
case DiscType.GDROM:
lbl_Status.Content = string.Format("{0} discs are partially supported by DIC", Utilities.DiscTypeToString(tuple.Item3));
btn_StartStop.IsEnabled = true;
break;
case DiscType.HDDVD:
case DiscType.UMD:
lbl_Status.Content = string.Format("{0} discs are not currently supported by DIC", Utilities.DiscTypeToString(tuple.Item3));
btn_StartStop.IsEnabled = true;
break;
default:
lbl_Status.Content = string.Format("{0} ready to dump", Utilities.DiscTypeToString(tuple.Item3));
btn_StartStop.IsEnabled = true;
break;
}
// Get the selected system info
var selectedSystem = systemKvp?.Value;
MediaType? selectedMediaType = cmb_MediaType.SelectedItem as MediaType? ?? MediaType.NONE;
Result result = GetSupportStatus(selectedSystem, selectedMediaType);
lbl_Status.Content = result.message;
btn_StartStop.IsEnabled = result && (_drives.Count > 0 ? true : false);
// If we're in a type that doesn't support drive speeds
switch (tuple.Item3)
{
case DiscType.BD25:
case DiscType.BD50:
cmb_DriveSpeed.IsEnabled = false;
break;
default:
cmb_DriveSpeed.IsEnabled = true;
break;
}
cmb_DriveSpeed.IsEnabled = selectedMediaType.DoesSupportDriveSpeed() && selectedSystem.DoesSupportDriveSpeed();
// Special case for Custom input
if (tuple.Item1 == "Custom Input" && tuple.Item2 == KnownSystem.NONE && tuple.Item3 == DiscType.NONE)
if (selectedSystem == KnownSystem.Custom)
{
txt_CustomParameters.IsEnabled = true;
txt_Parameters.IsEnabled = true;
txt_OutputFilename.IsEnabled = false;
txt_OutputDirectory.IsEnabled = false;
btn_OutputDirectoryBrowse.IsEnabled = false;
cmb_DriveLetter.IsEnabled = false;
cmb_DriveSpeed.IsEnabled = false;
btn_StartStop.IsEnabled = true;
btn_StartStop.IsEnabled = (_drives.Count > 0 ? true : false);
lbl_Status.Content = "User input mode";
}
else
{
txt_CustomParameters.IsEnabled = false;
txt_Parameters.IsEnabled = false;
txt_OutputFilename.IsEnabled = true;
txt_OutputDirectory.IsEnabled = true;
btn_OutputDirectoryBrowse.IsEnabled = true;
cmb_DriveLetter.IsEnabled = true;
cmb_DriveSpeed.IsEnabled = true;
// Populate with the correct params for inputs (if we're not on the default option)
if (cmb_DiscType.SelectedIndex > 0)
if (selectedSystem != KnownSystem.NONE && selectedMediaType != MediaType.NONE)
{
var selected = cmb_DiscType.SelectedValue as Tuple<string, KnownSystem?, DiscType?>;
string discType = Utilities.GetBaseCommand(selected.Item3);
List<string> defaultParams = Utilities.GetDefaultParameters(selected.Item2, selected.Item3);
txt_CustomParameters.Text = discType
+ " " + cmb_DriveLetter.Text
var driveletter = cmb_DriveLetter.SelectedValue as KeyValuePair<char, string>?;
// If drive letter is invalid, skip this
if (driveletter == null)
return;
string command = Converters.KnownSystemAndMediaTypeToBaseCommand(selectedSystem, selectedMediaType);
List<string> defaultParams = Converters.KnownSystemAndMediaTypeToParameters(selectedSystem, selectedMediaType);
txt_Parameters.Text = command
+ " " + driveletter?.Key
+ " \"" + Path.Combine(txt_OutputDirectory.Text, txt_OutputFilename.Text) + "\" "
+ (selected.Item3 != DiscType.BD25 && selected.Item3 != DiscType.BD50 ? (int)cmb_DriveSpeed.SelectedItem + " " : "")
+ (selectedMediaType != MediaType.Floppy
&& selectedMediaType != MediaType.BluRay
&& selectedSystem != KnownSystem.MicrosoftXBOX
&& selectedSystem != KnownSystem.MicrosoftXBOX360XDG2
&& selectedSystem != KnownSystem.MicrosoftXBOX360XDG3
? (int)cmb_DriveSpeed.SelectedItem + " " : "")
+ string.Join(" ", defaultParams);
}
}
}
/// <summary>
/// Verify that, given a system and a media type, they are correct
/// </summary>
private Result GetSupportStatus(KnownSystem? system, MediaType? type)
{
// No system chosen, update status
if (system == KnownSystem.NONE)
return Result.Failure("Please select a valid system");
// custom system chosen, then don't check anything
else if (system == KnownSystem.Custom)
return Result.Success("{0} ready to dump", type.Name());
// 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());
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:
if (system == KnownSystem.MicrosoftXBOX360XDG3)
{
return Result.Failure("{0} discs are not currently supported by DIC", type.Name());
}
else
{
// TODO: this code should adjust things in a method which is meant to verify values so maybe we can find a better fit
// Take care of the selected item
if (_currentMediaType != null && _currentMediaType != MediaType.NONE)
{
int index = _mediaTypes.IndexOf(_currentMediaType);
if (index != -1)
{
if (cmb_MediaType.SelectedIndex != index)
{
cmb_MediaType.SelectedIndex = index;
}
}
else
{
return Result.Success("Disc of type {0} found, but the current system does not support it!", type.Name());
}
}
}
break;
}
return Result.Success("{0} ready to dump", type.Name());
}
/// <summary>
/// Get the default output directory name from the currently selected drive
/// </summary>
private void GetOutputNames()
{
var driveTuple = cmb_DriveLetter.SelectedItem as Tuple<char, string>;
var discTuple = cmb_DiscType.SelectedItem as Tuple<string, KnownSystem?, DiscType?>;
var driveKvp = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
var systemKvp = cmb_SystemType.SelectedItem as KeyValuePair<string, KnownSystem?>?;
MediaType? mediaType = cmb_MediaType.SelectedItem as MediaType?;
if (driveTuple != null && discTuple != null)
if (driveKvp != null
&& !String.IsNullOrWhiteSpace(driveKvp?.Value)
&& driveKvp?.Value != UIElements.FloppyDriveString
&& systemKvp != null
&& mediaType != null)
{
txt_OutputDirectory.Text = Path.Combine(defaultOutputPath, driveTuple.Item2);
txt_OutputFilename.Text = driveTuple.Item2 + Utilities.GetDefaultExtension(discTuple.Item3);
txt_OutputDirectory.Text = Path.Combine(_options.defaultOutputPath, driveKvp?.Value);
txt_OutputFilename.Text = driveKvp?.Value + mediaType.Extension();
}
else
{
txt_OutputDirectory.Text = defaultOutputPath;
txt_OutputDirectory.Text = _options.defaultOutputPath;
txt_OutputFilename.Text = "disc.bin";
}
}
@@ -443,26 +440,33 @@ namespace DICUI
/// </summary>
private void SetSupportedDriveSpeed()
{
// Set generic drive speed just in case
cmb_DriveSpeed.SelectedItem = 8;
// Get the drive letter from the selected item
var selected = cmb_DriveLetter.SelectedItem as Tuple<char, string>;
if (selected == null)
var selected = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
if (selected == null || (selected?.Value == UIElements.FloppyDriveString))
{
return;
}
// Validate that the required program exits
if (!File.Exists(dicPath))
//Validators.GetDriveSpeed((char)selected?.Key);
//Validators.GetDriveSpeedEx((char)selected?.Key, MediaType.CD);
// Validate that the required program exists and it's not DICUI itself
if (!File.Exists(_options.dicPath) ||
Path.GetFullPath(_options.dicPath) == Path.GetFullPath(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName))
{
return;
}
char driveLetter = selected.Item1;
childProcess = new Process()
char driveLetter = (char)selected?.Key;
Process childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = dicPath,
Arguments = DICCommands.DriveSpeedCommand + " " + driveLetter,
FileName = _options.dicPath,
Arguments = DICCommands.DriveSpeed + " " + driveLetter,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
@@ -474,170 +478,50 @@ namespace DICUI
int index = output.IndexOf("ReadSpeedMaximum:");
string readspeed = Regex.Match(output.Substring(index), @"ReadSpeedMaximum: [0-9]+KB/sec \(([0-9]*)x\)").Groups[1].Value;
if (!Int32.TryParse(readspeed, out int speed))
if (!Int32.TryParse(readspeed, out int speed) || speed <= 0)
{
return;
}
cmb_DriveSpeed.SelectedValue = speed;
// If the value is in the list, we can set it immediately
if (_driveSpeeds.Contains(speed))
cmb_DriveSpeed.SelectedValue = speed;
// Otherwise, we need to set the next lowest value
else
cmb_DriveSpeed.SelectedValue = _driveSpeeds.Where(s => s < speed).Last();
}
/// <summary>
/// Show all user-configurable settings in a new window
/// Set the current disc type in the combo box
/// </summary>
private void ShowSettings()
private void SetCurrentDiscType()
{
// Create the child window for settings
childWindow = new Window()
{
ShowInTaskbar = false,
Owner = Application.Current.MainWindow,
Width = 500,
Height = 250,
ResizeMode = ResizeMode.NoResize,
};
// Create the new Grid-based window
var grid = new Grid
{
Margin = new Thickness(5),
HorizontalAlignment = HorizontalAlignment.Stretch,
VerticalAlignment = VerticalAlignment.Stretch,
};
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = (GridLength)(new GridLengthConverter().ConvertFromString(String.Format("{0:n1}*", 1.2))) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = (GridLength)(new GridLengthConverter().ConvertFromString(String.Format("{0:n1}*", 2.5))) });
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
// Create all of the individual items in the panel
Label dicPathLabel = new Label();
dicPathLabel.Content = "DiscImageCreator Path:";
dicPathLabel.FontWeight = (FontWeight)(new FontWeightConverter().ConvertFromString("Bold"));
dicPathLabel.VerticalAlignment = VerticalAlignment.Center;
dicPathLabel.HorizontalAlignment = HorizontalAlignment.Right;
Grid.SetRow(dicPathLabel, 0);
Grid.SetColumn(dicPathLabel, 0);
TextBox dicPathSetting = new TextBox();
dicPathSetting.Text = ConfigurationManager.AppSettings["dicPath"];
dicPathSetting.VerticalAlignment = VerticalAlignment.Center;
dicPathSetting.HorizontalAlignment = HorizontalAlignment.Stretch;
Grid.SetRow(dicPathSetting, 0);
Grid.SetColumn(dicPathSetting, 1);
Label psxt001zPathLabel = new Label();
psxt001zPathLabel.Content = "psxt001z Path:";
psxt001zPathLabel.FontWeight = (FontWeight)(new FontWeightConverter().ConvertFromString("Bold"));
psxt001zPathLabel.VerticalAlignment = VerticalAlignment.Center;
psxt001zPathLabel.HorizontalAlignment = HorizontalAlignment.Right;
Grid.SetRow(psxt001zPathLabel, 1);
Grid.SetColumn(psxt001zPathLabel, 0);
TextBox psxt001zPathSetting = new TextBox();
psxt001zPathSetting.Text = ConfigurationManager.AppSettings["psxt001zPath"];
psxt001zPathSetting.VerticalAlignment = VerticalAlignment.Center;
psxt001zPathSetting.HorizontalAlignment = HorizontalAlignment.Stretch;
Grid.SetRow(psxt001zPathSetting, 1);
Grid.SetColumn(psxt001zPathSetting, 1);
Label sgRawPathLabel = new Label();
sgRawPathLabel.Content = "sg-raw Path:";
sgRawPathLabel.FontWeight = (FontWeight)(new FontWeightConverter().ConvertFromString("Bold"));
sgRawPathLabel.VerticalAlignment = VerticalAlignment.Center;
sgRawPathLabel.HorizontalAlignment = HorizontalAlignment.Right;
Grid.SetRow(sgRawPathLabel, 2);
Grid.SetColumn(sgRawPathLabel, 0);
TextBox sgRawPathSetting = new TextBox();
sgRawPathSetting.Text = ConfigurationManager.AppSettings["sgRawPath"];
sgRawPathSetting.VerticalAlignment = VerticalAlignment.Center;
sgRawPathSetting.HorizontalAlignment = HorizontalAlignment.Stretch;
Grid.SetRow(sgRawPathSetting, 2);
Grid.SetColumn(sgRawPathSetting, 1);
Label defaultOutputPathLabel = new Label();
defaultOutputPathLabel.Content = "Default Output Path:";
defaultOutputPathLabel.FontWeight = (FontWeight)(new FontWeightConverter().ConvertFromString("Bold"));
defaultOutputPathLabel.VerticalAlignment = VerticalAlignment.Center;
defaultOutputPathLabel.HorizontalAlignment = HorizontalAlignment.Right;
Grid.SetRow(defaultOutputPathLabel, 3);
Grid.SetColumn(defaultOutputPathLabel, 0);
TextBox defaultOutputPathSetting = new TextBox();
defaultOutputPathSetting.Text = ConfigurationManager.AppSettings["defaultOutputPath"];
defaultOutputPathSetting.VerticalAlignment = VerticalAlignment.Center;
defaultOutputPathSetting.HorizontalAlignment = HorizontalAlignment.Stretch;
Grid.SetRow(defaultOutputPathSetting, 3);
Grid.SetColumn(defaultOutputPathSetting, 1);
Button acceptButton = new Button();
acceptButton.Name = "btn_Settings_Accept";
acceptButton.Content = "Accept";
acceptButton.Click += btn_Settings_Accept_Click;
Grid.SetRow(acceptButton, 4);
Grid.SetColumn(acceptButton, 0);
Button cancelButton = new Button();
cancelButton.Name = "btn_Settings_Cancel";
cancelButton.Content = "Cancel";
cancelButton.Click += btn_Settings_Cancel_Click;
Grid.SetRow(cancelButton, 4);
Grid.SetColumn(cancelButton, 1);
// Add all of the UI elements
grid.Children.Add(dicPathLabel);
grid.Children.Add(dicPathSetting);
grid.Children.Add(psxt001zPathLabel);
grid.Children.Add(psxt001zPathSetting);
grid.Children.Add(sgRawPathLabel);
grid.Children.Add(sgRawPathSetting);
grid.Children.Add(defaultOutputPathLabel);
grid.Children.Add(defaultOutputPathSetting);
grid.Children.Add(acceptButton);
grid.Children.Add(cancelButton);
// Now show the child window
childWindow.Content = grid;
childWindow.Show();
}
/// <summary>
/// Save settings from the child window, if possible
/// </summary>
private void SaveSettings()
{
// If the child window is disposed, we don't think about it
if (childWindow == null)
// Get the drive letter from the selected item
var selected = cmb_DriveLetter.SelectedItem as KeyValuePair<char, string>?;
if (selected == null || (selected?.Value == UIElements.FloppyDriveString))
{
return;
}
// Clear the old settings and set new ones
var configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
configFile.AppSettings.Settings.Remove("dicPath");
configFile.AppSettings.Settings.Add("dicPath", ((TextBox)(((Grid)childWindow.Content).Children[1])).Text);
configFile.AppSettings.Settings.Remove("psxt001zPath");
configFile.AppSettings.Settings.Add("psxt001zPath", ((TextBox)(((Grid)childWindow.Content).Children[3])).Text);
configFile.AppSettings.Settings.Remove("sgRawPath");
configFile.AppSettings.Settings.Add("sgRawPath", ((TextBox)(((Grid)childWindow.Content).Children[5])).Text);
configFile.AppSettings.Settings.Remove("defaultOutputPath");
configFile.AppSettings.Settings.Add("defaultOutputPath", ((TextBox)(((Grid)childWindow.Content).Children[7])).Text);
configFile.Save(ConfigurationSaveMode.Modified);
}
// Get the current optical disc type
_currentMediaType = Validators.GetDiscType(selected?.Key);
/// <summary>
/// Get settings from the configuration, if possible
/// </summary>
private void GetSettings()
{
dicPath = ConfigurationManager.AppSettings["dicPath"] ?? "Programs\\DiscImageCreator.exe";
psxtPath = ConfigurationManager.AppSettings["psxt001zPath"] ?? "psxt001z.exe";
sgRawPath = ConfigurationManager.AppSettings["sgRawPath"] ?? "sg_raw.exe";
defaultOutputPath = ConfigurationManager.AppSettings["defaultOutputPath"] ?? "ISO";
// If we have an invalid current type, we don't care and return
if (_currentMediaType == null || _currentMediaType == MediaType.NONE)
{
return;
}
// Now set the selected item, if possible
int index = _mediaTypes.FindIndex(kvp => kvp.Value == _currentMediaType);
if (index != -1)
{
cmb_MediaType.SelectedIndex = index;
}
else
{
lbl_Status.Content = $"Disc of type '{Converters.MediaTypeToString(_currentMediaType)}' found, but the current system does not support it!";
}
}
#endregion

50
Options.cs Normal file
View File

@@ -0,0 +1,50 @@
using System;
using System.Configuration;
using System.Reflection;
namespace DICUI
{
public class Options
{
public string defaultOutputPath { get; private set; }
public string dicPath { get; private set; }
public string subdumpPath { get; private set; }
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: reflection is used
Array.ForEach(
GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
p => {
configFile.AppSettings.Settings.Remove(p.Name);
configFile.AppSettings.Settings.Add(p.Name, p.GetValue(this) as string);
}
);
configFile.Save(ConfigurationSaveMode.Modified);
}
public void Load()
{
//TODO: hardcoded, we should find a better way
dicPath = ConfigurationManager.AppSettings["dicPath"] ?? @"Programs\DiscImageCreator.exe";
subdumpPath = ConfigurationManager.AppSettings["subdumpPath"] ?? "subdump.exe";
defaultOutputPath = ConfigurationManager.AppSettings["defaultOutputPath"] ?? "ISO";
}
//TODO: probably should be generic for non-string options
//TODO: using reflection for Set and Get is orthodox but it works, should be changed to a key,value map probably
public void Set(string key, string value)
{
GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).SetValue(this, value);
}
public string Get(string key)
{
return GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).GetValue(this) as string;
}
}
}

59
OptionsWindow.xaml Normal file
View File

@@ -0,0 +1,59 @@
<Window x:Class="DICUI.OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Options" Height="260" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<GroupBox Grid.Column="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Paths">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2.0*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DicImageCreator Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_dicPath" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_dicPath" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_subdumpPath" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_subdumpPath" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click"/>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_defaultOutputPath" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_defaultOutputPath" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click" />
</Grid>
</GroupBox>
<Grid Height="22" Grid.Row="1" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn_Accept" Grid.Row="0" Grid.Column="1" Height="22" Width="80" Content="Accept" Click="btn_Accept_Click" />
<Button x:Name="btn_Cancel" Grid.Row="0" Grid.Column="2" Height="22" Width="80" Content="Cancel" Click="btn_Cancel_Click" />
</Grid>
</Grid>
</Window>

115
OptionsWindow.xaml.cs Normal file
View File

@@ -0,0 +1,115 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
namespace DICUI
{
/// <summary>
/// Interaction logic for OptionsWindow.xaml
/// </summary>
public partial class OptionsWindow : Window
{
private readonly Options _options;
public OptionsWindow(Options options)
{
InitializeComponent();
_options = options;
}
private OpenFileDialog CreateOpenFileDialog()
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
dialog.Filter = "Executables (*.exe)|*.exe";
dialog.FilterIndex = 0;
dialog.RestoreDirectory = true;
return dialog;
}
private FolderBrowserDialog CreateFolderBrowserDialog()
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
return dialog;
}
private string[] PathSettings()
{
string[] pathSettings = { "defaultOutputPath", "dicPath", "subdumpPath" };
return pathSettings;
}
private TextBox TextBoxForPathSetting(string name)
{
return FindName("txt_" + name) as TextBox;
}
private void btn_BrowseForPath_Click(object sender, EventArgs e)
{
Button button = sender as Button;
// strips button prefix to obtain the setting name
string pathSettingName = button.Name.Substring("btn_".Length);
// TODO: hack for now, then we'll see
bool shouldBrowseForPath = pathSettingName == "defaultOutputPath";
CommonDialog dialog = shouldBrowseForPath ? (CommonDialog)CreateFolderBrowserDialog() : CreateOpenFileDialog();
using (dialog)
{
DialogResult result = dialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
string path;
bool exists;
if (shouldBrowseForPath)
{
path = (dialog as FolderBrowserDialog).SelectedPath;
exists = Directory.Exists(path);
}
else
{
path = (dialog as OpenFileDialog).FileName;
exists = File.Exists(path);
}
if (exists)
TextBoxForPathSetting(pathSettingName).Text = path;
else
{
System.Windows.MessageBox.Show(
"Specified path doesn't exists!",
"Error",
MessageBoxButton.OK,
MessageBoxImage.Error
);
}
}
}
}
private void btn_Accept_Click(object sender, EventArgs e)
{
Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
_options.Save();
Hide();
}
private void btn_Cancel_Click(object sender, EventArgs e)
{
// just hide the window and don't care
Hide();
}
public void Refresh()
{
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
}
}
}

106
README.md
View File

@@ -1,87 +1,41 @@
# DICUI
This is my current progress on my C# Disc Image Creator UI.
I am using Disc Image Creator, created by Sarami, and would like to thanks him for this great software.
DiscImageCreator UI in C#
You can get the latest code and released on his github right here:
https://github.com/saramibreak/DiscImageCreator
This is a community project, so if you have some time and knowledge to give, we'll be glad to add you to the contributor of this project :)
I'm a hobbyist programmer, so this code might not be optimal, feel free to make your recommendation / Pull request.
We are using DiscImageCreator (DIC), created by Sarami, and we would like to thanks him for his great software. The latest release of DIC can be found on [the GitHub page](https://github.com/saramibreak/DiscImageCreator)
I would like this project to be a community project, so if you have some time and knowledge to give, I'll be glad to add you to the contributor of this project :)
## System Requirements
--------------------------------------------------------------------------
Currently working on the project:
ReignStumble - Co-Lead Programmer
Even though this is written in C#, this program can only be used on Windows systems due to the base program, DiscImageCreator, being Windows-only.
darksabre76 - Co-Lead Programmer
- Windows 7 (newest version of Windows recommended)
- .NET Framework 4.6.1 Runtimes
- 128 MB of free RAM
- As much hard drive space as amount of discs you will be dumping (20+ GB recommended)
NHellFire - Contributer
Dizzzy - Concept/Ideas/Beta tester
--------------------------------------------------------------------------
2018-06-13
--------------------------------------------------------------------------
Version 1.04b released:
- Added subIntention reading
- Fixed extra extensions being appended
- Fixed internationalization error (number formatting)
- Fixed "Custom Input" not working
--------------------------------------------------------------------------
2018-06-13
--------------------------------------------------------------------------
Version 1.04a released:
- Fixed issue with empty trays
- Added settings dialog
--------------------------------------------------------------------------
2018-06-13
--------------------------------------------------------------------------
Version 1.04 released:
- Behind-the-scenes fixes and formatting
- Better checks for external programs
- Automatically changing disc information
- Custom parameters (and parameter validation)
- Automatic drive speed selection
- Automatic submission information creation
- Add ability to stop a dump from the UI
--------------------------------------------------------------------------
2018-06-08
--------------------------------------------------------------------------
Version 1.03 released:
- edccchk now run on all CD-Roms
- Discs unsupported by Windows are now regonized
- Extra \ when accepting default save has been removed.
--------------------------------------------------------------------------
2018-05-18
--------------------------------------------------------------------------
Version 1.02b released:
- Fixed XBOX One and PS4 Drive Speed issue. (1.02)
- Started implementing DiscImageCreator Path selection. (1.02)
- Conforming my naming for objects and variable. (1.02)
- Added missing DLL (1.02b)
--------------------------------------------------------------------------
2018-05-14
--------------------------------------------------------------------------
Version 1.01d released:
Ensure that your operating system is as up-to-date as possible, since some features may rely on those updates.
## Releases
Download the latest release here:
https://github.com/reignstumble/DICUI/releases
[https://github.com/reignstumble/DICUI/releases](https://github.com/reignstumble/DICUI/releases)
## Changelist
A list of all changes can now be found [here](https://github.com/reignstumble/DICUI/blob/master/CHANGELIST.md).
## Contributors
Here are the talented people who have contributed to the project so far:
**ReignStumble** - Project Lead / UI Design
**darksabre76** - Project Co-Lead / Backend Design
**Jakz** - Feature Contributor
**NHellFire** - Feature Contributor
**Dizzzy** - Concept/Ideas/Beta tester

291
Tasks.cs Normal file
View File

@@ -0,0 +1,291 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Generic success/failure result object, with optional message
/// </summary>
public class Result
{
private bool success;
public string message { get; private set; }
private Result(bool success, string message)
{
this.success = success;
this.message = message;
}
public static Result Success() => new Result(true, "");
public static Result Success(string message) => new Result(true, message);
public static Result Success(string message, params object[] args) => new Result(true, string.Format(message, args));
public static Result Failure(string message) => new Result(false, message);
public static Result Failure(string message, params object[] args) => new Result(false, string.Format(message, args));
public static implicit operator bool(Result result) => result.success;
}
/// <summary>
/// Represents the state of all settings to be used during dumping
/// </summary>
public class DumpEnvironment
{
// Tool paths
public string DICPath;
public string SubdumpPath;
// Output paths
public string OutputDirectory;
public string OutputFilename;
// UI information
public char DriveLetter;
public KnownSystem? System;
public MediaType? Type;
public bool IsFloppy;
public string DICParameters;
// External process information
public Process dicProcess;
/// <summary>
/// Checks if the configuration is valid
/// </summary>
/// <returns>True if the configuration is valid, false otherwise</returns>
public bool IsConfigurationValid()
{
return !((string.IsNullOrWhiteSpace(DICParameters)
|| !Validators.ValidateParameters(DICParameters)
|| (IsFloppy ^ Type == Data.MediaType.Floppy)));
}
/// <summary>
/// Adjust the current environment if we are given custom parameters
/// </summary>
public void AdjustForCustomConfiguration()
{
// If we have a custom configuration, we need to extract the best possible information from it
if (System == KnownSystem.Custom)
{
Validators.DetermineFlags(DICParameters, out Type, out System, out string letter, out string path);
DriveLetter = letter[0];
OutputDirectory = Path.GetDirectoryName(path);
OutputFilename = Path.GetFileName(path);
}
}
/// <summary>
/// Fix the output paths to remove characters that DiscImageCreator can't handle
/// </summary>
/// <remarks>
/// TODO: Investigate why the `&` replacement is needed
/// </remarks>
public void FixOutputPaths()
{
OutputDirectory = OutputDirectory.Replace('.', '_').Replace('&', '_');
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_')).Replace('.', '_', 0, OutputFilename.LastIndexOf('.')).ToString();
}
}
/// <summary>
/// Class containing dumping tasks
/// </summary>
public class Tasks
{
/// <summary>
/// Validate the current DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result ValidateEnvironment(DumpEnvironment env)
{
// Validate that everything is good
if (!env.IsConfigurationValid())
return Result.Failure("Error! Current configuration is not supported!");
env.AdjustForCustomConfiguration();
env.FixOutputPaths();
// Validate that the required program exists
if (!File.Exists(env.DICPath))
return Result.Failure("Error! Could not find DiscImageCreator!");
// If a complete dump already exists
if (DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type))
{
MessageBoxResult result = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
{
return Result.Failure("Dumping aborted!");
}
}
return Result.Success();
}
/// <summary>
/// Run DiscImageCreator with the given DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
public static void ExecuteDiskImageCreator(DumpEnvironment env)
{
env.dicProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.DICPath,
Arguments = env.DICParameters,
},
};
env.dicProcess.Start();
env.dicProcess.WaitForExit();
}
/// <summary>
/// Execute subdump for a (potential) Sega Saturn dump
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
public static async void ExecuteSubdump(DumpEnvironment env)
{
await Task.Run(() =>
{
Process childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.SubdumpPath,
Arguments = "-i " + env.DriveLetter + ": -f " + Path.Combine(env.OutputDirectory, Path.GetFileNameWithoutExtension(env.OutputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2",
},
};
childProcess.Start();
childProcess.WaitForExit();
});
}
/// <summary>
/// Run any additional tools given a DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result ExecuteAdditionalToolsAfterDIC(DumpEnvironment env)
{
// Special cases
switch (env.System)
{
case KnownSystem.SegaSaturn:
if (!File.Exists(env.SubdumpPath))
return Result.Failure("Error! Could not find subdump!");
ExecuteSubdump(env);
break;
}
return Result.Success();
}
/// <summary>
/// Verify that the current environment has a complete dump and create submission info is possible
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result VerifyAndSaveDumpOutput(DumpEnvironment env)
{
// Check to make sure that the output had all the correct files
if (!DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type))
return Result.Failure("Error! Please check output directory as dump may be incomplete!");
Dictionary<string, string> templateValues = DumpInformation.ExtractOutputInformation(env.OutputDirectory, env.OutputFilename, env.System, env.Type, env.DriveLetter);
List<string> formattedValues = DumpInformation.FormatOutputData(templateValues, env.System, env.Type);
bool success = DumpInformation.WriteOutputData(env.OutputDirectory, env.OutputFilename, formattedValues);
return Result.Success();
}
/// <summary>
/// Eject the disc using DIC
/// </summary>
public static async void EjectDisc(DumpEnvironment env)
{
// Validate that the required program exists
if (!File.Exists(env.DICPath))
return;
CancelDumping(env);
if (env.IsFloppy)
return;
Process childProcess;
await Task.Run(() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.DICPath,
Arguments = DICCommands.Eject + " " + env.DriveLetter,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit();
});
}
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
public static void CancelDumping(DumpEnvironment env)
{
try
{
if (env.dicProcess != null && !env.dicProcess.HasExited)
env.dicProcess.Kill();
}
catch
{ }
}
/// <summary>
/// This executes the complete dump workflow on a DumpEnvironment
/// </summary>
public static async Task<Result> StartDumping(DumpEnvironment env)
{
Result result = Tasks.ValidateEnvironment(env);
// is something is wrong in environment return
if (!result)
return result;
// execute DIC
await Task.Run(() => Tasks.ExecuteDiskImageCreator(env));
// execute additional tools
result = Tasks.ExecuteAdditionalToolsAfterDIC(env);
// is something is wrong with additional tools report and return
// TODO: don't return, just keep generating output from DIC
/*if (!result.Item1)
{
lbl_Status.Content = result.Item2;
btn_StartStop.Content = UIElements.StartDumping;
return;
}*/
// verify dump output and save it
result = Tasks.VerifyAndSaveDumpOutput(env);
return result;
}
}
}

File diff suppressed because it is too large Load Diff

601
Utilities/Converters.cs Normal file
View File

@@ -0,0 +1,601 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using IMAPI2;
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Extensions for MediaType? for easier calling
/// </summary>
public static class MediaTypeExtensions
{
public static string Name(this MediaType? type)
{
return Converters.MediaTypeToString(type);
}
public static string Extension(this MediaType? type)
{
return Converters.MediaTypeToExtension(type);
}
public static bool DoesSupportDriveSpeed(this MediaType? type)
{
return type != MediaType.BluRay && type != MediaType.Floppy;
}
}
/// <summary>
/// Extensions for KnownSystem? for easier calling
/// </summary>
public static class KnownSystemExtensions
{
public static bool DoesSupportDriveSpeed(this KnownSystem? system)
{
return system != KnownSystem.MicrosoftXBOX
&& system != KnownSystem.MicrosoftXBOX360XDG2
&& system != KnownSystem.MicrosoftXBOX360XDG3;
}
}
/// <summary>
/// Used to provide a converter to XAML files to render comboboxes with enum values
/// </summary>
public class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is MediaType?)
return ((MediaType?)value).Name();
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
public static class Converters
{
/// <summary>
/// Get the MediaType associated with a given base command
/// </summary>
/// <param name="baseCommand">String value to check</param>
/// <returns>MediaType if possible, null on error</returns>
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
public static MediaType? BaseCommmandToMediaType(string baseCommand)
{
switch (baseCommand)
{
case DICCommands.CompactDisc:
return MediaType.CD;
case DICCommands.GDROM:
case DICCommands.Swap:
return MediaType.GDROM;
case DICCommands.DigitalVideoDisc:
case DICCommands.XBOX:
return MediaType.DVD;
case DICCommands.BluRay:
return MediaType.BluRay;
// Non-optical
case DICCommands.Floppy:
return MediaType.Floppy;
default:
return null;
}
}
/// <summary>
/// Get the most common known system for a given MediaType
/// </summary>
/// <param name="baseCommand">String value to check</param>
/// <returns>KnownSystem if possible, null on error</returns>
public static KnownSystem? BaseCommandToKnownSystem(string baseCommand)
{
switch (baseCommand)
{
case DICCommands.CompactDisc:
case DICCommands.DigitalVideoDisc:
case DICCommands.Floppy:
return KnownSystem.IBMPCCompatible;
case DICCommands.GDROM:
case DICCommands.Swap:
return KnownSystem.SegaDreamcast;
case DICCommands.BluRay:
return KnownSystem.SonyPlayStation3;
case DICCommands.XBOX:
return KnownSystem.MicrosoftXBOX;
default:
return null;
}
}
/// <summary>
/// Convert IMAPI physical media type to a MediaType
/// </summary>
/// <param name="type">IMAPI_MEDIA_PHYSICAL_TYPE value to check</param>
/// <returns>MediaType if possible, null on error</returns>
public static MediaType? IMAPIDiskTypeToMediaType(IMAPI_MEDIA_PHYSICAL_TYPE type)
{
switch (type)
{
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
return MediaType.NONE;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
return MediaType.CD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER:
return MediaType.DVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDRAM:
return MediaType.HDDVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE:
return MediaType.BluRay;
default:
return null;
}
}
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string MediaTypeToExtension(MediaType? type)
{
switch (type)
{
case MediaType.CD:
case MediaType.GDROM:
case MediaType.Cartridge:
return ".bin";
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.WiiOpticalDisc:
case MediaType.UMD:
return ".iso";
case MediaType.LaserDisc:
case MediaType.GameCubeGameDisc:
return ".raw";
case MediaType.WiiUOpticalDisc:
return ".wud";
case MediaType.Floppy:
return ".img";
case MediaType.Cassette:
return ".wav";
case MediaType.NONE:
case MediaType.CED:
default:
return null;
}
}
/// <summary>
/// Get the string representation of the MediaType enum values
/// </summary>
/// <param name="type">MediaType value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string MediaTypeToString(MediaType? type)
{
switch (type)
{
case MediaType.CD:
return "CD-ROM";
case MediaType.DVD:
return "DVD";
case MediaType.GDROM:
return "GD-ROM";
case MediaType.HDDVD:
return "HD-DVD";
case MediaType.BluRay:
return "BluRay";
case MediaType.LaserDisc:
return "LaserDisc";
case MediaType.CED:
return "CED";
case MediaType.GameCubeGameDisc:
return "GameCube Game";
case MediaType.WiiOpticalDisc:
return "Wii Optical";
case MediaType.WiiUOpticalDisc:
return "Wii U Optical";
case MediaType.UMD:
return "UMD";
case MediaType.Cartridge:
return "Cartridge";
case MediaType.Cassette:
return "Cassette Tape";
case MediaType.Floppy:
return "Floppy Disk";
case MediaType.NONE:
default:
return "Unknown";
}
}
/// <summary>
/// Get the DIC command to be used for a given MediaType
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>String containing the command, null on error</returns>
public static string KnownSystemAndMediaTypeToBaseCommand(KnownSystem? sys, MediaType? type)
{
switch (type)
{
case MediaType.CD:
if (sys == KnownSystem.MicrosoftXBOX)
{
return DICCommands.XBOX;
}
return DICCommands.CompactDisc;
case MediaType.DVD:
if (sys == KnownSystem.MicrosoftXBOX
|| sys == KnownSystem.MicrosoftXBOX360XDG2
|| sys == KnownSystem.MicrosoftXBOX360XDG3)
{
return DICCommands.XBOX;
}
return DICCommands.DigitalVideoDisc;
case MediaType.GDROM:
return DICCommands.GDROM;
case MediaType.HDDVD:
return null;
case MediaType.BluRay:
return DICCommands.BluRay;
// Special Formats
case MediaType.GameCubeGameDisc:
return DICCommands.DigitalVideoDisc;
case MediaType.WiiOpticalDisc:
return null;
case MediaType.WiiUOpticalDisc:
return null;
case MediaType.UMD:
return null;
// Non-optical
case MediaType.Floppy:
return DICCommands.Floppy;
default:
return null;
}
}
/// <summary>
/// Get list of default parameters for a given system and disc type
/// </summary>
/// <param name="sys">KnownSystem value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns>List of strings representing the parameters</returns>
public static List<string> KnownSystemAndMediaTypeToParameters(KnownSystem? sys, MediaType? type)
{
// First check to see if the combination of system and MediaType is valid
var validTypes = Validators.GetValidMediaTypes(sys);
if (!validTypes.Contains(type))
{
return null;
}
// Now sort based on disc type
List<string> parameters = new List<string>();
switch (type)
{
case MediaType.CD:
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
switch (sys)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.IBMPCCompatible:
parameters.Add(DICFlags.NoFixSubQSecuROM);
parameters.Add(DICFlags.ScanFileProtect);
parameters.Add(DICFlags.ScanSectorProtect);
break;
case KnownSystem.NECPCEngineTurboGrafxCD:
parameters.Add(DICFlags.MCN);
break;
case KnownSystem.SonyPlayStation:
parameters.Add(DICFlags.ScanAntiMod);
parameters.Add(DICFlags.NoFixSubQLibCrypt);
break;
}
break;
case MediaType.DVD:
// Currently no defaults set
break;
case MediaType.GDROM:
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
break;
case MediaType.HDDVD:
break;
case MediaType.BluRay:
// Currently no defaults set
break;
// Special Formats
case MediaType.GameCubeGameDisc:
parameters.Add(DICFlags.Raw);
break;
case MediaType.WiiOpticalDisc:
// Currently no defaults set
break;
case MediaType.WiiUOpticalDisc:
// Currently no defaults set
break;
case MediaType.UMD:
break;
// Non-optical
case MediaType.Floppy:
// Currently no defaults set
break;
}
return parameters;
}
/// <summary>
/// Get the string representation of the KnownSystem enum values
/// </summary>
/// <param name="sys">KnownSystem value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string KnownSystemToString(KnownSystem? sys)
{
switch (sys)
{
#region Consoles
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
return "Bandai Playdia Quick Interactive System";
case KnownSystem.BandaiApplePippin:
return "Bandai / Apple Pippin";
case KnownSystem.CommodoreAmigaCD32:
return "Commodore Amiga CD32";
case KnownSystem.CommodoreAmigaCDTV:
return "Commodore Amiga CDTV";
case KnownSystem.MattelHyperscan:
return "Mattel HyperScan";
case KnownSystem.MicrosoftXBOX:
return "Microsoft XBOX";
case KnownSystem.MicrosoftXBOX360XDG2:
return "Microsoft XBOX 360 (XDG2)";
case KnownSystem.MicrosoftXBOX360XDG3:
return "Microsoft XBOX 360 (XDG3)";
case KnownSystem.MicrosoftXBOXOne:
return "Microsoft XBOX One";
case KnownSystem.NECPCEngineTurboGrafxCD:
return "NEC PC-Engine / TurboGrafx CD";
case KnownSystem.NECPCFX:
return "NEC PC-FX / PC-FXGA";
case KnownSystem.NintendoGameCube:
return "Nintendo GameCube";
case KnownSystem.NintendoWii:
return "Nintendo Wii";
case KnownSystem.NintendoWiiU:
return "Nintendo Wii U";
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
return "Panasonic 3DO Interactive Multiplayer";
case KnownSystem.PhilipsCDi:
return "Philips CD-i";
case KnownSystem.SegaCDMegaCD:
return "Sega CD / Mega CD";
case KnownSystem.SegaDreamcast:
return "Sega Dreamcast";
case KnownSystem.SegaSaturn:
return "Sega Saturn";
case KnownSystem.SNKNeoGeoCD:
return "SNK Neo Geo CD";
case KnownSystem.SonyPlayStation:
return "Sony PlayStation";
case KnownSystem.SonyPlayStation2:
return "Sony PlayStation 2";
case KnownSystem.SonyPlayStation3:
return "Sony PlayStation 3";
case KnownSystem.SonyPlayStation4:
return "Sony PlayStation 4";
case KnownSystem.SonyPlayStationPortable:
return "Sony PlayStation Portable";
case KnownSystem.VMLabsNuon:
return "VM Labs NUON";
case KnownSystem.VTechVFlashVSmilePro:
return "VTech V.Flash - V.Smile Pro";
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
return "ZAPiT Games Game Wave Family Entertainment System";
#endregion
#region Computers
case KnownSystem.AcornArchimedes:
return "Acorn Archimedes";
case KnownSystem.AppleMacintosh:
return "Apple Macintosh";
case KnownSystem.CommodoreAmigaCD:
return "Commodore Amiga CD";
case KnownSystem.FujitsuFMTowns:
return "Fujitsu FM Towns series";
case KnownSystem.IBMPCCompatible:
return "IBM PC Compatible";
case KnownSystem.NECPC88:
return "NEC PC-88";
case KnownSystem.NECPC98:
return "NEC PC-98";
case KnownSystem.SharpX68000:
return "Sharp X68000";
#endregion
#region Arcade
case KnownSystem.AmigaCUBOCD32:
return "Amiga CUBO CD32";
case KnownSystem.AmericanLaserGames3DO:
return "American Laser Games 3DO";
case KnownSystem.Atari3DO:
return "Atari 3DO";
case KnownSystem.Atronic:
return "Atronic";
case KnownSystem.AUSCOMSystem1:
return "AUSCOM System 1";
case KnownSystem.BallyGameMagic:
return "Bally Game Magic";
case KnownSystem.CapcomCPSystemIII:
return "Capcom CP System III";
case KnownSystem.GlobalVRVarious:
return "Global VR PC-based Systems";
case KnownSystem.GlobalVRVortek:
return "Global VR Vortek";
case KnownSystem.GlobalVRVortekV3:
return "Global VR Vortek V3";
case KnownSystem.ICEPCHardware:
return "ICE PC-based Hardware";
case KnownSystem.IncredibleTechnologiesEagle:
return "Incredible Technologies Eagle";
case KnownSystem.IncredibleTechnologiesVarious:
return "Incredible Technologies PC-based Systems";
case KnownSystem.KonamiFirebeat:
return "Konami Firebeat";
case KnownSystem.KonamiGVSystem:
return "Konami GV System";
case KnownSystem.KonamiM2:
return "Konami M2";
case KnownSystem.KonamiPython:
return "Konami Python";
case KnownSystem.KonamiPython2:
return "Konami Python 2";
case KnownSystem.KonamiSystem573:
return "Konami System 573";
case KnownSystem.KonamiTwinkle:
return "Konami Twinkle";
case KnownSystem.KonamiVarious:
return "Konami PC-based Systems";
case KnownSystem.MeritIndustriesBoardwalk:
return "Merit Industries Boardwalk";
case KnownSystem.MeritIndustriesMegaTouchAurora:
return "Merit Industries MegaTouch Aurora";
case KnownSystem.MeritIndustriesMegaTouchForce:
return "Merit Industries MegaTouch Force";
case KnownSystem.MeritIndustriesMegaTouchION:
return "Merit Industries MegaTouch ION";
case KnownSystem.MeritIndustriesMegaTouchMaxx:
return "Merit Industries MegaTouch Maxx";
case KnownSystem.MeritIndustriesMegaTouchXL:
return "Merit Industries MegaTouch XL";
case KnownSystem.NamcoCapcomSystem256:
return "Namco / Capcom System 256/Super System 256";
case KnownSystem.NamcoCapcomTaitoSystem246:
return "Namco / Capcom / Taito System 246";
case KnownSystem.NamcoSegaNintendoTriforce:
return "Namco / Sega / Nintendo Triforce";
case KnownSystem.NamcoSystem12:
return "Namco System 12";
case KnownSystem.NamcoSystem357:
return "Namco System 357";
case KnownSystem.NewJatreCDi:
return "New Jatre CD-i";
case KnownSystem.NichibutsuHighRateSystem:
return "Nichibutsu High Rate System";
case KnownSystem.NichibutsuSuperCD:
return "Nichibutsu Super CD";
case KnownSystem.NichibutsuXRateSystem:
return "NichibutsuX-Rate System";
case KnownSystem.PhotoPlayVarious:
return "PhotoPlay PC-based Systems";
case KnownSystem.RawThrillsVarious:
return "Raw Thrills PC-based Systems";
case KnownSystem.SegaChihiro:
return "Sega Chihiro";
case KnownSystem.SegaEuropaR:
return "Sega Europa-R";
case KnownSystem.SegaLindbergh:
return "Sega Lindbergh";
case KnownSystem.SegaNaomi:
return "Sega Naomi";
case KnownSystem.SegaNaomi2:
return "Sega Naomi 2";
case KnownSystem.SegaNu:
return "Sega Nu";
case KnownSystem.SegaRingEdge:
return "Sega RingEdge";
case KnownSystem.SegaRingEdge2:
return "Sega RingEdge 2";
case KnownSystem.SegaRingWide:
return "Sega RingWide";
case KnownSystem.SegaSTV:
return "Sega STV";
case KnownSystem.SegaSystem32:
return "Sega System 32";
case KnownSystem.SeibuCATSSystem:
return "Seibu CATS System";
case KnownSystem.TABAustriaQuizard:
return "TAB-Austria Quizard";
case KnownSystem.TandyMemorexVisualInformationSystem:
return "Tandy / Memorex Visual Information System";
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
return "Tsunami TsuMo Multi-Game Motion System";
#endregion
#region Others
case KnownSystem.AudioCD:
return "Audio CD";
case KnownSystem.BDVideo:
return "BD-Video";
case KnownSystem.DVDVideo:
return "DVD-Video";
case KnownSystem.EnhancedCD:
return "Enhanced CD";
case KnownSystem.HDDVDVideo:
return "HD-DVD-Video";
case KnownSystem.PalmOS:
return "PalmOS";
case KnownSystem.PhilipsCDiDigitalVideo:
return "Philips CD-i Digital Video";
case KnownSystem.PhotoCD:
return "Photo CD";
case KnownSystem.PlayStationGameSharkUpdates:
return "PlayStation GameShark Updates";
case KnownSystem.TaoiKTV:
return "Tao iKTV";
case KnownSystem.TomyKissSite:
return "Tomy Kiss-Site";
case KnownSystem.VideoCD:
return "Video CD";
#endregion
case KnownSystem.Custom:
return "Custom Input";
case KnownSystem.NONE:
default:
return "Unknown";
}
}
}
}

1028
Utilities/DumpInformation.cs Normal file

File diff suppressed because it is too large Load Diff

1315
Utilities/Validators.cs Normal file

File diff suppressed because it is too large Load Diff

36
appveyor.yml Normal file
View File

@@ -0,0 +1,36 @@
# version format
version: 1.06_{build}
# vm template
image: Visual Studio 2017
# environment variables
environment:
EnableNuGetPackageRestore: true
# msbuild configuration
platform:
- AnyCPU
configuration:
- Debug
# install dependencies
install:
- ps: appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
# pre-build script
before_build:
- nuget restore
# build step
build:
verbosity: minimal
# post-build step
after_build:
- 7z a dicui_%APPVEYOR_BUILD_VERSION%.zip bin\Debug
# artifact linking
artifacts:
- path: dicui_$(version).zip
name: DICUI