├── .gitignore ├── LICENSE ├── ManiacEditor.sln ├── ManiacEditor ├── Actions │ ├── ActionAddDeleteEntities.cs │ ├── ActionChangeTile.cs │ ├── ActionDummy.cs │ ├── ActionEntityPropertyChange.cs │ ├── ActionMoveEntities.cs │ ├── ActionsGroup.cs │ ├── ActionsGroupCloseMarker.cs │ └── IAction.cs ├── App.config ├── ColorsCaching.cs ├── DeviceEventArgs.cs ├── DevicePanel.cs ├── DevicePanel.designer.cs ├── Editor.cs ├── Editor.designer.cs ├── Editor.resx ├── EditorBackground.cs ├── EditorEntities.cs ├── EditorEntity.cs ├── EditorLayer.cs ├── EntitiesToolbar.Designer.cs ├── EntitiesToolbar.cs ├── EntitiesToolbar.resx ├── FolderSelectDialog.cs ├── IDrawArea.cs ├── IDrawable.cs ├── ImageViewer.cs ├── ImageViewer.designer.cs ├── ImageViewer.resx ├── LocalProperty.cs ├── LocalPropertyGrid.cs ├── ManiacEditor.csproj ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Reflector.cs ├── Resources │ ├── file.ico │ ├── folder.ico │ └── objects_attributes.ini ├── SceneSelect.Designer.cs ├── SceneSelect.cs ├── SceneSelect.resx ├── TextureCreator.cs ├── ThumbnailFlowLayoutPanel.cs ├── TilesList.Designer.cs ├── TilesList.cs ├── TilesList.resx ├── TilesToolbar.Designer.cs ├── TilesToolbar.cs ├── TilesToolbar.resx └── packages.config ├── README.md ├── RSDKv5 ├── AttributeInfo.cs ├── AttributeValue.cs ├── Color.cs ├── CommonConfig.cs ├── GIF.cs ├── GameConfig.cs ├── NameIdentifier.cs ├── ObjectInfo.cs ├── Objects.cs ├── Palette.cs ├── PaletteColor.cs ├── Position.cs ├── Properties │ └── AssemblyInfo.cs ├── RSDKv5.csproj ├── Reader.cs ├── Scene.cs ├── SceneEditorMetadata.cs ├── SceneEntity.cs ├── SceneLayer.cs ├── SceneObjects.cs ├── Sprite.cs ├── StageConfig.cs ├── StageTiles.cs ├── TilesConfig.cs ├── WAVConfiguration.cs ├── Writer.cs └── packages.config └── appveyor.yml /.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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 koolkdev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ManiacEditor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.16 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ManiacEditor", "ManiacEditor\ManiacEditor.csproj", "{297BA354-5E1E-4701-A6A2-73784BC8C8B1}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {CF5496F8-002B-408F-9B3D-67C88F610283} = {CF5496F8-002B-408F-9B3D-67C88F610283} 9 | EndProjectSection 10 | EndProject 11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RSDKv5", "RSDKv5\RSDKv5.csproj", "{CF5496F8-002B-408F-9B3D-67C88F610283}" 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Release|Any CPU = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {297BA354-5E1E-4701-A6A2-73784BC8C8B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 20 | {297BA354-5E1E-4701-A6A2-73784BC8C8B1}.Debug|Any CPU.Build.0 = Debug|Any CPU 21 | {297BA354-5E1E-4701-A6A2-73784BC8C8B1}.Release|Any CPU.ActiveCfg = Release|Any CPU 22 | {297BA354-5E1E-4701-A6A2-73784BC8C8B1}.Release|Any CPU.Build.0 = Release|Any CPU 23 | {CF5496F8-002B-408F-9B3D-67C88F610283}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {CF5496F8-002B-408F-9B3D-67C88F610283}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {CF5496F8-002B-408F-9B3D-67C88F610283}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {CF5496F8-002B-408F-9B3D-67C88F610283}.Release|Any CPU.Build.0 = Release|Any CPU 27 | EndGlobalSection 28 | GlobalSection(SolutionProperties) = preSolution 29 | HideSolutionNode = FALSE 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionAddDeleteEntities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ManiacEditor.Actions 7 | { 8 | class ActionAddDeleteEntities : IAction 9 | { 10 | Action> addEntity; 11 | Action> deleteEntity; 12 | List entities; 13 | bool add; 14 | 15 | public ActionAddDeleteEntities(List entities, bool add, Action> addEntity, Action> deleteEntity) 16 | { 17 | this.entities = entities; 18 | this.add = add; 19 | this.addEntity = addEntity; 20 | this.deleteEntity = deleteEntity; 21 | } 22 | 23 | public void Undo() 24 | { 25 | if (add) 26 | deleteEntity(entities); 27 | else 28 | addEntity(entities); 29 | } 30 | 31 | public IAction Redo() 32 | { 33 | return new ActionAddDeleteEntities(entities, !add, addEntity, deleteEntity); 34 | } 35 | 36 | } 37 | } -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionChangeTile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Drawing; 7 | 8 | namespace ManiacEditor.Actions 9 | { 10 | class ActionChangeTile : IAction 11 | { 12 | Action setLayer; 13 | Point position; 14 | private ushort oldValue, newValue; 15 | 16 | public ActionChangeTile(Action setLayer, Point position, ushort oldValue, ushort newValue) 17 | { 18 | this.setLayer = setLayer; 19 | this.position = position; 20 | this.oldValue = oldValue; 21 | this.newValue = newValue; 22 | } 23 | 24 | public void Undo() 25 | { 26 | setLayer(position, oldValue); 27 | } 28 | 29 | public IAction Redo() 30 | { 31 | return new ActionChangeTile(setLayer, position, newValue, oldValue); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionDummy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ManiacEditor.Actions 8 | { 9 | class ActionDummy : IAction 10 | { 11 | public ActionDummy() { } 12 | public void Undo() { } 13 | public IAction Redo() { return this; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionEntityPropertyChange.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using RSDKv5; 7 | 8 | namespace ManiacEditor.Actions 9 | { 10 | class ActionEntityPropertyChange : IAction 11 | { 12 | SceneEntity entity; 13 | string tag; 14 | object oldValue; 15 | object newValue; 16 | Action setValue; 17 | 18 | public ActionEntityPropertyChange(SceneEntity entity, string tag, object oldValue, object newValue, Action setValue) 19 | { 20 | this.entity = entity; 21 | this.tag = tag; 22 | this.oldValue = oldValue; 23 | this.newValue = newValue; 24 | this.setValue = setValue; 25 | } 26 | 27 | public void Undo() 28 | { 29 | setValue(entity, tag, oldValue, newValue); 30 | } 31 | 32 | public IAction Redo() 33 | { 34 | return new ActionEntityPropertyChange(entity, tag, newValue, oldValue, setValue); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionMoveEntities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace ManiacEditor.Actions 8 | { 9 | class ActionMoveEntities : IAction 10 | { 11 | List entities; 12 | Point diff; 13 | bool key; 14 | 15 | public ActionMoveEntities(List entities, Point diff, bool key=false) 16 | { 17 | this.entities = entities; 18 | this.diff = new Point(-diff.X, -diff.Y); 19 | this.key = key; 20 | } 21 | 22 | public bool UpdateFromKey(List entities, Point change) 23 | { 24 | if (!key) return false; 25 | if (entities.Count != this.entities.Count) return false; 26 | for (int i = 0; i < entities.Count; ++i) 27 | if (entities[i] != this.entities[i]) 28 | return false; 29 | 30 | diff.X -= change.X; 31 | diff.Y -= change.Y; 32 | return true; 33 | } 34 | 35 | public void Undo() 36 | { 37 | foreach (var entity in entities) 38 | entity.Move(diff); 39 | } 40 | 41 | public IAction Redo() 42 | { 43 | // Don't pass key, because we don't want to merge with it after 44 | return new ActionMoveEntities(entities, diff); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionsGroup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ManiacEditor.Actions 8 | { 9 | class ActionsGroup : IAction 10 | { 11 | private bool closed; 12 | 13 | private List actions = new List(); 14 | 15 | public bool IsClosed 16 | { 17 | get 18 | { 19 | return closed; 20 | } 21 | } 22 | 23 | public ActionsGroup() 24 | { 25 | } 26 | 27 | public void AddAction(IAction action) 28 | { 29 | if (closed) throw new Exception("Can't add action to closed group."); 30 | 31 | if (action is ActionsGroupCloseMarker) 32 | { 33 | Close(); 34 | } 35 | else 36 | { 37 | actions.Add(action); 38 | } 39 | } 40 | 41 | public void Close() 42 | { 43 | if (closed) throw new Exception("Can't close closed group."); 44 | 45 | closed = true; 46 | actions.Reverse(); 47 | } 48 | 49 | public void Undo() 50 | { 51 | if (!closed) throw new Exception("Can't undn unclosed group."); 52 | foreach (IAction action in actions) { 53 | action.Undo(); 54 | } 55 | } 56 | 57 | public IAction Redo() 58 | { 59 | if (!closed) throw new Exception("Can't redo unclosed group."); 60 | 61 | ActionsGroup group = new ActionsGroup(); 62 | group.actions = new List(actions).Select(x => x.Redo()).ToList(); 63 | group.actions.Reverse(); 64 | group.closed = true; 65 | 66 | return group; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/ActionsGroupCloseMarker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ManiacEditor.Actions 8 | { 9 | class ActionsGroupCloseMarker : IAction 10 | { 11 | public void Undo() 12 | { 13 | 14 | } 15 | 16 | public IAction Redo() 17 | { 18 | return null; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ManiacEditor/Actions/IAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ManiacEditor.Actions 7 | { 8 | public interface IAction 9 | { 10 | void Undo(); 11 | IAction Redo(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ManiacEditor/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ManiacEditor/ColorsCaching.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections; 6 | using System.Drawing; 7 | 8 | namespace ManiacEditor 9 | { 10 | class ColorsCaching 11 | { 12 | private static Hashtable cache; 13 | private static Hashtable cacheb; 14 | 15 | public static Color Get(int transparency) 16 | { 17 | if (cache == null) cache = new Hashtable(); 18 | if (!cache.Contains(transparency)) cache.Add(transparency, Color.FromArgb(transparency, Color.White)); 19 | return (Color)cache[transparency]; 20 | } 21 | public static Color GetBlack(int transparency) 22 | { 23 | if (cacheb == null) cacheb = new Hashtable(); 24 | if (!cacheb.Contains(transparency)) cacheb.Add(transparency, Color.FromArgb(transparency, Color.Black)); 25 | return (Color)cacheb[transparency]; 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ManiacEditor/DeviceEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using SharpDX.Direct3D9; 6 | 7 | namespace ManiacEditor 8 | { 9 | public delegate void RenderEventHandler(object sender, DeviceEventArgs e); 10 | public delegate void CreateDeviceEventHandler(object sender, DeviceEventArgs e); 11 | 12 | public class DeviceEventArgs : EventArgs 13 | { 14 | private Device _device; 15 | 16 | public Device Device 17 | { 18 | get 19 | { 20 | return _device; 21 | } 22 | } 23 | 24 | public DeviceEventArgs(Device device) 25 | { 26 | _device = device; 27 | } 28 | 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ManiacEditor/DevicePanel.designer.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace ManiacEditor 4 | { 5 | partial class DevicePanel 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private System.ComponentModel.IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | base.Dispose(disposing); 23 | } 24 | 25 | #region Component Designer generated code 26 | 27 | /// 28 | /// Required method for Designer support - do not modify 29 | /// the contents of this method with the code editor. 30 | /// 31 | private void InitializeComponent() 32 | { 33 | components = new System.ComponentModel.Container(); 34 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 35 | } 36 | 37 | #endregion 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ManiacEditor/EditorBackground.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Drawing; 7 | using RSDKv5Color = RSDKv5.Color; 8 | 9 | namespace ManiacEditor 10 | { 11 | class EditorBackground : IDrawable 12 | { 13 | const int BOX_SIZE = 8; 14 | 15 | static int DivideRoundUp(int number, int by) 16 | { 17 | return (number + by - 1) / by; 18 | } 19 | 20 | public void Draw(Graphics g) 21 | { 22 | 23 | } 24 | 25 | public void Draw(DevicePanel d) 26 | { 27 | Rectangle screen = d.GetScreen(); 28 | 29 | RSDKv5Color rcolor1 = Editor.Instance.Scene.EditorMetadata.BackgroundColor1; 30 | RSDKv5Color rcolor2 = Editor.Instance.Scene.EditorMetadata.BackgroundColor2; 31 | 32 | Color color1 = Color.FromArgb(rcolor1.A, rcolor1.R, rcolor1.G, rcolor1.B); 33 | Color color2 = Color.FromArgb(rcolor2.A, rcolor2.R, rcolor2.G, rcolor2.B); 34 | 35 | int start_x = screen.X / (BOX_SIZE * EditorLayer.TILE_SIZE); 36 | int end_x = Math.Min(DivideRoundUp(screen.X + screen.Width, BOX_SIZE * EditorLayer.TILE_SIZE), Editor.Instance.SceneWidth); 37 | int start_y = screen.Y / (BOX_SIZE * EditorLayer.TILE_SIZE); 38 | int end_y = Math.Min(DivideRoundUp(screen.Y + screen.Height, BOX_SIZE * EditorLayer.TILE_SIZE), Editor.Instance.Height); 39 | 40 | // Draw with first color everything 41 | d.DrawRectangle(screen.X, screen.Y, screen.X + screen.Width, screen.Y + screen.Height, color1); 42 | 43 | if (color2.A != 0) { 44 | for (int y = start_y; y < end_y; ++y) 45 | { 46 | for (int x = start_x; x < end_x; ++x) 47 | { 48 | if ((x + y) % 2 == 1) d.DrawRectangle(x * BOX_SIZE * EditorLayer.TILE_SIZE, y * BOX_SIZE * EditorLayer.TILE_SIZE, (x + 1) * BOX_SIZE * EditorLayer.TILE_SIZE, (y + 1) * BOX_SIZE * EditorLayer.TILE_SIZE, color2); 49 | } 50 | } 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ManiacEditor/EditorEntities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Drawing; 7 | using System.Windows.Forms; 8 | 9 | namespace ManiacEditor 10 | { 11 | class EditorEntities : IDrawable 12 | { 13 | List entities = new List(); 14 | List selectedEntities = new List(); 15 | List tempSelection = new List(); 16 | 17 | Dictionary entitiesBySlot = new Dictionary(); 18 | 19 | ushort nextFreeSlot = 0; 20 | 21 | public List Entities { get { return entities; } } 22 | public List SelectedEntities { get { return selectedEntities; } } 23 | 24 | public class TooManyEntitiesException : Exception { } 25 | 26 | public Actions.IAction LastAction; 27 | 28 | 29 | public EditorEntities(RSDKv5.Scene scene) 30 | { 31 | foreach (var obj in scene.Objects) 32 | entities.AddRange(obj.Entities.Select(x => new EditorEntity(x))); 33 | entitiesBySlot = entities.ToDictionary(x => x.Entity.SlotID); 34 | } 35 | 36 | private ushort getFreeSlot(RSDKv5.SceneEntity preferred) 37 | { 38 | if (preferred != null && !entitiesBySlot.ContainsKey(preferred.SlotID)) return preferred.SlotID; 39 | while (entitiesBySlot.ContainsKey(nextFreeSlot)) 40 | { 41 | ++nextFreeSlot; 42 | } 43 | if (nextFreeSlot == 2048) 44 | { 45 | if (entitiesBySlot.Count < 2048) 46 | { 47 | // Next time search from beggining 48 | nextFreeSlot = 0; 49 | } 50 | throw new TooManyEntitiesException(); 51 | } 52 | return nextFreeSlot++; 53 | } 54 | 55 | public void Select(Rectangle area, bool addSelection = false, bool deselectIfSelected = false) 56 | { 57 | if (!addSelection) Deselect(); 58 | foreach (var entity in entities) 59 | { 60 | if (entity.IsInArea(area)) 61 | { 62 | if (deselectIfSelected && selectedEntities.Contains(entity)) 63 | { 64 | selectedEntities.Remove(entity); 65 | entity.Selected = false; 66 | } 67 | else if (!selectedEntities.Contains(entity)) 68 | { 69 | selectedEntities.Add(entity); 70 | entity.Selected = true; 71 | } 72 | } 73 | } 74 | } 75 | 76 | public void Select(Point point, bool addSelection = false, bool deselectIfSelected = false) 77 | { 78 | if (!addSelection) Deselect(); 79 | // In reverse because we want to select the top one 80 | foreach (EditorEntity entity in entities.Reverse()) 81 | { 82 | if (entity.ContainsPoint(point)) 83 | { 84 | if (deselectIfSelected && selectedEntities.Contains(entity)) 85 | { 86 | selectedEntities.Remove(entity); 87 | entity.Selected = false; 88 | } 89 | else 90 | { 91 | selectedEntities.Add(entity); 92 | entity.Selected = true; 93 | } 94 | // Only the top 95 | break; 96 | } 97 | } 98 | } 99 | 100 | public void SelectSlot(int slot) 101 | { 102 | Deselect(); 103 | if (entitiesBySlot.ContainsKey((ushort)slot)) 104 | { 105 | selectedEntities.Add(entitiesBySlot[(ushort)slot]); 106 | entitiesBySlot[(ushort)slot].Selected = true; 107 | } 108 | } 109 | 110 | private void AddEntities(List entities) 111 | { 112 | foreach (var entity in entities) 113 | { 114 | entity.Entity.Object.Entities.Add(entity.Entity); 115 | this.entities.Add(entity); 116 | entitiesBySlot[entity.Entity.SlotID] = entity; 117 | } 118 | } 119 | 120 | private void DeleteEntities(List entities) 121 | { 122 | foreach (var entity in entities) 123 | { 124 | entity.Entity.Object.Entities.Remove(entity.Entity); 125 | this.entities.Remove(entity); 126 | entitiesBySlot.Remove(entity.Entity.SlotID); 127 | if (entity.Entity.SlotID < nextFreeSlot) nextFreeSlot = entity.Entity.SlotID; 128 | } 129 | } 130 | 131 | private void DuplicateEntities(List entities) 132 | { 133 | var new_entities = entities.Select(x => new EditorEntity(new RSDKv5.SceneEntity(x.Entity, getFreeSlot(x.Entity)))).ToList(); 134 | if (new_entities.Count > 0) 135 | LastAction = new Actions.ActionAddDeleteEntities(new_entities.ToList(), true, x => AddEntities(x), x => DeleteEntities(x)); 136 | AddEntities(new_entities); 137 | Deselect(); 138 | selectedEntities.AddRange(new_entities); 139 | foreach (var entity in new_entities) 140 | entity.Selected = true; 141 | } 142 | 143 | public void MoveSelected(Point oldPos, Point newPos, bool duplicate) 144 | { 145 | Point diff = new Point(newPos.X - oldPos.X, newPos.Y - oldPos.Y); 146 | if (duplicate) DuplicateEntities(selectedEntities); 147 | foreach (var entity in selectedEntities) 148 | { 149 | entity.Move(diff); 150 | } 151 | } 152 | 153 | public bool IsSelected() 154 | { 155 | return selectedEntities.Count > 0 || tempSelection.Count > 0; 156 | } 157 | 158 | public void DeleteSelected() 159 | { 160 | if (selectedEntities.Count > 0) 161 | LastAction = new Actions.ActionAddDeleteEntities(selectedEntities.ToList(), false, x => AddEntities(x), x => DeleteEntities(x)); 162 | DeleteEntities(selectedEntities); 163 | Deselect(); 164 | } 165 | 166 | public List CopyToClipboard(bool keepPosition = false) 167 | { 168 | if (selectedEntities.Count == 0) return null; 169 | short minX = 0, minY = 0; 170 | 171 | List copiedEntities = selectedEntities.Select(x => new EditorEntity(new RSDKv5.SceneEntity(x.Entity, x.Entity.SlotID))).ToList(); 172 | if (!keepPosition) 173 | { 174 | minX = copiedEntities.Min(x => x.Entity.Position.X.High); 175 | minY = copiedEntities.Min(x => x.Entity.Position.Y.High); 176 | copiedEntities.ForEach(x => x.Move(new Point(-minX, -minY))); 177 | } 178 | 179 | return copiedEntities; 180 | } 181 | 182 | public void PasteFromClipboard(Point newPos, List entities) 183 | { 184 | DuplicateEntities(entities); 185 | foreach (var entity in selectedEntities) 186 | { 187 | // Move them 188 | entity.Move(newPos); 189 | } 190 | } 191 | 192 | public EditorEntity GetEntityAt(Point point) 193 | { 194 | foreach (EditorEntity entity in entities.Reverse()) 195 | if (entity.ContainsPoint(point)) 196 | return entity; 197 | return null; 198 | } 199 | 200 | public void TempSelection(Rectangle area, bool deselectIfSelected) 201 | { 202 | List newSelection = (from entity in entities where entity.IsInArea(area) select entity).ToList(); 203 | 204 | foreach (var entity in (from entity in tempSelection where !newSelection.Contains(entity) select entity)) 205 | { 206 | entity.Selected = selectedEntities.Contains(entity); 207 | } 208 | 209 | tempSelection = newSelection; 210 | 211 | foreach (var entity in newSelection) 212 | { 213 | entity.Selected = !deselectIfSelected || !selectedEntities.Contains(entity); 214 | } 215 | } 216 | public void Deselect() 217 | { 218 | foreach (var entity in entities) 219 | { 220 | entity.Selected = false; 221 | } 222 | selectedEntities.Clear(); 223 | } 224 | 225 | public void EndTempSelection() 226 | { 227 | tempSelection.Clear(); 228 | } 229 | 230 | public void Draw(Graphics g) 231 | { 232 | 233 | } 234 | 235 | public void Draw(DevicePanel d) 236 | { 237 | foreach (var entity in entities) 238 | entity.Draw(d); 239 | } 240 | 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /ManiacEditor/EditorEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Drawing; 7 | 8 | namespace ManiacEditor 9 | { 10 | class EditorEntity : IDrawable 11 | { 12 | const int NAME_BOX_WIDTH = 20; 13 | const int NAME_BOX_HEIGHT = 20; 14 | 15 | public bool Selected; 16 | 17 | private RSDKv5.SceneEntity entity; 18 | 19 | public RSDKv5.SceneEntity Entity { get { return entity; } } 20 | 21 | public EditorEntity(RSDKv5.SceneEntity entity) 22 | { 23 | this.entity = entity; 24 | } 25 | 26 | public void Draw(Graphics g) 27 | { 28 | } 29 | 30 | public bool ContainsPoint(Point point) 31 | { 32 | return GetDimensions().Contains(point); 33 | } 34 | 35 | public bool IsInArea(Rectangle area) 36 | { 37 | return GetDimensions().IntersectsWith(area); 38 | } 39 | 40 | public void Move(Point diff) 41 | { 42 | entity.Position.X.High += (short)diff.X; 43 | entity.Position.Y.High += (short)diff.Y; 44 | } 45 | 46 | public Rectangle GetDimensions() 47 | { 48 | return new Rectangle(entity.Position.X.High, entity.Position.Y.High, NAME_BOX_WIDTH, NAME_BOX_HEIGHT); 49 | } 50 | 51 | public void Draw(DevicePanel d) 52 | { 53 | if (!d.IsObjectOnScreen(entity.Position.X.High, entity.Position.Y.High, NAME_BOX_WIDTH, NAME_BOX_HEIGHT)) return; 54 | Color color = Selected ? Color.MediumPurple : Color.MediumTurquoise; 55 | Color color2 = Color.DarkBlue; 56 | int Transparency = (Editor.Instance.EditLayer == null) ? 0xff : 0x32; 57 | 58 | int x = entity.Position.X.High; 59 | int y = entity.Position.Y.High; 60 | 61 | d.DrawRectangle(x, y, x + NAME_BOX_WIDTH, y + NAME_BOX_HEIGHT, Color.FromArgb(Transparency, color)); 62 | d.DrawLine(x, y, x + NAME_BOX_WIDTH, y, Color.FromArgb(Transparency, color2)); 63 | d.DrawLine(x, y, x, y + NAME_BOX_HEIGHT, Color.FromArgb(Transparency, color2)); 64 | d.DrawLine(x, y + NAME_BOX_HEIGHT, x + NAME_BOX_WIDTH, y + NAME_BOX_HEIGHT, Color.FromArgb(Transparency, color2)); 65 | d.DrawLine(x + NAME_BOX_WIDTH, y, x + NAME_BOX_WIDTH, y + NAME_BOX_HEIGHT, Color.FromArgb(Transparency, color2)); 66 | 67 | if (Editor.Instance.GetZoom() >= 1) d.DrawTextSmall(String.Format("{0} (ID: {1})", entity.Object.Name, entity.SlotID), x + 2, y + 2, NAME_BOX_WIDTH - 4, Color.FromArgb(Transparency, Color.Black), true); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ManiacEditor/EntitiesToolbar.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ManiacEditor 2 | { 3 | partial class EntitiesToolbar 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 Component 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 | this.entitiesList = new System.Windows.Forms.ComboBox(); 32 | this.entityProperties = new System.Windows.Forms.PropertyGrid(); 33 | this.SuspendLayout(); 34 | // 35 | // entitiesList 36 | // 37 | this.entitiesList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 38 | | System.Windows.Forms.AnchorStyles.Right))); 39 | this.entitiesList.FormattingEnabled = true; 40 | this.entitiesList.Location = new System.Drawing.Point(6, 3); 41 | this.entitiesList.Name = "entitiesList"; 42 | this.entitiesList.Size = new System.Drawing.Size(247, 21); 43 | this.entitiesList.TabIndex = 0; 44 | this.entitiesList.DropDown += new System.EventHandler(this.entitiesList_DropDown); 45 | this.entitiesList.SelectedIndexChanged += new System.EventHandler(this.entitiesList_SelectedIndexChanged); 46 | // 47 | // entityProperties 48 | // 49 | this.entityProperties.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 50 | | System.Windows.Forms.AnchorStyles.Left) 51 | | System.Windows.Forms.AnchorStyles.Right))); 52 | this.entityProperties.HelpVisible = false; 53 | this.entityProperties.LineColor = System.Drawing.SystemColors.ControlDark; 54 | this.entityProperties.Location = new System.Drawing.Point(6, 30); 55 | this.entityProperties.Name = "entityProperties"; 56 | this.entityProperties.PropertySort = System.Windows.Forms.PropertySort.Categorized; 57 | this.entityProperties.Size = new System.Drawing.Size(247, 454); 58 | this.entityProperties.TabIndex = 1; 59 | this.entityProperties.ToolbarVisible = false; 60 | this.entityProperties.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.entityProperties_PropertyValueChanged); 61 | // 62 | // EntitiesToolbar 63 | // 64 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 65 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 66 | this.Controls.Add(this.entityProperties); 67 | this.Controls.Add(this.entitiesList); 68 | this.Name = "EntitiesToolbar"; 69 | this.Size = new System.Drawing.Size(256, 487); 70 | this.ResumeLayout(false); 71 | 72 | } 73 | 74 | #endregion 75 | 76 | private System.Windows.Forms.ComboBox entitiesList; 77 | private System.Windows.Forms.PropertyGrid entityProperties; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ManiacEditor/EntitiesToolbar.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 | -------------------------------------------------------------------------------- /ManiacEditor/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | // ------------------------------------------------------------------ 5 | // Wraps System.Windows.Forms.OpenFileDialog to make it present 6 | // a vista-style dialog. 7 | // ------------------------------------------------------------------ 8 | 9 | namespace ManiacEditor 10 | { 11 | /// 12 | /// Wraps System.Windows.Forms.OpenFileDialog to make it present 13 | /// a vista-style dialog. 14 | /// 15 | public class FolderSelectDialog 16 | { 17 | // Wrapped dialog 18 | System.Windows.Forms.OpenFileDialog ofd = null; 19 | 20 | /// 21 | /// Default constructor 22 | /// 23 | public FolderSelectDialog() 24 | { 25 | ofd = new System.Windows.Forms.OpenFileDialog(); 26 | 27 | ofd.Filter = "Folders|\n"; 28 | ofd.AddExtension = false; 29 | ofd.CheckFileExists = false; 30 | ofd.DereferenceLinks = true; 31 | ofd.Multiselect = false; 32 | } 33 | 34 | #region Properties 35 | 36 | /// 37 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 38 | /// 39 | public string InitialDirectory 40 | { 41 | get { return ofd.InitialDirectory; } 42 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 43 | } 44 | 45 | /// 46 | /// Gets/Sets the title to show in the dialog 47 | /// 48 | public string Title 49 | { 50 | get { return ofd.Title; } 51 | set { ofd.Title = value == null ? "Select a folder" : value; } 52 | } 53 | 54 | /// 55 | /// Gets the selected folder 56 | /// 57 | public string FileName 58 | { 59 | get { return ofd.FileName; } 60 | } 61 | 62 | #endregion 63 | 64 | #region Methods 65 | 66 | /// 67 | /// Shows the dialog 68 | /// 69 | /// True if the user presses OK else false 70 | public bool ShowDialog() 71 | { 72 | return ShowDialog(IntPtr.Zero); 73 | } 74 | 75 | /// 76 | /// Shows the dialog 77 | /// 78 | /// Handle of the control to be parent 79 | /// True if the user presses OK else false 80 | public bool ShowDialog(IntPtr hWndOwner) 81 | { 82 | bool flag = false; 83 | 84 | if (Environment.OSVersion.Version.Major >= 6) 85 | { 86 | var r = new Reflector("System.Windows.Forms"); 87 | 88 | uint num = 0; 89 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 90 | object dialog = r.Call(ofd, "CreateVistaDialog"); 91 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 92 | 93 | uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 94 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 95 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 96 | 97 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 98 | object[] parameters = new object[] { pfde, num }; 99 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 100 | num = (uint)parameters[1]; 101 | try 102 | { 103 | int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 104 | flag = 0 == num2; 105 | } 106 | finally 107 | { 108 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 109 | GC.KeepAlive(pfde); 110 | } 111 | } 112 | else 113 | { 114 | var fbd = new FolderBrowserDialog(); 115 | fbd.Description = this.Title; 116 | fbd.SelectedPath = this.InitialDirectory; 117 | fbd.ShowNewFolderButton = false; 118 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return false; 119 | ofd.FileName = fbd.SelectedPath; 120 | flag = true; 121 | } 122 | 123 | return flag; 124 | } 125 | 126 | #endregion 127 | } 128 | 129 | /// 130 | /// Creates IWin32Window around an IntPtr 131 | /// 132 | public class WindowWrapper : System.Windows.Forms.IWin32Window 133 | { 134 | /// 135 | /// Constructor 136 | /// 137 | /// Handle to wrap 138 | public WindowWrapper(IntPtr handle) 139 | { 140 | _hwnd = handle; 141 | } 142 | 143 | /// 144 | /// Original ptr 145 | /// 146 | public IntPtr Handle 147 | { 148 | get { return _hwnd; } 149 | } 150 | 151 | private IntPtr _hwnd; 152 | } 153 | 154 | } -------------------------------------------------------------------------------- /ManiacEditor/IDrawArea.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Drawing; 7 | 8 | namespace ManiacEditor 9 | { 10 | public interface IDrawArea 11 | { 12 | void DisposeTextures(); 13 | 14 | Rectangle GetScreen(); 15 | double GetZoom(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ManiacEditor/IDrawable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Drawing; 6 | 7 | namespace ManiacEditor 8 | { 9 | interface IDrawable 10 | { 11 | void Draw(Graphics g); 12 | 13 | void Draw(DevicePanel d); 14 | 15 | //void DrawAnimation(DevicePanel d); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ManiacEditor/ImageViewer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | using System.Drawing.Drawing2D; 9 | 10 | namespace ManiacEditor 11 | { 12 | public partial class ImageViewer : UserControl 13 | { 14 | private Image m_Image; 15 | private string m_ImageLocation; 16 | 17 | private bool m_IsThumbnail; 18 | private bool m_IsActive; 19 | 20 | public int MaxWidth; 21 | public int MaxHeight; 22 | 23 | public bool IsText; 24 | 25 | public ImageViewer() 26 | { 27 | m_IsThumbnail = false; 28 | m_IsActive = false; 29 | 30 | InitializeComponent(); 31 | } 32 | 33 | public Image Image 34 | { 35 | set { m_Image = value; } 36 | get { return m_Image; } 37 | } 38 | 39 | public string ImageLocation 40 | { 41 | set { m_ImageLocation = value; } 42 | get { return m_ImageLocation; } 43 | } 44 | 45 | public bool IsActive 46 | { 47 | set 48 | { 49 | m_IsActive = value; 50 | this.Invalidate(); 51 | } 52 | get { return m_IsActive; } 53 | } 54 | 55 | public bool IsThumbnail 56 | { 57 | set { m_IsThumbnail = value; } 58 | get { return m_IsThumbnail; } 59 | } 60 | 61 | /* public void ImageSizeChanged(object sender, ThumbnailImageEventArgs e) 62 | { 63 | this.Width = e.Size; 64 | this.Height = e.Size; 65 | this.Invalidate(); 66 | }*/ 67 | 68 | public void LoadImage(string imageFilename, int width, int height) 69 | { 70 | Image tempImage = Image.FromFile(imageFilename); 71 | m_ImageLocation = imageFilename; 72 | 73 | int dw = tempImage.Width; 74 | int dh = tempImage.Height; 75 | int tw = width; 76 | int th = height; 77 | double zw = (tw / (double)dw); 78 | double zh = (th / (double)dh); 79 | double z = (zw <= zh) ? zw : zh; 80 | dw = (int)(dw * z); 81 | dh = (int)(dh * z); 82 | 83 | m_Image = new Bitmap(dw, dh); 84 | Graphics g = Graphics.FromImage(m_Image); 85 | g.InterpolationMode = InterpolationMode.HighQualityBicubic; 86 | g.DrawImage(tempImage, 0, 0, dw, dh); 87 | g.Dispose(); 88 | 89 | tempImage.Dispose(); 90 | } 91 | 92 | protected override void OnPaint(PaintEventArgs e) 93 | { 94 | Graphics g = e.Graphics; 95 | if (g == null) return; 96 | if (m_Image == null) return; 97 | 98 | float mp = 1; 99 | float dx = 0, dy = 0; 100 | if (MaxWidth > 0 && m_Image.Width > MaxWidth) 101 | { 102 | dx = (float)MaxWidth / m_Image.Width; 103 | } 104 | if (MaxHeight > 0 && m_Image.Height > MaxHeight) 105 | { 106 | dy = (float)MaxHeight / m_Image.Height; 107 | } 108 | 109 | if (dx != 0 && dy == 0) mp = dx; 110 | if (dy != 0 && dx == 0) mp = dy; 111 | if (dx != 0 && dx != 0) mp = Math.Min(dx, dy); 112 | 113 | g.Clear(Color.White); 114 | g.DrawImage(m_Image, 4, 4, m_Image.Width * mp, m_Image.Height * mp); 115 | if (m_IsActive) 116 | { 117 | g.DrawRectangle(new Pen(Color.White, 1), 3, 3, m_Image.Width * mp + 2, m_Image.Height * mp + 2); 118 | g.DrawRectangle(new Pen(Color.Blue, 2), 1, 1, m_Image.Width * mp + 6, m_Image.Height * mp + 6); 119 | } 120 | if (IsText) 121 | g.DrawString(Name, new System.Drawing.Font("Microsoft Sans Serif", 8.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(177))), Brushes.Black, 0, m_Image.Height * mp + 7); 122 | /*g.DrawRectangle(new Pen(Color.Gray), dl, dt, dw, dh); 123 | 124 | if (m_IsThumbnail) 125 | for (int j = 0; j < 3; j++) 126 | { 127 | g.DrawLine(new Pen(Color.DarkGray), 128 | new Point(dl + 3, dt + dh + 1 + j), 129 | new Point(dl + dw + 3, dt + dh + 1 + j)); 130 | g.DrawLine(new Pen(Color.DarkGray), 131 | new Point(dl + dw + 1 + j, dt + 3), 132 | new Point(dl + dw + 1 + j, dt + dh + 3)); 133 | } 134 | 135 | 136 | g.DrawImage(m_Image, dl, dt, dw, dh); 137 | 138 | if (m_IsActive) 139 | { 140 | g.DrawRectangle(new Pen(Color.White, 1), dl, dt, dw, dh); 141 | g.DrawRectangle(new Pen(Color.Blue, 2), dl-2, dt-2, dw+4, dh+4); 142 | }*/ 143 | } 144 | 145 | private void OnResize(object sender, EventArgs e) 146 | { 147 | this.Invalidate(); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /ManiacEditor/ImageViewer.designer.cs: -------------------------------------------------------------------------------- 1 | namespace ManiacEditor 2 | { 3 | partial class ImageViewer 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 Component 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 | this.SuspendLayout(); 32 | // 33 | // ImageViewer 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange; 38 | this.BackColor = System.Drawing.SystemColors.ControlLightLight; 39 | this.DoubleBuffered = true; 40 | this.Name = "ImageViewer"; 41 | this.Size = new System.Drawing.Size(227, 210); 42 | this.ResumeLayout(false); 43 | } 44 | 45 | #endregion 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ManiacEditor/ImageViewer.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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ManiacEditor/LocalProperty.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ManiacEditor 7 | { 8 | /// 9 | /// / 10 | /// 11 | public class LocalProperty 12 | { 13 | private string _name; 14 | private string _type; //data type 15 | private int _categoryIndex; 16 | private string _groupName; //group name 17 | private string _displayName; //display name 18 | private Boolean _display; //true to show 19 | private Boolean _readonly; //true is readonly 20 | private string _description; 21 | private object _value; 22 | private List _options = new List(); 23 | /// 24 | /// construcator 25 | /// 26 | public LocalProperty() 27 | { 28 | _display = true; 29 | _readonly = false; 30 | } 31 | public LocalProperty(string name, 32 | string type, string description) 33 | { 34 | _display = true; 35 | _readonly = false; 36 | // 37 | _name = name; 38 | _type = type; 39 | _description = description; 40 | } 41 | public LocalProperty(string name, 42 | string type, 43 | int category_index, 44 | string group, 45 | string display, 46 | Boolean is_display, 47 | Boolean is_readonly, 48 | object value, 49 | string description, 50 | List options = null) 51 | { 52 | _display = is_display; 53 | _readonly = is_readonly; 54 | // 55 | _name = name; 56 | _type = type; 57 | _categoryIndex = category_index; 58 | _groupName = group; 59 | _displayName = display; 60 | _value = value; 61 | _description = description; 62 | if (options != null) 63 | { 64 | foreach (object v in options) 65 | { 66 | _options.Add(v); 67 | } 68 | } 69 | } 70 | public void AddOption(object value) 71 | { 72 | _options.Add(value); 73 | } 74 | /// 75 | /// 76 | /// 77 | /// 78 | public List GetOptions() 79 | { 80 | return _options; 81 | } 82 | public Type ValueType() 83 | { 84 | return _value.GetType(); 85 | } 86 | /// 87 | /// 88 | /// 89 | public string Name { get { return _name; } set { _name = value; } } 90 | public string Type { get { return _type; } set { _type = value; } } 91 | public Boolean Display { get { return _display; } set { _display = value; } } 92 | public Boolean Readonly { get { return _readonly; } set { _readonly = value; } } 93 | public string DisplayName { get { return _displayName; } set { _displayName = value; } } 94 | public string Description { get { return _description; } set { _description = value; } } 95 | public string Group { get { return String.Concat(Enumerable.Repeat("\t", _categoryIndex)) + _groupName; } set { _groupName = value; } } 96 | public object Value { get { return _value; } set { _value = value; } } 97 | } 98 | 99 | public class LocalProperties : Dictionary 100 | { 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /ManiacEditor/ManiacEditor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {297BA354-5E1E-4701-A6A2-73784BC8C8B1} 8 | WinExe 9 | ManiacEditor 10 | ManiacEditor 11 | v4.5.2 12 | 512 13 | true 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 | ..\packages\SharpDX.4.0.1\lib\net45\SharpDX.dll 37 | 38 | 39 | ..\packages\SharpDX.Desktop.4.0.1\lib\net45\SharpDX.Desktop.dll 40 | 41 | 42 | ..\packages\SharpDX.Direct3D9.4.0.1\lib\net45\SharpDX.Direct3D9.dll 43 | 44 | 45 | ..\packages\SharpDX.Mathematics.4.0.1\lib\net45\SharpDX.Mathematics.dll 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | UserControl 73 | 74 | 75 | EntitiesToolbar.cs 76 | 77 | 78 | 79 | 80 | UserControl 81 | 82 | 83 | ImageViewer.cs 84 | 85 | 86 | 87 | 88 | Form 89 | 90 | 91 | Editor.cs 92 | 93 | 94 | 95 | 96 | 97 | 98 | Form 99 | 100 | 101 | SceneSelect.cs 102 | 103 | 104 | 105 | Component 106 | 107 | 108 | UserControl 109 | 110 | 111 | TilesList.cs 112 | 113 | 114 | UserControl 115 | 116 | 117 | TilesToolbar.cs 118 | 119 | 120 | UserControl 121 | 122 | 123 | DevicePanel.cs 124 | 125 | 126 | 127 | 128 | 129 | EntitiesToolbar.cs 130 | 131 | 132 | ImageViewer.cs 133 | 134 | 135 | Editor.cs 136 | 137 | 138 | SceneSelect.cs 139 | 140 | 141 | TilesList.cs 142 | 143 | 144 | TilesToolbar.cs 145 | 146 | 147 | ResXFileCodeGenerator 148 | Resources.Designer.cs 149 | Designer 150 | 151 | 152 | True 153 | Resources.resx 154 | True 155 | 156 | 157 | 158 | SettingsSingleFileGenerator 159 | Settings.Designer.cs 160 | 161 | 162 | True 163 | Settings.settings 164 | True 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | {cf5496f8-002b-408f-9b3d-67c88f610283} 180 | RSDKv5 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /ManiacEditor/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Threading.Tasks; 7 | using System.Windows.Forms; 8 | 9 | namespace ManiacEditor 10 | { 11 | static class Program 12 | { 13 | /// 14 | /// The main entry point for the application. 15 | /// 16 | [STAThread] 17 | static void Main() 18 | { 19 | Application.EnableVisualStyles(); 20 | Application.SetCompatibleTextRenderingDefault(false); 21 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ManiacEditor.Resources.objects_attributes.ini")) 22 | { 23 | RSDKv5.Objects.InitObjects(stream); 24 | } 25 | new Editor().Run(); 26 | //Application.Run(new GUI.MapEditor()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ManiacEditor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ManiacEditor")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ManiacEditor")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("297ba354-5e1e-4701-a6a2-73784bc8c8b1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /ManiacEditor/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 ManiacEditor.Properties { 12 | using System; 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 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ManiacEditor.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 65 | /// 66 | internal static System.Drawing.Icon file { 67 | get { 68 | object obj = ResourceManager.GetObject("file", resourceCulture); 69 | return ((System.Drawing.Icon)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 75 | /// 76 | internal static System.Drawing.Icon folder { 77 | get { 78 | object obj = ResourceManager.GetObject("folder", resourceCulture); 79 | return ((System.Drawing.Icon)(obj)); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /ManiacEditor/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 | 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 | 122 | ..\Resources\file.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\folder.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | -------------------------------------------------------------------------------- /ManiacEditor/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 ManiacEditor.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 | -------------------------------------------------------------------------------- /ManiacEditor/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ManiacEditor/Reflector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace ManiacEditor 5 | { 6 | /// 7 | /// This class is from the Front-End for Dosbox and is used to present a 'vista' dialog box to select folders. 8 | /// Being able to use a vista style dialog box to select folders is much better then using the shell folder browser. 9 | /// http://code.google.com/p/fed/ 10 | /// 11 | /// Example: 12 | /// var r = new Reflector("System.Windows.Forms"); 13 | /// 14 | public class Reflector 15 | { 16 | #region variables 17 | 18 | string m_ns; 19 | Assembly m_asmb; 20 | 21 | #endregion 22 | 23 | #region Constructors 24 | 25 | /// 26 | /// Constructor 27 | /// 28 | /// The namespace containing types to be used 29 | public Reflector(string ns) 30 | : this(ns, ns) 31 | { } 32 | 33 | /// 34 | /// Constructor 35 | /// 36 | /// A specific assembly name (used if the assembly name does not tie exactly with the namespace) 37 | /// The namespace containing types to be used 38 | public Reflector(string an, string ns) 39 | { 40 | m_ns = ns; 41 | m_asmb = null; 42 | foreach (AssemblyName aN in Assembly.GetExecutingAssembly().GetReferencedAssemblies()) 43 | { 44 | if (aN.FullName.StartsWith(an)) 45 | { 46 | m_asmb = Assembly.Load(aN); 47 | break; 48 | } 49 | } 50 | } 51 | 52 | #endregion 53 | 54 | #region Methods 55 | 56 | /// 57 | /// Return a Type instance for a type 'typeName' 58 | /// 59 | /// The name of the type 60 | /// A type instance 61 | public Type GetType(string typeName) 62 | { 63 | Type type = null; 64 | string[] names = typeName.Split('.'); 65 | 66 | if (names.Length > 0) 67 | type = m_asmb.GetType(m_ns + "." + names[0]); 68 | 69 | for (int i = 1; i < names.Length; ++i) 70 | { 71 | type = type.GetNestedType(names[i], BindingFlags.NonPublic); 72 | } 73 | return type; 74 | } 75 | 76 | /// 77 | /// Create a new object of a named type passing along any params 78 | /// 79 | /// The name of the type to create 80 | /// 81 | /// An instantiated type 82 | public object New(string name, params object[] parameters) 83 | { 84 | Type type = GetType(name); 85 | 86 | ConstructorInfo[] ctorInfos = type.GetConstructors(); 87 | foreach (ConstructorInfo ci in ctorInfos) 88 | { 89 | try 90 | { 91 | return ci.Invoke(parameters); 92 | } 93 | catch { } 94 | } 95 | 96 | return null; 97 | } 98 | 99 | /// 100 | /// Calls method 'func' on object 'obj' passing parameters 'parameters' 101 | /// 102 | /// The object on which to excute function 'func' 103 | /// The function to execute 104 | /// The parameters to pass to function 'func' 105 | /// The result of the function invocation 106 | public object Call(object obj, string func, params object[] parameters) 107 | { 108 | return Call2(obj, func, parameters); 109 | } 110 | 111 | /// 112 | /// Calls method 'func' on object 'obj' passing parameters 'parameters' 113 | /// 114 | /// The object on which to excute function 'func' 115 | /// The function to execute 116 | /// The parameters to pass to function 'func' 117 | /// The result of the function invocation 118 | public object Call2(object obj, string func, object[] parameters) 119 | { 120 | return CallAs2(obj.GetType(), obj, func, parameters); 121 | } 122 | 123 | /// 124 | /// Calls method 'func' on object 'obj' which is of type 'type' passing parameters 'parameters' 125 | /// 126 | /// The type of 'obj' 127 | /// The object on which to excute function 'func' 128 | /// The function to execute 129 | /// The parameters to pass to function 'func' 130 | /// The result of the function invocation 131 | public object CallAs(Type type, object obj, string func, params object[] parameters) 132 | { 133 | return CallAs2(type, obj, func, parameters); 134 | } 135 | 136 | /// 137 | /// Calls method 'func' on object 'obj' which is of type 'type' passing parameters 'parameters' 138 | /// 139 | /// The type of 'obj' 140 | /// The object on which to excute function 'func' 141 | /// The function to execute 142 | /// The parameters to pass to function 'func' 143 | /// The result of the function invocation 144 | public object CallAs2(Type type, object obj, string func, object[] parameters) 145 | { 146 | MethodInfo methInfo = type.GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 147 | return methInfo.Invoke(obj, parameters); 148 | } 149 | 150 | /// 151 | /// Returns the value of property 'prop' of object 'obj' 152 | /// 153 | /// The object containing 'prop' 154 | /// The property name 155 | /// The property value 156 | public object Get(object obj, string prop) 157 | { 158 | return GetAs(obj.GetType(), obj, prop); 159 | } 160 | 161 | /// 162 | /// Returns the value of property 'prop' of object 'obj' which has type 'type' 163 | /// 164 | /// The type of 'obj' 165 | /// The object containing 'prop' 166 | /// The property name 167 | /// The property value 168 | public object GetAs(Type type, object obj, string prop) 169 | { 170 | PropertyInfo propInfo = type.GetProperty(prop, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 171 | return propInfo.GetValue(obj, null); 172 | } 173 | 174 | /// 175 | /// Returns an enum value 176 | /// 177 | /// The name of enum type 178 | /// The name of the value 179 | /// The enum value 180 | public object GetEnum(string typeName, string name) 181 | { 182 | Type type = GetType(typeName); 183 | FieldInfo fieldInfo = type.GetField(name); 184 | return fieldInfo.GetValue(null); 185 | } 186 | 187 | #endregion 188 | 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /ManiacEditor/Resources/file.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koolkdev/ManiacEditor/887432d02ddb1b111ef4cf6d9fff8a57e1831029/ManiacEditor/Resources/file.ico -------------------------------------------------------------------------------- /ManiacEditor/Resources/folder.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koolkdev/ManiacEditor/887432d02ddb1b111ef4cf6d9fff8a57e1831029/ManiacEditor/Resources/folder.ico -------------------------------------------------------------------------------- /ManiacEditor/SceneSelect.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ManiacEditor 2 | { 3 | partial class SceneSelect 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 | this.scenesTree = new System.Windows.Forms.TreeView(); 32 | this.selectButton = new System.Windows.Forms.Button(); 33 | this.cancelButton = new System.Windows.Forms.Button(); 34 | this.isFilesView = new System.Windows.Forms.CheckBox(); 35 | this.searchLabel = new System.Windows.Forms.Label(); 36 | this.FilterText = new System.Windows.Forms.TextBox(); 37 | this.browse = new System.Windows.Forms.Button(); 38 | this.SuspendLayout(); 39 | // 40 | // scenesTree 41 | // 42 | this.scenesTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 43 | | System.Windows.Forms.AnchorStyles.Left) 44 | | System.Windows.Forms.AnchorStyles.Right))); 45 | this.scenesTree.Location = new System.Drawing.Point(12, 35); 46 | this.scenesTree.Name = "scenesTree"; 47 | this.scenesTree.Size = new System.Drawing.Size(460, 278); 48 | this.scenesTree.TabIndex = 0; 49 | this.scenesTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.scenesTree_AfterSelect); 50 | this.scenesTree.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.scenesTree_NodeMouseDoubleClick); 51 | this.scenesTree.MouseUp += new System.Windows.Forms.MouseEventHandler(this.scenesTree_MouseUp); 52 | // 53 | // selectButton 54 | // 55 | this.selectButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 56 | this.selectButton.Enabled = false; 57 | this.selectButton.Location = new System.Drawing.Point(367, 319); 58 | this.selectButton.Name = "selectButton"; 59 | this.selectButton.Size = new System.Drawing.Size(105, 28); 60 | this.selectButton.TabIndex = 4; 61 | this.selectButton.Text = "Select"; 62 | this.selectButton.UseVisualStyleBackColor = true; 63 | this.selectButton.Click += new System.EventHandler(this.selectButton_Click); 64 | // 65 | // cancelButton 66 | // 67 | this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 68 | this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; 69 | this.cancelButton.Location = new System.Drawing.Point(256, 319); 70 | this.cancelButton.Name = "cancelButton"; 71 | this.cancelButton.Size = new System.Drawing.Size(105, 28); 72 | this.cancelButton.TabIndex = 5; 73 | this.cancelButton.Text = "Cancel"; 74 | this.cancelButton.UseVisualStyleBackColor = true; 75 | this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); 76 | // 77 | // isFilesView 78 | // 79 | this.isFilesView.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); 80 | this.isFilesView.AutoSize = true; 81 | this.isFilesView.Location = new System.Drawing.Point(12, 328); 82 | this.isFilesView.Name = "isFilesView"; 83 | this.isFilesView.Size = new System.Drawing.Size(81, 19); 84 | this.isFilesView.TabIndex = 6; 85 | this.isFilesView.Text = "Files View"; 86 | this.isFilesView.UseVisualStyleBackColor = true; 87 | this.isFilesView.CheckedChanged += new System.EventHandler(this.isFilesView_CheckedChanged); 88 | // 89 | // searchLabel 90 | // 91 | this.searchLabel.AutoSize = true; 92 | this.searchLabel.Location = new System.Drawing.Point(9, 9); 93 | this.searchLabel.Name = "searchLabel"; 94 | this.searchLabel.Size = new System.Drawing.Size(37, 15); 95 | this.searchLabel.TabIndex = 8; 96 | this.searchLabel.Text = "Filter:"; 97 | // 98 | // FilterText 99 | // 100 | this.FilterText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 101 | | System.Windows.Forms.AnchorStyles.Right))); 102 | this.FilterText.Location = new System.Drawing.Point(52, 9); 103 | this.FilterText.Name = "FilterText"; 104 | this.FilterText.Size = new System.Drawing.Size(420, 20); 105 | this.FilterText.TabIndex = 7; 106 | this.FilterText.TextChanged += new System.EventHandler(this.FilterText_TextChanged); 107 | // 108 | // browse 109 | // 110 | this.browse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 111 | this.browse.Location = new System.Drawing.Point(145, 319); 112 | this.browse.Name = "browse"; 113 | this.browse.Size = new System.Drawing.Size(105, 28); 114 | this.browse.TabIndex = 9; 115 | this.browse.Text = "Browse..."; 116 | this.browse.UseVisualStyleBackColor = true; 117 | this.browse.Click += new System.EventHandler(this.browse_Click); 118 | // 119 | // SceneSelect 120 | // 121 | this.AcceptButton = this.selectButton; 122 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 123 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 124 | this.CancelButton = this.cancelButton; 125 | this.ClientSize = new System.Drawing.Size(484, 359); 126 | this.Controls.Add(this.browse); 127 | this.Controls.Add(this.searchLabel); 128 | this.Controls.Add(this.FilterText); 129 | this.Controls.Add(this.isFilesView); 130 | this.Controls.Add(this.cancelButton); 131 | this.Controls.Add(this.selectButton); 132 | this.Controls.Add(this.scenesTree); 133 | this.MaximizeBox = false; 134 | this.MinimizeBox = false; 135 | this.MinimumSize = new System.Drawing.Size(350, 200); 136 | this.Name = "SceneSelect"; 137 | this.ShowIcon = false; 138 | this.Text = "Select Scene..."; 139 | this.ResumeLayout(false); 140 | this.PerformLayout(); 141 | 142 | } 143 | 144 | #endregion 145 | 146 | private System.Windows.Forms.TreeView scenesTree; 147 | private System.Windows.Forms.Button selectButton; 148 | private System.Windows.Forms.Button cancelButton; 149 | private System.Windows.Forms.CheckBox isFilesView; 150 | private System.Windows.Forms.Label searchLabel; 151 | private System.Windows.Forms.TextBox FilterText; 152 | private System.Windows.Forms.Button browse; 153 | } 154 | } -------------------------------------------------------------------------------- /ManiacEditor/SceneSelect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using RSDKv5; 11 | 12 | namespace ManiacEditor 13 | { 14 | public partial class SceneSelect : Form 15 | { 16 | List>>> Categories = new List>>>(); 17 | Dictionary> Directories = new Dictionary>(); 18 | 19 | public string Result = null; 20 | 21 | public SceneSelect(GameConfig config) 22 | { 23 | foreach (GameConfig.Category category in config.Categories) 24 | { 25 | List> scenes = new List>(); 26 | foreach (GameConfig.SceneInfo scene in category.Scenes) 27 | { 28 | scenes.Add(new Tuple(scene.Name, scene.Zone + "/Scene" + scene.SceneID + ".bin")); 29 | 30 | List files; 31 | if (!Directories.TryGetValue(scene.Zone, out files)) 32 | { 33 | files = new List(); 34 | Directories[scene.Zone] = files; 35 | } 36 | files.Add("Scene" + scene.SceneID + ".bin"); 37 | } 38 | Categories.Add(new Tuple>>(category.Name, scenes)); 39 | } 40 | 41 | // Sort 42 | Directories = Directories.OrderBy(key => key.Key).ToDictionary((keyItem) => keyItem.Key, (valueItem) => valueItem.Value); 43 | foreach (KeyValuePair> dir in Directories) 44 | dir.Value.Sort(); 45 | 46 | InitializeComponent(); 47 | this.scenesTree.ImageList = new ImageList(); 48 | this.scenesTree.ImageList.Images.Add("Folder", Properties.Resources.folder); 49 | this.scenesTree.ImageList.Images.Add("File", Properties.Resources.file); 50 | 51 | UpdateTree(); 52 | } 53 | 54 | private void selectButton_Click(object sender, EventArgs e) 55 | { 56 | Result = scenesTree.SelectedNode.Tag as string; 57 | Close(); 58 | } 59 | 60 | private void cancelButton_Click(object sender, EventArgs e) 61 | { 62 | Close(); 63 | } 64 | 65 | private void UpdateTree() 66 | { 67 | Show(FilterText.Text); 68 | } 69 | 70 | private void Show(string filter) 71 | { 72 | scenesTree.Nodes.Clear(); 73 | if (isFilesView.Checked) 74 | { 75 | foreach (KeyValuePair> directory in Directories) 76 | { 77 | TreeNode dir_node = new TreeNode(directory.Key); 78 | dir_node.ImageKey = "Folder"; 79 | dir_node.SelectedImageKey = "Folder"; 80 | foreach (string file in directory.Value) { 81 | TreeNode file_node = new TreeNode(file); 82 | file_node.Tag = directory.Key + "/" + file; 83 | file_node.ImageKey = "File"; 84 | file_node.ImageKey = "File"; 85 | file_node.SelectedImageKey = "File"; 86 | if (filter == "" || (directory.Key + "/" + file).ToLower().Contains(filter.ToLower())) 87 | dir_node.Nodes.Add(file_node); 88 | } 89 | if (dir_node.Nodes.Count > 0) 90 | scenesTree.Nodes.Add(dir_node); 91 | } 92 | } 93 | else 94 | { 95 | foreach (Tuple>> category in Categories) 96 | { 97 | TreeNode dir_node = new TreeNode(category.Item1); 98 | dir_node.ImageKey = "Folder"; 99 | dir_node.SelectedImageKey = "Folder"; 100 | string last = ""; 101 | foreach (Tuple scene in category.Item2) 102 | { 103 | string scene_name = scene.Item1; 104 | if (char.IsDigit(scene.Item1[0])) 105 | scene_name = last + scene.Item1; 106 | 107 | TreeNode file_node = new TreeNode(scene_name + " (" + scene.Item2 + ")"); 108 | file_node.Tag = scene.Item2; 109 | file_node.ImageKey = "File"; 110 | file_node.SelectedImageKey = "File"; 111 | if (filter == "" || scene.Item2.ToLower().Contains(filter.ToLower()) || scene_name.ToLower().Contains(filter.ToLower())) 112 | dir_node.Nodes.Add(file_node); 113 | 114 | // Only the first act specify the full name, so lets save it 115 | int i = scene_name.Length; 116 | while (char.IsDigit(scene_name[i - 1]) || (i >= 2 && char.IsDigit(scene_name[i - 2]))) 117 | --i; 118 | last = scene_name.Substring(0, i); 119 | } 120 | if (dir_node.Nodes.Count > 0) 121 | scenesTree.Nodes.Add(dir_node); 122 | } 123 | } 124 | if (filter != "") 125 | { 126 | scenesTree.ExpandAll(); 127 | } 128 | } 129 | 130 | private void isFilesView_CheckedChanged(object sender, EventArgs e) 131 | { 132 | UpdateTree(); 133 | } 134 | 135 | private void FilterText_TextChanged(object sender, EventArgs e) 136 | { 137 | UpdateTree(); 138 | } 139 | 140 | private void scenesTree_AfterSelect(object sender, TreeViewEventArgs e) 141 | { 142 | selectButton.Enabled = scenesTree.SelectedNode.Tag != null; 143 | } 144 | 145 | private void scenesTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) 146 | { 147 | if (selectButton.Enabled) 148 | { 149 | selectButton_Click(sender, e); 150 | } 151 | } 152 | 153 | private void scenesTree_MouseUp(object sender, MouseEventArgs e) 154 | { 155 | if (scenesTree.SelectedNode == null) 156 | { 157 | selectButton.Enabled = false; 158 | } 159 | } 160 | 161 | private void scenesTree_KeyDown(object sender, KeyEventArgs e) 162 | { 163 | 164 | } 165 | 166 | private void browse_Click(object sender, EventArgs e) 167 | { 168 | OpenFileDialog open = new OpenFileDialog(); 169 | open.Filter = "Scene File|*.bin"; 170 | if (open.ShowDialog() != DialogResult.Cancel) 171 | { 172 | Result = open.FileName; 173 | Close(); 174 | } 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /ManiacEditor/SceneSelect.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 | -------------------------------------------------------------------------------- /ManiacEditor/TextureCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using System.Drawing; 8 | using SharpDX.Direct3D9; 9 | using SharpDX; 10 | using System.Drawing.Imaging; 11 | using System.Runtime.InteropServices; 12 | 13 | namespace ManiacEditor 14 | { 15 | public class TextureCreator 16 | { 17 | public static Texture FromBitmap(Device device, Bitmap bitmap) 18 | { 19 | Texture texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.Dynamic, Format.A8R8G8B8, Pool.Default); 20 | DataStream data; 21 | DataRectangle rec = texture.LockRectangle(0, LockFlags.None, out data); 22 | BitmapData bd = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 23 | 24 | int bufferSize = bd.Height * bd.Stride; 25 | 26 | //create data buffer 27 | byte[] bytes = new byte[bufferSize]; 28 | 29 | // copy bitmap data into buffer 30 | Marshal.Copy(bd.Scan0, bytes, 0, bytes.Length); 31 | data.Write(bytes, 0, bytes.Length); 32 | 33 | texture.UnlockRectangle(0); 34 | bitmap.UnlockBits(bd); 35 | return texture; 36 | } 37 | 38 | public static Texture FromBitmapSlow(Device device, Bitmap bitmap) 39 | { 40 | // The fast function doesn't work for all textures, even with correct pixel format, not sure why 41 | using (MemoryStream memoryStream = new MemoryStream()) 42 | { 43 | bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); 44 | memoryStream.Seek(0, SeekOrigin.Begin); 45 | return Texture.FromStream(device, memoryStream); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ManiacEditor/ThumbnailFlowLayoutPanel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Drawing; 4 | 5 | namespace ManiacEditor 6 | { 7 | public class ThumbnailFlowLayoutPanel : FlowLayoutPanel 8 | { 9 | protected override Point ScrollToControl(Control activeControl) 10 | { 11 | return this.AutoScrollPosition; 12 | } 13 | public ImageViewer Add(Bitmap bitmap, String name, bool Text) 14 | { 15 | ImageViewer imageViewer = new ImageViewer(); 16 | imageViewer.Dock = DockStyle.Bottom; 17 | imageViewer.Image = bitmap; 18 | imageViewer.IsText = Text; 19 | imageViewer.Width = bitmap.Width + 8; 20 | imageViewer.Height = bitmap.Height + 8 + ((Text) ? 12 : 0); 21 | imageViewer.Name = name; 22 | imageViewer.IsThumbnail = false; 23 | 24 | Controls.Add(imageViewer); 25 | 26 | return imageViewer; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /ManiacEditor/TilesList.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ManiacEditor 2 | { 3 | partial class TilesList 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 Component 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 | this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); 32 | this.panel1 = new System.Windows.Forms.Panel(); 33 | this.graphicPanel = new ManiacEditor.DevicePanel(); 34 | this.panel1.SuspendLayout(); 35 | this.SuspendLayout(); 36 | // 37 | // vScrollBar1 38 | // 39 | this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right; 40 | this.vScrollBar1.Location = new System.Drawing.Point(126, 0); 41 | this.vScrollBar1.Name = "vScrollBar1"; 42 | this.vScrollBar1.Size = new System.Drawing.Size(20, 146); 43 | this.vScrollBar1.TabIndex = 0; 44 | this.vScrollBar1.ValueChanged += new System.EventHandler(this.vScrollBar1_ValueChanged); 45 | // 46 | // panel1 47 | // 48 | this.panel1.Controls.Add(this.graphicPanel); 49 | this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; 50 | this.panel1.Location = new System.Drawing.Point(0, 0); 51 | this.panel1.Name = "panel1"; 52 | this.panel1.Size = new System.Drawing.Size(126, 146); 53 | this.panel1.TabIndex = 2; 54 | this.panel1.Resize += new System.EventHandler(this.panel1_Resize); 55 | // 56 | // graphicPanel 57 | // 58 | this.graphicPanel.AllowDrop = true; 59 | this.graphicPanel.DeviceBackColor = System.Drawing.Color.White; 60 | this.graphicPanel.Location = new System.Drawing.Point(0, 0); 61 | this.graphicPanel.Name = "graphicPanel"; 62 | this.graphicPanel.Size = new System.Drawing.Size(126, 146); 63 | this.graphicPanel.TabIndex = 2; 64 | this.graphicPanel.OnRender += new ManiacEditor.RenderEventHandler(this.graphicPanel_OnRender); 65 | this.graphicPanel.DragEnter += new System.Windows.Forms.DragEventHandler(this.graphicPanel_DragEnter); 66 | this.graphicPanel.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.graphicPanel_MouseDoubleClick); 67 | this.graphicPanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.graphicPanel_MouseDown); 68 | this.graphicPanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.graphicPanel_MouseMove); 69 | this.graphicPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.graphicPanel_MouseUp); 70 | this.graphicPanel.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.graphicPanel_MouseWheel); 71 | this.graphicPanel.Resize += new System.EventHandler(this.graphicPanel_Resize); 72 | // 73 | // TilesList 74 | // 75 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 76 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 77 | this.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; 78 | this.Controls.Add(this.panel1); 79 | this.Controls.Add(this.vScrollBar1); 80 | this.Name = "TilesList"; 81 | this.Size = new System.Drawing.Size(146, 146); 82 | this.panel1.ResumeLayout(false); 83 | this.ResumeLayout(false); 84 | 85 | } 86 | 87 | #endregion 88 | 89 | private System.Windows.Forms.VScrollBar vScrollBar1; 90 | private System.Windows.Forms.Panel panel1; 91 | private DevicePanel graphicPanel; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ManiacEditor/TilesList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using RSDKv5; 11 | 12 | namespace ManiacEditor 13 | { 14 | public partial class TilesList : UserControl, IDrawArea 15 | { 16 | public GIF TilesImage; 17 | 18 | const int TILE_SIZE = 16; 19 | 20 | int _tileScale = 2; 21 | public int TileScale { get { return _tileScale; } set { _tileScale = value; AdjustControls(); } } 22 | 23 | public int BorderSize = 1; 24 | 25 | public int SelectedTile = -1; 26 | 27 | public Action TileDoubleClick; 28 | 29 | public Point mouseDownPos; 30 | 31 | bool _flipHorizontal; 32 | bool _flipVertical; 33 | 34 | public bool FlipHorizontal { get { return _flipHorizontal; } set { _flipHorizontal = value; graphicPanel.Render(); } } 35 | public bool FlipVertical { get { return _flipVertical; } set { _flipVertical = value; graphicPanel.Render(); } } 36 | 37 | public TilesList() 38 | { 39 | InitializeComponent(); 40 | 41 | graphicPanel.Init(this); 42 | } 43 | 44 | private void ResizeGraphicPanel(int width = 0, int height = 0) 45 | { 46 | graphicPanel.Width = width; 47 | graphicPanel.Height = height; 48 | } 49 | 50 | public void DisposeTextures() 51 | { 52 | TilesImage?.DisposeTextures(); 53 | } 54 | 55 | private void graphicPanel_Resize(object sender, EventArgs e) 56 | { 57 | graphicPanel.ResetDevice(); 58 | 59 | } 60 | 61 | private void graphicPanel_OnRender(object sender, DeviceEventArgs e) 62 | { 63 | 64 | if (TilesImage != null) { 65 | // Create a local version of the graphics object for the PictureBox. 66 | 67 | int tile_size = (TILE_SIZE + BorderSize * 2); 68 | 69 | int tiles_per_line = panel1.Width / tile_size / TileScale; 70 | 71 | // Draw a string on the PictureBox. 72 | for (int i = (vScrollBar1.Value / tile_size / TileScale) * tiles_per_line; i < ((vScrollBar1.Value + panel1.Height) / tile_size / TileScale) * tiles_per_line + tiles_per_line; ++i) 73 | { 74 | if (i < 0x400) 75 | { 76 | graphicPanel.DrawBitmap(TilesImage.GetTexture(graphicPanel._device, new Rectangle(0, i * TILE_SIZE, TILE_SIZE, TILE_SIZE), _flipHorizontal, _flipVertical), 77 | (i % tiles_per_line) * tile_size + BorderSize, (i / tiles_per_line) * tile_size + BorderSize, TILE_SIZE, TILE_SIZE, false, 255); 78 | } 79 | else 80 | { 81 | // Draw red X 82 | graphicPanel.DrawLine( 83 | (i % tiles_per_line) * tile_size + BorderSize, 84 | (i / tiles_per_line) * tile_size + BorderSize, 85 | (i % tiles_per_line) * tile_size + tile_size - BorderSize, 86 | (i / tiles_per_line) * tile_size + tile_size - BorderSize, 87 | System.Drawing.Color.Red); 88 | graphicPanel.DrawLine( 89 | (i % tiles_per_line) * tile_size + tile_size - BorderSize * 2, 90 | (i / tiles_per_line) * tile_size + BorderSize, 91 | (i % tiles_per_line) * tile_size, 92 | (i / tiles_per_line) * tile_size + tile_size - BorderSize, 93 | System.Drawing.Color.Red); 94 | } 95 | } 96 | for (int i = 0; i < tiles_per_line; ++i) 97 | { 98 | graphicPanel.DrawLine(i * tile_size, vScrollBar1.Value / TileScale, i * tile_size, (vScrollBar1.Value + panel1.Height) / TileScale, System.Drawing.Color.Black); 99 | graphicPanel.DrawLine(i * tile_size + tile_size - BorderSize, vScrollBar1.Value / TileScale, i * tile_size + tile_size - BorderSize, (vScrollBar1.Value + panel1.Height) / TileScale, System.Drawing.Color.Black); 100 | } 101 | for (int i = (vScrollBar1.Value / tile_size / TileScale); i < ((vScrollBar1.Value + panel1.Height) / tile_size / TileScale) + 1; ++i) 102 | { 103 | graphicPanel.DrawLine(0, i * tile_size, tiles_per_line * tile_size, i * tile_size, System.Drawing.Color.Black); 104 | graphicPanel.DrawLine(0, i * tile_size + tile_size - BorderSize, tiles_per_line * tile_size, i * tile_size + tile_size - BorderSize, System.Drawing.Color.Black); 105 | } 106 | if (SelectedTile != -1) 107 | { 108 | graphicPanel.DrawLine((SelectedTile % tiles_per_line) * tile_size, (SelectedTile / tiles_per_line) * tile_size, (SelectedTile % tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile / tiles_per_line) * tile_size, System.Drawing.Color.Red); 109 | graphicPanel.DrawLine((SelectedTile % tiles_per_line) * tile_size, (SelectedTile / tiles_per_line) * tile_size, (SelectedTile % tiles_per_line) * tile_size, (SelectedTile / tiles_per_line) * tile_size + tile_size - BorderSize, System.Drawing.Color.Red); 110 | graphicPanel.DrawLine((SelectedTile % tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile / tiles_per_line) * tile_size, (SelectedTile % tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile / tiles_per_line) * tile_size + tile_size - BorderSize, System.Drawing.Color.Red); 111 | graphicPanel.DrawLine((SelectedTile % tiles_per_line) * tile_size, (SelectedTile / tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile % tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile / tiles_per_line) * tile_size + tile_size - BorderSize, System.Drawing.Color.Red); 112 | // TODO: Need to fix the line drawing the DevicePanel 113 | graphicPanel.DrawLine((SelectedTile % tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile / tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile % tiles_per_line) * tile_size + tile_size - BorderSize, (SelectedTile / tiles_per_line) * tile_size + tile_size - BorderSize, System.Drawing.Color.Red); 114 | } 115 | } 116 | } 117 | 118 | public Rectangle GetScreen() 119 | { 120 | return new Rectangle(0, vScrollBar1.Value, graphicPanel.DrawWidth, graphicPanel.DrawHeight); 121 | } 122 | 123 | public double GetZoom() 124 | { 125 | return TileScale; 126 | } 127 | 128 | private void panel1_Resize(object sender, EventArgs e) 129 | { 130 | AdjustControls(); 131 | } 132 | 133 | private void AdjustControls() 134 | { 135 | int tile_size = (TILE_SIZE + BorderSize * 2); 136 | int tiles_per_line = panel1.Width / tile_size / TileScale; 137 | 138 | vScrollBar1.Maximum = ((0x400 + tiles_per_line + 1) / tiles_per_line) * tile_size * TileScale; 139 | vScrollBar1.LargeChange = Math.Min(panel1.Height, vScrollBar1.Maximum); 140 | if (vScrollBar1.LargeChange == vScrollBar1.Maximum) 141 | vScrollBar1.Enabled = false; 142 | else 143 | vScrollBar1.Enabled = true; 144 | vScrollBar1.SmallChange = tile_size * TileScale * (panel1.Height / tile_size / TileScale); 145 | vScrollBar1.Value = Math.Min(vScrollBar1.Value, vScrollBar1.Maximum - vScrollBar1.LargeChange); 146 | 147 | graphicPanel.DrawWidth = panel1.Width; 148 | graphicPanel.DrawHeight = Math.Max(vScrollBar1.Maximum, panel1.Height); 149 | while (panel1.Width > graphicPanel.Width) 150 | graphicPanel.Width *= 2; 151 | while (panel1.Height > graphicPanel.Height) 152 | graphicPanel.Height *= 2; 153 | graphicPanel.Render(); 154 | } 155 | 156 | private void vScrollBar1_ValueChanged(object sender, EventArgs e) 157 | { 158 | graphicPanel.Render(); 159 | } 160 | 161 | private void graphicPanel_MouseWheel(object sender, MouseEventArgs e) 162 | { 163 | vScrollBar1.Value = Math.Max(Math.Min(vScrollBar1.Value - (e.Delta * vScrollBar1.SmallChange / 120), vScrollBar1.Maximum - vScrollBar1.LargeChange), 0); 164 | } 165 | 166 | private void ClickTile(int x, int y) 167 | { 168 | int tile_size = (TILE_SIZE + BorderSize * 2); 169 | int tiles_per_line = panel1.Width / tile_size / TileScale; 170 | 171 | int tile_number = ((y / tile_size / TileScale) * tiles_per_line) + (x / tile_size / TileScale); 172 | if (x / tile_size / TileScale < tiles_per_line && tile_number >= 0 && tile_number < 0x400) 173 | { 174 | SelectedTile = tile_number; 175 | } 176 | else 177 | { 178 | SelectedTile = -1; 179 | } 180 | graphicPanel.Render(); 181 | } 182 | 183 | private void graphicPanel_MouseDown(object sender, MouseEventArgs e) 184 | { 185 | if (e.Button == MouseButtons.Left) 186 | { 187 | ClickTile(e.X, e.Y); 188 | mouseDownPos = e.Location; 189 | } 190 | } 191 | 192 | private void graphicPanel_MouseDoubleClick(object sender, MouseEventArgs e) 193 | { 194 | if (e.Button == MouseButtons.Left) 195 | { 196 | ClickTile(e.X, e.Y); 197 | if (SelectedTile != -1 && TileDoubleClick != null) 198 | { 199 | TileDoubleClick(SelectedTile); 200 | } 201 | } 202 | } 203 | 204 | private void graphicPanel_MouseUp(object sender, MouseEventArgs e) 205 | { 206 | } 207 | 208 | private void graphicPanel_DragEnter(object sender, DragEventArgs e) 209 | { 210 | e.Effect = DragDropEffects.Move; 211 | } 212 | 213 | private void graphicPanel_MouseMove(object sender, MouseEventArgs e) 214 | { 215 | if (e.Button == MouseButtons.Left) 216 | { 217 | dynamic dx = e.X - mouseDownPos.X; 218 | dynamic dy = e.Y - mouseDownPos.Y; 219 | if (Math.Abs(dx) >= SystemInformation.DoubleClickSize.Width || Math.Abs(dy) >= SystemInformation.DoubleClickSize.Height) 220 | { 221 | if (SelectedTile != -1) 222 | { 223 | Int32 val = SelectedTile; 224 | DoDragDrop(val, DragDropEffects.Move); 225 | } 226 | } 227 | } 228 | } 229 | 230 | public new void Dispose() 231 | { 232 | graphicPanel.Dispose(); 233 | base.Dispose(); 234 | } 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /ManiacEditor/TilesList.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 | -------------------------------------------------------------------------------- /ManiacEditor/TilesToolbar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using RSDKv5; 11 | 12 | namespace ManiacEditor 13 | { 14 | public partial class TilesToolbar : UserControl 15 | { 16 | public Action TileDoubleClick 17 | { 18 | get 19 | { 20 | return tilesList.TileDoubleClick; 21 | } 22 | set 23 | { 24 | tilesList.TileDoubleClick = value; 25 | } 26 | } 27 | 28 | public Action TileOptionChanged; 29 | 30 | CheckBox[] selectTileOptionsCheckboxes = new CheckBox[6]; 31 | CheckBox[] tileOptionsCheckboxes = new CheckBox[4]; 32 | bool setCheckboxes; 33 | 34 | public int SelectedTile 35 | { 36 | get { 37 | int res = tilesList.SelectedTile; 38 | for (int i = 0; i < selectTileOptionsCheckboxes.Length; ++i) 39 | if (selectTileOptionsCheckboxes[i].Checked) res |= 1 << (10 + i); 40 | return res; 41 | } 42 | } 43 | 44 | public bool ShowShortcuts { set { UpdateShortcuts(value); } } 45 | 46 | public enum TileOptionState 47 | { 48 | Disabled, 49 | Checked, 50 | Unchcked, 51 | Indeterminate 52 | } 53 | 54 | public void SetSelectTileOption(int option, bool state) 55 | { 56 | selectTileOptionsCheckboxes[option].Checked = state; 57 | } 58 | 59 | public void SetTileOptionState(int option, TileOptionState state) 60 | { 61 | setCheckboxes = true; 62 | switch (state) 63 | { 64 | case TileOptionState.Disabled: 65 | tileOptionsCheckboxes[option].Enabled = false; 66 | tileOptionsCheckboxes[option].Checked = false; 67 | break; 68 | case TileOptionState.Checked: 69 | tileOptionsCheckboxes[option].Enabled = true; 70 | tileOptionsCheckboxes[option].CheckState = CheckState.Checked; 71 | break; 72 | case TileOptionState.Unchcked: 73 | tileOptionsCheckboxes[option].Enabled = true; 74 | tileOptionsCheckboxes[option].CheckState = CheckState.Unchecked; 75 | break; 76 | case TileOptionState.Indeterminate: 77 | tileOptionsCheckboxes[option].Enabled = true; 78 | tileOptionsCheckboxes[option].CheckState = CheckState.Indeterminate; 79 | break; 80 | } 81 | setCheckboxes = false; 82 | } 83 | 84 | public TilesToolbar(StageTiles tiles) 85 | { 86 | InitializeComponent(); 87 | 88 | tileOptionsCheckboxes[0] = tileOption1; 89 | tileOptionsCheckboxes[1] = tileOption2; 90 | tileOptionsCheckboxes[2] = tileOption3; 91 | tileOptionsCheckboxes[3] = tileOption4; 92 | 93 | selectTileOptionsCheckboxes[0] = option1CheckBox; 94 | selectTileOptionsCheckboxes[1] = option2CheckBox; 95 | selectTileOptionsCheckboxes[2] = option3CheckBox; 96 | selectTileOptionsCheckboxes[3] = option4CheckBox; 97 | selectTileOptionsCheckboxes[4] = option5CheckBox; 98 | selectTileOptionsCheckboxes[5] = option6CheckBox; 99 | 100 | tilesList.TilesImage = tiles.Image.Clone(); 101 | tilesList.TileScale = 1 << trackBar1.Value; 102 | 103 | UpdateShortcuts(); 104 | } 105 | 106 | private void trackBar1_ValueChanged(object sender, EventArgs e) 107 | { 108 | tilesList.TileScale = 1 << trackBar1.Value; 109 | } 110 | 111 | public new void Dispose() 112 | { 113 | tilesList.Dispose(); 114 | base.Dispose(); 115 | } 116 | 117 | private void TilesToolbar_Load(object sender, EventArgs e) 118 | { 119 | 120 | } 121 | 122 | private void option1CheckBox_CheckedChanged(object sender, EventArgs e) 123 | { 124 | tilesList.FlipHorizontal = option1CheckBox.Checked; 125 | } 126 | 127 | private void option2CheckBox_CheckedChanged(object sender, EventArgs e) 128 | { 129 | tilesList.FlipVertical = option2CheckBox.Checked; 130 | } 131 | 132 | private void tileOption1_CheckedChanged(object sender, EventArgs e) 133 | { 134 | if (!setCheckboxes) TileOptionChanged?.Invoke(0, tileOption1.Checked); 135 | } 136 | 137 | private void tileOption2_CheckedChanged(object sender, EventArgs e) 138 | { 139 | if (!setCheckboxes) TileOptionChanged?.Invoke(1, tileOption2.Checked); 140 | } 141 | 142 | private void tileOption3_CheckedChanged(object sender, EventArgs e) 143 | { 144 | if (!setCheckboxes) TileOptionChanged?.Invoke(2, tileOption3.Checked); 145 | } 146 | 147 | private void tileOption4_CheckedChanged(object sender, EventArgs e) 148 | { 149 | if (!setCheckboxes) TileOptionChanged?.Invoke(3, tileOption4.Checked); 150 | } 151 | 152 | private void UpdateShortcuts(bool show=false) 153 | { 154 | if (show) 155 | { 156 | option1CheckBox.Text = "Flip Horizontal (Ctrl)"; 157 | option2CheckBox.Text = "Flip Vertical (Shift)"; 158 | } 159 | else 160 | { 161 | option1CheckBox.Text = "Flip Horizontal"; 162 | option2CheckBox.Text = "Flip Vertical"; 163 | } 164 | } 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /ManiacEditor/TilesToolbar.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 | -------------------------------------------------------------------------------- /ManiacEditor/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Maniac Editor - Sonic Mania Scene Editor 2 | 3 | ### [Download (BETA)](https://github.com/koolkdev/ManiacEditor/releases/latest) 4 | 5 | 6 | ## Status 7 | [![Build status](https://ci.appveyor.com/api/projects/status/fpgsoc21l14lb743/branch/master?svg=true)](https://ci.appveyor.com/project/koolkdev/maniaceditor/branch/master) 8 | 9 | ## Tiles editing 10 | 11 | ### Keyboard shortcuts 12 | **Ctrl + D** - Duplicate selected 13 | **Ctrl + X / C / V** - Cut / Copy / Paste 14 | **Ctrl + Z / Y** - Redo / Undo 15 | **Delete** - Delete selected 16 | **M** - Mirror tile image (X-axis) 17 | **F** - Flip tile image (Y-axis) 18 | **Arrow keys** - Move selected tiles 19 | 20 | ### Editing modes 21 | ![Pointer tool](https://github.com/koolkdev/m_e_images/blob/master/pointerButton.Image.png) - Default mode 22 | Clicked tile is immediatily selected. To select multiple tiles, you can click and drag from empty spot to create a selection box. 23 | You can move selected tiles by click on one of them and dragging them with your mouse. 24 | You can use **Shift** and **Ctrl** + click (and drag) to add/remove items from your selection. 25 | You can duplicate tiles by holding **Ctrl** and dragging the selected tiles. 26 | You can add new tiles by dragging them from the selection window or double click on them. 27 | You can change the properties of the selected tiles by click on the checkboxes at the bottom of the tiles sidebar. 28 | 29 | ![Selection tool](https://github.com/koolkdev/m_e_images/blob/master/selectTool.Image.png) - Selection tool 30 | Clicking and dragging will create a selection box, even if you clicked on a tile. (in the default mode it will drag the tile instead) 31 | You can move selected tiles by click on one of them and dragging them with your mouse. 32 | You can use **Shift** and **Ctrl** + click (and drag) to add/remove items from your selection. 33 | You can duplicate tiles by holding **Ctrl** and dragging the selected tiles. 34 | You can add new tiles by dragging them from the selection window or double click on them. 35 | You can change the properties of the selected tiles by click on the checkboxes at the bottom of the tiles sidebar. 36 | 37 | ![Place tiles tool](https://github.com/koolkdev/m_e_images/blob/master/placeTilesButton.Image.png) - Place tiles tool 38 | With this mode you can paint the current selected tile (in the tiles sidebar) by clicking and dragging. 39 | You can remove tile by doing the same with the right mouse button. 40 | You can hold **Ctrl** and/or **Shift** to mirror/flip the placed tile. 41 | You can choose which properties the placed tiles will have by clicking on the checkboxes below the tiles selection window. 42 | 43 | 44 | -------------------------------------------------------------------------------- /RSDKv5/AttributeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public enum AttributeTypes 11 | { 12 | UINT8 = 0, 13 | UINT16 = 1, 14 | UINT32 = 2, 15 | INT8 = 3, 16 | INT16 = 4, 17 | INT32 = 5, 18 | VAR = 6, 19 | BOOL = 7, 20 | STRING = 8, 21 | POSITION = 9, 22 | COLOR = 11, 23 | } 24 | 25 | public class AttributeInfo 26 | { 27 | public readonly NameIdentifier Name; 28 | public readonly AttributeTypes Type; 29 | 30 | public AttributeInfo(NameIdentifier name, AttributeTypes type) 31 | { 32 | this.Name = name; 33 | this.Type = type; 34 | } 35 | 36 | public AttributeInfo(string name, AttributeTypes type) : this(new NameIdentifier(name), type) { } 37 | 38 | internal AttributeInfo(Reader reader, ObjectInfo info = null) 39 | { 40 | Name = new NameIdentifier(reader); 41 | Type = (AttributeTypes)reader.ReadByte(); 42 | if (info != null) 43 | { 44 | var attribute = info.GetAttributeInfo(Name); 45 | if (attribute != null) 46 | { 47 | // Type mismatch 48 | if (attribute.Type != Type) return; 49 | Name = attribute.Name; 50 | } 51 | } 52 | } 53 | 54 | internal void Write(Writer writer) 55 | { 56 | Name.Write(writer); 57 | writer.Write((byte)Type); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /RSDKv5/AttributeValue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class AttributeValue 11 | { 12 | byte value_uint8; 13 | ushort value_uint16; 14 | uint value_uint32; 15 | sbyte value_int8; 16 | short value_int16; 17 | int value_int32; 18 | uint value_var; 19 | bool value_bool; 20 | string value_string; 21 | Position value_position; 22 | Color value_color; 23 | 24 | public readonly AttributeTypes Type; 25 | 26 | private void CheckType(AttributeTypes type) 27 | { 28 | if (type != Type) 29 | { 30 | throw new Exception("Unexpected value type."); 31 | } 32 | } 33 | public byte ValueUInt8 34 | { 35 | get { CheckType(AttributeTypes.UINT8); return value_uint8; } 36 | set { CheckType(AttributeTypes.UINT8); value_uint8 = value; } 37 | } 38 | public ushort ValueUInt16 39 | { 40 | get { CheckType(AttributeTypes.UINT16); return value_uint16; } 41 | set { CheckType(AttributeTypes.UINT16); value_uint16 = value; } 42 | } 43 | public uint ValueUInt32 44 | { 45 | get { CheckType(AttributeTypes.UINT32); return value_uint32; } 46 | set { CheckType(AttributeTypes.UINT32); value_uint32 = value; } 47 | } 48 | public sbyte ValueInt8 49 | { 50 | get { CheckType(AttributeTypes.INT8); return value_int8; } 51 | set { CheckType(AttributeTypes.INT8); value_int8 = value; } 52 | } 53 | public short ValueInt16 54 | { 55 | get { CheckType(AttributeTypes.INT16); return value_int16; } 56 | set { CheckType(AttributeTypes.INT16); value_int16 = value; } 57 | } 58 | public int ValueInt32 59 | { 60 | get { CheckType(AttributeTypes.INT32); return value_int32; } 61 | set { CheckType(AttributeTypes.INT32); value_int32 = value; } 62 | } 63 | public uint ValueVar 64 | { 65 | get { CheckType(AttributeTypes.VAR); return value_var; } 66 | set { CheckType(AttributeTypes.VAR); value_var = value; } 67 | } 68 | public bool ValueBool 69 | { 70 | get { CheckType(AttributeTypes.BOOL); return value_bool; } 71 | set { CheckType(AttributeTypes.BOOL); value_bool = value; } 72 | } 73 | public string ValueString 74 | { 75 | get { CheckType(AttributeTypes.STRING); return value_string; } 76 | set { CheckType(AttributeTypes.STRING); value_string = value; } 77 | } 78 | public Position ValuePosition 79 | { 80 | get { CheckType(AttributeTypes.POSITION); return value_position; } 81 | set { CheckType(AttributeTypes.POSITION); value_position = value; } 82 | } 83 | public Color ValueColor 84 | { 85 | get { CheckType(AttributeTypes.COLOR); return value_color; } 86 | set { CheckType(AttributeTypes.COLOR); value_color = value; } 87 | } 88 | 89 | public AttributeValue(AttributeTypes type) 90 | { 91 | Type = type; 92 | } 93 | 94 | public AttributeValue Clone() 95 | { 96 | AttributeValue n = new AttributeValue(Type); 97 | 98 | n.value_uint8 = value_uint8; 99 | n.value_uint16 = value_uint16; 100 | n.value_uint32 = value_uint32; 101 | n.value_int8 = value_int8; 102 | n.value_int16 = value_int16; 103 | n.value_int32 = value_int32; 104 | n.value_var = value_var; 105 | n.value_bool = value_bool; 106 | n.value_string = value_string; 107 | n.value_position = value_position; 108 | n.value_color = value_color; 109 | 110 | return n; 111 | } 112 | 113 | internal AttributeValue(Reader reader, AttributeTypes type) 114 | { 115 | Type = type; 116 | Read(reader); 117 | } 118 | 119 | internal void Read(Reader reader) 120 | { 121 | switch (Type) 122 | { 123 | case AttributeTypes.UINT8: 124 | value_uint8 = reader.ReadByte(); 125 | break; 126 | case AttributeTypes.UINT16: 127 | value_uint16 = reader.ReadUInt16(); 128 | break; 129 | case AttributeTypes.UINT32: 130 | value_uint32 = reader.ReadUInt32(); 131 | break; 132 | case AttributeTypes.INT8: 133 | value_int8 = reader.ReadSByte(); 134 | break; 135 | case AttributeTypes.INT16: 136 | value_int16 = reader.ReadInt16(); 137 | break; 138 | case AttributeTypes.INT32: 139 | value_int32 = reader.ReadInt32(); 140 | break; 141 | case AttributeTypes.VAR: 142 | value_var = reader.ReadUInt32(); 143 | break; 144 | case AttributeTypes.BOOL: 145 | value_bool = reader.ReadUInt32() != 0; 146 | break; 147 | case AttributeTypes.STRING: 148 | value_string = reader.ReadRSDKUnicodeString(); 149 | break; 150 | case AttributeTypes.POSITION: 151 | value_position = new Position(reader); 152 | break; 153 | case AttributeTypes.COLOR: 154 | value_color = new Color(reader); 155 | break; 156 | } 157 | } 158 | 159 | internal void Write(Writer writer) 160 | { 161 | switch (Type) 162 | { 163 | case AttributeTypes.UINT8: 164 | writer.Write(value_uint8); 165 | break; 166 | case AttributeTypes.UINT16: 167 | writer.Write(value_uint16); 168 | break; 169 | case AttributeTypes.UINT32: 170 | writer.Write(value_uint32); 171 | break; 172 | case AttributeTypes.INT8: 173 | writer.Write(value_int8); 174 | break; 175 | case AttributeTypes.INT16: 176 | writer.Write(value_int16); 177 | break; 178 | case AttributeTypes.INT32: 179 | writer.Write(value_int32); 180 | break; 181 | case AttributeTypes.VAR: 182 | writer.Write(value_var); 183 | break; 184 | case AttributeTypes.BOOL: 185 | writer.Write((uint)(value_bool ? 1 : 0)); 186 | break; 187 | case AttributeTypes.STRING: 188 | writer.WriteRSDKUnicodeString(value_string); 189 | break; 190 | case AttributeTypes.POSITION: 191 | value_position.Write(writer); 192 | break; 193 | case AttributeTypes.COLOR: 194 | value_color.Write(writer); 195 | break; 196 | } 197 | } 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /RSDKv5/Color.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public struct Color 11 | { 12 | 13 | public byte R, G, B, A; 14 | 15 | public static Color EMPTY = new Color(0, 0, 0, 0); 16 | 17 | public Color(byte R=0, byte G=0, byte B=0, byte A=255) 18 | { 19 | this.R = R; 20 | this.G = G; 21 | this.B = B; 22 | this.A = A; 23 | } 24 | 25 | internal Color(Reader reader) : this() 26 | { 27 | Read(reader); 28 | } 29 | 30 | internal void Read(Reader reader) 31 | { 32 | B = reader.ReadByte(); 33 | G = reader.ReadByte(); 34 | R = reader.ReadByte(); 35 | A = reader.ReadByte(); 36 | } 37 | 38 | internal void Write(Writer writer) 39 | { 40 | writer.Write(B); 41 | writer.Write(G); 42 | writer.Write(R); 43 | writer.Write(A); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /RSDKv5/CommonConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class CommonConfig 11 | { 12 | public static readonly byte[] MAGIC = new byte[] { (byte)'C', (byte)'F', (byte)'G', (byte)'\0' }; 13 | 14 | const int PALETTES_COUNT = 8; 15 | 16 | public List ObjectsNames = new List(); 17 | public Palette[] Palettes = new Palette[PALETTES_COUNT]; 18 | public List WAVs = new List(); 19 | 20 | internal void ReadMagic(Reader reader) 21 | { 22 | if (!reader.ReadBytes(4).SequenceEqual(MAGIC)) 23 | throw new Exception("Invalid config file header magic"); 24 | } 25 | 26 | internal void WriteMagic(Writer writer) 27 | { 28 | writer.Write(MAGIC); 29 | } 30 | 31 | internal void ReadCommonConfig(Reader reader) 32 | { 33 | this.ReadObjectsNames(reader); 34 | this.ReadPalettes(reader); 35 | this.ReadWAVConfiguration(reader); 36 | } 37 | 38 | internal void WriteCommonConfig(Writer writer) 39 | { 40 | this.WriteObjectsNames(writer); 41 | this.WritePalettes(writer); 42 | this.WriteWAVConfiguration(writer); 43 | } 44 | 45 | internal void ReadObjectsNames(Reader reader) 46 | { 47 | byte objects_count = reader.ReadByte(); 48 | for (int i = 0; i < objects_count; ++i) 49 | ObjectsNames.Add(reader.ReadRSDKString()); 50 | } 51 | 52 | internal void WriteObjectsNames(Writer writer) 53 | { 54 | writer.Write((byte)ObjectsNames.Count); 55 | foreach (string name in ObjectsNames) 56 | writer.WriteRSDKString(name); 57 | } 58 | 59 | internal void ReadPalettes(Reader reader) 60 | { 61 | for (int i = 0; i < PALETTES_COUNT; ++i) 62 | Palettes[i] = new Palette(reader); 63 | } 64 | 65 | internal void WritePalettes(Writer writer) 66 | { 67 | foreach (Palette palette in Palettes) 68 | palette.Write(writer); 69 | } 70 | 71 | internal void ReadWAVConfiguration(Reader reader) 72 | { 73 | byte wavs_count = reader.ReadByte(); 74 | for (int i = 0; i < wavs_count; ++i) 75 | WAVs.Add(new WAVConfiguration(reader)); 76 | } 77 | 78 | internal void WriteWAVConfiguration(Writer writer) 79 | { 80 | writer.Write((byte)WAVs.Count); 81 | foreach (WAVConfiguration wav in WAVs) 82 | wav.Write(writer); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /RSDKv5/GIF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Drawing; 6 | using System.Threading.Tasks; 7 | using SharpDX.Direct3D9; 8 | using SystemColor = System.Drawing.Color; 9 | using System.IO; 10 | 11 | namespace RSDKv5 12 | { 13 | public class GIF : IDisposable 14 | { 15 | Bitmap bitmap; 16 | 17 | Dictionary, Bitmap> bitmapCache = new Dictionary, Bitmap>(); 18 | Dictionary, Texture> texturesCache = new Dictionary, Texture>(); 19 | 20 | public GIF(string filename) 21 | { 22 | bitmap = new Bitmap(filename); 23 | // TODO: Proper transparent (palette index 0) 24 | bitmap.MakeTransparent(SystemColor.FromArgb(0xff00ff)); 25 | } 26 | 27 | public GIF(Bitmap bitmap) 28 | { 29 | this.bitmap = new Bitmap(bitmap); 30 | } 31 | 32 | private Bitmap CropImage(Bitmap source, Rectangle section) 33 | { 34 | // An empty bitmap which will hold the cropped image 35 | Bitmap bmp = new Bitmap(section.Width, section.Height); 36 | 37 | Graphics g = Graphics.FromImage(bmp); 38 | 39 | // Draw the given area (section) of the source image 40 | // at location 0,0 on the empty bitmap (bmp) 41 | g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel); 42 | 43 | return bmp; 44 | } 45 | 46 | public Bitmap GetBitmap(Rectangle section, bool flipX = false, bool flipY = false) 47 | { 48 | Bitmap bmp; 49 | if (bitmapCache.TryGetValue(new Tuple(section, flipX, flipY), out bmp)) return bmp; 50 | 51 | bmp = CropImage(bitmap, section); 52 | if (flipX) 53 | { 54 | bmp.RotateFlip(RotateFlipType.RotateNoneFlipX); 55 | } 56 | if (flipY) 57 | { 58 | bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); 59 | } 60 | 61 | bitmapCache[new Tuple(section, flipX, flipY)] = bmp; 62 | return bmp; 63 | } 64 | 65 | // TOREMOVE 66 | public Texture GetTexture(Device device, Rectangle section, bool flipX = false, bool flipY = false) 67 | { 68 | Texture texture; 69 | if (texturesCache.TryGetValue(new Tuple(section, flipX, flipY), out texture)) return texture; 70 | 71 | using (MemoryStream memoryStream = new MemoryStream()) 72 | { 73 | GetBitmap(section, flipX, flipY).Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); 74 | memoryStream.Seek(0, SeekOrigin.Begin); 75 | texture = Texture.FromStream(device, memoryStream); 76 | } 77 | 78 | texturesCache[new Tuple(section, flipX, flipY)] = texture; 79 | return texture; 80 | } 81 | 82 | public void Dispose() 83 | { 84 | bitmap.Dispose(); 85 | texturesCache = null; 86 | } 87 | 88 | public void DisposeTextures() 89 | { 90 | foreach (Texture texture in texturesCache.Values) 91 | texture.Dispose(); 92 | texturesCache = new Dictionary, Texture>(); 93 | } 94 | 95 | public GIF Clone() 96 | { 97 | return new GIF(bitmap); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /RSDKv5/GameConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class GameConfig : CommonConfig 11 | { 12 | public String GameName; 13 | public String GameSubname; 14 | public String Version; 15 | 16 | public byte StartSceneCategoryIndex; 17 | public ushort StartSceneIndex; 18 | 19 | public class SceneInfo 20 | { 21 | public string Name; 22 | public string Zone; 23 | public string SceneID; 24 | 25 | internal SceneInfo(Reader reader) 26 | { 27 | Name = reader.ReadRSDKString(); 28 | Zone = reader.ReadRSDKString(); 29 | SceneID = reader.ReadRSDKString(); 30 | } 31 | 32 | internal void Write(Writer writer) 33 | { 34 | writer.WriteRSDKString(Name); 35 | writer.WriteRSDKString(Zone); 36 | writer.WriteRSDKString(SceneID); 37 | } 38 | } 39 | 40 | public class Category 41 | { 42 | public string Name; 43 | public List Scenes = new List(); 44 | 45 | internal Category(Reader reader) 46 | { 47 | Name = reader.ReadRSDKString(); 48 | 49 | byte scenes_count = reader.ReadByte(); 50 | for (int i = 0; i < scenes_count; ++i) 51 | Scenes.Add(new SceneInfo(reader)); 52 | } 53 | 54 | internal void Write(Writer writer) 55 | { 56 | writer.WriteRSDKString(Name); 57 | 58 | writer.Write((byte)Scenes.Count); 59 | foreach (SceneInfo scene in Scenes) 60 | scene.Write(writer); 61 | } 62 | } 63 | 64 | public class ConfigurableMemoryEntry 65 | { 66 | public uint Index; 67 | public int[] Data; 68 | 69 | internal ConfigurableMemoryEntry(Reader reader) 70 | { 71 | Index = reader.ReadUInt32(); 72 | uint Count = reader.ReadUInt32(); 73 | Data = new int[Count]; 74 | for (int i = 0; i < Count; ++i) 75 | Data[i] = reader.ReadInt32(); 76 | } 77 | 78 | internal void Write(Writer writer) 79 | { 80 | writer.Write(Index); 81 | writer.Write((uint)Data.Length); 82 | foreach (uint val in Data) 83 | writer.Write(val); 84 | } 85 | } 86 | 87 | public List Categories = new List(); 88 | 89 | public List ConfigMemory = new List(); 90 | 91 | public GameConfig(string filename) : this(new Reader(filename)) 92 | { 93 | 94 | } 95 | 96 | public GameConfig(Stream stream) : this(new Reader(stream)) 97 | { 98 | 99 | } 100 | 101 | private GameConfig(Reader reader) 102 | { 103 | base.ReadMagic(reader); 104 | 105 | GameName = reader.ReadRSDKString(); 106 | GameSubname = reader.ReadRSDKString(); 107 | Version = reader.ReadRSDKString(); 108 | 109 | StartSceneCategoryIndex = reader.ReadByte(); 110 | StartSceneIndex = reader.ReadUInt16(); 111 | 112 | base.ReadCommonConfig(reader); 113 | 114 | ushort TotalScenes = reader.ReadUInt16(); 115 | 116 | byte categories_count = reader.ReadByte(); 117 | for (int i = 0; i < categories_count; ++i) 118 | Categories.Add(new Category(reader)); 119 | 120 | byte config_memory_count = reader.ReadByte(); 121 | for (int i = 0; i < config_memory_count; ++i) 122 | ConfigMemory.Add(new ConfigurableMemoryEntry(reader)); 123 | } 124 | 125 | public void Write(string filename) 126 | { 127 | using (Writer writer = new Writer(filename)) 128 | this.Write(writer); 129 | } 130 | 131 | public void Write(Stream stream) 132 | { 133 | using (Writer writer = new Writer(stream)) 134 | this.Write(writer); 135 | } 136 | 137 | internal void Write(Writer writer) 138 | { 139 | base.WriteMagic(writer); 140 | 141 | writer.WriteRSDKString(GameName); 142 | writer.WriteRSDKString(GameSubname); 143 | writer.WriteRSDKString(Version); 144 | 145 | writer.Write(StartSceneCategoryIndex); 146 | writer.Write(StartSceneIndex); 147 | 148 | base.WriteCommonConfig(writer); 149 | 150 | writer.Write((ushort)Categories.Select(x => x.Scenes.Count).Sum()); 151 | 152 | writer.Write((byte)Categories.Count); 153 | foreach (Category cat in Categories) 154 | cat.Write(writer); 155 | 156 | writer.Write((byte)ConfigMemory.Count); 157 | foreach (ConfigurableMemoryEntry c in ConfigMemory) 158 | c.Write(writer); 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /RSDKv5/NameIdentifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class NameIdentifier 11 | { 12 | public readonly byte[] Hash; 13 | public readonly String Name = null; 14 | 15 | public NameIdentifier(string name) 16 | { 17 | using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) { 18 | Hash = md5.ComputeHash(new System.Text.ASCIIEncoding().GetBytes(name)); 19 | } 20 | Name = name; 21 | } 22 | 23 | public NameIdentifier(byte[] hash) 24 | { 25 | Hash = hash; 26 | } 27 | 28 | internal NameIdentifier(Reader reader) 29 | { 30 | Hash = reader.ReadBytes(16); 31 | } 32 | 33 | internal void Write(Writer writer) 34 | { 35 | writer.Write(Hash); 36 | } 37 | 38 | public string HashString() 39 | { 40 | return BitConverter.ToString(Hash).Replace("-", string.Empty).ToLower(); 41 | } 42 | 43 | public override string ToString() 44 | { 45 | if (Name != null) return Name; 46 | return HashString(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /RSDKv5/ObjectInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace RSDKv5 8 | { 9 | public class ObjectInfo 10 | { 11 | public readonly NameIdentifier Name; 12 | 13 | public readonly List Attributes; 14 | Dictionary hashToAttribute; 15 | 16 | internal ObjectInfo(NameIdentifier name, List attributes) 17 | { 18 | Name = name; 19 | Attributes = attributes; 20 | hashToAttribute = Attributes.ToDictionary(x => x.Name.HashString()); 21 | } 22 | 23 | public AttributeInfo GetAttributeInfo(NameIdentifier name) 24 | { 25 | AttributeInfo res = null; 26 | hashToAttribute.TryGetValue(name.HashString(), out res); 27 | return res; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RSDKv5/Objects.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using IniParser; 7 | using IniParser.Model; 8 | using System.IO; 9 | 10 | 11 | namespace RSDKv5 12 | { 13 | public class Objects 14 | { 15 | static List objects = new List(); 16 | static Dictionary hashToObject = new Dictionary(); 17 | 18 | public static void InitObjects(Stream stream) 19 | { 20 | var parser = new IniParser.StreamIniDataParser(); 21 | IniData data = parser.ReadData(new StreamReader(stream)); 22 | foreach (var section in data.Sections) 23 | { 24 | List attributes = new List(); 25 | foreach (var key in section.Keys) 26 | { 27 | AttributeTypes type; 28 | switch (key.Value) 29 | { 30 | case "UINT8": 31 | type = AttributeTypes.UINT8; 32 | break; 33 | case "UINT16": 34 | type = AttributeTypes.UINT16; 35 | break; 36 | case "UINT32": 37 | type = AttributeTypes.UINT32; 38 | break; 39 | case "INT8": 40 | type = AttributeTypes.INT8; 41 | break; 42 | case "INT16": 43 | type = AttributeTypes.INT16; 44 | break; 45 | case "INT32": 46 | type = AttributeTypes.INT32; 47 | break; 48 | case "VAR": 49 | type = AttributeTypes.VAR; 50 | break; 51 | case "BOOL": 52 | type = AttributeTypes.BOOL; 53 | break; 54 | case "STRING": 55 | type = AttributeTypes.STRING; 56 | break; 57 | case "POSITION": 58 | type = AttributeTypes.POSITION; 59 | break; 60 | case "COLOR": 61 | type = AttributeTypes.COLOR; 62 | break; 63 | default: 64 | // Unknown attribute 65 | continue; 66 | } 67 | 68 | attributes.Add(new AttributeInfo(new NameIdentifier(key.KeyName), type)); 69 | } 70 | objects.Add(new ObjectInfo(new NameIdentifier(section.SectionName), attributes)); 71 | } 72 | hashToObject = objects.ToDictionary(x => x.Name.HashString()); 73 | } 74 | 75 | public static ObjectInfo GetObjectInfo(NameIdentifier name) 76 | { 77 | ObjectInfo res = null; 78 | hashToObject.TryGetValue(name.HashString(), out res); 79 | return res; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /RSDKv5/Palette.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace RSDKv5 8 | { 9 | public class Palette 10 | { 11 | public const int PALETTE_COLUMNS = 0x10; 12 | public const int COLORS_PER_COLUMN = 0x10; 13 | public const int PALETTE_COLORS = 0x100; 14 | 15 | public PaletteColor[][] Colors = new PaletteColor[PALETTE_COLUMNS][]; 16 | 17 | internal Palette(Reader reader) 18 | { 19 | ushort columns_bitmap = reader.ReadUInt16(); 20 | for (int i = 0; i < PALETTE_COLUMNS; ++i) 21 | { 22 | if ((columns_bitmap & (1 << i)) != 0) 23 | { 24 | Colors[i] = new PaletteColor[COLORS_PER_COLUMN]; 25 | for (int j = 0; j < COLORS_PER_COLUMN; ++j) 26 | Colors[i][j] = new PaletteColor(reader); 27 | } 28 | } 29 | } 30 | 31 | internal void Write(Writer writer) 32 | { 33 | ushort columns_bitmap = 0; 34 | for (int i = 0; i < PALETTE_COLUMNS; ++i) 35 | if (Colors[i] != null) 36 | columns_bitmap |= (ushort)(1 << i); 37 | writer.Write(columns_bitmap); 38 | 39 | foreach (PaletteColor[] column in Colors) 40 | if (column != null) 41 | foreach (PaletteColor color in column) 42 | color.Write(writer); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /RSDKv5/PaletteColor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class PaletteColor 11 | { 12 | 13 | public byte R, G, B; 14 | 15 | public PaletteColor(byte R = 0, byte G = 0, byte B = 0) 16 | { 17 | this.R = R; 18 | this.G = G; 19 | this.B = B; 20 | } 21 | 22 | internal PaletteColor(Reader reader) 23 | { 24 | this.Read(reader); 25 | } 26 | 27 | internal void Read(Reader reader) 28 | { 29 | R = reader.ReadByte(); 30 | G = reader.ReadByte(); 31 | B = reader.ReadByte(); 32 | } 33 | 34 | internal void Write(Writer writer) 35 | { 36 | writer.Write(R); 37 | writer.Write(G); 38 | writer.Write(B); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /RSDKv5/Position.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public struct Position 11 | { 12 | 13 | public struct Value 14 | { 15 | public Value(short high = 0, ushort low = 0) 16 | { 17 | Low = low; 18 | High = high; 19 | } 20 | 21 | public short High; 22 | public ushort Low; 23 | }; 24 | 25 | public Value X; 26 | public Value Y; 27 | 28 | public Position(short x=0, short y=0) 29 | { 30 | X = new Value(x); 31 | Y = new Value(y); 32 | } 33 | 34 | internal Position(Reader reader) : this() 35 | { 36 | Read(reader); 37 | } 38 | 39 | internal void Read(Reader reader) 40 | { 41 | X.Low = reader.ReadUInt16(); 42 | X.High = reader.ReadInt16(); 43 | 44 | Y.Low = reader.ReadUInt16(); 45 | Y.High = reader.ReadInt16(); 46 | } 47 | 48 | internal void Write(Writer writer) 49 | { 50 | writer.Write(X.Low); 51 | writer.Write(X.High); 52 | 53 | writer.Write(Y.Low); 54 | writer.Write(Y.High); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /RSDKv5/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("RSDKv5")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("RSDKv5")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cf5496f8-002b-408f-9b3d-67c88f610283")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /RSDKv5/RSDKv5.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CF5496F8-002B-408F-9B3D-67C88F610283} 8 | Library 9 | Properties 10 | RSDKv5 11 | RSDKv5 12 | v4.5.2 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 | ..\packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll 35 | 36 | 37 | ..\packages\SharpDX.4.0.1\lib\net45\SharpDX.dll 38 | 39 | 40 | ..\packages\SharpDX.Direct3D9.4.0.1\lib\net45\SharpDX.Direct3D9.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | ..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 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 | -------------------------------------------------------------------------------- /RSDKv5/Reader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using zlib; 8 | 9 | namespace RSDKv5 10 | { 11 | internal class Reader : BinaryReader 12 | { 13 | public Reader(Stream stream) : base(stream) 14 | { 15 | } 16 | 17 | public Reader(string file) : base(File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read)) 18 | { 19 | } 20 | 21 | public byte[] ReadBytes(long count) 22 | { 23 | if (count < 0 || count > Int32.MaxValue) 24 | throw new ArgumentOutOfRangeException("requested " + count + " bytes, while only non-negative int32 amount of bytes possible"); 25 | byte[] bytes = base.ReadBytes((int)count); 26 | if (bytes.Length < count) 27 | throw new EndOfStreamException("requested " + count + " bytes, but got only " + bytes.Length + " bytes"); 28 | return bytes; 29 | } 30 | 31 | public byte[] ReadBytes(ulong count) 32 | { 33 | if (count > Int32.MaxValue) 34 | throw new ArgumentOutOfRangeException("requested " + count + " bytes, while only non-negative int32 amount of bytes possible"); 35 | int cnt = (int)count; 36 | byte[] bytes = base.ReadBytes(cnt); 37 | if (bytes.Length < cnt) 38 | throw new EndOfStreamException("requested " + count + " bytes, but got only " + bytes.Length + " bytes"); 39 | return bytes; 40 | } 41 | 42 | public bool IsEof 43 | { 44 | get { return BaseStream.Position >= BaseStream.Length; } 45 | } 46 | 47 | public void Seek(long position, SeekOrigin org) 48 | { 49 | BaseStream.Seek(position, org); 50 | } 51 | 52 | public long Pos 53 | { 54 | get { return BaseStream.Position; } 55 | } 56 | 57 | public long Size 58 | { 59 | get { return BaseStream.Length; } 60 | } 61 | 62 | public uint ReadUInt32BE() 63 | { 64 | byte[] bytes = ReadBytes(4); 65 | Array.Reverse(bytes); 66 | return BitConverter.ToUInt32(bytes, 0); 67 | } 68 | 69 | public string ReadRSDKString() 70 | { 71 | return new UTF8Encoding().GetString(ReadBytes(this.ReadByte())); 72 | } 73 | 74 | public string ReadRSDKUnicodeString() 75 | { 76 | return new UnicodeEncoding().GetString(ReadBytes(this.ReadUInt16() * 2)); 77 | } 78 | 79 | public byte[] ReadCompressed() 80 | { 81 | uint compresed_size = this.ReadUInt32(); 82 | uint uncompressed_size = this.ReadUInt32BE(); 83 | using (MemoryStream outMemoryStream = new MemoryStream()) 84 | using (ZOutputStream decompress = new ZOutputStream(outMemoryStream)) 85 | { 86 | decompress.Write(this.ReadBytes(compresed_size - 4), 0, (int)compresed_size - 4); 87 | decompress.finish(); 88 | return outMemoryStream.ToArray(); 89 | } 90 | } 91 | 92 | public Reader GetCompressedStream() 93 | { 94 | return new Reader(new MemoryStream(this.ReadCompressed())); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /RSDKv5/Scene.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class Scene 11 | { 12 | public static readonly byte[] MAGIC = new byte[] { (byte)'S', (byte)'C', (byte)'N', (byte)'\0' }; 13 | 14 | public SceneEditorMetadata EditorMetadata; 15 | 16 | public List Layers = new List(); 17 | public List Objects = new List(); 18 | 19 | 20 | public Scene() 21 | { 22 | EditorMetadata = new SceneEditorMetadata(); 23 | } 24 | 25 | public Scene(string filename) : this(new Reader(filename)) 26 | { 27 | 28 | } 29 | 30 | public Scene(Stream stream) : this(new Reader(stream)) 31 | { 32 | 33 | } 34 | 35 | private Scene(Reader reader) 36 | { 37 | // Load scene 38 | if (!reader.ReadBytes(4).SequenceEqual(MAGIC)) 39 | throw new Exception("Invalid scene file header magic"); 40 | 41 | EditorMetadata = new SceneEditorMetadata(reader); 42 | 43 | byte layers_count = reader.ReadByte(); 44 | for (int i = 0; i < layers_count; ++i) 45 | Layers.Add(new SceneLayer(reader)); 46 | 47 | byte objects_count = reader.ReadByte(); 48 | for (int i = 0; i < objects_count; ++i) 49 | Objects.Add(new SceneObject(reader)); 50 | } 51 | 52 | public void Write(string filename) 53 | { 54 | using (Writer writer = new Writer(filename)) 55 | this.Write(writer); 56 | } 57 | 58 | public void Write(Stream stream) 59 | { 60 | using (Writer writer = new Writer(stream)) 61 | this.Write(writer); 62 | } 63 | 64 | internal void Write(Writer writer) 65 | { 66 | writer.Write(MAGIC); 67 | 68 | EditorMetadata.Write(writer); 69 | 70 | writer.Write((byte)Layers.Count); 71 | foreach (SceneLayer layer in Layers) 72 | layer.Write(writer); 73 | 74 | writer.Write((byte)Objects.Count); 75 | foreach (SceneObject obj in Objects) 76 | obj.Write(writer); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /RSDKv5/SceneEditorMetadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace RSDKv5 8 | { 9 | public class SceneEditorMetadata 10 | { 11 | byte UnknownByte; // 2/3/4 12 | public Color BackgroundColor1; 13 | public Color BackgroundColor2; 14 | byte[] UnknownBytes; // Const: 01010400010400 15 | string BinName; 16 | byte UnknownByte2; 17 | 18 | public SceneEditorMetadata() 19 | { 20 | UnknownByte = 3; 21 | BackgroundColor1 = Color.EMPTY; 22 | BackgroundColor2 = Color.EMPTY; 23 | UnknownBytes = new byte[] { 0x1, 0x1, 0x4, 0x0, 0x1, 0x4, 0x0 }; 24 | } 25 | 26 | internal SceneEditorMetadata(Reader reader) 27 | { 28 | UnknownByte = reader.ReadByte(); 29 | BackgroundColor1 = new Color(reader); 30 | BackgroundColor2 = new Color(reader); 31 | UnknownBytes = reader.ReadBytes(7); 32 | BinName = reader.ReadRSDKString(); 33 | UnknownByte2 = reader.ReadByte(); 34 | } 35 | 36 | internal void Write(Writer writer) 37 | { 38 | writer.Write(UnknownByte); 39 | BackgroundColor1.Write(writer); 40 | BackgroundColor2.Write(writer); 41 | writer.Write(UnknownBytes); 42 | writer.WriteRSDKString(BinName); 43 | writer.Write(UnknownByte2); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /RSDKv5/SceneEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class SceneEntity 11 | { 12 | public readonly ushort SlotID; 13 | public Position Position; 14 | public readonly SceneObject Object; 15 | public List Attributes = new List(); 16 | private Dictionary attributesMap = new Dictionary(); 17 | 18 | public SceneEntity(SceneObject obj, ushort slotID) 19 | { 20 | Object = obj; 21 | SlotID = slotID; 22 | 23 | foreach (AttributeInfo attribute in Object.Attributes) 24 | { 25 | Attributes.Add(new AttributeValue(attribute.Type)); 26 | attributesMap[attribute.Name.ToString()] = Attributes.Last(); 27 | } 28 | } 29 | 30 | public SceneEntity(SceneEntity other, ushort slotID) 31 | { 32 | Object = other.Object; 33 | SlotID = slotID; 34 | Position = other.Position; 35 | 36 | foreach (AttributeInfo attribute in Object.Attributes) 37 | { 38 | Attributes.Add(other.GetAttribute(attribute.Name).Clone()); 39 | attributesMap[attribute.Name.ToString()] = Attributes.Last(); 40 | } 41 | } 42 | 43 | internal SceneEntity(Reader reader, SceneObject obj) 44 | { 45 | Object = obj; 46 | SlotID = reader.ReadUInt16(); 47 | Position = new Position(reader); 48 | 49 | foreach (AttributeInfo attribute in Object.Attributes) 50 | { 51 | Attributes.Add(new AttributeValue(reader, attribute.Type)); 52 | attributesMap[attribute.Name.ToString()] = Attributes.Last(); 53 | } 54 | } 55 | 56 | public AttributeValue GetAttribute(string name) 57 | { 58 | return attributesMap[name]; 59 | } 60 | 61 | public AttributeValue GetAttribute(NameIdentifier name) 62 | { 63 | return GetAttribute(name.ToString()); 64 | } 65 | 66 | internal void Write(Writer writer) 67 | { 68 | writer.Write(SlotID); 69 | Position.Write(writer); 70 | 71 | foreach (AttributeValue attribute in Attributes) 72 | attribute.Write(writer); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /RSDKv5/SceneLayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class SceneLayer 11 | { 12 | byte IgnoredByte; 13 | public string Name; 14 | 15 | public byte IsScrollingVertical; 16 | public byte UnknownByte2; 17 | 18 | public ushort Width; 19 | public ushort Height; 20 | 21 | public ushort UnknownWord1; 22 | public ushort UnknownWord2; 23 | 24 | public class ScrollInfo 25 | { 26 | ushort UnknownWord1; 27 | ushort UnknownWord2; 28 | byte UnknownByte1; 29 | byte UnknownByte2; 30 | 31 | public ScrollInfo(ushort word1 = 0x100, ushort word2 = 0, byte byte1 = 0, byte byte2 = 0) 32 | { 33 | this.UnknownWord1 = word1; 34 | this.UnknownWord2 = word2; 35 | 36 | this.UnknownByte1 = byte1; 37 | this.UnknownByte2 = byte2; 38 | } 39 | 40 | internal ScrollInfo(Reader reader) 41 | { 42 | UnknownWord1 = reader.ReadUInt16(); 43 | UnknownWord2 = reader.ReadUInt16(); 44 | 45 | UnknownByte1 = reader.ReadByte(); 46 | UnknownByte2 = reader.ReadByte(); 47 | } 48 | 49 | internal void Write(Writer writer) 50 | { 51 | writer.Write(UnknownWord1); 52 | writer.Write(UnknownWord2); 53 | 54 | writer.Write(UnknownByte1); 55 | writer.Write(UnknownByte2); 56 | } 57 | } 58 | 59 | public List ScrollingInfo = new List(); 60 | 61 | public byte[] ScrollIndexes; 62 | 63 | public ushort[][] Tiles; 64 | 65 | 66 | public SceneLayer(string name, ushort Width, ushort Height) 67 | { 68 | ScrollingInfo.Add(new ScrollInfo()); 69 | // Per pixel (of height or of width, depends if it scrolls horizontal or veritcal) 70 | ScrollIndexes = new byte[Height * 16]; 71 | Tiles = new ushort[Height][]; 72 | for (int i = 0; i < Height; ++i) 73 | { 74 | Tiles[i] = new ushort[Width]; 75 | for (int j = 0; j < Width; ++j) 76 | Tiles[i][j] = 0xffff; 77 | } 78 | } 79 | 80 | internal SceneLayer(Reader reader) 81 | { 82 | IgnoredByte = reader.ReadByte(); 83 | 84 | Name = reader.ReadRSDKString(); 85 | 86 | IsScrollingVertical = reader.ReadByte(); 87 | UnknownByte2 = reader.ReadByte(); 88 | 89 | Width = reader.ReadUInt16(); 90 | Height = reader.ReadUInt16(); 91 | 92 | UnknownWord1 = reader.ReadUInt16(); 93 | UnknownWord2 = reader.ReadUInt16(); 94 | 95 | ushort scrolling_info_count = reader.ReadUInt16(); 96 | for (int i = 0; i < scrolling_info_count; ++i) 97 | ScrollingInfo.Add(new ScrollInfo(reader)); 98 | 99 | ScrollIndexes = reader.ReadCompressed(); 100 | 101 | Tiles = new ushort[Height][]; 102 | using (Reader creader = reader.GetCompressedStream()) 103 | { 104 | for (int i = 0; i < Height; ++i) 105 | { 106 | Tiles[i] = new ushort[Width]; 107 | for (int j = 0; j < Width; ++j) 108 | Tiles[i][j] = creader.ReadUInt16(); 109 | } 110 | } 111 | } 112 | 113 | internal void Write(Writer writer) 114 | { 115 | writer.Write(IgnoredByte); 116 | 117 | writer.WriteRSDKString(Name); 118 | 119 | writer.Write(IsScrollingVertical); 120 | writer.Write(UnknownByte2); 121 | 122 | writer.Write(Width); 123 | writer.Write(Height); 124 | 125 | writer.Write(UnknownWord1); 126 | writer.Write(UnknownWord2); 127 | 128 | writer.Write((ushort)ScrollingInfo.Count); 129 | foreach (ScrollInfo info in ScrollingInfo) 130 | info.Write(writer); 131 | 132 | writer.WriteCompressed(ScrollIndexes); 133 | 134 | using (MemoryStream cmem = new MemoryStream()) 135 | using (Writer cwriter = new Writer(cmem)) 136 | { 137 | for (int i = 0; i < Height; ++i) 138 | for (int j = 0; j < Width; ++j) 139 | cwriter.Write(Tiles[i][j]); 140 | cwriter.Close(); 141 | writer.WriteCompressed(cmem.ToArray()); 142 | } 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /RSDKv5/SceneObjects.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class SceneObject 11 | { 12 | public readonly NameIdentifier Name; 13 | public readonly List Attributes = new List(); 14 | public List Entities = new List(); 15 | 16 | 17 | /*public SceneObjects(NameIdentifier name, List attributes) 18 | { 19 | this.Name = name; 20 | this.Attributes = attributes; 21 | } 22 | 23 | public SceneObjects(string name, List attributes) : this(new NameIdentifier(name), attributes) { }*/ 24 | 25 | internal SceneObject(Reader reader) 26 | { 27 | Name = new NameIdentifier(reader); 28 | var info = Objects.GetObjectInfo(Name); 29 | if (info != null) Name = info.Name; 30 | 31 | byte attributes_count = reader.ReadByte(); 32 | for (int i = 1; i < attributes_count; ++i) 33 | Attributes.Add(new AttributeInfo(reader, info)); 34 | 35 | ushort entities_count = reader.ReadUInt16(); 36 | for (int i = 0; i < entities_count; ++i) 37 | Entities.Add(new SceneEntity(reader, this)); 38 | } 39 | 40 | internal void Write(Writer writer) 41 | { 42 | Name.Write(writer); 43 | 44 | writer.Write((byte)(Attributes.Count + 1)); 45 | foreach (AttributeInfo attribute in Attributes) 46 | attribute.Write(writer); 47 | 48 | writer.Write((ushort)Entities.Count); 49 | foreach (SceneEntity entity in Entities) 50 | entity.Write(writer); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /RSDKv5/Sprite.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace RSDKv5 8 | { 9 | public class Sprite 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /RSDKv5/StageConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class StageConfig : CommonConfig 11 | { 12 | bool UseGameObjects; 13 | 14 | public StageConfig(string filename) : this(new Reader(filename)) 15 | { 16 | 17 | } 18 | 19 | public StageConfig(Stream stream) : this(new Reader(stream)) 20 | { 21 | 22 | } 23 | 24 | internal StageConfig(Reader reader) 25 | { 26 | base.ReadMagic(reader); 27 | 28 | UseGameObjects = reader.ReadBoolean(); 29 | 30 | base.ReadCommonConfig(reader); 31 | } 32 | 33 | public void Write(string filename) 34 | { 35 | using (Writer writer = new Writer(filename)) 36 | this.Write(writer); 37 | } 38 | 39 | public void Write(Stream stream) 40 | { 41 | using (Writer writer = new Writer(stream)) 42 | this.Write(writer); 43 | } 44 | 45 | internal void Write(Writer writer) 46 | { 47 | base.WriteMagic(writer); 48 | 49 | writer.Write(UseGameObjects); 50 | 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /RSDKv5/StageTiles.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class StageTiles : IDisposable 11 | { 12 | public readonly GIF Image; 13 | public readonly TilesConfig Config; 14 | 15 | public StageTiles(string stage_directory) 16 | { 17 | Image = new GIF(Path.Combine(stage_directory, "16x16Tiles.gif")); 18 | if (File.Exists(Path.Combine(stage_directory, "TileConfig.bin"))) 19 | Config = new TilesConfig(Path.Combine(stage_directory, "TileConfig.bin")); 20 | } 21 | 22 | public void Dispose() 23 | { 24 | Image.Dispose(); 25 | } 26 | 27 | public void DisposeTextures() 28 | { 29 | Image.DisposeTextures(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /RSDKv5/TilesConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | 8 | namespace RSDKv5 9 | { 10 | public class TilesConfig 11 | { 12 | public static readonly byte[] MAGIC = new byte[] { (byte)'T', (byte)'I', (byte)'L', (byte)'\0' }; 13 | 14 | const int TILES_COUNT = 0x400; 15 | 16 | TileConfig[] CollisionPath1 = new TileConfig[TILES_COUNT]; 17 | TileConfig[] CollisionPath2 = new TileConfig[TILES_COUNT]; 18 | 19 | public class TileConfig 20 | { 21 | // Collision position for each pixel 22 | public byte[] Collision; 23 | 24 | // If has collision 25 | public bool[] HasCollision; 26 | 27 | // If is celing, the collision is from below 28 | public bool IsCeiling; 29 | 30 | // Unknow 5 bytes config 31 | public byte[] Config; 32 | 33 | public TileConfig(Stream stream) : this(new Reader(stream)) { } 34 | 35 | internal TileConfig(Reader reader) 36 | { 37 | Collision = reader.ReadBytes(16); 38 | HasCollision = reader.ReadBytes(16).Select(x => x != 0).ToArray(); 39 | IsCeiling = reader.ReadBoolean(); 40 | Config = reader.ReadBytes(5); 41 | } 42 | } 43 | 44 | public TilesConfig(string filename) : this(new Reader(filename)) 45 | { 46 | 47 | } 48 | 49 | public TilesConfig(Stream stream) : this(new Reader(stream)) 50 | { 51 | 52 | } 53 | 54 | private TilesConfig(Reader reader) 55 | { 56 | if (!reader.ReadBytes(4).SequenceEqual(MAGIC)) 57 | throw new Exception("Invalid tiles config file header magic"); 58 | 59 | using (Reader creader = reader.GetCompressedStream()) 60 | { 61 | for (int i = 0; i < TILES_COUNT; ++i) 62 | CollisionPath1[i] = new TileConfig(creader); 63 | for (int i = 0; i < TILES_COUNT; ++i) 64 | CollisionPath2[i] = new TileConfig(creader); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /RSDKv5/WAVConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace RSDKv5 8 | { 9 | public class WAVConfiguration 10 | { 11 | public string Name; 12 | public byte MaxConcurrentPlay; 13 | 14 | internal WAVConfiguration(Reader reader) 15 | { 16 | Name = reader.ReadRSDKString(); 17 | MaxConcurrentPlay = reader.ReadByte(); 18 | } 19 | 20 | internal void Write(Writer writer) 21 | { 22 | writer.WriteRSDKString(Name); 23 | writer.Write(MaxConcurrentPlay); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RSDKv5/Writer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.IO; 7 | using zlib; 8 | 9 | namespace RSDKv5 10 | { 11 | internal class Writer : BinaryWriter 12 | { 13 | public Writer(Stream stream) : base(stream) 14 | { 15 | } 16 | 17 | public Writer(string file) : base(File.Open(file, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) 18 | { 19 | } 20 | 21 | public bool IsEof 22 | { 23 | get { return BaseStream.Position >= BaseStream.Length; } 24 | } 25 | 26 | public void Seek(long position, SeekOrigin org) 27 | { 28 | BaseStream.Seek(position, org); 29 | } 30 | 31 | public long Pos 32 | { 33 | get { return BaseStream.Position; } 34 | } 35 | 36 | public long Size 37 | { 38 | get { return BaseStream.Length; } 39 | } 40 | 41 | public void WriteUInt32BE(uint val) 42 | { 43 | val = ((val >> 24) & 0xff) | ((val << 8) & 0xff0000) | ((val >> 8) & 0xff00) | ((val << 24) & 0xff000000); 44 | base.Write(val); 45 | } 46 | 47 | public void WriteRSDKString(string val) 48 | { 49 | base.Write((byte)val.Length); 50 | base.Write(new UTF8Encoding().GetBytes(val)); 51 | } 52 | 53 | public void WriteRSDKUnicodeString(string val) 54 | { 55 | base.Write((ushort)val.Length); 56 | base.Write(new UnicodeEncoding().GetBytes(val)); 57 | } 58 | 59 | public void WriteCompressed(byte[] bytes) 60 | { 61 | using (MemoryStream outMemoryStream = new MemoryStream()) 62 | using (ZOutputStream compress = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION)) { 63 | compress.Write(bytes, 0, bytes.Length); 64 | compress.finish(); 65 | 66 | byte[] data = outMemoryStream.ToArray(); 67 | this.Write((uint)data.Length + sizeof(uint)); 68 | this.WriteUInt32BE((uint)bytes.Length); 69 | this.Write(data); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /RSDKv5/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | os: 2 | - Visual Studio 2017 3 | 4 | shallow_clone: true 5 | 6 | configuration: 7 | - Release 8 | 9 | before_build: 10 | - nuget restore 11 | 12 | after_build: 13 | - 7z a ManiacEditor-%APPVEYOR_BUILD_VERSION%.zip %APPVEYOR_BUILD_FOLDER%\%PLATFORM_DIR%\ManiacEditor\bin\Release\*.exe %APPVEYOR_BUILD_FOLDER%\%PLATFORM_DIR%\ManiacEditor\bin\Release\*.dll 14 | 15 | artifacts: 16 | - path: ManiacEditor-%APPVEYOR_BUILD_VERSION%.zip --------------------------------------------------------------------------------