예제 #1
0
        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());
        }
예제 #2
0
        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());
        }
예제 #3
0
 private static void ConvertBlock(BinaryWriter bw, Bitmap map, uint address, int src_x, int src_y, int start_x, int start_y, int offset_x, int offset_y, int w, int h, int lineWidth)
 {
     for (int yy = start_y, loopTo = h - 1; yy <= loopTo; yy++)
     {
         for (int xx = start_x, loopTo1 = w - 1; xx <= loopTo1; xx++)
         {
             var pixel = map.GetPixel(src_x + xx, src_y + yy);
             int r     = pixel.R / 8;
             int g     = pixel.G / 8;
             int b     = pixel.B / 8;
             int a     = pixel.A == 0xFF ? 1 : 0;
             bw.BaseStream.Position = address + ((yy + offset_y) * lineWidth + xx + offset_x) * 2;
             bw.Write(SwapInts.SwapUInt16(Conversions.ToUShort(r << 11 | g << 6 | b << 1 | a)));
         }
     }
 }
예제 #4
0
 private static void ParseBlock(BinaryReader br, Bitmap map, uint address, Rectangle rect)
 {
     for (int yy = 0, loopTo = rect.Height - 1; yy <= loopTo; yy++)
     {
         for (int xx = 0, loopTo1 = rect.Width - 1; xx <= loopTo1; xx++)
         {
             int offset = (int)(address + (yy * (rect.Width + 1) + xx) * 2);
             br.BaseStream.Position = offset;
             ushort pixel  = SwapInts.SwapUInt16(br.ReadUInt16());
             byte   red    = Conversions.ToByte((pixel >> 11 & 0x1F) * 8);
             byte   green  = Conversions.ToByte((pixel >> 6 & 0x1F) * 8);
             byte   blue   = Conversions.ToByte((pixel >> 1 & 0x1F) * 8);
             byte   alpha  = Conversions.ToByte((pixel & 1) > 0 ? 0xFF : 0);
             var    pixcol = Color.FromArgb(alpha, red, green, blue);
             map.SetPixel(rect.X + xx, rect.Y + yy, pixcol);
         }
     }
 }
예제 #5
0
 public float ReadSingle()
 {
     return(SwapInts.SwapSingle(Reader.ReadSingle()));
 }
예제 #6
0
 public ulong ReadUInt64()
 {
     return(SwapInts.SwapUInt64(Reader.ReadUInt64()));
 }
예제 #7
0
 public long ReadInt64()
 {
     return(SwapInts.SwapInt64(Reader.ReadInt64()));
 }
예제 #8
0
 public uint ReadUInt32()
 {
     return(SwapInts.SwapUInt32(Reader.ReadUInt32()));
 }
예제 #9
0
 public int ReadInt32()
 {
     return(SwapInts.SwapInt32(Reader.ReadInt32()));
 }
예제 #10
0
        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;
        }
예제 #11
0
 public short ReadInt16()
 {
     return(SwapInts.SwapInt16(Reader.ReadInt16()));
 }
예제 #12
0
 public void Write(float value)
 {
     Writer.Write(SwapInts.SwapSingle(value));
 }
예제 #13
0
 public void Write(ulong value)
 {
     Writer.Write(SwapInts.SwapUInt64(value));
 }
예제 #14
0
 public void Write(uint value)
 {
     Writer.Write(SwapInts.SwapUInt32(value));
 }
예제 #15
0
 public void Write(ushort value)
 {
     Writer.Write(SwapInts.SwapUInt16(value));
 }
예제 #16
0
        /// <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();
        }
예제 #17
0
 public ushort ReadUInt16()
 {
     return(SwapInts.SwapUInt16(Reader.ReadUInt16()));
 }