├── .gitignore ├── Injector ├── App.config ├── Injector.Designer.cs ├── Injector.cs ├── Injector.csproj ├── Injector.resx ├── Program.cs ├── Project.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── injection.ico └── packages.config ├── ProjectFiles ├── Proof of concept.ijp ├── Stealth Patterns.ijp └── Wrecklamation.ijp ├── README.md ├── XMSerializer ├── ExtendedModule.cs ├── InjectorPlan.cs ├── Properties │ └── AssemblyInfo.cs ├── XMPixel.cs ├── XMReader.cs ├── XMTools.csproj ├── XMWriter.cs └── XmSerializer.cs ├── XMSerializerTest ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── XMSerializerTest.csproj └── test │ ├── 2 sample.xm │ ├── clap.wav │ ├── dupepatterns.ijp │ ├── patpack.xm │ ├── single sample.xm │ ├── test project.ijp │ ├── test-blank.xm │ └── test.xm └── XMTools.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /Injector/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Injector/Injector.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Injector 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 32 | this._btnLoadProject = new System.Windows.Forms.Button(); 33 | this._btnSaveProject = new System.Windows.Forms.Button(); 34 | this._btnNewProject = new System.Windows.Forms.Button(); 35 | this._btnImportXM = new System.Windows.Forms.Button(); 36 | this._lblXMTitle = new System.Windows.Forms.Label(); 37 | this._btnAddPlan = new System.Windows.Forms.Button(); 38 | this._dgvPlans = new System.Windows.Forms.DataGridView(); 39 | this.PlanName = new System.Windows.Forms.DataGridViewTextBoxColumn(); 40 | this.SongPosition = new System.Windows.Forms.DataGridViewTextBoxColumn(); 41 | this.DestinationLine = new System.Windows.Forms.DataGridViewTextBoxColumn(); 42 | this.LoopSize = new System.Windows.Forms.DataGridViewTextBoxColumn(); 43 | this.LoopLineInc = new System.Windows.Forms.DataGridViewTextBoxColumn(); 44 | this.FrameLineInc = new System.Windows.Forms.DataGridViewTextBoxColumn(); 45 | this.TotalFrames = new System.Windows.Forms.DataGridViewTextBoxColumn(); 46 | this.PatternHeight = new System.Windows.Forms.DataGridViewTextBoxColumn(); 47 | this.PixelMode = new System.Windows.Forms.DataGridViewTextBoxColumn(); 48 | this.PatternAllFrames = new System.Windows.Forms.DataGridViewTextBoxColumn(); 49 | this._btnDelPlan = new System.Windows.Forms.Button(); 50 | this._btnDelImage = new System.Windows.Forms.Button(); 51 | this._dgvImages = new System.Windows.Forms.DataGridView(); 52 | this.Image = new System.Windows.Forms.DataGridViewTextBoxColumn(); 53 | this.PatternHeightImage = new System.Windows.Forms.DataGridViewTextBoxColumn(); 54 | this._btnDumpTheFuck = new System.Windows.Forms.Button(); 55 | this._nudChannels = new System.Windows.Forms.NumericUpDown(); 56 | this._lblChannels = new System.Windows.Forms.Label(); 57 | this._btnPlayTheFuck = new System.Windows.Forms.Button(); 58 | this._lblSize = new System.Windows.Forms.Label(); 59 | this._pgbSize = new System.Windows.Forms.ProgressBar(); 60 | this._chkCentreSource = new System.Windows.Forms.CheckBox(); 61 | this._lblSongLength = new System.Windows.Forms.Label(); 62 | this._pgbLength = new System.Windows.Forms.ProgressBar(); 63 | this._btnDupe = new System.Windows.Forms.Button(); 64 | this._dgvStills = new System.Windows.Forms.DataGridView(); 65 | this.button1 = new System.Windows.Forms.Button(); 66 | this.button2 = new System.Windows.Forms.Button(); 67 | this.StillName = new System.Windows.Forms.DataGridViewTextBoxColumn(); 68 | this.StillSongPos = new System.Windows.Forms.DataGridViewTextBoxColumn(); 69 | this.StillPixelMode = new System.Windows.Forms.DataGridViewTextBoxColumn(); 70 | ((System.ComponentModel.ISupportInitialize)(this._dgvPlans)).BeginInit(); 71 | ((System.ComponentModel.ISupportInitialize)(this._dgvImages)).BeginInit(); 72 | ((System.ComponentModel.ISupportInitialize)(this._nudChannels)).BeginInit(); 73 | ((System.ComponentModel.ISupportInitialize)(this._dgvStills)).BeginInit(); 74 | this.SuspendLayout(); 75 | // 76 | // _btnLoadProject 77 | // 78 | this._btnLoadProject.Location = new System.Drawing.Point(116, 12); 79 | this._btnLoadProject.Name = "_btnLoadProject"; 80 | this._btnLoadProject.Size = new System.Drawing.Size(98, 23); 81 | this._btnLoadProject.TabIndex = 0; 82 | this._btnLoadProject.Text = "Load Project"; 83 | this._btnLoadProject.UseVisualStyleBackColor = true; 84 | this._btnLoadProject.Click += new System.EventHandler(this._btnLoadProject_Click); 85 | // 86 | // _btnSaveProject 87 | // 88 | this._btnSaveProject.Location = new System.Drawing.Point(220, 12); 89 | this._btnSaveProject.Name = "_btnSaveProject"; 90 | this._btnSaveProject.Size = new System.Drawing.Size(98, 23); 91 | this._btnSaveProject.TabIndex = 0; 92 | this._btnSaveProject.Text = "Save Project"; 93 | this._btnSaveProject.UseVisualStyleBackColor = true; 94 | this._btnSaveProject.Click += new System.EventHandler(this._btnSaveProject_Click); 95 | // 96 | // _btnNewProject 97 | // 98 | this._btnNewProject.Location = new System.Drawing.Point(12, 12); 99 | this._btnNewProject.Name = "_btnNewProject"; 100 | this._btnNewProject.Size = new System.Drawing.Size(98, 23); 101 | this._btnNewProject.TabIndex = 0; 102 | this._btnNewProject.Text = "New Project"; 103 | this._btnNewProject.UseVisualStyleBackColor = true; 104 | this._btnNewProject.Click += new System.EventHandler(this._btnNewProject_Click); 105 | // 106 | // _btnImportXM 107 | // 108 | this._btnImportXM.Location = new System.Drawing.Point(12, 57); 109 | this._btnImportXM.Name = "_btnImportXM"; 110 | this._btnImportXM.Size = new System.Drawing.Size(98, 23); 111 | this._btnImportXM.TabIndex = 0; 112 | this._btnImportXM.Text = "Import XM"; 113 | this._btnImportXM.UseVisualStyleBackColor = true; 114 | this._btnImportXM.Click += new System.EventHandler(this._btnImportXM_Click); 115 | // 116 | // _lblXMTitle 117 | // 118 | this._lblXMTitle.AutoSize = true; 119 | this._lblXMTitle.Location = new System.Drawing.Point(117, 62); 120 | this._lblXMTitle.Name = "_lblXMTitle"; 121 | this._lblXMTitle.Size = new System.Drawing.Size(90, 13); 122 | this._lblXMTitle.TabIndex = 1; 123 | this._lblXMTitle.Text = "Please Import XM"; 124 | // 125 | // _btnAddPlan 126 | // 127 | this._btnAddPlan.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 128 | this._btnAddPlan.Location = new System.Drawing.Point(916, 62); 129 | this._btnAddPlan.Name = "_btnAddPlan"; 130 | this._btnAddPlan.Size = new System.Drawing.Size(52, 23); 131 | this._btnAddPlan.TabIndex = 3; 132 | this._btnAddPlan.Text = "Add"; 133 | this._btnAddPlan.UseVisualStyleBackColor = true; 134 | this._btnAddPlan.Click += new System.EventHandler(this._btnAddPlan_Click); 135 | // 136 | // _dgvPlans 137 | // 138 | this._dgvPlans.AllowUserToAddRows = false; 139 | this._dgvPlans.AllowUserToDeleteRows = false; 140 | this._dgvPlans.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 141 | | System.Windows.Forms.AnchorStyles.Right))); 142 | this._dgvPlans.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 143 | this._dgvPlans.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 144 | this.PlanName, 145 | this.SongPosition, 146 | this.DestinationLine, 147 | this.LoopSize, 148 | this.LoopLineInc, 149 | this.FrameLineInc, 150 | this.TotalFrames, 151 | this.PatternHeight, 152 | this.PixelMode, 153 | this.PatternAllFrames}); 154 | this._dgvPlans.Location = new System.Drawing.Point(12, 91); 155 | this._dgvPlans.Name = "_dgvPlans"; 156 | this._dgvPlans.RowHeadersVisible = false; 157 | this._dgvPlans.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 158 | this._dgvPlans.Size = new System.Drawing.Size(956, 218); 159 | this._dgvPlans.TabIndex = 4; 160 | this._dgvPlans.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this._dgvPlans_CellClick); 161 | this._dgvPlans.SelectionChanged += new System.EventHandler(this._dgvPlans_SelectionChanged); 162 | // 163 | // PlanName 164 | // 165 | this.PlanName.DataPropertyName = "Name"; 166 | this.PlanName.HeaderText = "Name"; 167 | this.PlanName.Name = "PlanName"; 168 | this.PlanName.Width = 130; 169 | // 170 | // SongPosition 171 | // 172 | this.SongPosition.DataPropertyName = "SongPosition"; 173 | this.SongPosition.HeaderText = "SongPosition"; 174 | this.SongPosition.Name = "SongPosition"; 175 | this.SongPosition.Width = 80; 176 | // 177 | // DestinationLine 178 | // 179 | this.DestinationLine.DataPropertyName = "DestinationLine"; 180 | this.DestinationLine.HeaderText = "DestinationLine"; 181 | this.DestinationLine.Name = "DestinationLine"; 182 | // 183 | // LoopSize 184 | // 185 | this.LoopSize.DataPropertyName = "LoopSize"; 186 | this.LoopSize.HeaderText = "LoopSize"; 187 | this.LoopSize.Name = "LoopSize"; 188 | this.LoopSize.Width = 80; 189 | // 190 | // LoopLineInc 191 | // 192 | this.LoopLineInc.DataPropertyName = "LoopLineInc"; 193 | this.LoopLineInc.HeaderText = "LoopLineInc"; 194 | this.LoopLineInc.Name = "LoopLineInc"; 195 | // 196 | // FrameLineInc 197 | // 198 | this.FrameLineInc.DataPropertyName = "FrameLineInc"; 199 | this.FrameLineInc.HeaderText = "FrameLineInc"; 200 | this.FrameLineInc.Name = "FrameLineInc"; 201 | // 202 | // TotalFrames 203 | // 204 | this.TotalFrames.DataPropertyName = "TotalFrames"; 205 | this.TotalFrames.HeaderText = "TotalFrames"; 206 | this.TotalFrames.Name = "TotalFrames"; 207 | this.TotalFrames.Width = 80; 208 | // 209 | // PatternHeight 210 | // 211 | this.PatternHeight.DataPropertyName = "PatternHeight"; 212 | this.PatternHeight.HeaderText = "PatternHeight"; 213 | this.PatternHeight.Name = "PatternHeight"; 214 | this.PatternHeight.Width = 80; 215 | // 216 | // PixelMode 217 | // 218 | this.PixelMode.DataPropertyName = "PixelMode"; 219 | this.PixelMode.HeaderText = "PixelMode"; 220 | this.PixelMode.Name = "PixelMode"; 221 | // 222 | // PatternAllFrames 223 | // 224 | this.PatternAllFrames.DataPropertyName = "PatternAllFrames"; 225 | this.PatternAllFrames.HeaderText = "PatternAllFrames"; 226 | this.PatternAllFrames.Name = "PatternAllFrames"; 227 | // 228 | // _btnDelPlan 229 | // 230 | this._btnDelPlan.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 231 | this._btnDelPlan.Location = new System.Drawing.Point(858, 62); 232 | this._btnDelPlan.Name = "_btnDelPlan"; 233 | this._btnDelPlan.Size = new System.Drawing.Size(52, 23); 234 | this._btnDelPlan.TabIndex = 3; 235 | this._btnDelPlan.Text = "Del"; 236 | this._btnDelPlan.UseVisualStyleBackColor = true; 237 | this._btnDelPlan.Click += new System.EventHandler(this._btnDelPlan_Click); 238 | // 239 | // _btnDelImage 240 | // 241 | this._btnDelImage.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 242 | this._btnDelImage.Location = new System.Drawing.Point(1192, 12); 243 | this._btnDelImage.Name = "_btnDelImage"; 244 | this._btnDelImage.Size = new System.Drawing.Size(48, 23); 245 | this._btnDelImage.TabIndex = 3; 246 | this._btnDelImage.Text = "Del"; 247 | this._btnDelImage.UseVisualStyleBackColor = true; 248 | this._btnDelImage.Click += new System.EventHandler(this._btnDelImage_Click); 249 | // 250 | // _dgvImages 251 | // 252 | this._dgvImages.AllowDrop = true; 253 | this._dgvImages.AllowUserToAddRows = false; 254 | this._dgvImages.AllowUserToDeleteRows = false; 255 | this._dgvImages.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 256 | | System.Windows.Forms.AnchorStyles.Right))); 257 | this._dgvImages.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 258 | this._dgvImages.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 259 | this.Image, 260 | this.PatternHeightImage}); 261 | this._dgvImages.Location = new System.Drawing.Point(985, 41); 262 | this._dgvImages.Name = "_dgvImages"; 263 | this._dgvImages.RowHeadersVisible = false; 264 | this._dgvImages.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 265 | this._dgvImages.Size = new System.Drawing.Size(255, 455); 266 | this._dgvImages.TabIndex = 5; 267 | this._dgvImages.DragDrop += new System.Windows.Forms.DragEventHandler(this._dgvImages_DragDrop); 268 | this._dgvImages.DragEnter += new System.Windows.Forms.DragEventHandler(this._dgvImages_DragEnter); 269 | // 270 | // Image 271 | // 272 | this.Image.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill; 273 | this.Image.DataPropertyName = "FileName"; 274 | this.Image.HeaderText = "Image"; 275 | this.Image.Name = "Image"; 276 | this.Image.ReadOnly = true; 277 | // 278 | // PatternHeightImage 279 | // 280 | this.PatternHeightImage.DataPropertyName = "PatternHeight"; 281 | this.PatternHeightImage.HeaderText = "Height"; 282 | this.PatternHeightImage.Name = "PatternHeightImage"; 283 | // 284 | // _btnDumpTheFuck 285 | // 286 | this._btnDumpTheFuck.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 287 | this._btnDumpTheFuck.Location = new System.Drawing.Point(985, 502); 288 | this._btnDumpTheFuck.Name = "_btnDumpTheFuck"; 289 | this._btnDumpTheFuck.Size = new System.Drawing.Size(255, 60); 290 | this._btnDumpTheFuck.TabIndex = 6; 291 | this._btnDumpTheFuck.Text = "DUMP THE F**K!"; 292 | this._btnDumpTheFuck.UseVisualStyleBackColor = true; 293 | this._btnDumpTheFuck.Click += new System.EventHandler(this._btnDumpTheFuck_Click); 294 | // 295 | // _nudChannels 296 | // 297 | this._nudChannels.Increment = new decimal(new int[] { 298 | 2, 299 | 0, 300 | 0, 301 | 0}); 302 | this._nudChannels.Location = new System.Drawing.Point(423, 15); 303 | this._nudChannels.Maximum = new decimal(new int[] { 304 | 64, 305 | 0, 306 | 0, 307 | 0}); 308 | this._nudChannels.Name = "_nudChannels"; 309 | this._nudChannels.Size = new System.Drawing.Size(66, 20); 310 | this._nudChannels.TabIndex = 7; 311 | this._nudChannels.Value = new decimal(new int[] { 312 | 32, 313 | 0, 314 | 0, 315 | 0}); 316 | this._nudChannels.ValueChanged += new System.EventHandler(this._nudChannels_ValueChanged); 317 | // 318 | // _lblChannels 319 | // 320 | this._lblChannels.AutoSize = true; 321 | this._lblChannels.Location = new System.Drawing.Point(366, 17); 322 | this._lblChannels.Name = "_lblChannels"; 323 | this._lblChannels.Size = new System.Drawing.Size(51, 13); 324 | this._lblChannels.TabIndex = 8; 325 | this._lblChannels.Text = "Channels"; 326 | // 327 | // _btnPlayTheFuck 328 | // 329 | this._btnPlayTheFuck.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 330 | this._btnPlayTheFuck.Location = new System.Drawing.Point(713, 502); 331 | this._btnPlayTheFuck.Name = "_btnPlayTheFuck"; 332 | this._btnPlayTheFuck.Size = new System.Drawing.Size(255, 60); 333 | this._btnPlayTheFuck.TabIndex = 6; 334 | this._btnPlayTheFuck.Text = "PLAY THE F**K!"; 335 | this._btnPlayTheFuck.UseVisualStyleBackColor = true; 336 | this._btnPlayTheFuck.Click += new System.EventHandler(this._btnPlayTheFuck_Click); 337 | // 338 | // _lblSize 339 | // 340 | this._lblSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 341 | this._lblSize.AutoSize = true; 342 | this._lblSize.Location = new System.Drawing.Point(20, 506); 343 | this._lblSize.Name = "_lblSize"; 344 | this._lblSize.Size = new System.Drawing.Size(69, 13); 345 | this._lblSize.TabIndex = 9; 346 | this._lblSize.Text = "Actual Size ;)"; 347 | // 348 | // _pgbSize 349 | // 350 | this._pgbSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 351 | this._pgbSize.Location = new System.Drawing.Point(23, 522); 352 | this._pgbSize.Name = "_pgbSize"; 353 | this._pgbSize.Size = new System.Drawing.Size(133, 23); 354 | this._pgbSize.TabIndex = 10; 355 | // 356 | // _chkCentreSource 357 | // 358 | this._chkCentreSource.AutoSize = true; 359 | this._chkCentreSource.Location = new System.Drawing.Point(423, 41); 360 | this._chkCentreSource.Name = "_chkCentreSource"; 361 | this._chkCentreSource.Size = new System.Drawing.Size(132, 17); 362 | this._chkCentreSource.TabIndex = 11; 363 | this._chkCentreSource.Text = "Centre Source Module"; 364 | this._chkCentreSource.UseVisualStyleBackColor = true; 365 | this._chkCentreSource.CheckedChanged += new System.EventHandler(this._chkCentreSource_CheckedChanged); 366 | // 367 | // _lblSongLength 368 | // 369 | this._lblSongLength.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 370 | this._lblSongLength.AutoSize = true; 371 | this._lblSongLength.Location = new System.Drawing.Point(177, 506); 372 | this._lblSongLength.Name = "_lblSongLength"; 373 | this._lblSongLength.Size = new System.Drawing.Size(82, 13); 374 | this._lblSongLength.TabIndex = 12; 375 | this._lblSongLength.Text = "Actual Length ;)"; 376 | // 377 | // _pgbLength 378 | // 379 | this._pgbLength.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 380 | this._pgbLength.Location = new System.Drawing.Point(180, 522); 381 | this._pgbLength.Name = "_pgbLength"; 382 | this._pgbLength.Size = new System.Drawing.Size(133, 23); 383 | this._pgbLength.TabIndex = 13; 384 | // 385 | // _btnDupe 386 | // 387 | this._btnDupe.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 388 | this._btnDupe.Location = new System.Drawing.Point(800, 62); 389 | this._btnDupe.Name = "_btnDupe"; 390 | this._btnDupe.Size = new System.Drawing.Size(52, 23); 391 | this._btnDupe.TabIndex = 14; 392 | this._btnDupe.Text = "Dupe"; 393 | this._btnDupe.UseVisualStyleBackColor = true; 394 | this._btnDupe.Click += new System.EventHandler(this._btnDupe_Click); 395 | // 396 | // _dgvStills 397 | // 398 | this._dgvStills.AllowUserToAddRows = false; 399 | this._dgvStills.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; 400 | this._dgvStills.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { 401 | this.StillName, 402 | this.StillSongPos, 403 | this.StillPixelMode}); 404 | this._dgvStills.Location = new System.Drawing.Point(12, 313); 405 | this._dgvStills.Name = "_dgvStills"; 406 | this._dgvStills.RowHeadersVisible = false; 407 | this._dgvStills.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; 408 | this._dgvStills.Size = new System.Drawing.Size(956, 149); 409 | this._dgvStills.TabIndex = 15; 410 | this._dgvStills.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this._dgvStills_CellClick); 411 | this._dgvStills.SelectionChanged += new System.EventHandler(this._dgvStills_SelectionChanged); 412 | // 413 | // button1 414 | // 415 | this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 416 | this.button1.Location = new System.Drawing.Point(916, 468); 417 | this.button1.Name = "button1"; 418 | this.button1.Size = new System.Drawing.Size(52, 23); 419 | this.button1.TabIndex = 3; 420 | this.button1.Text = "Add"; 421 | this.button1.UseVisualStyleBackColor = true; 422 | this.button1.Click += new System.EventHandler(this._btnAddStill_Click); 423 | // 424 | // button2 425 | // 426 | this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 427 | this.button2.Location = new System.Drawing.Point(858, 468); 428 | this.button2.Name = "button2"; 429 | this.button2.Size = new System.Drawing.Size(52, 23); 430 | this.button2.TabIndex = 3; 431 | this.button2.Text = "Del"; 432 | this.button2.UseVisualStyleBackColor = true; 433 | this.button2.Click += new System.EventHandler(this._btnDelStill_Click); 434 | // 435 | // StillName 436 | // 437 | this.StillName.DataPropertyName = "Name"; 438 | this.StillName.HeaderText = "Name"; 439 | this.StillName.Name = "StillName"; 440 | this.StillName.Width = 150; 441 | // 442 | // StillSongPos 443 | // 444 | this.StillSongPos.DataPropertyName = "SongPosition"; 445 | this.StillSongPos.HeaderText = "Song Position"; 446 | this.StillSongPos.Name = "StillSongPos"; 447 | // 448 | // StillPixelMode 449 | // 450 | this.StillPixelMode.DataPropertyName = "PixelMode"; 451 | this.StillPixelMode.HeaderText = "PixelMode"; 452 | this.StillPixelMode.Name = "StillPixelMode"; 453 | // 454 | // Form1 455 | // 456 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 457 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 458 | this.ClientSize = new System.Drawing.Size(1252, 574); 459 | this.Controls.Add(this._dgvStills); 460 | this.Controls.Add(this._btnDupe); 461 | this.Controls.Add(this._pgbLength); 462 | this.Controls.Add(this._lblSongLength); 463 | this.Controls.Add(this._chkCentreSource); 464 | this.Controls.Add(this._pgbSize); 465 | this.Controls.Add(this._lblSize); 466 | this.Controls.Add(this._lblChannels); 467 | this.Controls.Add(this._nudChannels); 468 | this.Controls.Add(this._btnPlayTheFuck); 469 | this.Controls.Add(this._btnDumpTheFuck); 470 | this.Controls.Add(this._dgvImages); 471 | this.Controls.Add(this._dgvPlans); 472 | this.Controls.Add(this._btnDelImage); 473 | this.Controls.Add(this.button2); 474 | this.Controls.Add(this._btnDelPlan); 475 | this.Controls.Add(this.button1); 476 | this.Controls.Add(this._btnAddPlan); 477 | this.Controls.Add(this._lblXMTitle); 478 | this.Controls.Add(this._btnSaveProject); 479 | this.Controls.Add(this._btnImportXM); 480 | this.Controls.Add(this._btnNewProject); 481 | this.Controls.Add(this._btnLoadProject); 482 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 483 | this.Name = "Form1"; 484 | this.Text = "Injector"; 485 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); 486 | ((System.ComponentModel.ISupportInitialize)(this._dgvPlans)).EndInit(); 487 | ((System.ComponentModel.ISupportInitialize)(this._dgvImages)).EndInit(); 488 | ((System.ComponentModel.ISupportInitialize)(this._nudChannels)).EndInit(); 489 | ((System.ComponentModel.ISupportInitialize)(this._dgvStills)).EndInit(); 490 | this.ResumeLayout(false); 491 | this.PerformLayout(); 492 | 493 | } 494 | 495 | #endregion 496 | 497 | private System.Windows.Forms.Button _btnLoadProject; 498 | private System.Windows.Forms.Button _btnSaveProject; 499 | private System.Windows.Forms.Button _btnNewProject; 500 | private System.Windows.Forms.Button _btnImportXM; 501 | private System.Windows.Forms.Label _lblXMTitle; 502 | private System.Windows.Forms.Button _btnAddPlan; 503 | private System.Windows.Forms.DataGridView _dgvPlans; 504 | private System.Windows.Forms.Button _btnDelPlan; 505 | private System.Windows.Forms.Button _btnDelImage; 506 | private System.Windows.Forms.DataGridView _dgvImages; 507 | private System.Windows.Forms.Button _btnDumpTheFuck; 508 | private System.Windows.Forms.NumericUpDown _nudChannels; 509 | private System.Windows.Forms.Label _lblChannels; 510 | private System.Windows.Forms.Button _btnPlayTheFuck; 511 | private System.Windows.Forms.Label _lblSize; 512 | private System.Windows.Forms.ProgressBar _pgbSize; 513 | private System.Windows.Forms.CheckBox _chkCentreSource; 514 | private System.Windows.Forms.Label _lblSongLength; 515 | private System.Windows.Forms.ProgressBar _pgbLength; 516 | private System.Windows.Forms.Button _btnDupe; 517 | private System.Windows.Forms.DataGridViewTextBoxColumn Image; 518 | private System.Windows.Forms.DataGridViewTextBoxColumn PatternHeightImage; 519 | private System.Windows.Forms.DataGridViewTextBoxColumn PlanName; 520 | private System.Windows.Forms.DataGridViewTextBoxColumn SongPosition; 521 | private System.Windows.Forms.DataGridViewTextBoxColumn DestinationLine; 522 | private System.Windows.Forms.DataGridViewTextBoxColumn LoopSize; 523 | private System.Windows.Forms.DataGridViewTextBoxColumn LoopLineInc; 524 | private System.Windows.Forms.DataGridViewTextBoxColumn FrameLineInc; 525 | private System.Windows.Forms.DataGridViewTextBoxColumn TotalFrames; 526 | private System.Windows.Forms.DataGridViewTextBoxColumn PatternHeight; 527 | private System.Windows.Forms.DataGridViewTextBoxColumn PixelMode; 528 | private System.Windows.Forms.DataGridViewTextBoxColumn PatternAllFrames; 529 | private System.Windows.Forms.DataGridView _dgvStills; 530 | private System.Windows.Forms.Button button1; 531 | private System.Windows.Forms.Button button2; 532 | private System.Windows.Forms.DataGridViewTextBoxColumn StillName; 533 | private System.Windows.Forms.DataGridViewTextBoxColumn StillSongPos; 534 | private System.Windows.Forms.DataGridViewTextBoxColumn StillPixelMode; 535 | } 536 | } 537 | 538 | -------------------------------------------------------------------------------- /Injector/Injector.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Windows.Forms; 9 | using XMSerializer; 10 | 11 | namespace Injector 12 | { 13 | public partial class Form1 : Form 14 | { 15 | private Project _project; 16 | private XMSerializer.XMSerializer _ser; 17 | 18 | public Form1() 19 | { 20 | _project = new Project(); 21 | _ser = new XMSerializer.XMSerializer(); 22 | InitializeComponent(); 23 | } 24 | 25 | private void _btnNewProject_Click(object sender, EventArgs e) 26 | { 27 | if (AreYouSure()) 28 | { 29 | _project = new Project(); 30 | _project.XM = new ExtendedModule(); 31 | _project.XM.ModuleName = "Please Import XM"; 32 | RefreshData(); 33 | } 34 | } 35 | 36 | private bool AreYouSure() 37 | { 38 | if (MessageBox.Show("Are you sure?", "Generic input question", MessageBoxButtons.OKCancel) == DialogResult.OK) 39 | return true; 40 | 41 | return false; 42 | } 43 | 44 | private void _btnImportXM_Click(object sender, EventArgs e) 45 | { 46 | var ofd = new OpenFileDialog() 47 | { 48 | Filter = "Extended Module|*.xm" 49 | }; 50 | 51 | if (ofd.ShowDialog() == DialogResult.OK) 52 | { 53 | _project.SourceModule = File.ReadAllBytes(ofd.FileName); 54 | _project.ModuleFileName = Path.GetFileName(ofd.FileName); 55 | RefreshData(); 56 | } 57 | } 58 | 59 | private void RefreshData() 60 | { 61 | if (_project.SourceModule != null) 62 | _project.XM = _ser.DeSerialize(_project.SourceModule); 63 | 64 | var title = _project.XM.ModuleName.Replace("\0", "").Trim(); 65 | _lblXMTitle.Text = title == "" ? _project.ModuleFileName : title; 66 | _nudChannels.Value = _project.Channels; 67 | _chkCentreSource.Checked = _project.CentreSourceModule; 68 | 69 | var bl = new BindingList(_project.Plans); 70 | var src = new BindingSource(bl, null); 71 | _dgvPlans.AutoGenerateColumns = false; 72 | _dgvPlans.DataSource = src; 73 | 74 | var bl2 = new BindingList(_project.Stills); 75 | var src2 = new BindingSource(bl2, null); 76 | _dgvStills.AutoGenerateColumns = false; 77 | _dgvStills.DataSource = src2; 78 | } 79 | 80 | private void _btnSaveProject_Click(object sender, EventArgs e) 81 | { 82 | var sfd = new SaveFileDialog() 83 | { 84 | Filter = "Injector Project|*.ijp" 85 | }; 86 | 87 | if (sfd.ShowDialog() == DialogResult.OK) 88 | { 89 | var project = JsonConvert.SerializeObject(_project); 90 | File.WriteAllText(sfd.FileName, project); 91 | } 92 | } 93 | 94 | private void _btnLoadProject_Click(object sender, EventArgs e) 95 | { 96 | var ofd = new OpenFileDialog() 97 | { 98 | Filter = "Injector Project|*.ijp" 99 | }; 100 | 101 | if (ofd.ShowDialog() == DialogResult.OK) 102 | { 103 | var project = File.ReadAllText(ofd.FileName); 104 | _project = JsonConvert.DeserializeObject(project); 105 | RefreshData(); 106 | } 107 | } 108 | 109 | private void _btnAddPlan_Click(object sender, EventArgs e) 110 | { 111 | _project.Plans.Add(new InjectionPlan 112 | { 113 | Name = "New injection plan" 114 | }); 115 | RefreshData(); 116 | } 117 | 118 | private void _btnAddStill_Click(object sender, EventArgs e) 119 | { 120 | _project.Stills.Add(new InjectionStill 121 | { 122 | Name = "New injection stil" 123 | }); 124 | RefreshData(); 125 | } 126 | 127 | private void _btnDelPlan_Click(object sender, EventArgs e) 128 | { 129 | if (_dgvPlans.SelectedRows.Count > 0) 130 | { 131 | if (AreYouSure()) 132 | { 133 | List deletions = new List(); 134 | foreach (DataGridViewRow r in _dgvPlans.SelectedRows) 135 | { 136 | deletions.Add((InjectionPlan)r.DataBoundItem); 137 | } 138 | 139 | foreach (var d in deletions) 140 | { 141 | _project.Plans.RemoveAt(_project.Plans.IndexOf(d)); 142 | } 143 | 144 | RefreshData(); 145 | } 146 | } 147 | } 148 | 149 | private void _btnDelStill_Click(object sender, EventArgs e) 150 | { 151 | if (_dgvStills.SelectedRows.Count > 0) 152 | { 153 | if (AreYouSure()) 154 | { 155 | List deletions = new List(); 156 | foreach (DataGridViewRow r in _dgvStills.SelectedRows) 157 | { 158 | deletions.Add((InjectionStill)r.DataBoundItem); 159 | } 160 | 161 | foreach (var d in deletions) 162 | { 163 | _project.Stills.RemoveAt(_project.Stills.IndexOf(d)); 164 | } 165 | 166 | RefreshData(); 167 | } 168 | } 169 | } 170 | 171 | private void _btnDupe_Click(object sender, EventArgs e) 172 | { 173 | if (_dgvPlans.SelectedRows.Count > 0) 174 | { 175 | if (AreYouSure()) 176 | { 177 | List dupes = new List(); 178 | foreach (DataGridViewRow r in _dgvPlans.SelectedRows) 179 | { 180 | dupes.Add((InjectionPlan)r.DataBoundItem); 181 | } 182 | 183 | foreach (var d in dupes) 184 | { 185 | var p = new InjectionPlan() 186 | { 187 | DestinationLine = d.DestinationLine, 188 | Images = new List(), 189 | LoopLineInc = d.LoopLineInc, 190 | LoopSize = d.LoopSize, 191 | Name = d.Name + " copy", 192 | PatternHeight = d.PatternHeight, 193 | SongPosition = d.SongPosition, 194 | TotalFrames = d.TotalFrames, 195 | PixelMode = d.PixelMode, 196 | FrameLineInc = d.FrameLineInc, 197 | PatternAllFrames = d.PatternAllFrames 198 | }; 199 | 200 | foreach (var i in d.Images) 201 | { 202 | p.Images.Add(new InjectionImage() 203 | { 204 | FileName = i.FileName, 205 | Image = i.Image, 206 | PatternHeight = i.PatternHeight 207 | }); 208 | } 209 | 210 | _project.Plans.Add(p); 211 | } 212 | 213 | RefreshData(); 214 | } 215 | } 216 | } 217 | 218 | 219 | 220 | private void _dgvPlans_SelectionChanged(object sender, EventArgs e) 221 | { 222 | if (_dgvPlans.SelectedRows.Count == 0) 223 | return; 224 | 225 | var ijp = (InjectionPlan)_dgvPlans.SelectedRows[0].DataBoundItem; 226 | if (ijp == null) 227 | return; 228 | 229 | var bl = new BindingList(ijp.Images); 230 | var src = new BindingSource(bl, null); 231 | _dgvImages.AutoGenerateColumns = false; 232 | _dgvImages.DataSource = src; 233 | } 234 | 235 | private void _dgvStills_SelectionChanged(object sender, EventArgs e) 236 | { 237 | if (_dgvStills.SelectedRows.Count == 0) 238 | return; 239 | 240 | var ijp = (InjectionStill)_dgvStills.SelectedRows[0].DataBoundItem; 241 | if (ijp == null) 242 | return; 243 | 244 | var bl = new BindingList(ijp.Images); 245 | var src = new BindingSource(bl, null); 246 | _dgvImages.AutoGenerateColumns = false; 247 | _dgvImages.DataSource = src; 248 | } 249 | 250 | private void _dgvImages_DragDrop(object sender, DragEventArgs e) 251 | { 252 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 253 | { 254 | var files = ((string[])e.Data.GetData(DataFormats.FileDrop)).ToList(); 255 | files.Sort(); 256 | foreach (string filePath in files) 257 | { 258 | if (Path.GetExtension(filePath).ToUpper() == ".PNG") 259 | { 260 | var src = (BindingSource)_dgvImages.DataSource; 261 | if (src != null) 262 | { 263 | src.Add(new InjectionImage() 264 | { 265 | FileName = Path.GetFileNameWithoutExtension(filePath), 266 | Image = File.ReadAllBytes(filePath) 267 | }); 268 | } 269 | } 270 | } 271 | } 272 | } 273 | 274 | private void _dgvImages_DragEnter(object sender, DragEventArgs e) 275 | { 276 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 277 | e.Effect = DragDropEffects.Copy; 278 | else 279 | e.Effect = DragDropEffects.None; 280 | } 281 | 282 | private void _btnDelImage_Click(object sender, EventArgs e) 283 | { 284 | if (_dgvImages.SelectedRows.Count > 0) 285 | { 286 | if (AreYouSure()) 287 | { 288 | List deletions = new List(); 289 | foreach (DataGridViewRow r in _dgvImages.SelectedRows) 290 | { 291 | deletions.Add((InjectionImage)r.DataBoundItem); 292 | } 293 | 294 | foreach (var d in deletions) 295 | { 296 | var ijp = (InjectionPlan)_dgvPlans.SelectedRows[0].DataBoundItem; 297 | ijp.Images.RemoveAt(ijp.Images.IndexOf(d)); 298 | } 299 | 300 | RefreshData(); 301 | } 302 | } 303 | } 304 | 305 | private void _btnDumpTheFuck_Click(object sender, EventArgs e) 306 | { 307 | DoTheWork(); 308 | MessageBox.Show("M8 do you even compress?"); 309 | } 310 | 311 | private void _btnPlayTheFuck_Click(object sender, EventArgs e) 312 | { 313 | DoTheWork(); 314 | foreach (var p in Process.GetProcessesByName("XMPlay")) p.Kill(); 315 | Process.Start(@"XMPlay.exe", "output.xm"); 316 | } 317 | 318 | private void DoTheWork() 319 | { 320 | _project.XM = _ser.DeSerialize(_project.SourceModule); 321 | _project.XM.TrackerName = "Logicoma Rulez!"; 322 | var sourceChannels = _project.XM.ChannelCount; 323 | 324 | _project.XM.ResizeChannels(_project.Channels, _project.CentreSourceModule); 325 | 326 | // run the stills 327 | foreach (var s in _project.Stills) 328 | { 329 | _project.XM.RunInjectionStill(s); 330 | } 331 | 332 | // run the plans 333 | var plans = new List(); 334 | foreach (var p in _project.Plans) plans.Add(p); 335 | 336 | plans.Sort(delegate(InjectionPlan x, InjectionPlan y) 337 | { 338 | return y.SongPosition.CompareTo(x.SongPosition); 339 | }); 340 | 341 | InjectionPlan prevPlan = null; 342 | 343 | foreach (var plan in plans) 344 | { 345 | var followingDestinationLine = 0; 346 | 347 | if (prevPlan != null && prevPlan.SongPosition - 1 == plan.SongPosition) 348 | { 349 | followingDestinationLine = prevPlan.DestinationLine; 350 | } 351 | 352 | try 353 | { 354 | _project.XM.RunInjectionPlan(plan, sourceChannels, followingDestinationLine); 355 | } 356 | catch (Exception e) 357 | { 358 | MessageBox.Show(string.Format("Error with plan {0}: {1}", plan.Name, e.Message)); 359 | } 360 | prevPlan = plan; 361 | } 362 | 363 | _project.XM.CleanPatternOrderList(); 364 | _project.XM.RemoveDuplicatePatterns(); 365 | var modData = _ser.Serialize(_project.XM); 366 | 367 | var max = 2097152; 368 | if (modData.Length > max) 369 | { 370 | _lblSize.Text = "FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUK!"; 371 | _pgbSize.Maximum = max; 372 | _pgbSize.Value = max; 373 | } 374 | else 375 | { 376 | _lblSize.Text = string.Format("{0:n0} / {1:n0} bytes", modData.Length, max); 377 | _pgbSize.Maximum = max; 378 | _pgbSize.Value = modData.Length; 379 | } 380 | 381 | _lblSongLength.Text = string.Format("{0} / 256 positions", _project.XM.SongLength); 382 | _pgbLength.Maximum = 256; 383 | _pgbLength.Value = _project.XM.SongLength; 384 | 385 | File.WriteAllBytes("output.xm", modData); 386 | 387 | /* pattern debug export 388 | var patId = 0; 389 | foreach (var pat in _project.XM.Patterns) 390 | { 391 | File.WriteAllBytes(string.Format("C:\\Debug\\{0}.bin", patId), pat.UnpackedPatternData); 392 | patId++; 393 | } 394 | 395 | var list = ""; 396 | foreach (var patItemId in _project.XM.PatternOrderList) 397 | { 398 | list += patItemId.ToString() + "\n"; 399 | } 400 | File.WriteAllText("C:\\debug\\patorder.txt", list); 401 | */ 402 | } 403 | 404 | private void _nudChannels_ValueChanged(object sender, EventArgs e) 405 | { 406 | _project.Channels = (int)((NumericUpDown)sender).Value; 407 | } 408 | 409 | private void Form1_FormClosing(object sender, FormClosingEventArgs e) 410 | { 411 | foreach (var p in Process.GetProcessesByName("XMPlay")) p.Kill(); 412 | } 413 | 414 | private void _chkCentreSource_CheckedChanged(object sender, EventArgs e) 415 | { 416 | _project.CentreSourceModule = _chkCentreSource.Checked; 417 | } 418 | 419 | private void _dgvPlans_CellClick(object sender, DataGridViewCellEventArgs e) 420 | { 421 | _dgvPlans_SelectionChanged(null, null); 422 | } 423 | 424 | private void _dgvStills_CellClick(object sender, DataGridViewCellEventArgs e) 425 | { 426 | _dgvStills_SelectionChanged(null, null); 427 | } 428 | 429 | 430 | } 431 | } 432 | -------------------------------------------------------------------------------- /Injector/Injector.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5E87E2A0-02C7-4DB4-A444-A4AC2818F450} 8 | WinExe 9 | Properties 10 | Injector 11 | Injector 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | injection.ico 36 | 37 | 38 | 39 | ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll 40 | True 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Form 56 | 57 | 58 | Injector.cs 59 | 60 | 61 | 62 | 63 | 64 | Injector.cs 65 | 66 | 67 | ResXFileCodeGenerator 68 | Resources.Designer.cs 69 | Designer 70 | 71 | 72 | True 73 | Resources.resx 74 | 75 | 76 | 77 | SettingsSingleFileGenerator 78 | Settings.Designer.cs 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | {75eaf7ba-b71c-47db-addc-3ca80f337e73} 95 | XMTools 96 | 97 | 98 | 99 | 106 | -------------------------------------------------------------------------------- /Injector/Injector.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | True 125 | 126 | 127 | True 128 | 129 | 130 | True 131 | 132 | 133 | True 134 | 135 | 136 | True 137 | 138 | 139 | True 140 | 141 | 142 | True 143 | 144 | 145 | True 146 | 147 | 148 | True 149 | 150 | 151 | True 152 | 153 | 154 | True 155 | 156 | 157 | True 158 | 159 | 160 | True 161 | 162 | 163 | True 164 | 165 | 166 | 167 | 168 | AAABAAIAICAAAAEAIACoEAAAJgAAABAQAAABACAAaAQAAM4QAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQ 169 | AAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAABEAAAAVAAAADQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 170 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 171 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAJgAAADkAAAAuAAAAFQAAAAQAAAAAAAAAAAAA 172 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 173 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaikXf9n450/4t7ZMUAAAAyAAAAFQAA 174 | AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 175 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWhkHbtn450/4p7 176 | ZMIAAAAyAAAAFQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 177 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 178 | AAWhkHbrn450/4p7ZMIAAAAyAAAAFQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 179 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 180 | AAAAAAAAAAAAAAAAAAWhkHbrn450/4p7ZMIAAAAyAAAAFAAAAAkAAAAQAAAAFgAAABUAAAANAAAABAAA 181 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 182 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWhkHbrn450/4p7ZMEAAAAzAAAAJwAAADUAAABCAAAAPwAA 183 | AC4AAAAUAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 184 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWhkHbrn450/4h5Yr8AAABLh3pk7qZ8 185 | VP+jeVH/cWVWxQAAADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 186 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqfj3XpnY1z/5SE 187 | bv26mXP/+9ux//rYqf+hd0//cGRUwQAAADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 188 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAA 189 | ADWdjXT/waB6//jgwP/giDr/4plY//nYq/+hd1D/cGRUwQAAADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAA 190 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 191 | AAAAAAAWoZJ27Miogf/25M3/9cCQ/+SPQP/ei0H/4Zpa//nYq/+hd1D/cGRUwQAAADIAAAAUAAAAAwAA 192 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 193 | AAAAAAAAAAAAAAAAABbPsoz/+eze//7UqP/73sP/88KU/+ORQ//ejEL/4Zpa//nYq/+hd1D/cGRUwQAA 194 | ADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 195 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAENK2kf/47+f//6ZL//vUq//738X/88KV/+ORQ//ejEL/4Zpa//nY 196 | q/+hd1D/cGRUwQAAADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 197 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFsKCB69G1kP/38Or//qdM//vUq//73sP/88GT/+OQ 198 | Qv/ei0D/4ZlY//nXqf+hdk7/cGRTwQAAADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 199 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFr5+A59G1kP/37+n//qVJ//zR 200 | pf/7273/876N/+OMOv/dhTb/4JNO//jTo/+gdUz/cGNSwQAAADIAAAAUAAAAAwAAAAAAAAAAAAAAAAAA 201 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFr59/587C 202 | rf/37OP/+e3f//z38//+/fz//Pjy//nu4P/57d7/99/F//fQn/+sknP/b2JRwQAAADIAAAAUAAAAAwAA 203 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 204 | AAAAAAAFr55+58/Aqv/36t3/9OfY//nw6P/68+r/9ebS/+7Pqf/uzaP/8Mye//fQn/+sknL/bmFRwQAA 205 | ADMAAAAdAAAAFQAAAA4AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 206 | AAAAAAAAAAAAAAAAAAAAAAAFr55+586/qf/13L//9ObX//nw5//68+r/9ebT/+7Qq//uzqT/8Mye//fQ 207 | n/+sknL/aVxNwQAAAEcAAAA+AAAAKAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 208 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFr55+58q7o//57uP/9ObW//nw5//68+r/9efT/+7Q 209 | q//vzqX/8s6g//rSoP+JeWP/07OK/6qRcf9yY1PDAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 210 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFr55+58q7ov/57eL/9ObW//nw 211 | 5//78+r/9ufU//HTrv/uzqT/nIdu/+HDnP/71qb/0LGJ/3lqV7kAAAAEAAAAAAAAAAAAAAAAAAAAAAAA 212 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFr55+58q7 213 | ov/57eL/9ObW//rx6P/99u7/8+DJ/6GPdf/hx6b/+Niw/82yj/9yZFKyAAAAFwAAAAMAAAAAAAAAAAAA 214 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 215 | AAAAAAAFr55+58q7ov/57uP/9+ja//Xo2f+olnz/5M2v//fdvP/Ntpf/k4Fn/3NmVLgAAAAxAAAAFAAA 216 | AAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 217 | AAAAAAAAAAAAAAAAAAAAAAAFr55+58q7o//36+D/sqCE/+bSuv/44cf/0Lqe/7Cbfv/50J3/sph3/3Vo 218 | VsEAAAAzAAAAHQAAABUAAAAOAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 219 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFrp195rOig//p2sf/+ujT/9TBp/+3p47/9ty///PU 220 | rP/2zpv/sZd2/3FkU8EAAABHAAAAPgAAACgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 221 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAW59nJ//zv5P/by7b/q5t///3y 222 | 5//15ND/8tm8//PUrf/xy5r/kYFp/82wiv+vlnb/empZwwAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 223 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDSwqv/49XD/6KS 224 | c6SllHbdxbag//vv5P/25ND/8Ni7/6OQdv/jxqT//Nir/9O0jf+Ccl64AAAABAAAAAAAAAAAAAAAAAAA 225 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbuq 226 | iPa1pIS0AAAABAAAAAWnlnnmxbeg//fs3/+rmX//5M2x//ndu//TuJf/hndirwAAAAQAAAAAAAAAAAAA 227 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 228 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWllXfmq5p//+fVwf/65cz/1r+j/41/Z64AAAADAAAAAAAA 229 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 230 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABbf0r///e7h/9rIsv+Wh2yuAAAAAwAA 231 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 232 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEM6+p//f0sH/n45xrgAA 233 | AAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 234 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFs6KC9q2c 235 | frQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 236 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 237 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf///8D////Af///4D////Af///4AH///AA 238 | ///4AH///AA///wAH//8AA///AAH//wAA//8AAH//gAA//8AAH//gAAP/8AAD//gAA//8AAP//gAD//8 239 | AAf//gAA//8AAP//gAD//4AA//+AAf///AP///4H///+D////h//////KAAAABAAAAAgAAAAAQAgAAAA 240 | AABABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 241 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAno1z/wAAADMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 242 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACejXP/AAAAMwAAAAAAAAAzAAAAMwAA 243 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ6Ncv8AAAAziHlk/4Fy 244 | X/8AAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzlIZu//7N 245 | of/7yp//fXFg/wAAADMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAppZ7///w 246 | 2f/ul0P/55BA//jKoP98cF7/AAAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK2e 247 | gP//8tn/95xF/+yVQv/mjTr/+MWZ/3xtWv8AAAAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 248 | AAAAAAAAqZp8///////0487/8t3D//TZt///9N//fGtX/wAAADMAAAAjAAAAAAAAAAAAAAAAAAAAAAAA 249 | AAAAAAAAAAAAAAAAAACpmHj///////Pexf/x2bv/9Nez///24P98a1f/cGBQvwAAAAAAAAAAAAAAAAAA 250 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmXd///////9N/F//Xcvv+2ooT//9+1/4FwXf8AAAAAAAAAAAAA 251 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqZh3//////+1ooj/++LF/52LceCejnP/AAAAMwAA 252 | ADMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwnn7//+7c/6mXf+D74cL//Nu1/56P 253 | dP+ejnP/AAAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvayKr66dfv+aim///urV//rg 254 | wf/ErIz//9us/5KCa/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJeH 255 | bP/NuqL//+XG/45+Z/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 256 | AAChkHX///jq/56Ncv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 257 | AAAAAAAAAAAAAKCPdP8AAAAAAAAAAAAAAAC//wAAn/8AAMn/AADg/wAA4H8AAOA/AADgHwAA8AcAAPgH 258 | AAD8BwAA/gEAAP8AAAD/AAAA/+EAAP/jAAD/9wAA 259 | 260 | 261 | -------------------------------------------------------------------------------- /Injector/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Injector 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new Form1()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Injector/Project.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using XMSerializer; 3 | 4 | namespace Injector 5 | { 6 | class Project 7 | { 8 | public string ModuleFileName { get; set; } 9 | public byte[] SourceModule { get; set; } 10 | public ExtendedModule XM { get; set; } 11 | public List Plans { get; set; } 12 | public int Channels { get; set; } 13 | public bool CentreSourceModule { get; set; } 14 | public List Stills { get; set; } 15 | public Project() 16 | { 17 | Plans = new List(); 18 | Stills = new List(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Injector/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("Injector")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("Injector")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("941f8566-51f1-4538-86ce-a8add5e13c94")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Injector/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Injector.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Injector.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Injector/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Injector/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Injector.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Injector/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Injector/injection.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/Injector/injection.ico -------------------------------------------------------------------------------- /Injector/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # XmTools 2 | Tools set for XM music files 3 | 4 | Coded for the Wrecklamation "demo" in XMPlay by Logicoma released at the Revision 2018 Tracker Music Compo. 5 | 6 | Check out the results of this endeavour here.. 7 | 8 | Youtube - https://www.youtube.com/watch?v=O38R4YMJqeA \ 9 | Youtube Live - https://www.youtube.com/watch?v=r8Lm9CoxEHg \ 10 | Pouet - http://www.pouet.net/prod.php?which=75812 \ 11 | Demozoo - https://demozoo.org/music/185107/ 12 | 13 | More info in the wiki 14 | 15 | Injector app is still full of bugs but I'm not likely to make any changes now. 16 | 17 | I accept no responsibility for use or abuse of this code. 18 | 19 | Do with it as you please. 20 | 21 | -------------------------------------------------------------------------------- /XMSerializer/ExtendedModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | 7 | namespace XMSerializer 8 | { 9 | public class ExtendedModule 10 | { 11 | public string IdText { get; set; } 12 | public string ModuleName { get; set; } 13 | public byte Tag { get; set; } 14 | public string TrackerName { get; set; } 15 | public int HeaderSize { get; set; } 16 | public byte VersionHigh { get; set; } 17 | public byte VersionLow { get; set; } 18 | 19 | public UInt16 SongLength { get; set; } 20 | public UInt16 RestartPosition { get; set; } 21 | public UInt16 ChannelCount { get; set; } 22 | public UInt16 PatternCount { get; set; } 23 | public UInt16 InstrumentCount { get; set; } 24 | public byte[] Flags { get; set; } 25 | public UInt16 Tempo { get; set; } 26 | public UInt16 BPM { get; set; } 27 | 28 | public byte[] PatternOrderList { get; set; } 29 | 30 | public List Patterns { get; set; } 31 | public List Instruments { get; set; } 32 | 33 | private List Remaps { get; set; } 34 | 35 | public ExtendedModule() 36 | { 37 | Patterns = new List(); 38 | Instruments = new List(); 39 | Remaps = new List(); 40 | } 41 | 42 | public Pattern NewPattern(int lines) 43 | { 44 | if (lines > 256 || lines < 1) throw new Exception("Are you mental! max 256 lines"); 45 | 46 | return new Pattern() 47 | { 48 | PackedPatternData = null, 49 | PackingType = 0, 50 | HeaderLength = 9, 51 | RowCount = (ushort)lines, 52 | UnpackedPatternData = new byte[ChannelCount * 5 * lines] 53 | }; 54 | } 55 | 56 | public Pattern InsertNewPattern(int position, int size) 57 | { 58 | var pat = NewPattern(size); 59 | Patterns.Add(pat); 60 | int patId = Patterns.IndexOf(pat); 61 | var list = PatternOrderList.ToList(); 62 | list.Insert(position, (byte)patId); 63 | for (var i = 0; i < 256; i++) 64 | PatternOrderList[i] = list[i]; 65 | SongLength += 1; 66 | if (SongLength > 256) 67 | throw new Exception("You've ran out of song length"); 68 | return pat; 69 | } 70 | 71 | public Pattern DuplicatePattern(int position) 72 | { 73 | var source = Patterns[PatternOrderList[position]]; 74 | var pat = NewPattern(source.RowCount); 75 | for (var i = 0; i < source.UnpackedPatternData.Length; i++) 76 | { 77 | pat.UnpackedPatternData[i] = source.UnpackedPatternData[i]; 78 | } 79 | Patterns.Add(pat); 80 | int patId = Patterns.IndexOf(pat); 81 | PatternOrderList[position] = (byte)patId; 82 | return pat; 83 | } 84 | 85 | private void DeletePatternPosition(int position) 86 | { 87 | var list = PatternOrderList.ToList(); 88 | list.RemoveAt(position); 89 | list.Add(0); 90 | for (var i = 0; i < 256; i++) 91 | PatternOrderList[i] = list[i]; 92 | SongLength--; 93 | } 94 | 95 | private int PatternOccuranceCount(int patternId) 96 | { 97 | int count = 0; 98 | for (var i = 0; i < SongLength; i++) 99 | { 100 | var patId = PatternOrderList[i]; 101 | if (patternId == patId) count++; 102 | } 103 | return count; 104 | } 105 | 106 | private bool[] GetChannelMask(Pattern pat) 107 | { 108 | var mask = new bool[ChannelCount]; 109 | var index = 0; 110 | for (var y = 0; y < pat.RowCount; y++) 111 | { 112 | for (var x = 0; x < ChannelCount; x++) 113 | { 114 | var data = pat.UnpackedPatternData; 115 | if (data[index] + data[index + 1] + data[index + 2] + data[index + 3] + data[index + 4] > 0) 116 | { 117 | mask[x] = true; 118 | } 119 | index += 5; 120 | } 121 | } 122 | return mask; 123 | } 124 | 125 | public void RunInjectionPlans() 126 | { 127 | // TODO: take the code off the form! 128 | 129 | } 130 | 131 | public void RunInjectionStill(InjectionStill still) 132 | { 133 | var src = Patterns[PatternOrderList[still.SongPosition]]; 134 | var mask = GetChannelMask(src); 135 | 136 | var pat = NewPattern(src.RowCount); 137 | 138 | // inject image to new pattern 139 | pat.InjectImage(BinToImage(still.Images[0].Image), still.PixelMode); 140 | 141 | // inject pattern to new pattern 142 | var index = 0; 143 | for (var row = 0; row < src.RowCount; row++) 144 | { 145 | for (var i = 0; i < ChannelCount; i++) 146 | { 147 | if (mask[i]) 148 | { 149 | for (var x = 0; x < 5; x++) 150 | { 151 | pat.UnpackedPatternData[index + x] = src.UnpackedPatternData[index + x]; 152 | } 153 | } 154 | 155 | index += 5; 156 | } 157 | } 158 | 159 | // yep, done :) 160 | Patterns[PatternOrderList[still.SongPosition]] = pat; 161 | } 162 | 163 | public void RunInjectionPlan(InjectionPlan plan, int sourceChannels, int folloingDestinationLine) 164 | { 165 | var src = Patterns[PatternOrderList[plan.SongPosition]]; 166 | var mask = GetChannelMask(src); 167 | 168 | if (src.RowCount != plan.TotalFrames) 169 | throw new Exception(string.Format("Frame count {0} doesn't match row count {1}", plan.TotalFrames, 170 | src.RowCount)); 171 | 172 | if (plan.DestinationLine > 0 && plan.SongPosition > 0) 173 | { 174 | var prevPatId = PatternOrderList[plan.SongPosition - 1]; 175 | Pattern previous = null; 176 | if (PatternOccuranceCount(prevPatId) > 1) 177 | { 178 | // previous pattern occurs more than once, so dupe to prevent breakage 179 | previous = DuplicatePattern(plan.SongPosition - 1); 180 | } 181 | else 182 | { 183 | previous = Patterns[PatternOrderList[plan.SongPosition - 1]]; 184 | } 185 | 186 | var previousEnd = previous.UnpackedPatternData.Length - 2; 187 | previous.UnpackedPatternData[previousEnd - 3] = 0x00; 188 | previous.UnpackedPatternData[previousEnd - 2] = 0x00; 189 | previous.UnpackedPatternData[previousEnd - 1] = 0x00; 190 | previous.UnpackedPatternData[previousEnd] = 0x0D; 191 | previous.UnpackedPatternData[previousEnd + 1] = PatBreak(plan.DestinationLine); 192 | } 193 | 194 | // remove existing pattern position (so we dont play the same pattern twice) 195 | DeletePatternPosition(plan.SongPosition); 196 | 197 | var loop = 0; 198 | var destPos = plan.DestinationLine; 199 | var width = ChannelCount*5; 200 | var sourceIndex = 0; 201 | var songPos = plan.SongPosition; 202 | 203 | var loopList = new List(); 204 | bool loopActive = false; 205 | 206 | Pattern pat = null; 207 | 208 | for (var frame = 0; frame < plan.TotalFrames; frame++) 209 | { 210 | var destIndex = destPos*width; 211 | 212 | if (!loopActive) 213 | { 214 | InjectionImage image = null; 215 | 216 | if (plan.Images.Count > loop) 217 | image = plan.Images[loop]; 218 | 219 | // height override 220 | var height = image != null && image.PatternHeight > 0 ? image.PatternHeight : plan.PatternHeight; 221 | 222 | // create new pattern 223 | pat = InsertNewPattern(songPos, height); 224 | 225 | // if image exists, inject it 226 | if (image != null) 227 | pat.InjectImage(BinToImage(image.Image), plan.PixelMode); 228 | 229 | loopList.Add(songPos); 230 | } 231 | else 232 | { 233 | // first loop done, append to previous patterns instead 234 | pat = Patterns[PatternOrderList[loopList[loop]]]; 235 | } 236 | 237 | // copy current line 238 | if (plan.PatternAllFrames == 0) 239 | { 240 | for (var i = 0; i < ChannelCount; i++) 241 | { 242 | if (mask[i]) 243 | { 244 | for (var x = 0; x < 5; x++) 245 | { 246 | pat.UnpackedPatternData[destIndex + x] = src.UnpackedPatternData[sourceIndex + x]; 247 | } 248 | } 249 | 250 | destIndex += 5; 251 | sourceIndex += 5; 252 | } 253 | } 254 | else // copy whole pattern to destination 255 | { 256 | var thisIndex = 0; 257 | for (var line = 0; line < plan.PatternHeight-1; line++) 258 | { 259 | for (var i = 0; i < ChannelCount; i++) 260 | { 261 | if (mask[i]) 262 | { 263 | for (var x = 0; x < 5; x++) 264 | { 265 | pat.UnpackedPatternData[thisIndex + x] = src.UnpackedPatternData[thisIndex + x]; 266 | } 267 | } 268 | 269 | thisIndex += 5; 270 | } 271 | } 272 | 273 | destIndex += (5*ChannelCount); 274 | sourceIndex += (5*ChannelCount); 275 | } 276 | 277 | loop++; 278 | if (loop == plan.LoopSize) 279 | { 280 | loopActive = true; 281 | destPos += plan.LoopLineInc; 282 | 283 | // add song position jump to first loop frame but leave the last frame otherwise we'll loop 4 eva 284 | if (frame < plan.TotalFrames - 1) 285 | { 286 | pat.UnpackedPatternData[destIndex - 10] = 0x00; 287 | pat.UnpackedPatternData[destIndex - 9] = 0x00; 288 | pat.UnpackedPatternData[destIndex - 8] = 0x00; 289 | pat.UnpackedPatternData[destIndex - 7] = 0x0B; 290 | pat.UnpackedPatternData[destIndex - 6] = (byte) loopList[0]; 291 | 292 | Remaps.Add(new InjectionRemap() 293 | { 294 | Pattern = pat, 295 | Distance = loop - 1, 296 | ValueIndex = destIndex - 6 297 | }); 298 | 299 | } 300 | 301 | loop = 0; 302 | } 303 | else 304 | { 305 | destPos += plan.FrameLineInc; // move position for this frame 306 | } 307 | 308 | 309 | // now position jump if required 310 | pat.UnpackedPatternData[destIndex - 5] = 0x00; 311 | pat.UnpackedPatternData[destIndex - 4] = 0x00; 312 | pat.UnpackedPatternData[destIndex - 3] = 0x00; 313 | pat.UnpackedPatternData[destIndex - 2] = 0x0D; 314 | if (frame < plan.TotalFrames - 1) 315 | { 316 | pat.UnpackedPatternData[destIndex - 1] = PatBreak(destPos); 317 | } 318 | else 319 | { 320 | pat.UnpackedPatternData[destIndex - 1] = PatBreak(folloingDestinationLine); 321 | } 322 | 323 | songPos++; 324 | } 325 | 326 | Remap(); // stuff will have shifted so remap B commands 327 | CleanPatternOrderList(); 328 | RemoveUnusedPatterns(); 329 | RemoveDuplicatePatterns(); 330 | } 331 | 332 | private void Remap() 333 | { 334 | foreach (var r in Remaps) 335 | { 336 | var patId = Patterns.IndexOf(r.Pattern); 337 | for (var i = 0; i < SongLength; i++) 338 | { 339 | if (PatternOrderList[i] == patId) 340 | { 341 | // remap jump point 342 | if (r.Pattern.UnpackedPatternData[r.ValueIndex-1] != 0x0B) 343 | { 344 | throw new Exception("Found it"); 345 | } 346 | r.Pattern.UnpackedPatternData[r.ValueIndex] = (byte)(i - r.Distance); 347 | } 348 | } 349 | } 350 | } 351 | 352 | 353 | private Bitmap BinToImage(byte[] byteArrayIn) 354 | { 355 | using (var ms = new MemoryStream(byteArrayIn)) 356 | { 357 | Image returnImage = Image.FromStream(ms); 358 | return (Bitmap) returnImage; 359 | } 360 | } 361 | 362 | private void RemoveUnusedPatterns() 363 | { 364 | // based on song length, mark which patterns are actually used 365 | var used = new bool[256]; 366 | for (var i = 0; i < SongLength; i++) 367 | { 368 | used[PatternOrderList[i]] = true; 369 | } 370 | 371 | // copy highest used pattern to lowest unused pattern 372 | for (var current = 0; current < used.Length; current++) 373 | { 374 | if (!used[current]) 375 | { 376 | var lastUsed = FindLastUsedPattern(true, used); 377 | if (lastUsed > current) 378 | { 379 | Patterns[current] = Patterns[lastUsed]; 380 | RemapPattern(lastUsed, current); 381 | used[current] = true; 382 | used[lastUsed] = false; 383 | } 384 | else 385 | { 386 | break; 387 | } 388 | } 389 | } 390 | 391 | SanitizePatterns(); 392 | } 393 | 394 | public void RemoveDuplicatePatterns() 395 | { 396 | for (var a = 0; a < Patterns.Count; a++) 397 | { 398 | for (var b = a + 1; b < Patterns.Count; b++) 399 | { 400 | var pata = Patterns[a]; 401 | var patb = Patterns[b]; 402 | if (PatternCompare(pata, patb)) 403 | { 404 | RemapPattern(b, a); 405 | } 406 | } 407 | } 408 | 409 | SanitizePatterns(); 410 | } 411 | 412 | private bool PatternCompare(Pattern a, Pattern b) 413 | { 414 | if (a.RowCount != b.RowCount) 415 | return false; 416 | 417 | for (var i = 0; i < a.UnpackedPatternData.Length; i++) 418 | { 419 | if (a.UnpackedPatternData[i] != b.UnpackedPatternData[i]) 420 | { 421 | return false; 422 | } 423 | } 424 | 425 | return true; 426 | } 427 | 428 | private void SanitizePatterns() 429 | { 430 | var newPatterns = new List(); 431 | var maxUsedPattern = PatternOrderList.Max(); 432 | for (var p = 0; p <= maxUsedPattern; p++) 433 | { 434 | newPatterns.Add(Patterns[p]); 435 | } 436 | Patterns = newPatterns; 437 | PatternCount = (ushort)Patterns.Count; 438 | } 439 | 440 | private int FindLastUsedPattern(bool state, bool[] blist) 441 | { 442 | for (var i = blist.Length - 1; i >= 0; i--) 443 | { 444 | if (blist[i] == state) return i; 445 | } 446 | return -1; 447 | } 448 | 449 | public void CleanPatternOrderList() 450 | { 451 | for (var i = 0; i < 256; i++) 452 | { 453 | if (i >= SongLength) PatternOrderList[i] = 0; 454 | } 455 | } 456 | 457 | private void RemapPattern(int source, int dest) 458 | { 459 | for (var p = 0; p < SongLength; p++) 460 | { 461 | if (PatternOrderList[p] == source) 462 | PatternOrderList[p] = (byte)dest; 463 | } 464 | } 465 | 466 | private byte PatBreak(int value) 467 | { 468 | var faceValue = "0x" + value; 469 | return Convert.ToByte(faceValue, 16); 470 | } 471 | 472 | public void ResizeChannels(int newChannelCount, bool centre) 473 | { 474 | if (newChannelCount <= ChannelCount) 475 | throw new Exception("Don't reduce the channel count this much, you'll ruin the faaarkin tune mate!"); 476 | 477 | if ((newChannelCount % 2) == 1) 478 | throw new Exception("Channel count must be even"); 479 | 480 | if (newChannelCount > 64) 481 | throw new Exception("You bloody idiot"); 482 | 483 | int currentCount = ChannelCount; 484 | 485 | var space = new byte[((newChannelCount*5) - (currentCount*5))/2]; 486 | 487 | foreach (var pat in Patterns) 488 | { 489 | var reader = new BinaryReader(new MemoryStream(pat.UnpackedPatternData)); 490 | var writer = new BinaryWriter(new MemoryStream()); 491 | 492 | for (var row = 0; row < pat.RowCount; row++) 493 | { 494 | if (centre) 495 | { 496 | writer.Write(space); 497 | writer.Write(reader.ReadBytes((int)currentCount * 5)); 498 | writer.Write(space); 499 | } 500 | else 501 | { 502 | writer.Write(reader.ReadBytes((int) currentCount*5)); 503 | writer.Write(space); 504 | writer.Write(space); 505 | } 506 | } 507 | pat.UnpackedPatternData = ((MemoryStream)writer.BaseStream).ToArray(); 508 | } 509 | 510 | ChannelCount = (ushort)newChannelCount; 511 | } 512 | 513 | public void CreateTestCard() 514 | { 515 | var pat = InsertNewPattern(0, 256); 516 | int width = ChannelCount*5; 517 | int index = 0; 518 | 519 | for (var i = 0; i < 256; i++) 520 | { 521 | pat.UnpackedPatternData[index + 0] = (byte) i; 522 | pat.UnpackedPatternData[index + 5 + 1] = (byte)i; 523 | pat.UnpackedPatternData[index + 10 + 2] = (byte)i; 524 | pat.UnpackedPatternData[index + 15 + 3] = (byte)i; 525 | pat.UnpackedPatternData[index + 20 + 4] = (byte)i; 526 | 527 | index += width; 528 | } 529 | } 530 | 531 | public void UnpackPatterns() 532 | { 533 | byte space = 0x00; 534 | 535 | foreach (var pat in Patterns) 536 | { 537 | using (var writer = new BinaryWriter(new MemoryStream())) 538 | { 539 | using (var reader = new BinaryReader(new MemoryStream(pat.PackedPatternData))) 540 | { 541 | while (reader.BaseStream.Position < pat.PackedPatternData.Length) 542 | { 543 | var flags = reader.ReadByte(); 544 | if ((flags & 0x80) == 0) 545 | { 546 | // not packed 547 | writer.Write(flags); 548 | writer.Write(reader.ReadBytes(4)); 549 | } 550 | else 551 | { 552 | // packed, loop and test flags 553 | for (var i = 0; i < 5; i++) 554 | { 555 | if ((flags & (0x01 << i)) == 0) 556 | { 557 | writer.Write(space); 558 | } 559 | else 560 | { 561 | writer.Write(reader.ReadByte()); 562 | } 563 | } 564 | } 565 | } 566 | } 567 | 568 | pat.UnpackedPatternData = ((MemoryStream)writer.BaseStream).ToArray(); 569 | } 570 | } 571 | } 572 | 573 | public void PackPatterns() 574 | { 575 | foreach (var pat in Patterns) 576 | { 577 | using (var writer = new BinaryWriter(new MemoryStream())) 578 | { 579 | using (var reader = new BinaryReader(new MemoryStream(pat.UnpackedPatternData))) 580 | { 581 | while (reader.BaseStream.Position < pat.UnpackedPatternData.Length) 582 | { 583 | var item = reader.ReadBytes(5); 584 | if (item[0] > 0 && item[1] > 0 && item[2] > 0 && item[3] > 0 && item[4] > 0) 585 | { 586 | // all used, no packing required 587 | writer.Write(item); 588 | } 589 | else 590 | { 591 | // pack 592 | var flags = 0x80; 593 | var packed = new List(); 594 | for (var i = 0; i < 5; i++) 595 | { 596 | if (item[i] > 0) 597 | { 598 | flags += (0x01< channelCount) return; 632 | if (y >= RowCount) return; 633 | 634 | UnpackedPatternData[(x * 5) + (y * channelCount * 5) + pixel.Column] = pixel.Value; 635 | } 636 | 637 | public void InjectImage(Bitmap image, int pixelMode) 638 | { 639 | Color sourcePixel = new Color(); 640 | 641 | int channelCount = UnpackedPatternData.Length / RowCount / 5; 642 | 643 | var xoff = (image.Width - channelCount)/2; 644 | var yoff = (image.Height - RowCount)/2; 645 | 646 | for (var y = 0; y < RowCount; y++) 647 | { 648 | for (var x = 0; x < channelCount; x++) 649 | { 650 | var imageX = x + xoff; 651 | var imageY = y + yoff; 652 | if (imageX >= 0 && imageX < image.Width && imageY >= 0 && imageY < image.Height) 653 | { 654 | sourcePixel = image.GetPixel(imageX, imageY); 655 | } 656 | else 657 | { 658 | sourcePixel = new Color(); 659 | } 660 | 661 | if (sourcePixel != null) 662 | { 663 | Plot(x, y, ConvertPixel(sourcePixel, pixelMode)); 664 | } 665 | } 666 | } 667 | } 668 | 669 | private XMPixel ConvertPixel(Color source, int mode) 670 | { 671 | var pixel = new XMPixel(0,0); 672 | int value = 0; 673 | 674 | switch (mode) 675 | { 676 | case 0: 677 | value = (source.R + source.G + source.B) / 3; 678 | pixel = new XMPixel(1, (byte)value); 679 | break; 680 | case 1: 681 | value = (source.R) / 12; 682 | pixel = new XMPixel(1, (byte)value); 683 | break; 684 | case 2: 685 | value = (source.R) / 12; 686 | pixel = new XMPixel(2, (byte)value); 687 | break; 688 | default: 689 | throw new Exception(string.Format("Invalid pixel mode: {0}", mode)); 690 | } 691 | 692 | return pixel; 693 | } 694 | } 695 | 696 | public class Instrument 697 | { 698 | public int HeaderLength { get; set; } 699 | public string Name { get; set; } 700 | public byte Type { get; set; } 701 | public UInt16 SampleCount { get; set; } 702 | public List Samples { get; set; } 703 | 704 | public Instrument() 705 | { 706 | Samples = new List(); 707 | } 708 | } 709 | 710 | public class Sample 711 | { 712 | public int SampleHeaderSize { get; set; } 713 | public byte[] SampleNotes { get; set; } 714 | 715 | public byte[] VolumeEnvelopePoints { get; set; } 716 | public byte[] PanningEnvelopePoints { get; set; } 717 | 718 | public byte VolumePoints { get; set; } 719 | public byte PanningPoints { get; set; } 720 | public byte VolumeSustainPoint { get; set; } 721 | public byte VolumeLoopStartPoint { get; set; } 722 | public byte VolumeLoopEndPoint { get; set; } 723 | public byte PanningSustainPoint { get; set; } 724 | public byte PanningLoopStartPoint { get; set; } 725 | public byte PanningLoopEndPoint { get; set; } 726 | public byte VolumeType { get; set; } 727 | public byte PanningType { get; set; } 728 | public byte VibratoType { get; set; } 729 | public byte VibratoSweep { get; set; } 730 | public byte VibratoDepth { get; set; } 731 | public byte VibratoRate { get; set; } 732 | public UInt16 VolumeFadeout { get; set; } 733 | public UInt16 Reserved { get; set; } 734 | public byte[] Padding { get; set; } 735 | 736 | public int SampleLength { get; set; } 737 | public int SampleLoopStart { get; set; } 738 | public int SampleLoopLength { get; set; } 739 | public byte SampleVolume { get; set; } 740 | public byte SampleFinetune { get; set; } 741 | public byte SampleFlags { get; set; } 742 | public byte SamplePanning { get; set; } 743 | public byte SampleRelativeNote { get; set; } 744 | public byte SampleReserved { get; set; } 745 | public string SampleName { get; set; } 746 | public byte[] SampleData { get; set; } 747 | } 748 | } 749 | -------------------------------------------------------------------------------- /XMSerializer/InjectorPlan.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace XMSerializer 4 | { 5 | public class InjectionImage 6 | { 7 | public string FileName { get; set; } 8 | public byte[] Image { get; set; } 9 | public int PatternHeight { get; set; } 10 | } 11 | 12 | public class InjectionPlan 13 | { 14 | public string Name { get; set; } 15 | public int SongPosition { get; set; } 16 | public int DestinationLine { get; set; } 17 | public int LoopSize { get; set; } 18 | public int LoopLineInc { get; set; } 19 | public int FrameLineInc { get; set; } 20 | public int TotalFrames { get; set; } 21 | public int PatternHeight { get; set; } 22 | public int PixelMode { get; set; } 23 | public int PatternAllFrames { get; set; } 24 | public List Images { get; set; } 25 | 26 | public InjectionPlan() 27 | { 28 | Images = new List(); 29 | } 30 | } 31 | 32 | public class InjectionRemap 33 | { 34 | public Pattern Pattern { get; set; } 35 | public int Distance { get; set; } 36 | public int ValueIndex { get; set; } 37 | } 38 | 39 | public class InjectionStill 40 | { 41 | public string Name { get; set; } 42 | public int SongPosition { get; set; } 43 | public int PixelMode { get; set; } 44 | public List Images { get; set; } 45 | 46 | public InjectionStill() 47 | { 48 | Images = new List(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /XMSerializer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("XMSerializer")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("XMSerializer")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("5563157a-a0d6-42f7-a525-f1f60bead546")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /XMSerializer/XMPixel.cs: -------------------------------------------------------------------------------- 1 | namespace XMSerializer 2 | { 3 | public class XMPixel 4 | { 5 | public int Column { get; set; } 6 | public byte Value { get; set; } 7 | 8 | public XMPixel(int column, byte value) 9 | { 10 | Column = column; 11 | Value = value; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /XMSerializer/XMReader.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | namespace XMSerializer 5 | { 6 | public class XMReader : BinaryReader 7 | { 8 | public XMReader(Stream stream) : base(stream) { } 9 | 10 | public string ReadAscii(int length) 11 | { 12 | var data = base.ReadBytes(length); 13 | return Encoding.ASCII.GetString(data); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /XMSerializer/XMTools.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {75EAF7BA-B71C-47DB-ADDC-3CA80F337E73} 8 | Library 9 | Properties 10 | XMSerializer 11 | XMSerializer 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Code 50 | 51 | 52 | 53 | 54 | 61 | -------------------------------------------------------------------------------- /XMSerializer/XMWriter.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | 4 | namespace XMSerializer 5 | { 6 | public class XMWriter : BinaryWriter 7 | { 8 | public XMWriter(Stream stream) : base(stream) { } 9 | 10 | public void WriteAscii(string text, int length) 11 | { 12 | var output = new byte[length]; 13 | var convertedText = Encoding.ASCII.GetBytes(text); 14 | for (var i = 0; i < length; i++) 15 | { 16 | if (i < convertedText.Length) 17 | output[i] = convertedText[i]; 18 | else 19 | output[i] = 0; 20 | } 21 | 22 | this.Write(output); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /XMSerializer/XmSerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace XMSerializer 5 | { 6 | public class XMSerializer 7 | { 8 | public ExtendedModule DeSerialize(string fileName) 9 | { 10 | var data = File.ReadAllBytes(fileName); 11 | 12 | return DeSerialize(data); 13 | } 14 | 15 | public ExtendedModule DeSerialize(byte[] data) 16 | { 17 | if (data == null) 18 | return new ExtendedModule(); 19 | 20 | var xm = new ExtendedModule(); 21 | 22 | using (var reader = new XMReader(new MemoryStream(data))) 23 | { 24 | xm.IdText = reader.ReadAscii(17); 25 | if (xm.IdText != "Extended Module: ") 26 | throw new Exception("Invalid file format"); 27 | 28 | xm.ModuleName = reader.ReadAscii(20); 29 | xm.Tag = reader.ReadByte(); 30 | xm.TrackerName = reader.ReadAscii(20); 31 | 32 | xm.VersionHigh = reader.ReadByte(); 33 | if (xm.VersionHigh != 4) 34 | throw new Exception("Invalid file version"); 35 | 36 | xm.VersionLow = reader.ReadByte(); 37 | if (xm.VersionLow != 1) 38 | throw new Exception("Invalid file version"); 39 | 40 | xm.HeaderSize = reader.ReadInt32(); 41 | 42 | xm.SongLength = reader.ReadUInt16(); 43 | xm.RestartPosition = reader.ReadUInt16(); 44 | xm.ChannelCount = reader.ReadUInt16(); 45 | xm.PatternCount = reader.ReadUInt16(); 46 | xm.InstrumentCount = reader.ReadUInt16(); 47 | xm.Flags = reader.ReadBytes(2); 48 | xm.Tempo = reader.ReadUInt16(); 49 | xm.BPM = reader.ReadUInt16(); 50 | xm.PatternOrderList = reader.ReadBytes(256); 51 | 52 | for (var i = 0; i < xm.PatternCount; i++) 53 | { 54 | var pat = new Pattern(); 55 | pat.HeaderLength = reader.ReadInt32(); 56 | pat.PackingType = reader.ReadByte(); 57 | pat.RowCount = reader.ReadUInt16(); 58 | pat.PackedPatternSize = reader.ReadUInt16(); 59 | pat.PackedPatternData = reader.ReadBytes(pat.PackedPatternSize); 60 | 61 | xm.Patterns.Add(pat); 62 | } 63 | 64 | for (var i = 0; i < xm.InstrumentCount; i++) 65 | { 66 | var ins = new Instrument(); 67 | ins.HeaderLength = reader.ReadInt32(); 68 | ins.Name = reader.ReadAscii(22); 69 | ins.Type = reader.ReadByte(); 70 | ins.SampleCount = reader.ReadUInt16(); 71 | 72 | if (ins.SampleCount > 0) 73 | { 74 | var smp = new Sample(); 75 | smp.SampleHeaderSize = reader.ReadInt32(); 76 | smp.SampleNotes = reader.ReadBytes(96); 77 | smp.VolumeEnvelopePoints = reader.ReadBytes(48); 78 | smp.PanningEnvelopePoints = reader.ReadBytes(48); 79 | 80 | smp.VolumePoints = reader.ReadByte(); 81 | smp.PanningPoints = reader.ReadByte(); 82 | smp.VolumeSustainPoint = reader.ReadByte(); 83 | smp.VolumeLoopStartPoint = reader.ReadByte(); 84 | smp.VolumeLoopEndPoint = reader.ReadByte(); 85 | smp.PanningSustainPoint = reader.ReadByte(); 86 | smp.PanningLoopStartPoint = reader.ReadByte(); 87 | smp.PanningLoopEndPoint = reader.ReadByte(); 88 | smp.VolumeType = reader.ReadByte(); 89 | smp.PanningType = reader.ReadByte(); 90 | smp.VibratoType = reader.ReadByte(); 91 | smp.VibratoSweep = reader.ReadByte(); 92 | smp.VibratoDepth = reader.ReadByte(); 93 | smp.VibratoRate = reader.ReadByte(); 94 | 95 | smp.VolumeFadeout = reader.ReadUInt16(); 96 | smp.Reserved = reader.ReadUInt16(); 97 | 98 | var skipSize = ins.HeaderLength - 243; 99 | smp.Padding = reader.ReadBytes(skipSize); 100 | 101 | smp.SampleLength = reader.ReadInt32(); 102 | smp.SampleLoopStart = reader.ReadInt32(); 103 | smp.SampleLoopLength = reader.ReadInt32(); 104 | 105 | smp.SampleVolume = reader.ReadByte(); 106 | smp.SampleFinetune = reader.ReadByte(); 107 | smp.SampleFlags = reader.ReadByte(); 108 | smp.SamplePanning = reader.ReadByte(); 109 | smp.SampleRelativeNote = reader.ReadByte(); 110 | smp.SampleReserved = reader.ReadByte(); 111 | smp.SampleName = reader.ReadAscii(22); 112 | smp.SampleData = reader.ReadBytes(smp.SampleLength); 113 | 114 | ins.Samples.Add(smp); 115 | } 116 | 117 | xm.Instruments.Add(ins); 118 | } 119 | } 120 | 121 | xm.UnpackPatterns(); 122 | 123 | return xm; 124 | } 125 | 126 | public void Serialize(ExtendedModule xm, string fileName) 127 | { 128 | var data = Serialize(xm); 129 | File.WriteAllBytes(fileName, data); 130 | } 131 | 132 | public byte[] Serialize(ExtendedModule xm) 133 | { 134 | xm.PackPatterns(); 135 | 136 | using (var writer = new XMWriter(new MemoryStream())) 137 | { 138 | writer.WriteAscii(xm.IdText, 17); 139 | writer.WriteAscii(xm.ModuleName, 20); 140 | writer.Write(xm.Tag); 141 | 142 | writer.WriteAscii(xm.TrackerName,20); 143 | 144 | writer.Write(xm.VersionHigh); 145 | writer.Write(xm.VersionLow); 146 | 147 | writer.Write(xm.HeaderSize); 148 | 149 | writer.Write(xm.SongLength); 150 | writer.Write(xm.RestartPosition); 151 | writer.Write(xm.ChannelCount); 152 | writer.Write(xm.PatternCount); 153 | writer.Write(xm.InstrumentCount); 154 | writer.Write(xm.Flags); 155 | writer.Write(xm.Tempo); 156 | writer.Write(xm.BPM); 157 | writer.Write(xm.PatternOrderList); 158 | 159 | foreach (var pat in xm.Patterns) 160 | { 161 | writer.Write(pat.HeaderLength); 162 | writer.Write(pat.PackingType); 163 | writer.Write(pat.RowCount); 164 | writer.Write(pat.PackedPatternSize); 165 | writer.Write(pat.PackedPatternData); 166 | } 167 | 168 | foreach (var ins in xm.Instruments) 169 | { 170 | writer.Write(ins.HeaderLength); 171 | writer.WriteAscii(ins.Name, 22); 172 | writer.Write(ins.Type); 173 | writer.Write(ins.SampleCount); 174 | 175 | foreach (var smp in ins.Samples) 176 | { 177 | writer.Write(smp.SampleHeaderSize); 178 | writer.Write(smp.SampleNotes); 179 | writer.Write(smp.VolumeEnvelopePoints); 180 | writer.Write(smp.PanningEnvelopePoints); 181 | 182 | writer.Write(smp.VolumePoints); 183 | writer.Write(smp.PanningPoints); 184 | writer.Write(smp.VolumeSustainPoint); 185 | writer.Write(smp.VolumeLoopStartPoint); 186 | writer.Write(smp.VolumeLoopEndPoint); 187 | writer.Write(smp.PanningSustainPoint); 188 | writer.Write(smp.PanningLoopStartPoint); 189 | writer.Write(smp.PanningLoopEndPoint); 190 | writer.Write(smp.VolumeType); 191 | writer.Write(smp.PanningType); 192 | writer.Write(smp.VibratoType); 193 | writer.Write(smp.VibratoSweep); 194 | writer.Write(smp.VibratoDepth); 195 | writer.Write(smp.VibratoRate); 196 | 197 | writer.Write(smp.VolumeFadeout); 198 | writer.Write(smp.Reserved); 199 | 200 | writer.Write(smp.Padding); 201 | 202 | writer.Write(smp.SampleLength); 203 | writer.Write(smp.SampleLoopStart); 204 | writer.Write(smp.SampleLoopLength); 205 | 206 | writer.Write(smp.SampleVolume); 207 | writer.Write(smp.SampleFinetune); 208 | writer.Write(smp.SampleFlags); 209 | writer.Write(smp.SamplePanning); 210 | writer.Write(smp.SampleRelativeNote); 211 | writer.Write(smp.SampleReserved); 212 | writer.WriteAscii(smp.SampleName, 22); 213 | writer.Write(smp.SampleData); 214 | } 215 | } 216 | 217 | return ((MemoryStream) writer.BaseStream).ToArray(); 218 | } 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /XMSerializerTest/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /XMSerializerTest/Program.cs: -------------------------------------------------------------------------------- 1 | namespace XMSerializerTest 2 | { 3 | class Program 4 | { 5 | static void Main(string[] args) 6 | { 7 | 8 | var ser = new XMSerializer.XMSerializer(); 9 | var xm = ser.DeSerialize(@"C:\Users\h0ffman\Google Drive\XMTools\XMSerializerTest\test\test.xm"); 10 | ser.Serialize(xm, @"C:\test\output.xm"); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /XMSerializerTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("XMSerializerTest")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("XMSerializerTest")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("6c081e5d-0106-4928-ab45-b91179ee5264")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /XMSerializerTest/XMSerializerTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7F4F83A6-0A11-40D8-AC77-6C7FFEBC7202} 8 | Exe 9 | Properties 10 | XMSerializerTest 11 | XMSerializerTest 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {75eaf7ba-b71c-47db-addc-3ca80f337e73} 54 | XMTools 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /XMSerializerTest/test/2 sample.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/XMSerializerTest/test/2 sample.xm -------------------------------------------------------------------------------- /XMSerializerTest/test/clap.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/XMSerializerTest/test/clap.wav -------------------------------------------------------------------------------- /XMSerializerTest/test/patpack.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/XMSerializerTest/test/patpack.xm -------------------------------------------------------------------------------- /XMSerializerTest/test/single sample.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/XMSerializerTest/test/single sample.xm -------------------------------------------------------------------------------- /XMSerializerTest/test/test-blank.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/XMSerializerTest/test/test-blank.xm -------------------------------------------------------------------------------- /XMSerializerTest/test/test.xm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djh0ffman/XmTools/872f3bfc2a66d6cb8df4613bc57ca2a8f77e391a/XMSerializerTest/test/test.xm -------------------------------------------------------------------------------- /XMTools.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XMTools", "XMSerializer\XMTools.csproj", "{75EAF7BA-B71C-47DB-ADDC-3CA80F337E73}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XMSerializerTest", "XMSerializerTest\XMSerializerTest.csproj", "{7F4F83A6-0A11-40D8-AC77-6C7FFEBC7202}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Injector", "Injector\Injector.csproj", "{5E87E2A0-02C7-4DB4-A444-A4AC2818F450}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {75EAF7BA-B71C-47DB-ADDC-3CA80F337E73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {75EAF7BA-B71C-47DB-ADDC-3CA80F337E73}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {75EAF7BA-B71C-47DB-ADDC-3CA80F337E73}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {75EAF7BA-B71C-47DB-ADDC-3CA80F337E73}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {7F4F83A6-0A11-40D8-AC77-6C7FFEBC7202}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {7F4F83A6-0A11-40D8-AC77-6C7FFEBC7202}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {7F4F83A6-0A11-40D8-AC77-6C7FFEBC7202}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {7F4F83A6-0A11-40D8-AC77-6C7FFEBC7202}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {5E87E2A0-02C7-4DB4-A444-A4AC2818F450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {5E87E2A0-02C7-4DB4-A444-A4AC2818F450}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {5E87E2A0-02C7-4DB4-A444-A4AC2818F450}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {5E87E2A0-02C7-4DB4-A444-A4AC2818F450}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | --------------------------------------------------------------------------------