Jump to content
IGNORED

Sharing the data of sprites.


Gorf

Recommended Posts

How can one share the data bits that makes up a sprite?

 

normally we do it hard like so....

 

player0:
%11111111
%11111111
%11111111
%11111111
end

 

 

Can I put this int a data array

and point the player at it?

 

 

 

data frame
%11111111, %11111111, %11111111, %11111111, 
end

 

 

There are times i want to use a good deal of frames of animation

and will want more than one player to use them. Is ther a pointer to

the players data I can set like....

 

player0data = frame ...?

 

How can this be accompilished without repeating the data?

 

 

Thanks

Edited by Gorf
  • Like 1
Link to comment
Share on other sites

How can one share the data bits that makes up a sprite?

Yes, you can put all of the sprites data into one or more tables, and then manually set the "system variables" that bB uses for a particular sprite. I have used this technique before, and am reasonably familiar with the things you'll need to be aware of, so I'll post an example and some notes later tonight.

 

Michael

Link to comment
Share on other sites

How can one share the data bits that makes up a sprite?

Yes, you can put all of the sprites data into one or more tables, and then manually set the "system variables" that bB uses for a particular sprite. I have used this technique before, and am reasonably familiar with the things you'll need to be aware of, so I'll post an example and some notes later tonight.

 

Michael

 

 

 

Mike, you're the greatest for helping like you do. It is much appreciated.

 

Steve

Link to comment
Share on other sites

Here's an example of what I do when I'm trying to figure out how certain things "work" in bB. I write a short, simple bB program, compile it, and look at the .asm file that's created. You'll see all of the code from the .asm includes, which can be overwhelming-- but if you want to see the code that came from your bB statements, it starts at the label called "game" (which will be near the end of the .asm listing, if your program was short).

 

For example, here's a short program that displays player0:

 

   player0:
  %10101010
  %01010101
  %10101010
  %01010101
  %10101010
  %01010101
  %10101010
  %01010101
end
  player0x = 80
  player0y = 48
loop
  COLUP0 = $1A
  drawscreen
  goto loop

After you compile it, open the .asm file that's created and find where the "game" label is, and you can see how the program lines were compiled. You'll notice that the original lines of bB code are included, although they're commented out, so that will help you see how a particular statement was compiled:

 

game
.L00;  player0:

LDA #<playerL00_0

STA player0pointerlo
LDA #>playerL00_0

STA player0pointerhi
LDA #8
STA player0height
.L01;  player0x  =  80

LDA #80
STA player0x
.L02;  player0y  =  48

LDA #48
STA player0y
.loop
; loop

.L03;  COLUP0  =  $1A

LDA #$1A
STA COLUP0
.L04;  drawscreen

jsr drawscreen
.L05;  goto loop

jmp .loop

if (<*) > (<(*+9))
repeat ($100-<*)
.byte 0
repend
endif
playerL00_0

.byte 0
.byte	%10101010
.byte	%01010101
.byte	%10101010
.byte	%01010101
.byte	%10101010
.byte	%01010101
.byte	%10101010
.byte	%01010101

Note that bB doesn't actually put the sprite data (or playfield data, for that matter) where you coded it, but instead puts it at the end of your program. It also places some funny-looking code in front of the data, to ensure that the graphics data doesn't cross a page boundary. So right away that lets you draw a couple of conclusions: (1) You can store your player (or playfield) data "anywhere" in your code, if you use "data" statements instead of the "player0:" or "playfield:" statements. And (2) if you do that, you'll need to be careful that the data doesn't cross a page boundary. Actually, if you store several sprite images sequentially-- such as multiple shapes for an animated player image-- then your data *can* cross a page boundary, but only as long as the data for any particular "frame" of the animated image doesn't cross a page boundary. However, you also need to be aware that (3) the graphics data must be in memory at the same time that the display kernel is. In other words, if you're creating a bankswitched game, then the actual player data must be in the last bank, since that's the bank which will also contain the display kernel. For example, if you use "data" statements to manually store the player0 graphics in bank 1, then you'll end up with garbage when bB tries to draw player0, because when you call the display kernel using the "drawscreen" statement, bB will switch to the last bank to perform the display kernel, but when the display kernel tries to read the player0 data so it can draw player0 on the screen, it will be looking at the memory locations where the data was stored-- but the data actually resides in a different bank, so player0 will be drawn with "garbage" data. However, since zero-page RAM and Superchip RAM are always visible to all banks, (4) you can store the data in any bank, copy it into RAM-- if you have enough RAM to hold it-- and then point bB to the RAM copy.

 

But I'm getting ahead of myself!

 

In the example above, note that bB put the data just after a label called "playerL00_0." The name itself isn't very important-- bB uses a naming convention that helps it be sure the label is unique, so if you're storing the data manually on your own, you can use whatever label you want. In fact, if you're putting a series of images into a table, then you don't even need to use a label for each image, as long as you know where each image will be located in memory.

 

Back in the beginning of the example code, where the actual "player0:" statement is compiled, you'll notice that bB sets some lo-byte and hi-byte pointers to the bytes of the memory address where the data was placed. It also sets a variable that tells it how tall the player is, or its height. Furthermore, the data itself begins with an extra byte, which is set to 0. So if you want to store the graphics data on your own, in order to use the same data for both players, then you'll need to (1) store the data in a location where it won't cross a page boundary; (2) put an extra 0 byte at the beginning of the data; (3) set the lo-byte pointer for the player you want to display; (4) set the hi-byte pointer for the player; and (5) set the height of the player. For example, here's a short program that stores a table of three shapes, and animates both players using the same data:

 

   include div_mul.asm
  rem needed since we'll be using some math

  goto begin_program : rem skip over the data
  rem necessary if the data isn't after the end of the program

  asm
  align 256
end
  rem make sure the data begins on a page boundary
  rem might not be necessary if you know for sure where the data is
  rem and that it won't cross a page boundary

  data my_sprites
  0
  111100
  %01000010
  %10000001
  %10000001
  %10000001
  %10000001
  %01000010
  111100
  0
  %11111111
  %10000001
  %01000010
  %01000010
  100100
  100100
  011000
  011000
  0
  %11111111
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %11111111
end

begin_program
  rem this is where our executable bB code actually begins

  player0x = 30 : player0y = 30 : rem position player0
  player1x = 50 : player1y = 50 : rem position player1

  player0height = 8 : player1height = 8 : rem set the heights
  rem these won't change, so we can set them outside the loop

  asm
  LDA #<my_sprites
  STA a
  LDA #>my_sprites
  STA b
end
  rem let's store the lo/hi address bytes in a and b

  player0pointerhi = b : player1pointerhi = b
  rem all three shapes are on the same page
  rem so we can set the player0 and player1 hi pointers
  rem outside the loop and then leave them alone

  t = 0 : f = 0 : rem initialize a timer and frame counter

loop
  COLUP0 = $1A : COLUP1 = $44 : rem set the player colors

  player0pointerlo = a + 9 * f
  player1pointerlo = a + 9 * (2 - f)
  rem set the lo pointers based on which frame is displayed
  rem player0 and player1 will animate in reverse of each other
  rem i.e., player0 = circle triangle square circle triangle square
  rem player1 = square triangle circle square triangle circle

  drawscreen

  t = t + 1
  if t = 60 then t = 0 : f = f + 1
  if f = 3 then f = 0

  goto loop

Now, the above example might be a little difficult to follow, but you're welcome to study it and see if you can understand everything I'm doing-- but keep in mind, I don't claim that it's the best way. Note in particular that some inline assembly is needed to do things like align the data so it doesn't cross a page boundary, and set some variables to the lo and hi bytes of the beginning of the data table.

 

Another idea that might be easier to understand, is to use a "player0:" statement to let bB create the shape table itself, then save the player0 pointers for safekeeping, then set the player0 and player1 pointers as desired. This method has the advantage of avoiding the need for inline assembly:

 

   include div_mul.asm
  rem needed since we'll be using some math

  player0:
  111100
  %01000010
  %10000001
  %10000001
  %10000001
  %10000001
  %01000010
  111100
  0
  %11111111
  %10000001
  %01000010
  %01000010
  100100
  100100
  011000
  011000
  0
  %11111111
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %11111111
end
  rem define player0 as the entire shape table
  rem the initial 0 byte isn't needed, since bB will add it
  rem but the 0 bytes between the shapes must be included

  player0x = 30 : player0y = 30 : rem position player0
  player1x = 50 : player1y = 50 : rem position player1

  player0height = 8 : player1height = 8 : rem set the heights
  rem these won't change, so we can set them outside the loop

  a = player0pointerlo
  b = player0pointerhi
  rem save player0's pointers for safekeeping

  player1pointerhi = b
  rem all three shapes are on the same page
  rem so we can set the player0 and player1 hi pointers
  rem outside the loop and then leave them alone
  rem player0's hi pointer is already set by bB

  t = 0 : f = 0 : rem initialize a timer and frame counter

loop
  COLUP0 = $1A : COLUP1 = $44 : rem set the player colors

  player0pointerlo = a + 9 * f
  player1pointerlo = a + 9 * (2 - f)
  rem set the lo pointers based on which frame is displayed
  rem player0 and player1 will animate in reverse of each other
  rem i.e., player0 = circle triangle square circle triangle square
  rem player1 = square triangle circle square triangle circle

  drawscreen

  t = t + 1
  if t = 60 then t = 0 : f = f + 1
  if f = 3 then f = 0

  goto loop

Michael

  • Like 1
Link to comment
Share on other sites

   data my_sprites
  0
  111100
  %01000010
  %10000001
  %10000001
  %10000001
  %10000001
  %01000010
  111100
  0
  %11111111
  %10000001
  %01000010
  %01000010
  100100
  100100
  011000
  011000
  0
  %11111111
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %11111111
end

For some reason, the data didn't copy-and-paste like I was expecting. Other than the 0 byte lines, all of the other data lines should be binary values, so they should have a % in front of them-- %100100 or 100100, rather than just 100100, for example.

 

Michael

Link to comment
Share on other sites

For some reason, the data didn't copy-and-paste like I was expecting. Other than the 0 byte lines, all of the other data lines should be binary values, so they should have a % in front of them-- %100100 or 100100, rather than just 100100, for example.

That should have been "%100100 or %_00100100," but the forum software seems to be dropping the % if there are any leading 0s. :? I've inserted an underline after the % in the second value to try to keep that from happening again in this reply. :(

 

Michael

Link to comment
Share on other sites

No matter as I understood what you were trying to do...I think I can do that no problem.....I'll let you know as soon as I get to it.

 

Thanks again Mike!

I should add, if you simply want to share the data for one image, without animation, you can simply do the following:

 

   player0:
  %11111111
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %10000001
  %11111111
end
  player1pointerlo = player0pointerlo
  player1pointerhi = player0pointerhi
  player1height = player0height

Michael

Edited by SeaGtGruff
Link to comment
Share on other sites

  • 8 years later...

I still do not understand this. What is the "lo" and "hi" for?

 

 

I'm not even understanding the basic logic of;

 

1) Creating a data table for the sprite, then

 

2) Having Player0 look at that data table to know how it should look in that moment. , and

 

3) Having Player1 look at that data table to know how it should look in that moment.

 

 

I am utterly confused on the "hi", "lo" and "const" or "frame" commands.

 

 

I do not want to animate a still/idle sprite.

 

I simply want one shared set of sprites, or "library" that each player may "borrow" from at different times as they do different things.

 

Sometimes using the same identical sprite simultaneously, sometimes not.

 

At least 3 different sprites. Rock, Paper, Scissors.

 

Thank you.

Edited by freshbrood
Link to comment
Share on other sites

  • 3 weeks later...

Please help me.

This makes no sense.

There has to be a simpler way of sharing sprite data. The whole point is to save rom.

 

 

 

*METHOD 1 (293 characters)

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

const frame10lo = #<frame10
const frame10hi = #>frame10
player0pointerlo=frame10lo
player0pointerhi=frame10hi
player1pointerlo=frame10lo
player1pointerhi=frame10hi
data frame10:
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
end
*METHOD 2 (220 characters!)
--------------------------------------
player0:
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
end
player1:
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
%00000000
end
What am I doing wrong?
I want both player0 and player1 to use (share) the same sprites. But using the const/playerpointer method actually INCREASES rom size!!!?
WTF am I doing wrong? There's no point in sharing the same sprite data if the code it takes to point to it uses up more rom than simply drawing 2 separate sprites for each player.

PLEASE HELP!
How can I share sprite data AND save more memory than just drawing a unique sprite for each player?
Edited by freshbrood
Link to comment
Share on other sites

Lose the hash marks and the colon
 
  const frame10lo = <frame10
  const frame10hi = >frame10
 
  player0pointerlo = frame10lo
  player0pointerhi = frame10hi
 
  player1pointerlo = frame10lo
  player1pointerhi = frame10hi
 
  data frame10
  %00000000
  %00000000
  %00000000
  %00000000
  %00000000
  %00000000
  %00000000
  %00000000
end
 

 

your code is incomplete since you don't set the player1 or player0 height(s)

if you used the noinlinedata optimization you'd save 8 bytes

Edited by bogax
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...