public byte[] ToArrayBoxData() { var ms = new MemoryStream(0x20); var bw = new BinaryWriter(ms); ms.Position = 0; // Stand: SM64 Editor v2.0.7 bw.Write(SwapInts.SwapInt32(InvisibleWater ? 0x0 : 0x10000)); // Type = SpecialBoxType.ToxicHaze OrElse bw.Write(SwapInts.SwapInt16(0xF)); bw.Write(SwapInts.SwapInt16(Scale)); bw.Write(SwapInts.SwapInt16(X1)); bw.Write(SwapInts.SwapInt16(Z1)); bw.Write(SwapInts.SwapInt16(X2)); bw.Write(SwapInts.SwapInt16(Z1)); bw.Write(SwapInts.SwapInt16(X2)); bw.Write(SwapInts.SwapInt16(Z2)); bw.Write(SwapInts.SwapInt16(X1)); bw.Write(SwapInts.SwapInt16(Z2)); if (Type == SpecialBoxType.ToxicHaze) { bw.Write(SwapInts.SwapInt32(Alpha)); // &HB4 bw.Write(SwapInts.SwapInt32(0x10000)); } else { bw.Write(SwapInts.SwapInt32(0x10000 | Alpha)); bw.Write(SwapInts.SwapInt32((int)WaterType)); } ms.Close(); return(ms.GetBuffer()); }
public static SpecialBox[] ReadTable(Stream s, SpecialBoxType Type, int Levelscriptstart, int TabelStart) { var br = new BinaryReader(s); var boxlist = new List <SpecialBox>(); s.Position = TabelStart; if (SwapInts.SwapInt32(br.ReadInt32()) == 0x1010101) { return(Array.Empty <SpecialBox>()); } else { s.Position -= 0x4; } while (SwapInts.SwapUInt16(br.ReadUInt16()) != 0xFFFF) { s.Position += 0x2; var tbox = new SpecialBox(); tbox.Type = Type; int lastpos = (int)(s.Position + 0x4); s.Position = SwapInts.SwapInt32(br.ReadInt32()) - 0x19000000 + Levelscriptstart; if (Type == SpecialBoxType.Water) { tbox.InvisibleWater = SwapInts.SwapInt32(br.ReadInt32()) == 0x0; } else { s.Position += 0x4; } s.Position += 0x2; tbox.Scale = SwapInts.SwapInt16(br.ReadInt16()); tbox.X1 = SwapInts.SwapInt16(br.ReadInt16()); tbox.Z1 = SwapInts.SwapInt16(br.ReadInt16()); tbox.X2 = SwapInts.SwapInt16(br.ReadInt16()); s.Position += 0x4; tbox.Z2 = SwapInts.SwapInt16(br.ReadInt16()); s.Position += 0x7; tbox.Alpha = br.ReadByte(); tbox.WaterType = (WaterType)SwapInts.SwapInt32(br.ReadInt32()); s.Position = lastpos; boxlist.Add(tbox); } return(boxlist.ToArray()); }
/// <summary> /// Loads a ROM Manager Level from ROM. /// </summary> /// <param name="lvl"></param> /// <param name="rommgr"></param> /// <param name="LevelID"></param> /// <param name="segAddress"></param> public virtual void LoadLevel(Level lvl, RomManager rommgr, ushort LevelID, uint segAddress) { int customBGStart = 0; int customBGEnd = 0; lvl.LevelID = LevelID; // Load Bank 0x19 lvl.Bank0x19 = rommgr.GetSegBank(0x19); lvl.Bank0x19.ReadDataIfNull(rommgr.RomFile); // Close if not closed & re-open if (!lvl.Closed) { lvl.Close(); } lvl.Closed = false; // Lade Levelscript lvl.Levelscript = new Levelscript(); lvl.Levelscript.Read(rommgr, Conversions.ToInteger(segAddress)); // Erstelle Areas / Lade Einstellungen bool AreaOnFly = false; LevelArea tArea = null; var CurrentLevelScriptCommands = lvl.Levelscript.ToArray(); var cmdsToRemove = new List <LevelscriptCommand>(); foreach (LevelscriptCommand c in CurrentLevelScriptCommands) { var switchExpr = c.CommandType; switch (switchExpr) { case LevelscriptCommandTypes.StartArea: AreaOnFly = true; tArea = new RMLevelArea(); tArea.AreaID = clStartArea.GetAreaID(c); tArea.GeolayoutOffset = clStartArea.GetSegGeolayoutAddr(c); // - bank0x19.BankAddress + bank0x19.RomStart tArea.Geolayout.Read(rommgr, Conversions.ToInteger(tArea.GeolayoutOffset)); break; case LevelscriptCommandTypes.EndOfArea: tArea.Levelscript.Add(c); lvl.Levelscript.Remove(c); lvl.Areas.Add(tArea); AreaOnFly = false; break; case LevelscriptCommandTypes.AreaMusic: tArea.BGMusic = clAreaMusic.GetMusicID(c); break; case LevelscriptCommandTypes.AreaMusicSimple: tArea.BGMusic = clAreaMusicSimple.GetMusicID(c); break; case LevelscriptCommandTypes.Tarrain: tArea.TerrainType = (Geolayout.TerrainTypes)clTerrian.GetTerrainType(c); break; case LevelscriptCommandTypes.Normal3DObject: var scrollTexAddrs = new List <int>(new[] { 0x400000, 0x401700 }); if (rommgr.RomConfig.ScrollTexConfig.UseCustomBehavior) { scrollTexAddrs.Add(rommgr.RomConfig.ScrollTexConfig.CustomBehaviorAddress); } if (scrollTexAddrs.Contains((int)clNormal3DObject.GetSegBehaviorAddr(c))) { tArea.ScrollingTextures.Add(new ManagedScrollingTexture(c)); } else { tArea.Objects.Add(c); } break; case LevelscriptCommandTypes.ConnectedWarp: if ((new[] { 0xF0, 0xF1 }).Contains(clWarp.GetWarpID(c))) { tArea.WarpsForGame.Add(c); } else { tArea.Warps.Add(c); } break; case LevelscriptCommandTypes.PaintingWarp: case LevelscriptCommandTypes.InstantWarp: tArea.Warps.Add(c); break; case LevelscriptCommandTypes.LoadRomToRam: byte bankID = clLoadRomToRam.GetSegmentedID(c); int startAddr = clLoadRomToRam.GetRomStart(c); int endAddr = clLoadRomToRam.GetRomEnd(c); switch (bankID) { case 0xA: // Background-Image customBGStart = startAddr; customBGEnd = endAddr - 0x140; break; case 0x7: // Global Object Bank if (rommgr.GlobalModelBank?.CurSeg is object && startAddr == rommgr.GlobalModelBank.CurSeg.RomStart && endAddr == rommgr.GlobalModelBank.CurSeg.RomEnd) { lvl.EnableGlobalObjectBank = true; lvl.LastGobCmdSegLoad = c; } break; case 0x9: if (((RMLevel)lvl).Config.EnableLocalObjectBank) { lvl.EnableLocalObjectBank = true; } lvl.LastLobCmdSegLoad = c; break; } break; case LevelscriptCommandTypes.ShowDialog: if (AreaOnFly) { tArea.ShowMessage.Enabled = true; tArea.ShowMessage.DialogID = clShowDialog.GetDialogID(c); } break; case LevelscriptCommandTypes.JumpBack: case LevelscriptCommandTypes.JumpToSegAddr: if (tArea is object) { cmdsToRemove.Add(c); } break; } if (AreaOnFly && !cmdsToRemove.Contains(c)) { lvl.Levelscript.Remove(c); tArea.Levelscript.Add(c); } } // Lösche alle Jump-Commands aus dem Levelscript foreach (LevelscriptCommand cmd in cmdsToRemove) { lvl.Levelscript.Remove(cmd); cmd.Close(); } // Lösche alle Objekte und Warps aus dem Levelscript var lvlscrptidstoremove = new[] { LevelscriptCommandTypes.Normal3DObject, LevelscriptCommandTypes.ConnectedWarp, LevelscriptCommandTypes.PaintingWarp, LevelscriptCommandTypes.InstantWarp }; foreach (var a in lvl.Areas) { foreach (var c in a.Levelscript.Where(n => lvlscrptidstoremove.Contains(n.CommandType)).ToArray()) { a.Levelscript.Remove(c); } } // Load Local Object Bank if (lvl.LastLobCmdSegLoad is object) { var seg = new SegmentedBank() { BankID = clLoadRomToRam.GetSegmentedID(lvl.LastLobCmdSegLoad), RomStart = clLoadRomToRam.GetRomStart(lvl.LastLobCmdSegLoad), RomEnd = clLoadRomToRam.GetRomEnd(lvl.LastLobCmdSegLoad) }; lvl.LocalObjectBank.ReadFromSeg(rommgr, seg, ((RMLevel)lvl).Config.LocalObjectBank); } // Lese Custom Background Image var fs = new FileStream(rommgr.RomFile, FileMode.Open, FileAccess.Read); var br2 = new BinaryReader(fs); lvl.Background.Enabled = false; foreach (LevelArea a in lvl.Areas) { var bgglcmd = a.Geolayout.Geolayoutscript.GetFirst(GeolayoutCommandTypes.Background); if (cgBackground.GetBackgroundPointer(bgglcmd) == 0) { a.Background.Type = AreaBGs.Color; a.Background.Color = cgBackground.GetRrgbaColor(bgglcmd); } else { a.Background.Type = AreaBGs.Levelbackground; lvl.Background.ID = (Geolayout.BackgroundIDs)cgBackground.GetBackgroundID(bgglcmd); lvl.Background.Enabled = true; } } if (customBGStart != 0) { lvl.Background.IsCustom = true; } foreach (int val in Enum.GetValues(typeof(Geolayout.BackgroundPointers))) { if (val != 0 && customBGStart == val) { lvl.Background.IsCustom = false; } } if (lvl.Background.Enabled && lvl.Background.IsCustom) // .ID = Geolayout.BackgroundIDs.Custom Then { fs.Position = customBGStart; lvl.Background.ReadImage(fs, customBGStart); } int bank0x19RomStart; int bank0x19RomEnd; BinaryReader brToUse; bank0x19RomStart = 0; bank0x19RomEnd = lvl.Bank0x19.Length; brToUse = new BinaryReader(lvl.Bank0x19.Data); // Lese Area-Table foreach (LevelArea a in lvl.Areas) { // Fast3D-Daten brToUse.BaseStream.Position = bank0x19RomStart + 0x5F00 + a.AreaID * 0x10; a.Bank0x0EOffset = Conversions.ToUInteger(SwapInts.SwapInt32(brToUse.ReadInt32())); int romEnd0xE = SwapInts.SwapInt32(brToUse.ReadInt32()); rommgr.SetSegBank(0xE, Conversions.ToInteger(a.Bank0x0EOffset), romEnd0xE, a.AreaID); // 2D-Kamera brToUse.BaseStream.Position = bank0x19RomStart + 0x5F0F + a.AreaID * 0x10; a.Enable2DCamera = Bits.GetBoolOfByte(brToUse.ReadByte(), 7); } // Lese Area-Modelle foreach (LevelArea a in lvl.Areas) { a.AreaModel.FromStream(fs, Conversions.ToInteger(a.Bank0x0EOffset), 0xE000000, a.Fast3DBankRomStart, a.Fast3DLength, a.Geolayout.Geopointers.ToArray(), a.CollisionPointer); } // Lese alle Box-Daten int CurrentBoxOffset = bank0x19RomStart + 0x6A00; foreach (LevelArea a in lvl.Areas) { // Clear special boxes a.SpecialBoxes.Clear(); // Load special boxes a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Water, bank0x19RomStart, bank0x19RomStart + 0x6000 + 0x50 * a.AreaID)); a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.ToxicHaze, bank0x19RomStart, bank0x19RomStart + 0x6280 + 0x50 * a.AreaID)); a.SpecialBoxes.AddRange(SpecialBoxList.ReadTable(brToUse.BaseStream, SpecialBoxType.Mist, bank0x19RomStart, bank0x19RomStart + 0x6500 + 0x50 * a.AreaID)); for (int i = 0; i < a.SpecialBoxes.Count; i++) { var boxdata = a.AreaModel.Collision.SpecialBoxes.ElementAtOrDefault(i); if (boxdata is object) { a.SpecialBoxes[i].Y = boxdata.Y; } } } // One-Bank-0xE-System lvl.OneBank0xESystemEnabled = true; // Act Selector General.PatchClass.Open(fs); lvl.ActSelector = General.PatchClass.get_ActSelector_Enabled(LevelID); // Hardcoded Camera lvl.HardcodedCameraSettings = General.PatchClass.get_HardcodedCamera_Enabled(LevelID); // Area Reverb if (EnableLoadingAreaReverb) { foreach (var area in lvl.Areas) { if (area is RMLevelArea && area.AreaID >= 1 && area.AreaID <= 3) { fs.Position = 0xEE0C0 + lvl.LevelID * 3 + area.AreaID - 1; ((RMLevelArea)area).ReverbLevel = (AreaReverbLevel)fs.ReadByte(); } } } fs.Close(); }
public int ReadInt32() { return(SwapInts.SwapInt32(Reader.ReadInt32())); }
public void Write(int value) { Writer.Write(SwapInts.SwapInt32(value)); }
private void ButtonX_ImportMdl_Click(object sender, EventArgs e) { ButtonX_ImportMdl.Image = null; var pap = SelectedProfileAndPreset(); var profile = pap.profile; var preset = pap.preset; int romAddr = preset.RomAddress; // ValueFromText(TextBoxX_RomAddr.Text) int bankAddr = preset.RamAddress; // ValueFromText(TextBoxX_BankAddr.Text) int maxLength = preset.MaxLength; // ValueFromText(TextBoxX_MaxLength.Text) var pm = new PatchingManager(); var scriptparams = new Dictionary <string, object>() { { "romfile", RomFile }, { "presetName", preset.Name }, { "presetDescription", preset.Description }, { "RomAddress", preset.RomAddress }, { "RamAddress", preset.RamAddress }, { "MaxLength", preset.MaxLength }, { "CollisionPointersArray", preset.CollisionPointers.ToArray() }, { "GeoPointersArray", preset.GeometryPointers.ToArray() }, { "ConvertedModelLength", mdl.Length }, { "ConvertedModel", mdl }, { "profilepath", profile.FileName }, { "files", profile.EmbeddedFiles } }; if (maxLength > 0 && mdl.Length > maxLength) { MessageBoxEx.Show("Model is bigger then the max allowed length!", "Model too big", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } ClearOutput(); // Execute Script Before if (preset.ScriptBefore is object && !string.IsNullOrEmpty(preset.ScriptBefore.Script)) { WriteOutput("Executing Script ..."); scriptparams.AddOrUpdate("script", preset.ScriptBefore); pm.Patch(preset.ScriptBefore, this, scriptparams, General.GetAdditionalReferencedAssemblied()); } int col = -1; var geo = Array.Empty <Geopointer>(); int len = 0; ObjectModel.SaveResult sr = null; bool iscollisionempty = mdl.Collision is null; bool isf3disempty = mdl.Fast3DBuffer is null; var fs = new FileStream(_RomFile, FileMode.Open, FileAccess.ReadWrite); var bw = new BinaryWriter(fs); // Write to stream WriteOutput("Writing Model ..."); sr = mdl.ToStream(fs, romAddr, romAddr - (bankAddr & 0xFFFFFF), (int)(bankAddr & 0xFF000000)); if (sr is object) { geo = sr.GeoPointers.ToArray(); col = sr.CollisionPointer; len = Conversions.ToInteger(sr.Length); } // Write Collision Pointer if (col > -1) { WriteOutput("Chaning Collision Pointers ..."); foreach (int cp in SelectedPreset().CollisionPointers) { fs.Position = cp; bw.Write(SwapInts.SwapInt32(col)); } } // Write Geopointer if (geo.Length > 0) { WriteOutput("Chaning Geometry Pointers ..."); foreach (int gp in SelectedPreset().GeometryPointers) { fs.Position = gp; bw.Write(SwapInts.SwapInt32(geo[0].SegPointer)); fs.Position = gp - 4; if (fs.ReadByte() == 0x15) { fs.WriteByte(geo[0].Layer); } else { fs.Position = gp - 8; if (fs.ReadByte() == 0x13) { fs.WriteByte(geo[0].Layer); } } } } fs.Close(); if (preset.ScriptAfter is object && !string.IsNullOrEmpty(preset.ScriptAfter.Script)) { WriteOutput("Executing Script ..."); scriptparams.AddOrUpdate("script", preset.ScriptAfter); pm.Patch(preset.ScriptAfter, this, scriptparams, General.GetAdditionalReferencedAssemblied()); } if (col > -1) { WriteOutput($"Collision Pointer:{Constants.vbTab}{sr.CollisionPointer.ToString("X")}"); } foreach (Geopointer g in geo) { WriteOutput($"DL-Pointer:{Constants.vbTab}{g.SegPointer.ToString("X")} ({g.Layer.ToString()})"); } WriteOutput(); WriteOutput(DateAndTime.Now.ToShortTimeString() + " - Done"); // MessageBoxEx.Show("Model has been imported succesfully!", "Model imported", MessageBoxButtons.OK, MessageBoxIcon.Information) ButtonX_ImportMdl.Image = My.Resources.Resources.icons8_checkmark_16px_1; }