don't click here

SonLVL

Discussion in 'Engineering & Reverse Engineering' started by MainMemory, Feb 7, 2011.

  1. Hi, I'm new here and in this, and I have a question, when I want to import new chunks in S3K for some strange reason it doesn't allow me, it only happens in Angel Island, Launch Base, Mushroom Hill, Flying Battery, Sandopolis, Lava Reef Act 1 and Death Egg

    what could be the reason?:
    Captura de pantalla (151).png
    Import.png
     
  2. The Chunk list is full already. You can’t have more than 256 chunks in a level.
     
  3. Oh, I understand, is there any way I can just edit the art? I don't intend to add new chunks, just edit them
     
  4. Hivebrain

    Hivebrain

    Administrator
    3,049
    161
    43
    53.4N, 1.5W
    Github
    I'm trying to load level layouts for Sonic 1 in a "raw" format, meaning no width/height header, and expanded to $80 by 8 bytes. The background and foreground are separate, which is why it's $80 wide rather than $40. I thought layoutcmp=Uncompressed would work but it didn't. Is there a setting that'll allow for the format I've described?
     
    Last edited: Jan 26, 2024
  5. Devon

    Devon

    I'm a loser, baby, so why don't you kill me? Tech Member
    1,249
    1,420
    93
    your mom
    I think you need to create a custom layout handler in C#. "layoutcmp" is for if the layout is compressed with Nemesis, Enigma, Kosinski, etc. Luckily, it's not too difficult. In the INI file, you can define these:
    Code (Text):
    1. layoutfmt=Custom
    2. layoutcodefile=[Layout handler code file]
    3. layoutcodetype=[Namespace].[Class name]

    and then create your custom Layout class in the file you defined. For your case, you'd wanna inherit the "LayoutFormatSeparate" class and implement its functions. You can look at the Sonic 1 layout class as a reference point.

    I do think you need to add this to the top, too:
    Code (Text):
    1. using SonicRetro.SonLVL.API;
     
  6. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    Yeah, unfortunately none of the games use a format like that by default (closest is Sonic 2, but that has FG and BG merged as well), so a custom class is required. Devon is correct in their post.
     
  7. Hivebrain

    Hivebrain

    Administrator
    3,049
    161
    43
    53.4N, 1.5W
    Github
    I don't know any C# so writing a new class file is probably out of the question. I did try using Sonic 2's format but it failed to load. Perhaps adding a fake header ($7F07) to the raw file would work?
     
  8. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    Code (Text):
    1. using SonicRetro.SonLVL.API;
    2.  
    3. namespace CustomLayout
    4. {
    5.    public class CustomLayout : LayoutFormatSeparate
    6.    {
    7.        private void ReadLayoutInternal(byte[] rawdata, ref ushort[,] layout, ref bool[,] loop)
    8.        {
    9.            layout = new ushort[MaxSize.Width, MaxSize.Height];
    10.            loop = new bool[MaxSize.Width, MaxSize.Height];
    11.            for (int lr = 0; lr < MaxSize.Height; lr++)
    12.                for (int lc = 0; lc < MaxSize.Width; lc++)
    13.                {
    14.                    if ((lr * MaxSize.Width) + lc >= rawdata.Length) break;
    15.                    layout[lc, lr] = (byte)(rawdata[(lr * MaxSize.Width) + lc] & 0x7F);
    16.                    loop[lc, lr] = (rawdata[(lr * MaxSize.Width) + lc] & 0x80) == 0x80;
    17.                }
    18.        }
    19.  
    20.        public override void ReadFG(byte[] rawdata, LayoutData layout)
    21.        {
    22.            ReadLayoutInternal(rawdata, ref layout.FGLayout, ref layout.FGLoop);
    23.        }
    24.  
    25.        public override void ReadBG(byte[] rawdata, LayoutData layout)
    26.        {
    27.            ReadLayoutInternal(rawdata, ref layout.BGLayout, ref layout.BGLoop);
    28.        }
    29.  
    30.        private void WriteLayoutInternal(ushort[,] layout, bool[,] loop, out byte[] rawdata)
    31.        {
    32.            rawdata = new byte[MaxSize.Width * MaxSize.Height];
    33.            int c = 0;
    34.            for (int lr = 0; lr < MaxSize.Height; lr++)
    35.                for (int lc = 0; lc < MaxSize.Width; lc++)
    36.                    rawdata[c++] = (byte)(layout[lc, lr] | (loop[lc, lr] ? 0x80 : 0));
    37.        }
    38.  
    39.        public override void WriteFG(LayoutData layout, out byte[] rawdata)
    40.        {
    41.            WriteLayoutInternal(layout.FGLayout, layout.FGLoop, out rawdata);
    42.        }
    43.  
    44.        public override void WriteBG(LayoutData layout, out byte[] rawdata)
    45.        {
    46.            WriteLayoutInternal(layout.BGLayout, layout.BGLoop, out rawdata);
    47.        }
    48.  
    49.        public override bool HasLoopFlag { get { return true; } }
    50.  
    51.        public override bool IsResizable { get { return false; } }
    52.  
    53.        public override System.Drawing.Size MaxSize { get { return new System.Drawing.Size(128, 8); } }
    54.    }
    55. }
     
    Last edited: Jan 26, 2024
  9. Hivebrain

    Hivebrain

    Administrator
    3,049
    161
    43
    53.4N, 1.5W
    Github
    Perfect, thanks!
     
  10. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,742
    338
    63
    SonLVL
    Oops, forgot to remove some "+ 2"s in there.
     
  11. This layout format kinda sounds like a mix between 1 and 2; 2 got rid of the level header system in favor of interleaved foreground/background data (that is also compressed using Kosinski), but was otherwise raw.
     
  12. Hivebrain

    Hivebrain

    Administrator
    3,049
    161
    43
    53.4N, 1.5W
    Github
    Sonic 1 levels are also interleaved. The header is only present on the compressed data ("cropped" might be a better way to describe it) in the ROM. When it's unpacked to RAM I believe it ends up in basically the same format as Sonic 2. I'm not sure if there's a point to storing the data interleaved like that. There doesn't seem to be any advantage over storing the fg/bg separately.
     
  13. True, the format in RAM is identical to Sonic 2 (minus the different chunk format, obviously). I think the reason they ultimately combined both layouts is likely since it would compress better, as most of the background would be repeating empty rows, which the foreground also has (meaning Kosinski could simply use one reference). Sonic 3 & Knuckles actually can be seen as a combination of both due to the following:
    • Foreground and background layouts are combined (Sonic 2)
    • Level header, this time with distinct values for the FG and BG (Sonic 1)
    • Uncompressed (Sonic 1)
     
  14. Bobblen

    Bobblen

    Member
    380
    192
    43
    A year later, armed with @Devon 's excellent SCD PPZ definitions and @MainMemory 's SCDPCspr program to get the sprite numbers, I've started fixing up Sonic CD PC's object definitions. We have springs, rings, blocks and more! This continues an ongoing theme where clever people work out how all this stuff works and I take on the repetitive drudge many years later :-) Still don't know what's up with the monitor graphics offsets. Offsets are set in the monitor xml file, but changing them doesn't appear to make any difference to how things are displayed in SonLVL.
    upload_2024-3-7_14-6-45.png