Jump to content

Recommended Posts

Here's some bB examples of stuff that's not easy to figure out, so might save somebody some time.

 

 

 

Change color behind score without minikernel

CHANGE_COLOR_BEHIND_SCORE.bas

 

Change scorecolor

SCORE_COLORCYCLE.bas

 

Change playfieldcolor on any row/rows you want

CHANGE_PLAYFIELD_COLOR.bas

 

Change backgroundcolor on any row/rows you want

CHANGE_BACKGROUND_COLOR.bas

 

 

 

I'll try and come up with some more.

  • Like 6
Link to comment
https://forums.atariage.com/topic/291753-some-dpc-color-examples/
Share on other sites

This is awesome and might be just what I needed to get over my developmental hump!

 

Currently I had an issue where I would change parts of the playfield colors but had a difficult time changing them back when done with them. Probably an easy fix that I'm just not seeing but this might be an easier way then what I had been working with!

Edited by KevKelley

I was looking at the example code. I kind of understand it but trying to adapt it into my program is boggling me.

 

I see how moving the cursor and pressing fire changes the color but what is confusing me is how to basically have a line
(or couple lines change together) and how exactly everything works, like the purpose of the constants or what these do DF0LOW, DF0HI, DF0PUSH?

I might be wrong but this is how I understand it..

 

I recently had to ask about the constants myself and why you couldn't just do this

DF0LOW = #<(PFCOLS)
DF0HI = #(>PFCOLS) & $0F
RevEng had this to say:
"the "#" "<" and ">" value modifiers don't really belong to the language proper, they come from assembly language. So the parsing that happens during regular variable assignments doesn't work with them, but the const command doesn't do any parsing and passes them to the underlying assembly code intact"
So it's just a workaround to get the correct values when using bB, if you use inline assembly you don't need the constants
asm
lda #<(PFCOLS)
sta DF0LOW
lda #(>PFCOLS) & $0F
sta DF0HI
end

If you open bB.1.1d.reveng41 / includes / DPCplusbB you'll see that just like A is a nickname for a RIOT RAM address, PFCOLS is a nickname for a DPC RAM address, and the next 256 bytes after that is reserved for playfield color data,

 

the kernel points a Fractional Data Fetcher to that data..

lda <PFCOLS
sta DF4FRACLOW
lda (>PFCOLS) & $0F
sta DF4FRACHI
then reads that data every other line and stores it to the colupf register
lda #<DF4FRACDATA
sta COLUPF
how often the colors are updated depends on how you set up DF4FRACINC before drawscreen
DF4FRACINC = 255 will increment the fetcher after every read and update the color every other line
DF4FRACINC = 128 will icrement the fetcher every other read and update the color every fourth line etc.
These fetchers are part of why there's time to do so much in the DPC+ kernel, because they increment automaticly after each read, depending on how you primed them.
Anyway, this code just points to the color data and pushes new values into it, here's an assembly example if that makes more sense,
if you wanted three rows to be white, and those three rows to be another three rows from the top of the screen
asm
lda #<(PFCOLS+6) ; point to the sixth byte in the color data
sta DF0LOW
lda #(>PFCOLS) & $0F
sta DF0HI
lda $0E ; white
sta DF0PUSH ; changes the sixth byte/row
sta DF0PUSH ; changes the fifth byte/row
sta DF0PUSH ; changes the fourth byte/row
end

Okay. I think I understand. I had originally thought I was going crazy when I combed through Random Terrain's website and admittedly, when I look through many of the sample programs online I have a hard time figuring them out while they can be very well documented and rather straightforward... But I find them extremely valuable in my learning. I find this helpful since my end goal is to learn batariBasic and eventually assembly.

 

I think I got your explanation down and plan on playing around with it to see if I can get it work for my game.

 

So a recap:

 

asm

lda #<(PFCOLS+6) ; point to the sixth byte in the color data

sta DF0LOW

lda #(>PFCOLS) & $0F

sta DF0HI

 

lda $0E ; white

sta DF0PUSH ; changes the sixth byte/row

sta DF0PUSH ; changes the fifth byte/row

sta DF0PUSH ; changes the fourth byte/row

end

 

The first PFCOLS label sets the starting row (pointing to the bytes where the colors) and the second PFCOLS line sets the ending row, effectively creating a range for the later lines to change to a particular color. I would assume if I wanted different colors then a different lda would precede each DF0PUSH.

 

Currently, in my game when I have one area change playfield I redraw the entire playfield, or at most up until I don't need to change anything else so this method would probably use less space as well.

Since memory addresses are 16-bit such as $1234 you have to split it up into two bytes

< takes LSB (least significant byte) aka low byte, the $34 part of the address

> takes MSB (most significant byte) aka high byte, the $12 part of the address

 

$12 would be the page and $34 the location on that page, a page has 256 different locations.

 

I'm shure PFCOLS is the beginning of a page so there's 256 bytes until the next page begins,

that way the high byte that holds the page never has to change.

 

I'm not shure what address PFCOLS is, but let's say it's $0700

 

$0700 ; holds the first color

$0701 ; second color

$0702 ; etc..

$0703

 

then when compiling our previous example

 

lda #<(PFCOLS+6) ; point to the sixth byte in the color data
sta DF0LOW
lda #(>PFCOLS) & $0F
sta DF0HI

 

 

the compiler first replaces the labels with the values:

lda #<$0706 ; point to the sixth byte in the color data
sta DF0LOW
lda #>$0700
sta DF0HI

 

It then extracts the MSB and LSB:

lda #$06 ; point to the sixth byte in the color data
sta DF0LOW
lda #$07
sta DF0HI

 

then you will push to $0706, I did not explain the & $0F since I don't know what it does myself?

Edited by Lillapojkenpåön
  • 1 month later...

   ;; Manipulate virutal sprites

   ;; Alter sprite data using data tables stored OUTSIDE the "4k limit" thing

   ;; Data fetcher 2 is used, but you could use another.

 

   ;;  _Player_Data_Num = ( (** 1-9 integer number representing the virtual sprite you want**) - 1) *2)

   ;; _Player_Color_Num = ((( (** 1-9 integer number representing the virtual sprite you want**) - 1) *2)  + 18)

 

   lda #<(playerpointers+_Player_Data_Num)
   sta DF2LOW 
   lda #(>(playerpointers+_Player_Data_Num)) & $0F
   sta DF2HI

 

   ldx #<(_Sprite_Data_Table)
   stx DF2WRITE
   lda #((>_Sprite_Data_Table) & $0F) | (((>_Sprite_Data_Table) /2) & $70)
   sta DF2WRITE

 

   ldx #<(playerpointers+_Player_Color_Num)
   stx DF2LOW
   lda #(>(playerpointers+_Player_Color_Num)) & $0F
   sta DF2HI

 

   ldx #<(_Sprite_Color_Table)
   stx DF2WRITE
   lda #((>_Sprite_Color_Table) & $0F) | (((>_Sprite_Color_Table) /2) & $70)
   sta DF2WRITE

 

   lda #8 ;(CHANGE ME! **integer representing the height of the virtual sprite**)
   sta player1height  ;CHANGE ME to player1height, player2height, etc. etc. (all the way up to 9)

 

  ;;  Manipulate player0

 

   lda #<(_Sprite_Data_Table)
   sta player0pointerlo
   lda #((>_Sprite_Data_Table) & $0F) | (((>_Sprite_Data_Table) /2) & $70)
   sta player0pointerhi

 

   lda #<(_Sprite_Color_Table)
   sta player0color
   lda #((>_Sprite_Color_Table) & $0F) | (((>_Sprite_Color_Table) /2) & $70)
   sta player0color+1

 

   lda #8 ;CHANGE ME! **integer representing the height of the player0 sprite
   sta player0height

3 hours ago, Lillapojkenpåön said:

I have made an example that can do that, allmost exactly the same

If someone can color an entire sprite the color of a variable without tables that could be usefull tho, that's what I wanted to do originally that led to these examples.

 

I don't know how that could be done without rewriting the bB ARM code and the bB DPC+ kernel.

 

I guess we could point the player color pointers to a set of sequential variables, but that gets expensive really fast. 

 

As far as I can tell, we can't read sprite data from the DPC+ Stack area.  That would have been a convenient way to do it, in theory. 

Yeah I tried the sequential variables both in regular ram and dpc ram but when i pushed fire which was suppose to change the color of the sprite, i just got different color on each line that moved upwards, but I'm a noob so if you can get that to work I would appreciate it

6 hours ago, Lillapojkenpåön said:

Yeah I tried the sequential variables both in regular ram and dpc ram but when i pushed fire which was suppose to change the color of the sprite, i just got different color on each line that moved upwards, but I'm a noob so if you can get that to work I would appreciate it

Looks like that would require some heavy lifting as well.

 

The easiest hack would be to prevent the pointer from incrementing when reading the sprite color table, but I don't have a use case for that right now.

 

Could also use a sprite to mask the ball (block out portions to create a shape) and update the playfield colors.

  • 5 months later...

I finally have the attention span to adapt your programs for the bB page. The first one I'm working on is CHANGE_BACKGROUND_COLOR.bas. I see that we can push a color into a row from a variable, but can we do the reverse? Can we read the color of a row and temporarily store it in a variable?

11 hours ago, Random Terrain said:

I see that we can push a color into a row from a variable, but can we do the reverse? Can we read the color of a row and temporarily store it in a variable?

 

In case you missed that I posted twice, here's that question again.

1 hour ago, Lillapojkenpåön said:

Yes you can, this example reads when pushing left and writes when pushing right

READ_PLAYFIELD_COLOR.bas 5.09 kB · 1 download

 

 

I will need that for another program, but it looks like that reads and writes the playfield color. What do I use to read the background row color?

Can someone explain why you can't change the player colors btw?

Do they not get copied to the dpc+ ram?

You seem to be able to read and write anywhere in the ram, I just don't know where the colors end up?

 

And why is this needed when pointing to the color? what does it do?

| (((>color) / 2) & $70)

12 hours ago, Lillapojkenpåön said:

Can someone explain why you can't change the player colors btw?

Do they not get copied to the dpc+ ram?

You seem to be able to read and write anywhere in the ram, I just don't know where the colors end up?

 

And why is this needed when pointing to the color? what does it do?

| (((>color) / 2) & $70)

 

You might have to post that question it its own thread so it gets seen by those who can help.

 

If it helps, RevEng said this in a post:

 

"bB DPC+ players (and colors) are pointers to ROM, which can't be modified. (in theory, you can point them to RAM, and modify the RAM, but I can't get this to work.)"

 

 

Edited by Random Terrain
  • Thanks 1

If you figure out how to get DPC+ sprites into RAM so we can change any row color and replace any part of the shape, we'll be able to make it look like we have way more sprites than what was possible the regular way.  

Hmm, how are the pointers limited to only point to ROM?

I guess that's the problem since the player allways has random colors or is completely yellow no matter where I point,

I think any adress you put in turns into a rom adress somewhere in the kernel, otherwise it would have been all black at some point with all the adresses I've tried, I think.

 

This defenitely pushes random numbers to the stack $0c when pushing fire

but I can't get it to read from there, anyone is welcome to try

 

 

ram_color2.bas

 

EDIT:

 I looked in the kernel and color fetchers gets set to

 <P1COLOR

 (>P1COLOR) & $0F

 

 and graphics to

 <P1GFX

 (>P1GFX) & $0F

 

 Those adresses are defined in the DPCplusbB header, Isn't it RAM?

 C_function = FETCHER_BEGIN
 CcodeData = C_function + 4
 playerpointers = CcodeData + RAMcopylength
 P1GFX = playerpointers + 38
 P1COLOR = P1GFX + 256

 

 

Edited by Lillapojkenpåön

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