Jump to content
IGNORED

How to make a multi-color sprite


Just Jeff

Recommended Posts

Hi!

 

My kernal is far enough along to begin working on my muti-color players. I'm pretty sure I'm just going to have it change once- the head will be one color, the rest will be one other color. So I can make the head change outside the kernal and just need to change the body once inside. Does anyone know a cheap way to do this? The players move up and down so I just can't pick a scan line. All I can come up with is something like:

 

lda #HUMAN_HEIGHT-2 ; 2 2 - height of the human graphics, (minus one for where the color change would be)
cmp Player0Draw ; 5 7 - Player0Draw (previously decremented) and compare with height
bcs CDoColorGrp0 ; 2 9 - (3 10) if Carry is Set then player0 color change is on current scanline
lda HeadColor ; 2 11 - from RAM
.byte $2C ; 4 15 - $2C = BIT with absolute addressing, trick that
; causes the lda HeadColor to be skipped
CDoColorGrp0: ; 10 - from bcs DoDrawGRP0
lda BODY_COLOR ; 5 15 - load the head color for player0 from RAM
sta COLUP0 ; 3 18

 

So.. I'll have to do this for each player so its going to double in time

 

I'd like to just tack it on to my current DoDraw for the graphic but I don't think that will work.

Link to comment
Share on other sites

That is burning unnecessary cycle time by having to decide which color to use mid-scanline. Without careful timing, the color data and/or sprite data will be updated too late...leading to shearing or miscolored lines. It's probably better to use a color table and update it every line as part of your sprite drawing routine.

  • Like 1
Link to comment
Share on other sites

Just add 2 more lines of code to DoDraw:

DoDraw0:
        lda #HUMAN_HEIGHT-1 ; 2  2 - height of the humanoid graphics, subtract 1 due to starting with 0
        dcp HumanDraw       ; 5  7 - Decrement HumanDraw and compare with height
        bcs DoDrawGrp0      ; 2  9 - (3 10) if Carry is Set, then humanoid is on current scanline
        lda #0              ; 2 11 - otherwise use 0 to turn off player0
        .byte $2C           ; 4 15 - $2C = BIT with absolute addressing, trick that
                            ;        causes the lda (HumanPtr),y to be skipped
DoDrawGrp0:                 ;   10 - from bcs DoDrawGrp0
        lda (HumanPtr),y    ; 5 15 - load the shape for player0
        sta GRP0            ; 3 18 - update player0 to draw Human
        lda (HumanColorPtr),y
        sta COLUP0



Your data would be like this:
HumanGfx:
  .byte %00011100
  .byte %00011000
  .byte %00011000
  .byte %00011000
  .byte %01011010
  .byte %01011010
  .byte %00111100
  .byte %00000000
  .byte %00011000
  .byte %00011000

HumanColor:
  .byte FOOT_COLOR
  .byte LEG_COLOR
  .byte LEG_COLOR
  .byte LEG_COLOR
  .byte BODY_COLOR
  .byte BODY_COLOR
  .byte BODY_COLOR
  .byte HEAD_COLOR
  .byte HEAD_COLOR
  .byte HAIR_COLOR



And you'd initialize HumanColorPtr exactly the same way you do HumanPtr.

For the colors do something like this at the start of your program:
HAIR_COLOR = $24
HEAD_COLOR = $4C
BODY_COLOR = $82
LEG_COLOR  = $E4
FOOT_COLOR = $22



By doing that you can easily make a PAL60 version later.
Link to comment
Share on other sites

Ah!.. I get it. So similar to the existing DoDraw, the color pointer is going to cycle through a bunch of irrelevant indirect addressing, but it won't matter because colors won't appear during the times we are storing zero to GRP0. (yes I know the .byte2C actually makes it skip), but in this case it really is plugging in a bunch of random colors, except when it really matters. Another thing I didn't think of was coming up with an entirely new pointer. I was trying to think of a way to use the existing Human pointer.

 

So this does leave me lacking one thing though. I wanted the head color to change, using RAM. Any way to still do that? Or would it be too complicated?

 

Thanks again!

Edited by BNE Jeff
Link to comment
Share on other sites

You have two options for that, use RAM to store all the colors (10 bytes in my example) and change the head color on the fly, or have multiple "HumanColors" and pick the appropriate one when you're setting up HumanColorPtr. That's just like the animation logic which chooses one of multiple images to display.

Link to comment
Share on other sites

Hmm.. I think I'll use all RAM. I can spare it as of now. Using two HumanColors would put me back up 16 cycles or so- right?

 

If RAM becomes a problem later, I think I'll switch to the table in ROM. However, the ROM table answers a similar question I would have had for my playfield graphics you may remember me asking about. This will allow me to make them muti-colored which I really wanted to do.

 

Thank again! I learned something new, again..

Link to comment
Share on other sites

"All ram" as in a byte for each line? This is not necessary, and wasteful of resources. It's far easier to change a single pointer to a different color table (i.e. pattern) whenever you need to. The point I was making is that your kernel should not be deciding to do something twice ("Are we drawing the character?" followed by "Is it time to change colors?") Using color tables, the second question is eliminated.

  • Like 1
Link to comment
Share on other sites

"All ram" as in a byte for each line? This is not necessary, and wasteful of resources. It's far easier to change a single pointer to a different color table (i.e. pattern) whenever you need to. The point I was making is that your kernel should not be deciding to do something twice ("Are we drawing the character?" followed by "Is it time to change colors?") Using color tables, the second question is eliminated.

 

Thanks! Yeah- I meant a byte for each line. I have no programming experience so I tend to do wasteful things at first just so I can make it happen. Everything is baby steps with me... Remembering that myself, I dropped the RAM idea and put in the color table as first suggested by Darrell for now. After some tweaking, my robots are now ready for their first day at school in their blue polo shirts and olive chinos.

 

post-44582-0-39637900-1468585943_thumb.jpg Xycron and Glorax - 2016 6th Grade

 

I think I know what you are saying about changing color tables. I have (HumanColorPtr),y in the kernal- I would change the value of y by 13 (The height of my robot) outside the kernal- right? Actually, I can't mess with y so that would be replaced by a RAM location that is y or y+13 etc. Is that Correct?

 

I had to convince myself that when "initializing" the color pointer that I did not need to include something like this:

 

; Player1Draw = ARENA_HEIGHT + BOX_HEIGHT - Y_position

lda #(ARENA_HEIGHT + BOX_HEIGHT)

sec

sbc ObjectY+1

sta Player1Draw

 

And I was right. This is for deciding whether or not to take the branch in the kernal. My color changes occur on every scan line whether or not I'm drawing though I did notice this creates an effect where the missiles change color when I move the robot up or down.

 

Thanks again for all the help!

Link to comment
Share on other sites

 

I have (HumanColorPtr),y in the kernal- I would change the value of y by 13 (The height of my robot) outside the kernal- right? Actually, I can't mess with y so that would be replaced by a RAM location that is y or y+13 etc. Is that Correct?

 

Actually, you'd alter the HumanColorPtr address before kernel execution. It's too time-consuming to update the Y register just to fetch color data.

 

BTW the missile sprites get their color from the corresponding player sprites (and the ball sprite gets it's color from the playfield)

Link to comment
Share on other sites

 

Actually, you'd alter the HumanColorPtr address before kernel execution. It's too time-consuming to update the Y register just to fetch color data.

 

BTW the missile sprites get their color from the corresponding player sprites (and the ball sprite gets it's color from the playfield)

 

OK got it. Thanks.

 

So far, this is working great! 41 cycles for line 1 and 62 cycles for line 2. That leaves me 49 cycles to do more stuff...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...