Jump to content
IGNORED

Palette-swapping Player Colors?


jrok

Recommended Posts

I have a player sprite in my game that's has lots of animations. It's a huge ROM hog, so I want to reuse these shapes to draw enemies, changing the colors to distinguish them.

 

I went ahead and reserved 12 variables that I would use to apply color to each flickered, 16 pixel tall sprite:

 

 dim boot_col = a
dim leg1_col = b
dim leg2_col = c
dim leg3_col= d
dim leg4_col= e
dim shirt1_col = f
dim shirt2_col  = g
dim shirt3_col = h
dim shirt4_col  = i
dim head1_col  = j
dim head2_col = k
dim head3_col= l

 

The idea would be that I'd then define the player1 colors as vars, such as:

 

 player1color:
boot_col
boot_col
leg1_col
leg2_col
leg3_col
leg3_col
leg4_col
shirt1_col
shirt2_col
shirt3_col
shirt4_col
head1_col
head1_col
head3_col
head3_col
head3_col
end

 

However, when I attempt to redefine colors this way, I get a sprite with different shades of green, rather then the colors I set the variables too. The result is the same whether I try hex or decimal color values. I've attached a simplified example of this.

 

Is what I'm trying to do even possible? If so, what am I doing wrong. Any help would be much appreciated.

 

Thanks,

Jarod.

 

EDT: Just realized the BAS I attached didn't make any sense (the routines were pointing to two different sprites - duh). Attached correct BAS.

player1color_vars.bas

Edited by jrok
Link to comment
Share on other sites

Unless there is some hidden feature in bB, the only way I know to change color is by using numbers, not variables:

 

  player1color:
 $f5
 $f5
 $f5
 $43
 $f5
end

 

I think the best you can do without having a special file created for you is to have a different set of colors for each character.

Link to comment
Share on other sites

Unless there is some hidden feature in bB, the only way I know to change color is by using numbers, not variables:

 

  player1color:
 $f5
 $f5
 $f5
 $43
 $f5
end

 

I think the best you can do without having a special file created for you is to have a different set of colors for each character.

 

For some reason, I though I saw an example once where the playfield colors used variables in its definition. I could be mistaken.

 

Another way I was going to approach this was to define the player1colors twice, then do an if-then statement in the middle of the sprite definition to determine which palette to use (example attached). Is that what you mean? I could still do this, but I thought it would be much less of a bank-gobbler to define the colors as variables before the bankswitch, then just define player1colors once in the sprite bank.

player1color_if_then.bas

Link to comment
Share on other sites

Unless there is some hidden feature in bB, the only way I know to change color is by using numbers, not variables:

 

  player1color:
 $f5
 $f5
 $f5
 $43
 $f5
end

 

I think the best you can do without having a special file created for you is to have a different set of colors for each character.

You don't need to redefine the player shape again if it's always the same, you can just redefine the colors. I'll have to look at the .bas file to see what you're doing.

 

Michael

Link to comment
Share on other sites

Unless there is some hidden feature in bB, the only way I know to change color is by using numbers, not variables:

 

  player1color:
 $f5
 $f5
 $f5
 $43
 $f5
end

 

I think the best you can do without having a special file created for you is to have a different set of colors for each character.

You don't need to redefine the player shape again if it's always the same, you can just redefine the colors. I'll have to look at the .bas file to see what you're doing.

 

Michael

 

 

Thank you, Michael. I have them pointing to the same shape in both examples. Its just that in the first file, I tried to substitute the tia colors with variables in the "player1color:" definition. I had also tried defining all the colors I wanted to use in a data set, then using the array position in the definition, but that wouldn't even compile.

 

The weird thing is, the variable version is "almost" doing what I want it to do. The variance in the shades of green seem to correspond to the different colors I'm defining (except they are green.) Could this be a cycle count issue maybe?

 

Thanks again for your help.

Jarod.

Link to comment
Share on other sites

Another way I was going to approach this was to define the player1colors twice, then do an if-then statement in the middle of the sprite definition to determine which palette to use (example attached). Is that what you mean? I could still do this, but I thought it would be much less of a bank-gobbler to define the colors as variables before the bankswitch, then just define player1colors once in the sprite bank.

Yeah, that's what I'm talking about. You just jump to the color set you need at the time. Probably better to waste a little ROM space instead of precious variables.

Link to comment
Share on other sites

Actually, I remember now where I thought I saw pfcolors used as variables:

 

http://www.atariage.com/forums/index.php?s...t=#entry1486518

 

Batari had customized a version of 2600basic.h to allow Random Terrain to access colors in the pf color table independently. This seems a bit what like I need, except for a player's color table.

 

I'm going to try to tinker with it, but I sure would appreciate a clue if someone has one.

 

Cheers,

Jarod.

Link to comment
Share on other sites

(1) It *is* possible to put the player1color table in RAM, so that each row of color is a variable and can be set/changed at will. However,

 

(2) doing it that way uses up several RAM variables that could be used for other things. Also,

 

(3) if you need to set each of the color variables to define it, then that means your code has to have the colors defined in ROM anyway, either in a ROM table or embedded within the assignment statements-- so if you're going to have to define the colors in ROM anyway, then why not just use ROM color tables?

 

(4) On the other hand, if you're going to have one or more rows of color that could either have random values, or so many different possible values that it would take too many player1color ROM tables to define them all, then relocating the color table into RAM can be useful-- as long as you can spare enough RAM variables for it.

 

What I do to figure out how to move something like player1colors from ROM to RAM is make a simple test program that has the statement I'm interested in, then I compile it and look at the code to see what batari Basic did with it, as follows:

 

   set kernel_options player1colors

  player1color:
  $18
  $28
  $38
  $48
  $58
  $68
  $78
  $88
end

Note that the above code doesn't even make up an executable program, since it doesn't have a loop in it, let alone a drawscreen statement. Nevertheless, you can still compile it to see what kind of assembly code it generates. When I compile that code, and then look through the .bas.asm file to see how the statements were compiled, I see the following:

 

.L00;  set kernel_options player1colors

.
; 

.L01;  player1color:

LDA #<playercolorL01_1

STA player1color
LDA #>playercolorL01_1

STA player1color+1
if (<*) > (<(*+8))
repeat ($100-<*)
.byte 0
repend
endif
playercolorL01_1

.byte	$18
.byte	$28
.byte	$38
.byte	$48
.byte	$58
.byte	$68
.byte	$78
.byte	$88

This tells me what I must do to put the player1color table in RAM-- namely, I must set the player1color and player1color+1 pointers to the address (lo byte and hi byte) where I want the color table to begin in RAM. I also need enough consecutive RAM variables set aside for the colors-- one variable for each row of the player.

 

Now that I know that, I can do something like the following:

 

   set kernel_options player1colors

  dim p1color = a
  dim p1color_row1 = a
  dim p1color_row2 = b
  dim p1color_row3 = c
  dim p1color_row4 = d
  dim p1color_row5 = e
  dim p1color_row6 = f
  dim p1color_row7 = g

  rem * now set the player1color pointers
  rem * to the address of variable a (or p1color)

  asm
  LDA #<p1color
  STA player1color

  LDA #>p1color
  STA player1color+1
end

  rem * define the player1 shape

  player1:
  %00111100
  %01111110
  %11111111
  %11111111
  %11111111
  %01111110
  %00111100
end

  rem * set the initial color for each row

  p1color_row1 = $00
  p1color_row2 = $02
  p1color_row3 = $04
  p1color_row4 = $06
  p1color_row5 = $08
  p1color_row6 = $0A
  p1color_row7 = $0C

  rem * position the player

  player1x = 76
  player1y = 48

  rem * now do the display loop

loop

  drawscreen

  rem * cycle the colors

  p1color_row1 = p1color_row1 + 1
  p1color_row2 = p1color_row2 + 1
  p1color_row3 = p1color_row3 + 1
  p1color_row4 = p1color_row4 + 1
  p1color_row5 = p1color_row5 + 1
  p1color_row6 = p1color_row6 + 1
  p1color_row7 = p1color_row7 + 1

  rem * adding 1 instead of 2 makes them cycle a little slower

  goto loop

This same effect would be very tedious to do with player1color tables in ROM, because it would require 128 player1color statements-- plus, each one would take a minimum of 15 bytes (8 bytes of overhead to set the player1color pointers, plus 7 bytes for the 7 rows of color, and possibly several "filler" bytes to make sure the table doesn't cross a page boundary-- which would be a minimum of 1920 bytes of ROM (128 times 15). :-o

 

On the other hand, based on your description of what you're trying to do, it sounds like player1color statements would be more appropriate.

 

Michael

Link to comment
Share on other sites

First of all, thanks for your help with this. You are a generous man.

 

(1) It *is* possible to put the player1color table in RAM, so that each row of color is a variable and can be set/changed at will. However,

 

(2) doing it that way uses up several RAM variables that could be used for other things. Also,

 

(3) if you need to set each of the color variables to define it, then that means your code has to have the colors defined in ROM anyway, either in a ROM table or embedded within the assignment statements-- so if you're going to have to define the colors in ROM anyway, then why not just use ROM color tables?

 

This all makes sense to me, and so does your example. I guess I should've clarified my methods and my goal a bit.

 

I'm using bankswitching and supercharger RAM in my game. So the RAM isn't as much of a concern right now to me as the ROM is - particluarly the ROM available in bank 8 which, if I understand correctly, stores the all sprite shapes and color tables. There is one multicolor critter in my game that is currently using up 3064 bytes of bank8 :!:

 

Leaving aside that ridiculous statement for a moment, let's say that this critter and all his myriad animations are important to the game design, and that he'll be mainly battling creatures who look and act exactly like him, except they have different color outfits. Sort of like an Atari version of Wall Street. It would seem to me to be an uphill battle to define "playercolor1:" and if-then to define every single outfit for every frame of animation, and I could probably only get in a few different colors of clothing before bank8 ran out of bytes.

 

So what I assume what I would need would be to go ahead and reserve some additional variables, like:

 

   set kernel_options player1colors

  dim p1color = a
  dim p1color_row1 = a
  dim p1color_row2 = b
  dim p1color_row3 = c
  dim p1color_row4 = d
  dim p1color_row5 = e
  dim p1color_row6 = f
  dim p1color_row7 = g

  dim shoe_color = h
  dim pants_color = i
  dim jacket_color = j
  dim face_color = k
  dim hair_color = l

 

Then, if I had an animation of an investment banker counting his money, or running from the cops, or getting frogmarched into a courtroom, I could change the values of the player rows to equal the color of the applicable garment every time the shape is drawn. The idea would be that this would preserve space to draw more kinds of shapes, like bags of cash, foreclosure signs and prison cells, since I wouldn't be writing a new color table for every combination of outfit and sprite frame.

 

This may still not make any sense. I'll try to work up a small sample and post it.

 

Thanks again,

Jarod.

Link to comment
Share on other sites

My advice is to go with multiple color definitions and jump to the appropriate one as needed (that's how I do it). However, it is possible to manipulate them though you would probably need to use the Superchip to do so.

 

Attached is an experiment I did last year. I had considered doing a superhero rpg and to avoid copyright hassles I had planned to use a generic male & female sprite the player could paint to be whoever they wanted. This is the paint program. Basically you have the stretched version of the sprite at the top (to help determine what line you are on) and how the actual sprite would look on the bottom. The black line is the pointer. Up / down moves it. Right / left will change the color of the line. Note it jumps from 0 to 16 to 32 etc. To get the sub-colors, hit fire. The CL at the bottom will clear it. As you move down to a line that hasn't been painted yet it will copy the last used color. Anyway, in the end I opted not to go that route as I wanted to avoid the Superchip at all costs. This is test code, not as tight as it could be.

 

The screenshot is my stab at Marvel Girl.

post-6510-1225816535_thumb.png

paint2.bin

paint2.bas

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...