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?:
Oh, I understand, is there any way I can just edit the art? I don't intend to add new chunks, just edit them
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?
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): layoutfmt=Custom layoutcodefile=[Layout handler code file] 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): using SonicRetro.SonLVL.API;
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.
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?
Code (Text): using SonicRetro.SonLVL.API; namespace CustomLayout { public class CustomLayout : LayoutFormatSeparate { private void ReadLayoutInternal(byte[] rawdata, ref ushort[,] layout, ref bool[,] loop) { layout = new ushort[MaxSize.Width, MaxSize.Height]; loop = new bool[MaxSize.Width, MaxSize.Height]; for (int lr = 0; lr < MaxSize.Height; lr++) for (int lc = 0; lc < MaxSize.Width; lc++) { if ((lr * MaxSize.Width) + lc >= rawdata.Length) break; layout[lc, lr] = (byte)(rawdata[(lr * MaxSize.Width) + lc] & 0x7F); loop[lc, lr] = (rawdata[(lr * MaxSize.Width) + lc] & 0x80) == 0x80; } } public override void ReadFG(byte[] rawdata, LayoutData layout) { ReadLayoutInternal(rawdata, ref layout.FGLayout, ref layout.FGLoop); } public override void ReadBG(byte[] rawdata, LayoutData layout) { ReadLayoutInternal(rawdata, ref layout.BGLayout, ref layout.BGLoop); } private void WriteLayoutInternal(ushort[,] layout, bool[,] loop, out byte[] rawdata) { rawdata = new byte[MaxSize.Width * MaxSize.Height]; int c = 0; for (int lr = 0; lr < MaxSize.Height; lr++) for (int lc = 0; lc < MaxSize.Width; lc++) rawdata[c++] = (byte)(layout[lc, lr] | (loop[lc, lr] ? 0x80 : 0)); } public override void WriteFG(LayoutData layout, out byte[] rawdata) { WriteLayoutInternal(layout.FGLayout, layout.FGLoop, out rawdata); } public override void WriteBG(LayoutData layout, out byte[] rawdata) { WriteLayoutInternal(layout.BGLayout, layout.BGLoop, out rawdata); } public override bool HasLoopFlag { get { return true; } } public override bool IsResizable { get { return false; } } public override System.Drawing.Size MaxSize { get { return new System.Drawing.Size(128, 8); } } } }
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.
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.
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)
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.