How to work with palette cycling in Sonic 1 (Hivebrain 2005 disasembly)

Discussion in 'Tutorials Archive' started by <Deleted User>, Nov 28, 2016.

  1. <Deleted User>

    <Deleted User> :D Trialist

    Joined:
    Feb 15, 2016
    Messages:
    0
    Hey! It's <Deleted User> making a tutorial! That's right, instead of releasing Sonic 1 LSD, I will teach you (yes, YOU!) how to work with palette cycling in Sonic 1.

    First off, find the label loc_196A. When you do, you should see this:

    Code:
    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)
    I know what you are thinking. "But <Deleted User>, this is for the title screen!" You know how the title screen uses the same files as Green Hill Zone? It also
    shares the same palette cycling.
    Anyways, do you see these lines?

    Code:
    move.l    (a0,d0.w),(a1)+
            move.l    4(a0,d0.w),(a1)
    Well, these lines have to do with the palette line, and number. For example, if you change the number 4 to 5 in move.l 4(a0,d0.w),(a1), you get purple. Why?
    You just canged the palette line! Let's add a + to that line. This will affect which part of the foreground/background is affected.
    (Simply by changing the line.)

    Want to know how to change the colour being used? Well, you're in luck! Here, we will make the colours go from 1-5.

    Code:
    addq.w    #1,($FFFFF632).w
            andi.w    #3,d0
            lsl.w    #3,d0
    These lines are for what colour it starts with and ends with. let's turn the second line's 3 to 15. It should look like this:

    Code:
     addq.w    #1,($FFFFF632).w
            andi.w    #5,d0
            lsl.w    #1,d0
    Also, the lsl.w tells what the last palette line is. I'm sticking with 1. :U (Also, you can do this with other levels.)
     
    Last edited: Nov 28, 2016
  2. Soldaten

    Soldaten The Coilgun Root Admin

    Joined:
    Mar 10, 2016
    Messages:
    268
    Code tags for the love of god...
    Use them.
     
    Unlimited Trees likes this.
  3. Devon

    Devon I'm a loser, baby, so why don't you kill me? Member

    Joined:
    Aug 26, 2013
    Messages:
    1,376
    Location:
    your mom
    This tutorial contains quite a bit of false information.

    Code:
    move.l (a0,d0.w),(a1)+
    move.l 4(a0,d0;w),(a1)
    XX(aN,dN.w) makes it so that data would be read/written at aN+dN+XX (When XX isn't present, it's equal to 0).

    That means that whatever is in the address register plus whatever is in the data register is added to that plus XX is the address that data will be read/written at.

    In the context of the palette cycle routine, a0 contains the address for the palette cycle data, a1 contains the address for the destination palette buffer, and d0 is the index number of the palette cycle data multiplied by 8 (I'll get to that later).

    Let's say a0 is $00000010, d0 is $0000, and a1 is $FFFFFB00, and this was the data starting at $00000010:

    $00000010: $0E
    $00000011: $EE
    $00000012: $0C
    $00000013: $CC
    $00000014: $0A
    $00000015: $AA
    $00000016: $08
    $00000017: $88

    The first line would get the address to read from ($00000010+$0000+0 = $00000010), and get a longword from there, which would be $0EEE0CCC. That will then be stored into $FFFFFB00, and since there's a "+" at the end of that "(a1)", it will advance to the next longword (since the size indicated is longword), which would be $FFFFFB04, since a longword is 4 bytes in length.

    The second line gets the address ($00000010+$0000+4 = $00000014), and gets a longword from there, which would be $0AA0888. Then that's stored into $FFFFFB04.

    When you changed that 4 to a 5, you made it so that the second line would read data at whatever is in a0 + whatever is in d0 + 5. You're just changing how the palette data is read.

    For clarification, this is the format for MD colors in binary:

    0000 BBB0 GGG0 RRR0

    Each RBG color can only be 0, 2, 4, 6, 8, $A, $C, or $E, and the highest nibble there that's all 0's is unused.

    Now in the palette cycle routine, for the first set of colors to read, for that second line it was intended to read "0E CA 0E EC". We have 2 colors here. ECA and EEC, with the first color having E for blue, C for green, and A for red, and the second color having E for blue, E for green, and C for red.

    When you changed that 4 to a 5, it instead read "CA 0E EC 0E". In "CA" and "EC", the "C" in "CA" and "E" in "EC" are ignored, because of the MD color format, so the colors read will be "A0E" and "C0E", which are purple like colors. That's why when you changed it to 5, it made things go purple. (Although it's actually supposed to crash, because reading at an odd address is supposed to cause an address error, but Kega doesn't do that for some reason).

    $FFF632 is the index number for which set of colors from the palette cycle to write to the palette. This gets written into d0, and then it will increment the index number in RAM to prepare for the next cycle. (d0 is left unaffected).

    Code:
    andi.w #3,d0
    The AND instruction masks out certain bits. It compares each bit, and if they are both 1, then it will stay 1, otherwise, it will remain 0.

    3 in binary is 00000011. Let's say d0 contains 9, which is 00001001 in binary.

    00001001
    00000011
    ------------
    00000001

    Here, the only bits that were both 1 was the one on the farthest right, so in the final value, that was the only bit that was 1.

    Because we were ANDing with 3, that means we can only have the following values be the final result: 00000000, 00000001, 00000010, 00000011

    Those values in decimal/hexadecimal are 0, 1, 2, 3.

    In the context of the palette cycle routine, this limits the index number from 0-3, so no matter what's in $FFF632, that AND instruction will limit it to be only 0-3 (The palette cycle data has 4 sets of colors).

    Also, when d0 is 4 (00001000), ANDing it with 3 will result in 0, and when it's 5 (00001001), ANDing it with 3 will result in 1. See a pattern here?

    In the title screen's palette cycle, it uses 4 colors, which is 8 bytes (each color is a word in size), so, to get the proper base address for the set of colors for the current index, d0 needs to be multiplied by 8, which is done via

    Code:
    lsl.w    #3,d0
    "lsl" shifts the bits in whatever is in the destination by how many times that is desired (though, you can only really shift a max of 8 times in 68000 Assembly)

    So, if d0 were to contain 2 (00000010 in binary), and we wanted to shift that left 3 times, it would go like so:

    00000010 -> 00000100 -> 00001000 -> 00010000

    00010000 in hexadecimal is $10, which is the final result of the shifting.

    Each shift left is basically multiplying by 2 (which means shifting right divides by 2), so when you shift 3 times, it's like 2*2*2, which is 8. So, when we shifted 2 3 times to the left, it's like 2*8, which is $10.

    So, in the routine, it shifts whatever is in d0 3 times, which multiplies it by 8, which is what we want.

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    So, in the end, changing the 4 to 5 doesn't change the palette line, it changes where data is being read for that instance, that "and" keeps the index number for the palette cycle data within 0-3, and that "lsl" is used to make the index number be able to be used for calculating the address of the color data that is to be read for the current cycle.
     
    Last edited: Nov 29, 2016
  4. <Deleted User>

    <Deleted User> :D Trialist

    Joined:
    Feb 15, 2016
    Messages:
    0
    Please remove this. Too much backlash to handle.
     
  5. TheStoneBanana

    TheStoneBanana banana Member

    Joined:
    Nov 27, 2013
    Messages:
    602
    Location:
    The Milky Way Galaxy
    Two replies, one of which was giving you a suggestion to improve the post, and the other of which was correcting false information.
    So... what backlash are we talking about here?

    If you're referring about what was said on Discord, may I remind you that when people told you that this tutorial was pretty bad, you simply replied with "I don't care" and "I don't know what I'm doing".
     
    HackGame likes this.
  6. <Deleted User>

    <Deleted User> :D Trialist

    Joined:
    Feb 15, 2016
    Messages:
    0
    I'm sorry. I just got too frustrated.
     
  7. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Butt hurt 10 year olds make me laugh, and if you dont know what you are doing why even make a guide? I don't think this thread should be trashed especially with how detailed Ralakimus's post was, correcting your many mistakes. Also "That's right, instead of releasing Sonic 1 LSD" we kind of already have a hack by that name and its name is more thought out.
     
    Soldaten likes this.
  8. <Deleted User>

    <Deleted User> :D Trialist

    Joined:
    Feb 15, 2016
    Messages:
    0
    Or, I'm just a fucking idiot.
    Anyways, many apologies to all.
     
  9. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    A rough guide which needs a lot of work, but at least you tried.

    One thing I do admire (in-corrections aside here) is the humorous advertisement style you had going, it sounded like a 1950's American radio ad~
     
  10. <Deleted User>

    <Deleted User> :D Trialist

    Joined:
    Feb 15, 2016
    Messages:
    0
    Also, huge thanks to Ralakimus for the corrections! I'll re-do the guide with the corrections. (Not to forget MarkeyJester's constructive feedback. This helps me a lot.)
     
    Devon likes this.