public static FontMapper GetFontMapper(out MapperInfo info) { FontMapper mapper = null; info = MapperInfo.NotFound; Object[] fontMappers = Object.FindObjectsOfType(typeof(FontMapper)); // traverse mappers foreach (Object o in fontMappers) { mapper = (FontMapper)o; //if (mapper.Id == CreateFontMapperCommand.FontMapperId) if (mapper.Default) { if (!mapper.enabled) { info = MapperInfo.MapperNotEnabled; break; } if (null == mapper.Font) { info = MapperInfo.FontNotAttached; break; } info = MapperInfo.Ok; break; } } return mapper; }
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { MapperInfo info = (MapperInfo)context.Instance; //if (!info.DataUIMapper.DisplayMember) //{ // string[] sv = new string[] { string.Empty }; // return new StandardValuesCollection(sv); //} IDesignerHost host = (IDesignerHost)context.GetService(typeof(IDesignerHost)); IReferenceService svc = (IReferenceService)host.GetService(typeof(IReferenceService)); if (svc == null) { return(null); } object ctl = svc.GetReference(info.ControlID); if (ctl == null) { throw new ArgumentException("当前容器中未发现名称为 '" + info.ControlID + "' 的控件。"); } else { return(new StandardValuesCollection(MemberHelper.GetControlProperties(ctl))); } }
public static FontMapper GetFontMapper(out MapperInfo info) { FontMapper mapper = null; info = MapperInfo.NotFound; Object[] fontMappers = Object.FindObjectsOfType(typeof(FontMapper)); // traverse mappers foreach (Object o in fontMappers) { mapper = (FontMapper)o; //if (mapper.Id == CreateFontMapperCommand.FontMapperId) if (mapper.Default) { if (!mapper.enabled) { info = MapperInfo.MapperNotEnabled; break; } if (null == mapper.Font) { info = MapperInfo.FontNotAttached; break; } info = MapperInfo.Ok; break; } } return(mapper); }
private void btnAdd_Click(object sender, EventArgs e) { MapperInfo mi = new MapperInfo(); ListViewItem item = new ListViewItem(mi.ToString()); item.Tag = mi; lstMappings.Items.Add(item); item.Selected = true; item.Focused = true; }
public MapperInfoList GetMappings() { MapperInfoList miList = new MapperInfoList(); foreach (ListViewItem item in this.lstMappings.Items) { MapperInfo mi = item.Tag as MapperInfo; miList.Add(mi); } return(miList); }
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { try { MapperInfo info = (MapperInfo)context.Instance; return(new StandardValuesCollection(MemberHelper.GetDataPropertys(info.DataUIMapper.Type))); } catch { string[] sv = new string[] { string.Empty }; return(new StandardValuesCollection(sv)); } }
void OnComponentRename(object sender, ComponentRenameEventArgs e) { foreach (MapperInfo mi in CurrentMapper.Mappings) { if (mi.ControlID == e.OldName) { MapperInfo info = mi; info.ControlID = e.NewName; //CurrentMapper.Mappings.Remove(e.OldName); //CurrentMapper.Mappings.Add(e.NewName, info); RaiseComponentChanging(TypeDescriptor.GetProperties(CurrentMapper)["Mappings"]); break; } } }
private void cbControlProperty_DropDown(object sender, EventArgs e) { if (cbControl.SelectedItem == null) { return; } cbControlProperty.Items.Clear(); try { object control = ((ControlEntry)cbControl.SelectedItem).Control; string controlID2 = ((ControlEntry)cbControl.SelectedItem).Name; cbControlProperty.Items.Clear(); cbControlProperty.Text = String.Empty; cbControlProperty.Items.AddRange(MemberHelper.GetControlProperties(control)); string controlID = string.Empty; if (this.SelectedItem != null) { controlID = (this.SelectedItem.Tag as MapperInfo).ControlID; } if (controlID == controlID2) { MapperInfo mi = this.SelectedItem.Tag as MapperInfo; if (mi.ControlProperty != String.Empty) { cbControlProperty.SelectedIndex = cbControlProperty.FindStringExact(mi.ControlProperty); } else { this.SetDefaultControlProperty(control); } } else { this.SetDefaultControlProperty(control); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( "错误: " + ex.ToString()); } }
private void cbControlProperty_SelectedIndexChanged(object sender, EventArgs e) { try { if ((this.SelectedItem != null) && (this.cbControlProperty.SelectedIndex > -1)) { MapperInfo mi = this.SelectedItem.Tag as MapperInfo; mi.ControlProperty = cbControlProperty.Text; this.SelectedItem.Text = mi.ToString(); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( "出错: " + ex.ToString()); } }
public override object Serialize(IDesignerSerializationManager manager, object value) { CodeDomSerializer serial = GetConfiguredSerializer(manager, value); if (serial == null) { return(null); } CodeStatementCollection statements = (CodeStatementCollection)serial.Serialize(manager, value); PropertyDescriptor prop = TypeDescriptor.GetProperties(value)["WebMapping"]; MapperInfo info = (MapperInfo)prop.GetValue(value); DataUIMapper dm = (DataUIMapper) DesignUtils.ProviderProperty.GetValue(prop, new object[0]); //Attach the view mappings to the control attributes. if (info.ControlProperty != String.Empty && info.DataProperty != String.Empty) { CodeExpression ctlref = SerializeToExpression(manager, value); CodeCastExpression cast = new CodeCastExpression(typeof(IAttributeAccessor), ctlref); statements.Add(new CodeMethodInvokeExpression( cast, "SetAttribute", new CodeExpression[] { new CodePrimitiveExpression("DIM_Mapper"), new CodePrimitiveExpression(manager.GetName(dm)) })); statements.Add(new CodeMethodInvokeExpression( cast, "SetAttribute", new CodeExpression[] { new CodePrimitiveExpression("DIM_Format"), new CodePrimitiveExpression(info.Format) })); statements.Add(new CodeMethodInvokeExpression( cast, "SetAttribute", new CodeExpression[] { new CodePrimitiveExpression("DIM_DataProperty"), new CodePrimitiveExpression(info.DataProperty) })); statements.Add(new CodeMethodInvokeExpression( cast, "SetAttribute", new CodeExpression[] { new CodePrimitiveExpression("DIM_ControlProperty"), new CodePrimitiveExpression(info.ControlProperty) })); } return(statements); }
void tbModelProperty_TextChanged(object sender, EventArgs e) { try { if (this.SelectedItem != null) { MapperInfo mi = this.SelectedItem.Tag as MapperInfo; mi.DataProperty = tbModelProperty.Text; this.SelectedItem.Text = mi.ToString(); } } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( "错误: " + ex.ToString()); } }
private void cbControl_SelectedIndexChanged(object sender, EventArgs e) { try { if ((this.SelectedItem != null) && (this.cbControl.SelectedIndex > -1)) { MapperInfo mi = this.SelectedItem.Tag as MapperInfo; mi.ControlID = ((ControlEntry)cbControl.SelectedItem).Name; this.SelectedItem.Text = mi.ToString(); } cbControlProperty_DropDown(sender, e); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( "错误: " + ex.ToString()); } }
private static AudioPlayerMapper GetAudioMapper(out MapperInfo info) { AudioPlayerMapper mapper = null; info = MapperInfo.NotFound; Object[] audioMappers = Object.FindObjectsOfType(typeof(AudioPlayerMapper)); // traverse mappers foreach (Object o in audioMappers) { mapper = (AudioPlayerMapper)o; if (mapper.Default) { //if (!mapper.gameObject.activeInHierarchy) // info = AudioPlayerMapperInfo.MapperGameObjectNotEnabled; info = !mapper.enabled ? MapperInfo.MapperNotEnabled : MapperInfo.Ok; break; } } return(mapper); }
public void Map(ref MapperInfo _Info, ref object from, ref object to) { var dic = from as IDictionary <string, TValue>; IDictionary <string, TValue> tmpDic = dic; if (_Info.IgnoreCase) { tmpDic = new Dictionary <string, TValue>(dic, _Info.IgnoreCase ? StringComparer.InvariantCultureIgnoreCase : StringComparer.InvariantCulture); } var tmpMembers = _Info .DestinationMembers .Where(m => m.MemberType == MemberTypes.Field || m.MemberType == MemberTypes.Property) .ToArray(); var keys = tmpDic.Keys.ToList(); var ms = tmpMembers; foreach (var key in keys) { var tmpValue = tmpDic[key]; var m = ms.FirstOrDefault(s => string.Equals(s.Name, key, StringComparison.OrdinalIgnoreCase)); if (m != null) { BindProperty(ref to, tmpValue, m); } else { BindSubProperty(ref to, key, tmpValue); } } tmpDic.Clear(); tmpDic = null; }
public override object Serialize(IDesignerSerializationManager manager, object value) { CodeDomSerializer serial = GetBaseComponentSerializer(manager); if (serial == null) { return(null); } CodeStatementCollection statements = (CodeStatementCollection)serial.Serialize(manager, value); //serializer for web controls. if (!(manager.GetSerializer(typeof(System.Web.UI.Control), typeof(CodeDomSerializer)) is WebControlSerializer)) { manager.AddSerializationProvider(new WebControlSerializationProvider()); } IDesignerHost host = (IDesignerHost)manager.GetService(typeof(IDesignerHost)); if (host.RootComponent == value) { return(statements); } statements.AddRange(GetCommentHeader("Mapper code")); DataUIMapper cn = (DataUIMapper)value; CodeExpression cnref = SerializeToExpression(manager, value); #region Mapping property serialization CodePropertyReferenceExpression propref = new CodePropertyReferenceExpression(cnref, "Mappings"); foreach (MapperInfo mi in cn.Mappings) { MapperInfo info = mi; if (info.ControlID != String.Empty && info.ControlProperty != null && info.DataProperty != String.Empty) { object ctl = manager.GetInstance(info.ControlID); //if (ctl == null) //{ // manager.ReportError(String.Format("Control '{0}' associated with the view mapping in controller '{1}' doesn't exist in the page.", info.ControlID, manager.GetName(value))); // continue; //} if (ctl.GetType().GetProperty(info.ControlProperty) == null) { manager.ReportError(String.Format("Control property '{0}' in control '{1}' associated with the view mapping in datauimapper '{2}' doesn't exist.", info.ControlProperty, info.ControlID, manager.GetName(value))); continue; } statements.Add( new CodeMethodInvokeExpression( propref, "Add", new CodeExpression[] { new CodeObjectCreateExpression( typeof(MapperInfo), new CodeExpression[] { new CodePrimitiveExpression(info.ControlID), new CodePrimitiveExpression(info.ControlProperty), new CodePrimitiveExpression(info.DataProperty), new CodePrimitiveExpression((int)info.Format) } ) } )); } } #endregion statements.Add( new CodeCommentStatement("Connect the host environment.")); if (host.RootComponent as System.Windows.Forms.Form != null) { CodeObjectCreateExpression adapter = new CodeObjectCreateExpression(typeof(Adapter.WindowsFormsAdapter), new CodeExpression[0]); CodeExpression connect = new CodeMethodInvokeExpression(adapter, "Connect", new CodeExpression[] { cnref, new CodeThisReferenceExpression(), }); statements.Add(connect); } else if (host.RootComponent as System.Web.UI.Page != null) { CodeObjectCreateExpression adapter = new CodeObjectCreateExpression(typeof(Adapter.WebFormsAdapter), new CodeExpression[0]); CodeExpression connect = new CodeMethodInvokeExpression(adapter, "Connect", new CodeExpression[] { cnref, new CodeThisReferenceExpression(), }); statements.Add(connect); } return(statements); }
public MapperInfo GetMapperInfo(DataSet ds, PropertyInfo pi) { return(MapperInfo.FromProperty(ds, pi)); }
public T ToEntity <T>(DataSet ds) where T : class, new() { T obj = new T(); if (ds == null) { return(obj); } else { IDataTableMapper mapper = new DefaultTableMapper(); if (RefletUtil.IsClass(typeof(T))) { PropertyInfo[] properties = mapper.GetAllProperty(obj.GetType()); foreach (var property in properties) { MapperInfo mi = mapper.GetMapperInfo(ds, property); if (RefletUtil.IsBaseType(property.PropertyType)) { object pvalue = mi.HasExtend.Key ? mi.HasExtend.Value.Invoke(obj, new object[] { property.Name, mi.SourceTb.Rows[0][mi.ColumnName] }) : mi.SourceTb.Rows[0][mi.ColumnName]; property.SetValue(obj, Convert.ChangeType(pvalue, property.PropertyType), null); } if (RefletUtil.IsClass(property.PropertyType)) { object subClassInstance = RefletUtil.CreateClassInstance(property.PropertyType); PropertyInfo[] SubClassProperties = mapper.GetAllProperty(property.PropertyType); foreach (var SubClassProperty in SubClassProperties) { MapperInfo subClassPropertyMi = mapper.GetMapperInfo(ds, SubClassProperty); if (RefletUtil.IsBaseType(SubClassProperty.PropertyType)) { object subclasspvalue = subClassPropertyMi.HasExtend.Key ? subClassPropertyMi.HasExtend.Value.Invoke(subClassInstance, new object[] { SubClassProperty.Name, subClassPropertyMi.SourceTb.Rows[0][subClassPropertyMi.ColumnName] }) : subClassPropertyMi.SourceTb.Rows[0][subClassPropertyMi.ColumnName]; SubClassProperty.SetValue(subClassInstance, Convert.ChangeType(subclasspvalue, SubClassProperty.PropertyType), null); } } property.SetValue(obj, Convert.ChangeType(subClassInstance, property.PropertyType), null); } if (RefletUtil.IsListGeneric(property.PropertyType)) { var instance = RefletUtil.CreateGenericInstance(property.PropertyType, out Type instancetype); var instancelList = RefletUtil.CreateGeneric(instancetype); //GenricListSetValue(ds, property.PropertyType, ref instancelList); #region V1.0 for (int i = 0; i < mi.SourceTb.Rows.Count; i++) { //List<Class> => Class.Class instance = RefletUtil.CreateGenericInstance(property.PropertyType, out _); PropertyInfo[] insproperties = mapper.GetAllProperty(instancetype); foreach (var item in insproperties) { MapperInfo itemMI = mapper.GetMapperInfo(ds, item); if (RefletUtil.IsBaseType(item.PropertyType)) { object itemprovalue = itemMI.HasExtend.Key ? itemMI.HasExtend.Value.Invoke(instance, new object[] { item.Name, itemMI.SourceTb.Rows[i][itemMI.ColumnName] }) : itemMI.SourceTb.Rows[i][itemMI.ColumnName]; item.SetValue(instance, Convert.ChangeType(itemprovalue, item.PropertyType), null); } if (RefletUtil.IsClass(item.PropertyType)) { object itemsubclassInstance = RefletUtil.CreateClassInstance(item.PropertyType); PropertyInfo[] itemsubclassproperties = mapper.GetAllProperty(item.PropertyType); foreach (var subitemproperty in itemsubclassproperties) { MapperInfo subitemproMI = mapper.GetMapperInfo(ds, subitemproperty); if (RefletUtil.IsBaseType(subitemproperty.PropertyType)) { object subitemproValue = subitemproMI.HasExtend.Key ? subitemproMI.HasExtend.Value.Invoke(itemsubclassInstance, new object[] { subitemproperty.Name, subitemproMI.SourceTb.Rows[i][subitemproMI.ColumnName] }) : subitemproMI.SourceTb.Rows[i][subitemproMI.ColumnName]; subitemproperty.SetValue(itemsubclassInstance, Convert.ChangeType(subitemproValue, subitemproperty.PropertyType), null); } } item.SetValue(instance, Convert.ChangeType(itemsubclassInstance, item.PropertyType), null); } } RefletUtil.AddObjToGeneric(instancelList, instance); } #endregion property.SetValue(obj, instancelList, null); } } } //List else { var instance = RefletUtil.CreateGenericInstance(typeof(T), out Type instancetype); var instancelList = RefletUtil.CreateGeneric(instancetype); GenricListSetValue(ds, typeof(T), ref instancelList); obj = (T)instancelList; } } return(obj); }
private void GenricListSetValue(DataSet ds, Type listype, ref object instancelList) { var instance = RefletUtil.CreateGenericInstance(listype, out Type instancetype); IDataTableMapper mapper = new DefaultTableMapper(); MapperInfo insMI = MapperInfo.FromType(ds, instancetype); for (int i = 0; i < insMI.SourceTb.Rows.Count; i++) { instance = RefletUtil.CreateGenericInstance(listype, out _); PropertyInfo[] properties = mapper.GetAllProperty(instancetype); foreach (var property in properties) { MapperInfo mi = mapper.GetMapperInfo(ds, property); if (RefletUtil.IsBaseType(property.PropertyType)) { object pvalue = mi.HasExtend.Key ? mi.HasExtend.Value.Invoke(instance, new object[] { property.Name, mi.SourceTb.Rows[0][mi.ColumnName] }) : mi.SourceTb.Rows[0][mi.ColumnName]; property.SetValue(instance, Convert.ChangeType(pvalue, property.PropertyType), null); } if (RefletUtil.IsClass(property.PropertyType)) { object subClassInstance = RefletUtil.CreateClassInstance(property.PropertyType); PropertyInfo[] SubClassProperties = mapper.GetAllProperty(property.PropertyType); foreach (var SubClassProperty in SubClassProperties) { MapperInfo subClassPropertyMi = mapper.GetMapperInfo(ds, SubClassProperty); if (RefletUtil.IsBaseType(SubClassProperty.PropertyType)) { object subclasspvalue = subClassPropertyMi.HasExtend.Key ? subClassPropertyMi.HasExtend.Value.Invoke(subClassInstance, new object[] { SubClassProperty.Name, subClassPropertyMi.SourceTb.Rows[0][subClassPropertyMi.ColumnName] }) : subClassPropertyMi.SourceTb.Rows[0][subClassPropertyMi.ColumnName]; SubClassProperty.SetValue(subClassInstance, Convert.ChangeType(subclasspvalue, SubClassProperty.PropertyType), null); } } property.SetValue(instance, Convert.ChangeType(subClassInstance, property.PropertyType), null); } if (RefletUtil.IsListGeneric(property.PropertyType)) { var instancesub = RefletUtil.CreateGenericInstance(property.PropertyType, out Type instancesubtype); var instancesublList = RefletUtil.CreateGeneric(instancesubtype); for (int l = 0; l < mi.SourceTb.Rows.Count; l++) { //Llst<Class> => Class.Class instancesub = RefletUtil.CreateGenericInstance(property.PropertyType, out _); PropertyInfo[] insproperties = mapper.GetAllProperty(instancesubtype); foreach (var item in insproperties) { MapperInfo itemMI = mapper.GetMapperInfo(ds, item); if (RefletUtil.IsBaseType(item.PropertyType)) { object itemprovalue = itemMI.HasExtend.Key ? itemMI.HasExtend.Value.Invoke(instancesub, new object[] { item.Name, itemMI.SourceTb.Rows[l][itemMI.ColumnName] }) : itemMI.SourceTb.Rows[l][itemMI.ColumnName]; item.SetValue(instancesub, Convert.ChangeType(itemprovalue, item.PropertyType), null); } if (RefletUtil.IsClass(item.PropertyType)) { object itemsubclassInstance = RefletUtil.CreateClassInstance(item.PropertyType); PropertyInfo[] itemsubclassproperties = mapper.GetAllProperty(item.PropertyType); foreach (var subitemproperty in itemsubclassproperties) { MapperInfo subitemproMI = mapper.GetMapperInfo(ds, subitemproperty); if (RefletUtil.IsBaseType(subitemproperty.PropertyType)) { object subitemproValue = subitemproMI.HasExtend.Key ? subitemproMI.HasExtend.Value.Invoke(itemsubclassInstance, new object[] { subitemproperty.Name, subitemproMI.SourceTb.Rows[l][subitemproMI.ColumnName] }) : subitemproMI.SourceTb.Rows[l][subitemproMI.ColumnName]; subitemproperty.SetValue(itemsubclassInstance, Convert.ChangeType(subitemproValue, subitemproperty.PropertyType), null); } } item.SetValue(instancesub, Convert.ChangeType(itemsubclassInstance, item.PropertyType), null); } } RefletUtil.AddObjToGeneric(instancesublList, instancesub); } property.SetValue(instance, instancesublList, null); } } RefletUtil.AddObjToGeneric(instancelList, instance); } }
static int Main(string[] args) { var mappers = new Dictionary<byte, MapperInfo>(); mappers[0] = new MapperInfo { MapperReg = 0x00, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // NROM mappers[2] = new MapperInfo { MapperReg = 0x01, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // UxROM mappers[71] = new MapperInfo { MapperReg = 0x01, PrgMode = 0, ChrMode = 0, WramEnabled = false, MapperFlags = 1 }; // Codemasters mappers[3] = new MapperInfo { MapperReg = 0x02, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // CNROM mappers[78] = new MapperInfo { MapperReg = 0x03, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // Holy Diver mappers[97] = new MapperInfo { MapperReg = 0x04, PrgMode = 1, ChrMode = 0, WramEnabled = false }; // Irem's TAM-S1 mappers[93] = new MapperInfo { MapperReg = 0x05, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // Sunsoft-2 mappers[163] = new MapperInfo { MapperReg = 0x06, PrgMode = 7, ChrMode = 0, WramEnabled = true }; // Mapper 163 (Final Fantasy & chinese shit) mappers[18] = new MapperInfo { MapperReg = 0x07, PrgMode = 4, ChrMode = 7, WramEnabled = false }; // Jaleco SS88006 mappers[7] = new MapperInfo { MapperReg = 0x08, PrgMode = 7, ChrMode = 0, WramEnabled = false }; // AxROM mappers[241] = new MapperInfo { MapperReg = 0x08, PrgMode = 7, ChrMode = 0, WramEnabled = false, MapperFlags = 1 }; // BNROM - is it just AxROM clone whith fixed mirroring? Using flag. mappers[228] = new MapperInfo { MapperReg = 0x09, PrgMode = 7, ChrMode = 0, WramEnabled = false }; // Cheetahmen 2 mappers[11] = new MapperInfo { MapperReg = 0x0A, PrgMode = 7, ChrMode = 0, WramEnabled = false }; // Color Dreams mappers[66] = new MapperInfo { MapperReg = 0x0B, PrgMode = 7, ChrMode = 0, WramEnabled = false }; // GxROM mappers[87] = new MapperInfo { MapperReg = 0x0C, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // Mapper #87 mappers[90] = new MapperInfo { MapperReg = 0x0D, PrgMode = 4, ChrMode = 7, WramEnabled = false }; // Mapper #90 mappers[65] = new MapperInfo { MapperReg = 0x0E, PrgMode = 4, ChrMode = 7, WramEnabled = false }; // Mapper #65 - Irem's H3001 mappers[5] = new MapperInfo { MapperReg = 0x0F, PrgMode = 4, ChrMode = 7, WramEnabled = true }; // MMC5 mappers[1] = new MapperInfo { MapperReg = 0x10, PrgMode = 0, ChrMode = 0, WramEnabled = true }; // MMC1 mappers[9] = new MapperInfo { MapperReg = 0x11, PrgMode = 4, ChrMode = 5, WramEnabled = true }; // MMC2 mappers[10] = new MapperInfo { MapperReg = 0x11, PrgMode = 0, ChrMode = 5, WramEnabled = true, MapperFlags = 1 }; // MMC4 mappers[152] = new MapperInfo { MapperReg = 0x12, PrgMode = 0, ChrMode = 0, WramEnabled = false }; // Mapper #152 mappers[73] = new MapperInfo { MapperReg = 0x13, PrgMode = 0, ChrMode = 0, WramEnabled = true }; // VRC3 mappers[4] = new MapperInfo { MapperReg = 0x14, PrgMode = 4, ChrMode = 2, WramEnabled = true }; // MMC3 mappers[118] = new MapperInfo { MapperReg = 0x14, PrgMode = 4, ChrMode = 2, WramEnabled = true, MapperFlags = 1 }; // TxSROM (MMC3 with flag) mappers[189] = new MapperInfo { MapperReg = 0x14, PrgMode = 7, ChrMode = 2, WramEnabled = false, MapperFlags = 2 }; // Mapper #189 mappers[112] = new MapperInfo { MapperReg = 0x15, PrgMode = 4, ChrMode = 2, WramEnabled = true }; // Mapper #112 mappers[4] = new MapperInfo { MapperReg = 0x14, PrgMode = 4, ChrMode = 2, WramEnabled = true }; // MMC3 mappers[33] = new MapperInfo { MapperReg = 0x16, PrgMode = 4, ChrMode = 2, WramEnabled = true }; // Taito mappers[48] = new MapperInfo { MapperReg = 0x16, PrgMode = 4, ChrMode = 2, WramEnabled = true, MapperFlags = 1 }; // Taito mappers[21] = new MapperInfo { MapperReg = 0x18, PrgMode = 4, ChrMode = 7, WramEnabled = true, MapperFlags = 1 }; // VRC4a mappers[22] = new MapperInfo { MapperReg = 0x18, PrgMode = 4, ChrMode = 7, WramEnabled = true, MapperFlags = 1 | 2 }; // VRC2a mappers[23] = new MapperInfo { MapperReg = 0x18, PrgMode = 4, ChrMode = 7, WramEnabled = true }; // VRC2b mappers[25] = new MapperInfo { MapperReg = 0x18, PrgMode = 4, ChrMode = 7, WramEnabled = true, MapperFlags = 1 }; // VRC2c, VRC4 mappers[69] = new MapperInfo { MapperReg = 0x19, PrgMode = 4, ChrMode = 7, WramEnabled = true }; // Sunsoft FME-7 mappers[32] = new MapperInfo { MapperReg = 0x1A, PrgMode = 4, ChrMode = 7, WramEnabled = true }; // Irem's G-101 //mappers[255] = new MapperInfo { MapperReg = 0x1F, PrgMode = 7, ChrMode = 0, WramEnabled = false }; // Temp/test Console.WriteLine("COOLGIRL UNIF combiner"); Console.WriteLine("(c) Cluster, 2016"); Console.WriteLine("http://clusterrr.com"); Console.WriteLine("*****@*****.**"); Console.WriteLine(); bool needShowHelp = false; string command = null; string optionGames = null; string optionAsm = null; string optionOffsets = null; string optionReport = null; string optionLoader = null; string optionUnif = null; string optionBin = null; string optionLanguage = "eng"; bool optionNoSort = false; int optionMaxSize = 256; if (args.Length > 0) command = args[0].ToLower(); if (command != "prepare" && command != "combine") { if (!string.IsNullOrEmpty(command)) Console.WriteLine("Unknown command: " + command); needShowHelp = true; } for (int i = 1; i < args.Length; i++) { string param = args[i]; while (param.StartsWith("-")) param = param.Substring(1); string value = i < args.Length - 1 ? args[i + 1] : ""; switch (param.ToLower()) { case "games": optionGames = value; i++; break; case "asm": optionAsm = value; i++; break; case "offsets": optionOffsets = value; i++; break; case "report": optionReport = value; i++; break; case "loader": optionLoader = value; i++; break; case "unif": optionUnif = value; i++; break; case "bin": optionBin = value; i++; break; case "nosort": optionNoSort = true; break; case "maxsize": optionMaxSize = int.Parse(value); i++; break; case "language": optionLanguage = value.ToLower(); i++; break; default: Console.WriteLine("Unknown parameter: " + param); needShowHelp = true; break; } } if (command == "prepare") { if (optionGames == null) { Console.WriteLine("Missing required parameter: --games"); needShowHelp = true; } if (optionAsm == null) { Console.WriteLine("Missing required parameter: --asm"); needShowHelp = true; } if (optionOffsets == null) { Console.WriteLine("Missing required parameter: --offsets"); needShowHelp = true; } } else if (command == "combine") { if (optionLoader == null) { Console.WriteLine("Missing required parameter: --loader"); needShowHelp = true; } if (optionUnif == null && optionBin == null) { Console.WriteLine("At least one parameter required: --unif or --bin"); needShowHelp = true; } } if (needShowHelp) { Console.WriteLine(""); Console.WriteLine("--- Usage ---"); Console.WriteLine("First step:"); Console.WriteLine(" CoolgirlCombiner.exe prepare --games <games.txt> --asm <games.asm> --offsets <offsets.xml> [--report <report.txt>] [--nosort] [--maxsize sizemb] [--language <language>]"); Console.WriteLine(" {0,-20}{1}", "games", "- input plain text file with list of ROM files"); Console.WriteLine(" {0,-20}{1}", "asm", "- output file for loader"); Console.WriteLine(" {0,-20}{1}", "offsets", "- output file with offsets for every game"); Console.WriteLine(" {0,-20}{1}", "report", "- output report file (human readable)"); Console.WriteLine(" {0,-20}{1}", "nosort", "- disable automatic sort by name"); Console.WriteLine(" {0,-20}{1}", "maxsize", "- maximum size for final file (in megabytes)"); Console.WriteLine(" {0,-20}{1}", "language", "- language for system messages: \"eng\" or \"rus\""); Console.WriteLine("Second step:"); Console.WriteLine(" CoolgirlCombiner.exe combine --loader <menu.nes> --offsets <offsets.xml> [--unif <multirom.unf>] [--bin <multirom.bin>]"); Console.WriteLine(" {0,-20}{1}", "loader", "- loader (compiled using asm file generated by first step)"); Console.WriteLine(" {0,-20}{1}", "offsets", "- input file with offsets for every game (generated by first step)"); Console.WriteLine(" {0,-20}{1}", "unif", "- output UNIF file"); Console.WriteLine(" {0,-20}{1}", "bin", "- output raw binary file"); return 1; } try { if (command == "prepare") { var lines = File.ReadAllLines(optionGames); var result = new byte?[256 * 1024 * 1024]; var regs = new Dictionary<string, List<String>>(); var games = new List<Game>(); var namesIncluded = new List<String>(); // Reserved for loader for (int a = 0; a < 128 * 1024; a++) result[a] = 0xff; // Bad sector :( // for (int a = 1908 * 0x8000; a < 1908 * 0x8000 + 128 * 1024; a++) result[a] = 0xff; // Building list of ROMs foreach (var line in lines) { if (string.IsNullOrEmpty(line.Trim())) continue; if (line.StartsWith(";")) continue; int sepPos = line.TrimEnd().IndexOf('|'); string fileName; string menuName = null; if (sepPos < 0) { fileName = line.Trim(); } else { fileName = line.Substring(0, sepPos).Trim(); menuName = line.Substring(sepPos + 1).Trim(); } if (fileName.EndsWith("/") || fileName.EndsWith("\\")) { Console.WriteLine("Loading directory: {0}", fileName); var files = Directory.GetFiles(fileName, "*.nes"); foreach (var file in files) { LoadGames(games, file); } } else { LoadGames(games, fileName, menuName); } } // Removing separators if (!optionNoSort) games = new List<Game>((from game in games where !(string.IsNullOrEmpty(game.FileName) || game.FileName == "-") select game).ToArray()); // Sorting if (optionNoSort) { games = new List<Game>((from game in games where !game.ToString().StartsWith("?") select game) .Union(from game in games where game.ToString().StartsWith("?") orderby game.ToString().ToUpper() ascending select game) .ToArray()); } else { games = new List<Game>((from game in games where !game.ToString().StartsWith("?") orderby game.ToString().ToUpper() ascending select game) .Union(from game in games where game.ToString().StartsWith("?") orderby game.ToString().ToUpper() ascending select game) .ToArray()); } int hiddenCount = games.Where(game => game.ToString().StartsWith("?")).Count(); byte saveId = 0; foreach (var game in games) { if (game.ROM.Battery) { saveId++; game.SaveId = saveId; } } int usedSpace = 0; var sortedPrgs = from game in games orderby game.ROM.PRG.Length descending select game; foreach (var game in sortedPrgs) { int prgRoundSize = 1; while (prgRoundSize < game.ROM.PRG.Length) prgRoundSize *= 2; Console.WriteLine("Fitting PRG for {0} ({1}kbytes)...", game, prgRoundSize / 1024); for (int pos = 0; pos < result.Length; pos += prgRoundSize) { if (WillFit(result, pos, prgRoundSize, game.ROM.PRG)) { game.PrgPos = pos; //Array.Copy(game.ROM.PRG, 0, result, pos, game.ROM.PRG.Length); for (var i = 0; i < game.ROM.PRG.Length; i++) result[pos + i] = game.ROM.PRG[i]; usedSpace = Math.Max(usedSpace, pos + game.ROM.PRG.Length); Console.WriteLine("Address: {0:X8}", pos); break; } } if (game.PrgPos < 0) throw new Exception("Can't fit " + game); } var sortedChrs = from game in games orderby game.ROM.CHR.Length descending select game; foreach (var game in sortedChrs) { int chrSize = game.ROM.CHR.Length; if (chrSize == 0) continue; Console.WriteLine("Fitting CHR for {0} ({1}kbytes)...", game, chrSize / 1024); for (int pos = 0; pos < result.Length; pos += 0x2000) { if (WillFit(result, pos, chrSize, game.ROM.CHR)) { game.ChrPos = pos; //Array.Copy(game.ROM.CHR, 0, result, pos, game.ROM.CHR.Length); for (var i = 0; i < game.ROM.CHR.Length; i++) result[pos + i] = game.ROM.CHR[i]; usedSpace = Math.Max(usedSpace, pos + game.ROM.CHR.Length); Console.WriteLine("Address: {0:X8}", pos); break; } } if (game.ChrPos < 0) throw new Exception("Can't fit " + game.FileName); } while (usedSpace % 0x8000 != 0) usedSpace++; int romSize = usedSpace; usedSpace += 128 * 1024 * (int)Math.Ceiling(saveId / 4.0); int totalSize = 0; int maxChrSize = 0; namesIncluded.Add(string.Format("{0,-33} {1,-10} {2,-10} {3,-10} {4,0}", "Game name", "Mapper", "Save ID", "Size", "Total size")); namesIncluded.Add(string.Format("{0,-33} {1,-10} {2,-10} {3,-10} {4,0}", "------------", "-------", "-------", "-------", "--------------")); var mapperStats = new Dictionary<byte, int>(); foreach (var game in games) { if (!game.ToString().StartsWith("?")) { totalSize += game.ROM.PRG.Length; totalSize += game.ROM.CHR.Length; namesIncluded.Add(string.Format("{0,-33} {1,-10} {2,-10} {3,-10} {4,0}", FirstCharToUpper(game.ToString().Replace("_", " ").Replace("+", "")), game.ROM.Mapper, game.SaveId == 0 ? "-" : game.SaveId.ToString(), ((game.ROM.PRG.Length + game.ROM.CHR.Length) / 1024) + " KB", (totalSize / 1024) + " KB total")); if (!mapperStats.ContainsKey(game.ROM.Mapper)) mapperStats[game.ROM.Mapper] = 0; mapperStats[game.ROM.Mapper]++; } if (game.ROM.CHR.Length > maxChrSize) maxChrSize = game.ROM.CHR.Length; } namesIncluded.Add(""); namesIncluded.Add(string.Format("{0,-10} {1,0}", "Mapper", "Count")); namesIncluded.Add(string.Format("{0,-10} {1,0}", "------", "-----")); foreach (var mapper in from m in mapperStats.Keys orderby m ascending select m) { namesIncluded.Add(string.Format("{0,-10} {1,0}", mapper, mapperStats[mapper])); } namesIncluded.Add(""); namesIncluded.Add("Total games: " + (games.Count - hiddenCount)); namesIncluded.Add("Final ROM size: " + Math.Round(usedSpace / 1024.0 / 1024.0, 3) + "MB"); namesIncluded.Add("Maximum CHR size: " + maxChrSize / 1024 + "KB"); namesIncluded.Add("Battery-backed games: " + saveId); Console.WriteLine("Total games: " + (games.Count - hiddenCount)); Console.WriteLine("Final ROM size: " + Math.Round(usedSpace / 1024.0 / 1024.0, 3) + "MB"); Console.WriteLine("Maximum CHR size: " + maxChrSize / 1024 + "KB"); Console.WriteLine("Battery-backed games: " + saveId); if (optionReport != null) File.WriteAllLines(optionReport, namesIncluded.ToArray()); if (games.Count - hiddenCount == 0) throw new Exception("Games list is empty"); if (usedSpace > optionMaxSize * 1024 * 1024) throw new Exception(string.Format("ROM is too big: {0} MB", Math.Round(usedSpace / 1024.0 / 1024.0, 3))); if (games.Count > 768) throw new Exception("Too many ROMs: " + games.Count); if (saveId > 128) throw new Exception("Too many battery backed games: " + saveId); regs["reg_0"] = new List<String>(); regs["reg_1"] = new List<String>(); regs["reg_2"] = new List<String>(); regs["reg_3"] = new List<String>(); regs["reg_4"] = new List<String>(); regs["reg_5"] = new List<String>(); regs["reg_6"] = new List<String>(); regs["reg_7"] = new List<String>(); regs["chr_start_bank_h"] = new List<String>(); regs["chr_start_bank_l"] = new List<String>(); regs["chr_start_bank_s"] = new List<String>(); regs["chr_count"] = new List<String>(); regs["game_save"] = new List<String>(); regs["game_type"] = new List<String>(); regs["cursor_pos"] = new List<String>(); int c = 0; foreach (var game in games) { int prgSize = game.ROM.PRG.Length; int chrSize = game.ROM.CHR.Length; int prgPos = game.PrgPos; int chrPos = Math.Max(game.ChrPos, 0); int chrBase = (chrPos / 0x2000) >> 4; int prgBase = (prgPos / 0x2000) >> 4; int prgRoundSize = 1; while (prgRoundSize < prgSize) prgRoundSize *= 2; int chrRoundSize = 1; while (chrRoundSize < chrSize || chrRoundSize < 0x2000) chrRoundSize *= 2; MapperInfo mapperInfo; if (!mappers.TryGetValue(game.ROM.Mapper, out mapperInfo)) throw new Exception(string.Format("Unknowm mapper #{0} for {1} ", game.ROM.Mapper, game.FileName)); if (chrSize > 256 * 1024) throw new Exception(string.Format("CHR is too big in {0} ", game.FileName)); if (game.ROM.Mirroring == NesFile.MirroringType.FourScreenVram && game.ROM.CHR.Length > 256 * 1024 - 0x1000) throw new Exception(string.Format("Four-screen and such big CHR is not supported for {0} ", game.FileName)); // Some unusual games if (game.ROM.Mapper == 1) // MMC1 ? { switch (game.ROM.CRC32) { case 0xc6182024: // Romance of the 3 Kingdoms case 0x2225c20f: // Genghis Khan case 0x4642dda6: // Nobunaga's Ambition case 0x29449ba9: // "" "" (J) case 0x2b11e0b0: // "" "" (J) case 0xb8747abf: // Best Play Pro Yakyuu Special (J) case 0xc9556b36: // Final Fantasy I & II (J) [!] Console.WriteLine("WARNING! {0} uses 16KB of WRAM", game.FileName); mapperInfo.MapperFlags |= 1; // flag to support 16KB of WRAM break; } } if (game.ROM.Mapper == 4) // MMC3 ? { switch (game.ROM.CRC32) { case 0x93991433: // Low-G-Man case 0xaf65aa84: // Low-G-Man Console.WriteLine("WARNING! WRAM will be disabled for {0}", Path.GetFileName(game.FileName)); mapperInfo.WramEnabled = false; // disable WRAM break; } } switch (game.ROM.CRC32) { case 0x78b657ac: // "Armadillo (J) [!].nes" case 0xb3d92e78: // "Armadillo (J) [T+Eng1.01_Vice Translations].nes" case 0x0fe6e6a5: // "Armadillo (J) [T+Rus1.00 Chief-Net (23.05.2012)].nes" case 0xe62e3382: // "MiG 29 - Soviet Fighter (Camerica) [!].nes" case 0x1bc686a8: // "Fire Hawk (Camerica) [!].nes" Console.WriteLine("WARNING! {0} is not compatible with Dendy", Path.GetFileName(game.FileName)); game.Flags |= GameFlags.WillNotWorkOnDendy; break; } if (string.IsNullOrEmpty(game.ToString())) game.Flags = GameFlags.Separator; byte @params = 0; if (mapperInfo.WramEnabled) @params |= 1; // enable SRAM if (chrSize == 0) @params |= 2; // enable CHR write if (game.ROM.Mirroring == NesFile.MirroringType.Horizontal) @params |= 8; // default mirroring if (game.ROM.Mirroring == NesFile.MirroringType.FourScreenVram) { @params |= 32; // four screen game.Flags |= GameFlags.WillNotWorkOnNewDendy; // not external NTRAM on new famiclones :( } @params |= 0x80; // lockout regs["reg_0"].Add(string.Format("${0:X2}", ((prgPos / 0x4000) >> 8) & 0xFF)); // PRG base regs["reg_1"].Add(string.Format("${0:X2}", (prgPos / 0x4000) & 0xFF)); // PRG base regs["reg_2"].Add(string.Format("${0:X2}", (0xFF ^ (prgRoundSize / 0x4000 - 1)) & 0xFF)); // PRG mask regs["reg_3"].Add(string.Format("${0:X2}", (mapperInfo.PrgMode << 5) | 0)); // PRG mode regs["reg_4"].Add(string.Format("${0:X2}", (mapperInfo.ChrMode << 5) | (0xFF ^ (chrRoundSize / 0x2000 - 1)) & 0x1F)); // CHR mode, CHR mask regs["reg_5"].Add(string.Format("${0:X2}", (game.ROM.Battery ? 0x02 : 0x01))); // SRAM page regs["reg_6"].Add(string.Format("${0:X2}", (mapperInfo.MapperFlags << 5) | mapperInfo.MapperReg)); // Flags, mapper regs["reg_7"].Add(string.Format("${0:X2}", @params)); // Parameters regs["chr_start_bank_h"].Add(string.Format("${0:X2}", ((chrPos / 0x8000) >> 7) & 0xFF)); regs["chr_start_bank_l"].Add(string.Format("${0:X2}", ((chrPos / 0x8000) << 1) & 0xFF)); regs["chr_start_bank_s"].Add(string.Format("${0:X2}", ((chrPos % 0x8000) >> 8) | 0x80)); regs["chr_count"].Add(string.Format("${0:X2}", chrSize / 0x2000)); regs["game_save"].Add(string.Format("${0:X2}", !game.ROM.Battery ? 0 : game.SaveId)); regs["game_type"].Add(string.Format("${0:X2}", (byte)game.Flags)); regs["cursor_pos"].Add(string.Format("${0:X2}", game.ToString().Length + 4 /*+ (++c).ToString().Length*/)); } byte baseBank = 0; var asmResult = new StringBuilder(); asmResult.AppendLine("; Games database"); int regCount = 0; foreach (var reg in regs.Keys) { c = 0; foreach (var r in regs[reg]) { if (c % 256 == 0) { asmResult.AppendLine(); asmResult.AppendLine(" .bank " + (baseBank + c / 256 * 2)); asmResult.AppendLine(string.Format(" .org ${0:X4}", 0x8000 + regCount * 0x100)); asmResult.Append("loader_data_" + reg + (c == 0 ? "" : "_" + c.ToString()) + ":"); } //asmResult.AppendLine(" .db " + string.Join(", ", regs[reg])); if (c % 16 == 0) { asmResult.AppendLine(); asmResult.Append(" .db"); } asmResult.AppendFormat(((c % 16 != 0) ? "," : "") + " {0}", r); c++; } asmResult.AppendLine(); regCount++; } asmResult.AppendLine(); asmResult.AppendLine(); //asmResult.Append(" .dw"); c = 0; foreach (var game in games) { if (c % 256 == 0) { asmResult.AppendLine(); asmResult.AppendLine(" .bank " + (baseBank + c / 256 * 2)); asmResult.AppendLine(" .org $9000"); asmResult.AppendLine("game_names_list" + (c == 0 ? "" : "_" + c.ToString()) + ":"); asmResult.AppendLine(" .dw game_names" + (c == 0 ? "" : "_" + c.ToString())); asmResult.AppendLine("game_names" + (c == 0 ? "" : "_" + c.ToString()) + ":"); } //asmResult.AppendFormat(((c > 0) ? "," : "") + " game_name_" + c); asmResult.AppendLine(" .dw game_name_" + c); c++; } asmResult.AppendLine(); asmResult.AppendLine(); asmResult.AppendLine("; Game names"); c = 0; foreach (var game in games) { asmResult.AppendLine(); if (c % 256 == 0) { asmResult.AppendLine(" .bank " + (baseBank + c / 256 * 2 + 1)); if (baseBank + c / 256 * 2 + 1 >= 62) throw new Exception("Bank overflow! Too many games?"); asmResult.AppendLine(" .org $A000"); } asmResult.AppendLine("; " + game.ToString()); asmResult.AppendLine("game_name_" + c + ":"); var name = StringToTiles(string.Format(/*"{0}. "+*/"{1}", c + 1, game.ToString())); var asm = BytesToAsm(name); asmResult.Append(asm); c++; } asmResult.AppendLine(); asmResult.AppendLine(" .bank 14"); asmResult.AppendLine(" .org $C600"); asmResult.AppendLine(); asmResult.AppendLine("games_count:"); asmResult.AppendLine(" .dw " + (games.Count - hiddenCount)); asmResult.AppendLine(); asmResult.AppendLine(); asmResult.AppendLine("games_offset:"); asmResult.AppendLine(" .db " + ((games.Count - hiddenCount) > 10 ? 0 : 5 - (games.Count - hiddenCount) / 2)); asmResult.AppendLine(); asmResult.AppendLine(); asmResult.AppendLine("maximum_scroll:"); asmResult.AppendLine(" .dw " + Math.Max(0, games.Count - 11 - hiddenCount)); asmResult.AppendLine(); asmResult.AppendLine(); asmResult.AppendLine("build_info0:"); asmResult.Append(BytesToAsm(StringToTiles("FILE: " + Path.GetFileName(optionGames)))); asmResult.AppendLine("build_info2:"); asmResult.Append(BytesToAsm(StringToTiles("BUILD DATE: " + DateTime.Now.ToString("yyyy-MM-dd")))); asmResult.AppendLine("build_info3:"); asmResult.Append(BytesToAsm(StringToTiles("BUILD TIME: " + DateTime.Now.ToString("HH:mm:ss")))); asmResult.AppendLine("console_type_text:"); asmResult.Append(BytesToAsm(StringToTiles("CONSOLE TYPE:"))); asmResult.AppendLine("console_type_NTSC:"); asmResult.Append(BytesToAsm(StringToTiles("NTSC"))); asmResult.AppendLine("console_type_PAL:"); asmResult.Append(BytesToAsm(StringToTiles("PAL"))); asmResult.AppendLine("console_type_DENDY:"); asmResult.Append(BytesToAsm(StringToTiles("DENDY"))); asmResult.AppendLine("console_type_NEW:"); asmResult.Append(BytesToAsm(StringToTiles("NEW"))); asmResult.AppendLine("saving_text:"); if (optionLanguage == "rus") asmResult.Append(BytesToAsm(StringToTiles(" СОХРАНЯЕМСЯ... НЕ ВЫКЛЮЧАЙ! "))); else asmResult.Append(BytesToAsm(StringToTiles(" SAVING... KEEP POWER ON! "))); File.WriteAllText(optionAsm, asmResult.ToString()); asmResult.AppendLine("incompatible_console_text:"); if (optionLanguage == "rus") asmResult.Append(BytesToAsm(StringToTiles(" ИЗВИНИТЕ, ДАННАЯ ИГРА НЕСОВМЕСТИМА С ЭТОЙ КОНСОЛЬЮ НАЖМИТЕ ЛЮБУЮ КНОПКУ "))); else asmResult.Append(BytesToAsm(StringToTiles(" SORRY, THIS GAME IS NOT COMPATIBLE WITH THIS CONSOLE PRESS ANY BUTTON "))); asmResult.AppendLine("sram_test_ok_text:"); asmResult.Append(BytesToAsm(StringToTiles("PRG RAM TEST: OK"))); asmResult.AppendLine("sram_test_failed_text:"); asmResult.Append(BytesToAsm(StringToTiles("PRG RAM TEST: FAILED"))); asmResult.AppendLine("chr_test_ok_text:"); asmResult.Append(BytesToAsm(StringToTiles("CHR RAM TEST: OK"))); asmResult.AppendLine("chr_test_failed_text:"); asmResult.Append(BytesToAsm(StringToTiles("CHR RAM TEST: FAILED"))); File.WriteAllText(optionAsm, asmResult.ToString()); XmlWriterSettings xmlSettings = new XmlWriterSettings(); xmlSettings.Indent = true; StreamWriter str = new StreamWriter(optionOffsets); XmlWriter offsetsXml = XmlWriter.Create(str, xmlSettings); offsetsXml.WriteStartDocument(); offsetsXml.WriteStartElement("Offsets"); offsetsXml.WriteStartElement("Info"); offsetsXml.WriteElementString("Size", romSize.ToString()); offsetsXml.WriteElementString("RomCount", games.Count.ToString()); offsetsXml.WriteElementString("GamesFile", Path.GetFileName(optionGames)); offsetsXml.WriteEndElement(); offsetsXml.WriteStartElement("ROMs"); foreach (var game in games) { if (game.FileName == "-") continue; offsetsXml.WriteStartElement("ROM"); offsetsXml.WriteElementString("FileName", game.FileName); if (!game.ToString().StartsWith("?")) offsetsXml.WriteElementString("MenuName", game.ToString()); offsetsXml.WriteElementString("PrgOffset", string.Format("{0:X8}", game.PrgPos)); if (game.ROM.CHR.Length > 0) offsetsXml.WriteElementString("ChrOffset", string.Format("{0:X8}", game.ChrPos)); offsetsXml.WriteElementString("Mapper", game.ROM.Mapper.ToString()); if (game.SaveId > 0) offsetsXml.WriteElementString("SaveId", game.SaveId.ToString()); offsetsXml.WriteEndElement(); } offsetsXml.WriteEndElement(); offsetsXml.WriteEndElement(); offsetsXml.Close(); } else { using (var xmlFile = File.OpenRead(optionOffsets)) { var offsetsXml = new XPathDocument(xmlFile); XPathNavigator offsetsNavigator = offsetsXml.CreateNavigator(); XPathNodeIterator offsetsIterator = offsetsNavigator.Select("/Offsets/Info/Size"); int size = -1; while (offsetsIterator.MoveNext()) { size = offsetsIterator.Current.ValueAsInt; } //size = 64 * 1024 * 1024; if (size < 0) throw new Exception("Invalid offsets file"); var result = new byte[size]; Console.Write("Loading loader... "); var loaderFile = new NesFile(optionLoader); Array.Copy(loaderFile.PRG, 0, result, 0, loaderFile.PRG.Length); Console.WriteLine("OK."); offsetsIterator = offsetsNavigator.Select("/Offsets/ROMs/ROM"); while (offsetsIterator.MoveNext()) { var currentRom = offsetsIterator.Current; string filename = null; int prgOffset = -1; int chrOffset = -1; var descs = currentRom.SelectDescendants(XPathNodeType.Element, false); while (descs.MoveNext()) { var param = descs.Current; switch (param.Name.ToLower()) { case "filename": filename = param.Value; break; case "prgoffset": prgOffset = int.Parse(param.Value, System.Globalization.NumberStyles.HexNumber); break; case "chroffset": chrOffset = int.Parse(param.Value, System.Globalization.NumberStyles.HexNumber); break; } } if (!string.IsNullOrEmpty(filename)) { Console.Write("Loading {0}... ", filename); var nesFile = new NesFile(filename); if (prgOffset >= 0) Array.Copy(nesFile.PRG, 0, result, prgOffset, nesFile.PRG.Length); if (chrOffset >= 0) Array.Copy(nesFile.CHR, 0, result, chrOffset, nesFile.CHR.Length); Console.WriteLine("OK."); } } if (!string.IsNullOrEmpty(optionUnif)) { var u = new UnifFile(); u.Mapper = "COOLGIRL"; u.Fields["MIRR"] = new byte[] { 5 }; u.Fields["PRG0"] = result; u.Fields["BATR"] = new byte[] { 1 }; u.Version = 5; u.Save(optionUnif); uint sizeFixed = 1; while (sizeFixed < result.Length) sizeFixed <<= 1; var resultSizeFixed = new byte[sizeFixed]; Array.Copy(result, 0, resultSizeFixed, 0, result.Length); for (int i = result.Length; i < sizeFixed; i++) resultSizeFixed[i] = 0xFF; var md5 = System.Security.Cryptography.MD5.Create(); var md5hash = md5.ComputeHash(resultSizeFixed); Console.Write("ROM MD5: "); foreach (var b in md5hash) Console.Write("{0:x2}", b); Console.WriteLine(); } if (!string.IsNullOrEmpty(optionBin)) { File.WriteAllBytes(optionBin, result); } } } Console.WriteLine("Done."); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message + ex.StackTrace); return 2; } return 0; }
private static AudioPlayerMapper GetAudioMapper(out MapperInfo info) { AudioPlayerMapper mapper = null; info = MapperInfo.NotFound; Object[] audioMappers = Object.FindObjectsOfType(typeof(AudioPlayerMapper)); // traverse mappers foreach (Object o in audioMappers) { mapper = (AudioPlayerMapper)o; if (mapper.Default) { //if (!mapper.gameObject.activeInHierarchy) // info = AudioPlayerMapperInfo.MapperGameObjectNotEnabled; info = !mapper.enabled ? MapperInfo.MapperNotEnabled : MapperInfo.Ok; break; } } return mapper; }
private void lstMappings_SelectedIndexChanged(object sender, EventArgs e) { if (this.SelectedItem == null) { return; } try { MapperInfo mi = this.SelectedItem.Tag as MapperInfo; if (mi == null) { pnlGeneral.Enabled = false; cbControl.SelectedIndex = -1; cbControlProperty.SelectedIndex = -1; cbFormat.SelectedIndex = 0; tbModelProperty.Text = string.Empty; return; } pnlGeneral.Enabled = true; if (mi.ControlID != String.Empty) { object ctl = _reference.GetReference(mi.ControlID); if (ctl == null) { mi.ControlID = String.Empty; } else { cbControl.SelectedIndex = cbControl.FindStringExact(new ControlEntry(ctl, _reference.GetName(ctl)).ToString()); } } if (mi.ControlProperty != String.Empty) { cbControlProperty.SelectedIndex = cbControlProperty.FindStringExact(mi.ControlProperty); } else { cbControlProperty.SelectedIndex = -1; } if (mi.DataProperty != string.Empty) { cbModelProperty.SelectedIndex = cbModelProperty.FindStringExact(mi.DataProperty); } else { cbModelProperty.SelectedIndex = cbModelProperty.FindStringExact(mi.DataProperty); } tbModelProperty.Text = mi.DataProperty; cbFormat.SelectedIndex = (int)mi.Format; } catch (Exception ex) { System.Windows.Forms.MessageBox.Show( "出错: " + ex.ToString()); } }