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.
Trying to compile the SonLVL in Visual Stuido 2019. It talks about some files being restricted? Any help would be appreciated.
Had to google this one, I've never seen that before. Did you download the repo as a zip instead of doing a git clone? Apparently you need to unblock the zip before extracting, right click -> properties. You may also be able to do this to the individual files. Source with more info. Also, is there a reason you're using VS2019 when 2022 is available? I've never tried to compile SonLVL.
Reeeal quick question, specifically with pallette changing in zones similar to Green Hill Zone, and welp, Green Hill Zone, when changing pallettes of zones in the edit header, stuff like the water sparkle effect get completely ignored. I know it has something to do with the background's animations as a similar thing happened for me on zones like Angel Island Zone, but not with zones like Marble Zone, is there a way to fix this? If so tell me, it bugs me alot.
This is not really SonLVL's fault. The issue is in-game, the palette is overwritten by new colours from a cycle palette list. You can find the instructions for this at "PalCycle_GHZ". Code (Text): PalCycle_GHZ: ; XREF: PalCycle lea (Pal_GHZCyc).l,a0 loc_196A: ; XREF: PalCycle_Title subq.w #1,($FFFFF634).w bpl.s locret_1990 move.w #5,($FFFFF634).w move.w ($FFFFF632).w,d0 addq.w #1,($FFFFF632).w andi.w #3,d0 lsl.w #3,d0 lea ($FFFFFB50).w,a1 move.l (a0,d0.w),(a1)+ move.l 4(a0,d0.w),(a1) locret_1990: rts So you'll need to modify the cycle palette data. There is a bypass for this however: Code (Text): PalCycle_GHZ: loc_196A: subq.w #1,($FFFFF634).w bpl.s locret_1990 move.w #5,($FFFFF634).w lea ($FFFFFB50+6).w,a1 move.w (a1),d0 move.w -(a1),2(a1) move.w -(a1),2(a1) move.w -(a1),2(a1) move.w d0,(a1) locret_1990: rts This will take the colours out of the palette (the ones you edited with SonLVL) and manually cycle them around for you, so you no longer need to worry about the cycle palette data. Hope this helps,
I have no idea if i've done this correctly as i'm completely lost when it comes to things such as coding.