Gorf Posted May 29, 2007 Share Posted May 29, 2007 (edited) 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 May 29, 2007 by Gorf 1 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted May 29, 2007 Share Posted May 29, 2007 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 Quote Link to comment Share on other sites More sharing options...
Gorf Posted May 30, 2007 Author Share Posted May 30, 2007 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 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted May 30, 2007 Share Posted May 30, 2007 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 1 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted May 30, 2007 Share Posted May 30, 2007 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 Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted May 30, 2007 Share Posted May 30, 2007 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 Quote Link to comment Share on other sites More sharing options...
Gorf Posted May 30, 2007 Author Share Posted May 30, 2007 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! Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted May 30, 2007 Share Posted May 30, 2007 (edited) 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 May 30, 2007 by SeaGtGruff Quote Link to comment Share on other sites More sharing options...
Gorf Posted May 31, 2007 Author Share Posted May 31, 2007 That will be usefull for some of the sprites actually. Thanks once again! Quote Link to comment Share on other sites More sharing options...
freshbrood Posted March 17, 2016 Share Posted March 17, 2016 (edited) 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 March 17, 2016 by freshbrood Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 17, 2016 Share Posted March 17, 2016 Have you looked at the code here: atariage.com/forums/topic/123441-tone-toy-2008-find-new-sound-effects-for-your-games/ SeaGtGruff fixed it so the same numbers could be reused by different sprites. 1 Quote Link to comment Share on other sites More sharing options...
freshbrood Posted March 17, 2016 Share Posted March 17, 2016 (edited) Thank you. The 13_SharedSpriteData.bas I've been trying to understand doesn't seem to use a kernel. Would that save a significant amount of memory? How is that accomplished without a kernel? Edited March 17, 2016 by freshbrood Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 17, 2016 Share Posted March 17, 2016 Tone Toy 2008 needed more sprites, so the multisprite kernel had to be used. Since every kernel is different, the magic that SeaGtGruff used with the multisprite kernel may not work with the standard kernel or any other kernel. Quote Link to comment Share on other sites More sharing options...
bogax Posted March 19, 2016 Share Posted March 19, 2016 (edited) here's a simple animation I did a while ago animated_sprite.bas (Pastebin) Edited March 19, 2016 by bogax Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted March 19, 2016 Share Posted March 19, 2016 here's a simple animation I did a while ago animated_sprite.bas[/size] (Pastebin) Does that have player0 and player1 sharing the same data? Quote Link to comment Share on other sites More sharing options...
freshbrood Posted April 5, 2016 Share Posted April 5, 2016 (edited) DELETE Edited April 7, 2016 by freshbrood Quote Link to comment Share on other sites More sharing options...
freshbrood Posted April 5, 2016 Share Posted April 5, 2016 (edited) DELETE Edited April 7, 2016 by freshbrood Quote Link to comment Share on other sites More sharing options...
freshbrood Posted April 7, 2016 Share Posted April 7, 2016 (edited) DELETE Edited April 7, 2016 by freshbrood Quote Link to comment Share on other sites More sharing options...
freshbrood Posted April 14, 2016 Share Posted April 14, 2016 (edited) 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 April 14, 2016 by freshbrood Quote Link to comment Share on other sites More sharing options...
+KaeruYojimbo Posted April 14, 2016 Share Posted April 14, 2016 Have you actually compiled both versions? The file size of your basic file does not equal the size of the assembly code or the .bin file. Quote Link to comment Share on other sites More sharing options...
bogax Posted April 17, 2016 Share Posted April 17, 2016 (edited) 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 April 17, 2016 by bogax Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.