public SceneCommand this[HeaderCommands c] { get { return(cmds.SingleOrDefault(x => x.ID == (int)c)); } }
public Scene_MQJson(BinaryReader br, int id, int start, int end) { File = new File_MQJson() { Name = $"Scene {id}", Start = start.ToString("X8"), End = end.ToString("X8"), }; Id = id; SceneWord cmd = new SceneWord(); do { br.Read(cmd, 0, 8); var seekback = br.BaseStream.Position; HeaderCommands code = (HeaderCommands)cmd.Code; if (code == HeaderCommands.PathList) { SegmentAddress offset = cmd.Data2; br.BaseStream.Position = offset.Offset; InitPaths(br); } else if (code == HeaderCommands.TransitionActorList) { SegmentAddress actorOff = cmd.Data2; br.BaseStream.Position = actorOff.Offset; for (int i = 0; i < cmd.Data1; i++) { TActors.Add(Actor_MQJson.Read(br)); } } if (code == HeaderCommands.RoomList) { RoomsCount = (int)cmd.Data1; RoomsAddress = cmd.Data2; } br.BaseStream.Position = seekback; }while ((HeaderCommands)cmd.Code != HeaderCommands.End); }
public void ReadScene(HeaderCommands.Rooms forcerooms = null) { Program.Status.Message = string.Format("Reading scene '{0}'...", this.Name); ROM.SegmentMapping.Remove((byte)0x02); ROM.SegmentMapping.Add((byte)0x02, data); sceneHeaders = new List<HeaderLoader>(); HeaderLoader newheader = null; HeaderCommands.Rooms rooms = null; HeaderCommands.Collision coll = null; if (data[0] == (byte)HeaderLoader.CommandTypeIDs.SettingsSoundScene || data[0] == (byte)HeaderLoader.CommandTypeIDs.Rooms || BitConverter.ToUInt32(data, 0) == (byte)HeaderLoader.CommandTypeIDs.SubHeaders) { /* Get rooms & collision command from first header */ newheader = new HeaderLoader(ROM, this, (byte)0x02, 0, 0); /* If external rooms should be forced, overwrite command in header */ if (forcerooms != null) { int roomidx = newheader.Commands.FindIndex(x => x.Command == HeaderLoader.CommandTypeIDs.Rooms); if (roomidx != -1) newheader.Commands[roomidx] = forcerooms; } rooms = newheader.Commands.FirstOrDefault(x => x.Command == HeaderLoader.CommandTypeIDs.Rooms) as HeaderCommands.Rooms; coll = newheader.Commands.FirstOrDefault(x => x.Command == HeaderLoader.CommandTypeIDs.Collision) as HeaderCommands.Collision; sceneHeaders.Add(newheader); if (BitConverter.ToUInt32(((byte[])ROM.SegmentMapping[(byte)0x02]), 0) == 0x18) { int hnum = 1; uint aofs = Endian.SwapUInt32(BitConverter.ToUInt32(((byte[])ROM.SegmentMapping[(byte)0x02]), 4)); while (true) { uint rofs = Endian.SwapUInt32(BitConverter.ToUInt32(((byte[])ROM.SegmentMapping[(byte)0x02]), (int)(aofs & 0x00FFFFFF))); if (rofs != 0) { if ((rofs & 0x00FFFFFF) > ((byte[])ROM.SegmentMapping[(byte)0x02]).Length || (rofs >> 24) != 0x02) break; newheader = new HeaderLoader(ROM, this, (byte)0x02, (int)(rofs & 0x00FFFFFF), hnum++); /* Get room command index... */ int roomidx = newheader.Commands.FindIndex(x => x.Command == HeaderLoader.CommandTypeIDs.Rooms); /* If external rooms should be forced, overwrite command in header */ if (roomidx != -1 && forcerooms != null) newheader.Commands[roomidx] = forcerooms; /* If rooms were found in first header, force using these! */ if (roomidx != -1 && rooms != null) newheader.Commands[roomidx] = rooms; /* If collision was found in header, force */ int collidx = newheader.Commands.FindIndex(x => x.Command == HeaderLoader.CommandTypeIDs.Collision); if (collidx != -1 && coll != null) newheader.Commands[collidx] = coll; sceneHeaders.Add(newheader); } aofs += 4; } } currentSceneHeader = sceneHeaders[0]; } }
private void RenderMeshHeader(HeaderCommands.MeshHeader mh) { if (mh.DLs == null || displayListsDirty || mh.CachedWithTextures != Configuration.RenderTextures || mh.CachedWithCombinerType != Configuration.CombinerType) { /* Display lists aren't yet cached OR cached DLs are wrong */ if (mh.DLs != null) { foreach (DisplayList gldl in mh.DLs) gldl.Dispose(); mh.DLs.Clear(); } mh.CreateDisplayLists(Configuration.RenderTextures, Configuration.CombinerType); RefreshCurrentData(); } /* Render DLs */ foreach (DisplayList gldl in mh.DLs) gldl.Render(); /* Bounds test */ /*GL.PushAttrib(AttribMask.AllAttribBits); GL.UseProgram(0); GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.Fog); if (supportsGenProgramsARB) GL.Disable((EnableCap)All.FragmentProgram); if (supportsCreateShader) GL.UseProgram(0); for (int i = 0; i < mh.MinClipBounds.Count; i++) { GL.Color4(Color.FromArgb((mh.GetHashCode() & 0xFFFFFF) | (0xFF << 24))); GL.Begin(PrimitiveType.Lines); GL.Vertex3(mh.MinClipBounds[i]); GL.Vertex3(mh.MaxClipBounds[i]); GL.End(); //OpenGLHelpers.MiscDrawingHelpers.DrawBox(mh.MinClipBounds[i], mh.MaxClipBounds[i]); } GL.PopAttrib();*/ }
private void RefreshWaypointPathList(HeaderCommands.Waypoints wp) { if (wp == null) return; List<HeaderCommands.Waypoints.PathHeader> pathlist = new List<HeaderCommands.Waypoints.PathHeader>(); pathlist.Add(new HeaderCommands.Waypoints.PathHeader()); pathlist.AddRange(wp.Paths); waypointPathComboDataBinding = new BindingSource(); waypointPathComboDataBinding.DataSource = pathlist; cbPathHeaders.DataSource = waypointPathComboDataBinding; cbPathHeaders.DisplayMember = "Description"; cbPathHeaders.Enabled = true; }
public static void SetValueInActor(Definition.Item item, HeaderCommands.Actors.Entry ac, object value) { if (item == null || ac == null || value == null) return; object oldval = null; if (item.ValueType == typeof(Byte)) { ac.RawData[item.Index] = (byte)((ac.RawData[item.Index] & ~(Byte)item.Mask) | Convert.ToByte(value)); } else if (item.ValueType == typeof(UInt16)) { oldval = (UInt16)(Endian.SwapUInt16(BitConverter.ToUInt16(ac.RawData, item.Index)) & ~(UInt16)item.Mask); UInt16 newval = Endian.SwapUInt16((UInt16)(Convert.ToUInt16(oldval) | Convert.ToUInt16(value))); BitConverter.GetBytes(newval).CopyTo(ac.RawData, item.Index); } else if (item.ValueType == typeof(Int16)) { oldval = (Int16)(Endian.SwapInt16(BitConverter.ToInt16(ac.RawData, item.Index)) & ~(Int16)item.Mask); Int16 newval = Endian.SwapInt16((Int16)(Convert.ToInt16(oldval) | Convert.ToInt16(value))); BitConverter.GetBytes(newval).CopyTo(ac.RawData, item.Index); } if (item.Usage == Definition.Item.Usages.ActorNumber) ac.RefreshVariables(); }
public static void RefreshActorPositionRotation(HeaderCommands.Actors.Entry ac, Controls.TableLayoutPanelEx tlpex) { foreach (Control ctrl in tlpex.Controls) { if (ctrl is TextBox && ctrl.Tag is Definition.Item) { Definition.Item item = (ctrl.Tag as Definition.Item); if (item.Usage == Definition.Item.Usages.PositionX || item.Usage == Definition.Item.Usages.PositionY || item.Usage == Definition.Item.Usages.PositionZ || item.Usage == Definition.Item.Usages.RotationX || item.Usage == Definition.Item.Usages.RotationY || item.Usage == Definition.Item.Usages.RotationZ) { string fstr = "{0}"; switch (item.DisplayStyle) { case Definition.Item.DisplayStyles.Hexadecimal: fstr = "0x{0:X}"; break; case Definition.Item.DisplayStyles.Decimal: fstr = "{0:D}"; break; } object val = GetValueFromActor(item, ac); item.ControlType.GetProperty("Text").SetValue(ctrl, string.Format(fstr, val), null); } } } }
public static object GetValueFromActor(Definition.Item item, HeaderCommands.Actors.Entry ac) { if (item == null || ac == null) return null; object val = null; if (item.ValueType == typeof(Byte)) val = (ac.RawData[item.Index] & (Byte)item.Mask); if (item.ValueType == typeof(UInt16)) val = (Endian.SwapUInt16(BitConverter.ToUInt16(ac.RawData, item.Index)) & (UInt16)item.Mask); else if (item.ValueType == typeof(Int16)) val = (Endian.SwapInt16(BitConverter.ToInt16(ac.RawData, item.Index)) & (Int16)item.Mask); return Convert.ChangeType(val, item.ValueType); }
public static void CreateActorEditingControls(HeaderCommands.Actors.Entry ac, Controls.TableLayoutPanelEx tlpex, Action numberchanged, object tag = null, bool individual = false) { //TODO TODO TODO: more value types, more control types, etc, etc!!! /* No proper actor entry given? */ if (ac == null || ac.Definition == null) { tlpex.Controls.Clear(); return; } /* Get current definition */ Definition def = ac.Definition; /* No definition given? */ if (def == null) return; /* Begin layout creation */ tlpex.SuspendLayout(); tlpex.Controls.Clear(); /* Create description label */ Label desc = new Label() { Text = (ac.InternalName == string.Empty ? ac.Name : string.Format("{0} ({1})", ac.Name, ac.InternalName)), TextAlign = ContentAlignment.MiddleLeft, Dock = DockStyle.Fill }; tlpex.Controls.Add(desc, 0, 0); tlpex.SetColumnSpan(desc, 2); /* Parse items */ for (int i = 0; i < def.Items.Count; i++) { /* Get current item */ Definition.Item item = def.Items[i]; /* UGLY HACK -> for room number in transition actor with individual file mode... */ if (item.Usage == Definition.Item.Usages.NextRoomBack || item.Usage == Definition.Item.Usages.NextRoomFront) item.ControlType = (individual ? typeof(TextBox) : typeof(ComboBox)); /* Get value, create control */ object val = GetValueFromActor(item, ac); object ctrl = Activator.CreateInstance(item.ControlType); /* First ControlType check; ex. is label needed? */ if (item.ControlType == typeof(CheckBox)) { /* Add control alone */ tlpex.Controls.Add(ctrl as Control, 0, (i + 1)); } else { /* Add label and control */ Label lbl = new Label() { Text = string.Format("{0}:", item.Description), TextAlign = ContentAlignment.MiddleLeft, Dock = DockStyle.Fill }; tlpex.Controls.Add(lbl, 0, (i + 1)); tlpex.Controls.Add(ctrl as Control, 1, (i + 1)); } /* Set control properties */ item.ControlType.GetProperty("Dock").SetValue(ctrl, DockStyle.Fill, null); item.ControlType.GetProperty("Tag").SetValue(ctrl, item, null); item.ControlType.GetProperty("Name").SetValue(ctrl, item.Usage.ToString(), null); /* ControlType-specific settings */ if (item.ControlType == typeof(ComboBox)) { /* Set ComboBox */ item.ControlType.GetProperty("DropDownStyle").SetValue(ctrl, ComboBoxStyle.DropDownList, null); item.ControlType.GetProperty("DisplayMember").SetValue(ctrl, "Description", null); if (!individual && (item.Usage == Definition.Item.Usages.NextRoomBack || item.Usage == Definition.Item.Usages.NextRoomFront) && (tag is List<HeaderCommands.Rooms.RoomInfoClass>)) { /* Item usage is room number in transition actor; get room listing from function tag */ item.Options = new List<Definition.Item.Option>(); foreach (HeaderCommands.Rooms.RoomInfoClass ric in (tag as List<HeaderCommands.Rooms.RoomInfoClass>)) item.Options.Add(new Definition.Item.Option() { Description = ric.Description, Value = ric.Number }); } if (item.Options.Count > 0) { item.ControlType.GetProperty("DataSource").SetValue(ctrl, item.Options, null); item.ControlType.GetProperty("SelectedItem").SetValue(ctrl, item.Options.Find(x => x.Value == (Convert.ToUInt64(val) & item.Mask)), null); (ctrl as ComboBox).SelectedIndexChanged += new EventHandler((s, ex) => { SetValueInActor(item, ac, ((Definition.Item.Option)((ComboBox)s).SelectedItem).Value); }); } } else if (item.ControlType == typeof(CheckBox)) { /* Set CheckBox */ item.ControlType.GetProperty("Checked").SetValue(ctrl, Convert.ToBoolean(val), null); item.ControlType.GetProperty("Text").SetValue(ctrl, item.Description, null); tlpex.SetColumnSpan(ctrl as Control, 2); (ctrl as CheckBox).CheckedChanged += new EventHandler((s, ex) => { ChangeBitInActor(item, ac, item.Mask, ((CheckBox)s).Checked); }); } else { /* Fallback */ if (item.ControlType.GetProperty("Text") != null) { string fstr = "{0}"; switch (item.DisplayStyle) { case Definition.Item.DisplayStyles.Hexadecimal: fstr = "0x{0:X}"; break; case Definition.Item.DisplayStyles.Decimal: fstr = "{0:D}"; break; } item.ControlType.GetProperty("Text").SetValue(ctrl, string.Format(fstr, val), null); (ctrl as Control).TextChanged += new EventHandler((s, ex) => { object newval = Activator.CreateInstance(item.ValueType); System.Reflection.MethodInfo mi = item.ValueType.GetMethod("Parse", new Type[] { typeof(string), typeof(System.Globalization.NumberStyles) }); if (mi != null) { /* Determine NumberStyle to use */ System.Globalization.NumberStyles ns = (item.DisplayStyle == Definition.Item.DisplayStyles.Hexadecimal ? System.Globalization.NumberStyles.HexNumber : System.Globalization.NumberStyles.Integer); /* Hex number; is text long enough? */ if (ns == System.Globalization.NumberStyles.HexNumber && ((Control)s).Text.Length < 2) return; /* Get value string, depending on NumberStyle */ string valstr = (ns == System.Globalization.NumberStyles.HexNumber ? ((Control)s).Text.Substring(2) : ((Control)s).Text); /* Proper value string found? */ if (valstr != null && valstr != "") { try { /* Invoke Parse function and get parsed value */ newval = mi.Invoke(newval, new object[] { valstr, ns }); /* Set new value in actor; if usage is ActorNumber, also do callback */ SetValueInActor(item, ac, newval); if (item.Usage == Definition.Item.Usages.ActorNumber && numberchanged != null) numberchanged(); } catch (TargetInvocationException tiex) { if (tiex.InnerException is FormatException) { /* Ignore; happens with ex. malformed hex numbers (i.e. "0xx0") */ } } } } }); } } } /* Done */ tlpex.ResumeLayout(); }
public static void ChangeBitInActor(Definition.Item item, HeaderCommands.Actors.Entry ac, object value, bool set) { if (item == null || ac == null || value == null) return; //TODO TODO TODO allow bit toggle in non-byte types?? if (set == true) { if (item.ValueType == typeof(Byte)) ac.RawData[item.Index] |= (byte)(Convert.ToByte(value) & (Byte)item.Mask); else throw new Exception("Cannot toggle bits in non-byte value"); } else { if (item.ValueType == typeof(Byte)) ac.RawData[item.Index] &= (byte)~(Convert.ToByte(value) & (Byte)item.Mask); else throw new Exception("Cannot toggle bits in non-byte value"); } }