SNES game programing help
Moderator: Moderators
Forum rules
- For making cartridges of your Super NES games, see Reproduction.
Re: SNES game programing help
Normally you wouldn't check everything against everything (O(n^2)). You might divide objects into groups and then test only appropriate groups against others. For example, in Contra, enemies and enemy bullets can collide only with players and player bullets. Or you might enforce a rule that sprites shall be sorted from left to right, which allows checking each sprite against only a certain range of another group. You can maintain this invariant by running a sort that behaves well on nearly-sorted data (such as Shell sort) on objects in a group before running collision.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES game programing help
Because everything is so particular in the way it is set up, I am guessing that each set of objects use a part of OAM set aside specially for them? E.g. Players: Sprites 1-2, Player Bullets: Sprites 3-50. Enemies: Sprites 51-72, etc... I previously thought that the games would have the sprites get stacked on top of each other based on what order they would appear in.
Re: SNES game programing help
Some games do that. Other games start at the beginning of OAM each frame and just translate game state variables to sprites as they are encountered. In any case, that which is in front must appear first in OAM.Espozo wrote:Because everything is so particular in the way it is set up, I am guessing that each set of objects use a part of OAM set aside specially for them?
-
psycopathicteen
- Posts: 3001
- Joined: Wed May 19, 2010 6:12 pm
Re: SNES game programing help
I've always did sprites like a stack.
The question about BG collision is a good question. Collision with solid and pass-through-bottom blocks aren't that bad, but slopes are a pain in the butt. Instead of doing it with hit-boxes, it's usually done by calculating the corners of the sprites, and dividing the x and y axis by 16 to find what block in the level they're in, and check if its solid or clear.
As I said about slopes earlier, is there any easy way of doing it? The way I did it had to check both the previous and current bottom center points, with both the block and the block directly above it, and if it has scrolled to the block left or right of the previous block, it has to perform it with both sets of blocks, so the ground is continuous.
The question about BG collision is a good question. Collision with solid and pass-through-bottom blocks aren't that bad, but slopes are a pain in the butt. Instead of doing it with hit-boxes, it's usually done by calculating the corners of the sprites, and dividing the x and y axis by 16 to find what block in the level they're in, and check if its solid or clear.
As I said about slopes earlier, is there any easy way of doing it? The way I did it had to check both the previous and current bottom center points, with both the block and the block directly above it, and if it has scrolled to the block left or right of the previous block, it has to perform it with both sets of blocks, so the ground is continuous.
- benjaminsantiago
- Posts: 84
- Joined: Mon Jan 20, 2014 9:40 pm
- Location: Astoria, NY
- Contact:
Re: SNES game programing help
Hey guys
I just wanted to chime in, I just started graduate school (for graphic design not "computational fluid dynamics" or anything directly math/computer science related as 93143 pointed out
) so I haven't been active on this forum.
I use Sublime Text which a few people have made syntax highlighting definitions for. I'm using the one by "optiroc" at the moment:
https://github.com/Optiroc/wla-65816-sublime
It's less difficult with ASM, but I like syntax highlighting to see what's going on "at a glance"
I know there are a bunch of text editing features that are specific to Sublime Text that a lot of people like, but I haven't used them yet.
I also made what's called a "build engine" in sublime so I can press CTRL + B to compile and link and then CTRL + SHIFT + B to run it in an emulator (NO$SNS), which is pretty cool. I can share the sublime-build file with you guys if you are interested. I would have to set something up separately for SPC-700 (music/sound) building but I haven't streamlined everything yet
I made a little mnemonic to remember BCC/BCS as greater than less than:
http://instagram.com/p/qPY-Llv9RV/?modal=true
I can share the code with you if you want (not on my personal computer at the moment), but I have some code that involves 2 sprites hitting each other in a "pong-like" fashion.
Kind of like this:
http://instagram.com/p/o02pGKP9eZ/?modal=true
I just wanted to chime in, I just started graduate school (for graphic design not "computational fluid dynamics" or anything directly math/computer science related as 93143 pointed out
I use Sublime Text which a few people have made syntax highlighting definitions for. I'm using the one by "optiroc" at the moment:
https://github.com/Optiroc/wla-65816-sublime
It's less difficult with ASM, but I like syntax highlighting to see what's going on "at a glance"
I know there are a bunch of text editing features that are specific to Sublime Text that a lot of people like, but I haven't used them yet.
I also made what's called a "build engine" in sublime so I can press CTRL + B to compile and link and then CTRL + SHIFT + B to run it in an emulator (NO$SNS), which is pretty cool. I can share the sublime-build file with you guys if you are interested. I would have to set something up separately for SPC-700 (music/sound) building but I haven't streamlined everything yet
I made a little mnemonic to remember BCC/BCS as greater than less than:
http://instagram.com/p/qPY-Llv9RV/?modal=true
I can share the code with you if you want (not on my personal computer at the moment), but I have some code that involves 2 sprites hitting each other in a "pong-like" fashion.
Kind of like this:
http://instagram.com/p/o02pGKP9eZ/?modal=true
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES game programing help
When you check the corners of sprites, do you just do a simple BEQ/BNE comparison because you are only comparing four values? And when you divide the x and y axis (of the corner positions?) by 16 (how big each collision tile is?), do you load the values to the division register or do some sort of shift? Also, I want to know how to actually attach a collision to the background. I always hear people talking about tables or something like that. Speaking of tables and stuff like that, what is the "stack"? what it sounds like to me is that you can keep loading values into the accumulator like some sort of bank and you can take the values out at some later time, but only in the order you put them in. (Is this what you meant psychopathicteen when you said that all your sprites are in a stack, or were you just saying that they are not using the method were certain parts of OAM are reserved for different sprites?)psycopathicteen wrote:The question about BG collision is a good question. Collision with solid and pass-through-bottom blocks aren't that bad, but slopes are a pain in the butt. Instead of doing it with hit-boxes, it's usually done by calculating the corners of the sprites, and dividing the x and y axis by 16 to find what block in the level they're in, and check if its solid or clear.
Although pretty off topic, how bad do you really need to try to use as little ram space as possible? I have been trying to expand the collision code that I worked on and kungfukirby fixed so that it is more situational and can compare more than one sprite by using registers instead of set values, but I always kind of feel like I'm wasting ram. I guess that I shouldn't worry though, because the main ram is way bigger than anything else. I always thought it was strange how the snes actually had more main ram than vram unlike several other arcade machines of the day. E.g. SNES: main ram:128kB, vram:64kb, CPS1: main ram: 64kb, vram: 384kB. (The SNES actually had more ram than the CPS1! Ha!)
By the way, I like you're BCS vs BCC picture benjaminsantiago!
-
psycopathicteen
- Posts: 3001
- Joined: Wed May 19, 2010 6:12 pm
Re: SNES game programing help
There are different ways you can attach collision to a background. You can have the tiles numbers themselves define the type of collision, (which is the way I usually do it, and the way Contra does it) or you can store the level in an encoded format, where you can derive both the collision map, and the tile map from. The first way is easier, but the second way is more flexible. You could divide by 16 by shifting right by 4. The specifics on calculating the address of the tile byte/word depends on how you want to store the map. A somewhat easy method is to store the background in xxxxxxxxxxyyyyy0 format.And when you divide the x and y axis (of the corner positions?) by 16 (how big each collision tile is?), do you load the values to the division register or do some sort of shift? Also, I want to know how to actually attach a collision to the background. I always hear people talking about tables or something like that.
I mean "stack" as putting the sprites in OAM the order the game logic draws them, with an incrementing pointer, as opposed to hard-coded sprite numbers. Don't confuse hardware sprites with game play objects. Reserving certain "object slots" for certain object types is a good idea, reserving certain parts of OAM for different sprite types, not so much.Speaking of tables and stuff like that, what is the "stack"? what it sounds like to me is that you can keep loading values into the accumulator like some sort of bank and you can take the values out at some later time, but only in the order you put them in. (Is this what you meant psychopathicteen when you said that all your sprites are in a stack, or were you just saying that they are not using the method were certain parts of OAM are reserved for different sprites?)
I've been using 128 bytes per object slot. If you're using direct page, you're limited to 64 objects, since direct page can only access bank $00, and you can only access the first 8kB of RAM in bank $00.Although pretty off topic, how bad do you really need to try to use as little ram space as possible? I have been trying to expand the collision code that I worked on and kungfukirby fixed so that it is more situational and can compare more than one sprite by using registers instead of set values, but I always kind of feel like I'm wasting ram.
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES game programing help
Yeah, yeah I know I'm bumping.
I just had a couple more questions to ask, But instead of asking them, I am just going to ask how everyone knows how to execute all of the game programing essentials like the things I asked earlier. The only way I even got as far as I did is by looking at other people's code and making mine from there's. I just pretty much stole what psychopathic teen wrote to make the collision detection code. (sorry about that
) I made a way for the code to be more flexible though.
(CollisionXWidth1, CollisionXWidth2, CollisionYWidth1, CollisionYWidth2, FinalCollisionXWidth, FinalCollisionYWidth, CollisionXLocation1, CollisionXLocation2, CollisionYLocation1, and CollisionYLocation1 are all registers that get a value loaded in them right before the code starts.)
(CollisionXWidth1, CollisionXWidth2, CollisionYWidth1, CollisionYWidth2, FinalCollisionXWidth, FinalCollisionYWidth, CollisionXLocation1, CollisionXLocation2, CollisionYLocation1, and CollisionYLocation1 are all registers that get a value loaded in them right before the code starts.)
Code: Select all
php ;Save processor status.
sep #$20 ;8-bit accumulator
lda CollisionXWidth1
clc
adc CollisionXWidth2
sta FinalCollisionXWidth
lda CollisionXLocation1
sec
sbc CollisionXLocation2 ; calculate the distance between objects center point
cmp FinalCollisionXWidth
bcc _y_check ; if distance < width, collision on x-axis has occured
clc
adc FinalCollisionXWidth
bcc _no_collision ; if distance + width < 0, no collision has occured
_y_check:
lda CollisionYWidth1
clc
adc CollisionYWidth2
sta FinalCollisionYWidth
lda CollisionYLocation1
sec
sbc CollisionYLocation2 ; calculate the distance between objects center point
cmp FinalCollisionYWidth
bcc _collision ; if distance < width, collision on y-axis has occured
clc
adc FinalCollisionYWidth
bcc _no_collision ; if distance + width < 0, no collision has occured
_collision:
lda #$01
plp
rts
_no_collision:
lda #$00
plp
rtsRe: SNES game programing help
"Use your mind" is how a lot of people learned their own solutions to their problems..
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES game programing help
I figured as much.bazz wrote:"Use your mind" is how a lot of people learned their own solutions to their problems..
Although a bit off topic, what is a "metasprite"? is that just multiple hardware sprites linked together to form what you would call a sprite? Kind of like in Donkey Kong Country how everything is made of multiple 8x8 and 16x16 sprites? I guess the way you would pull this off in a game is by treating the whole thing as one object (when checking collisions, when spawning it, when getting rid of it) and then dumping it into an incrementing pointer to OAM like what has been said earlier?
Re: SNES game programing help
it sounds like you're right on the money when it comes to metasprites. Can't say much else on your other questions, I don't know.
I can suggest that you contact the authors of the code you are analyzing, maybe they can fill you in.
Check these out: http://wiki.superfamicom.org
I can suggest that you contact the authors of the code you are analyzing, maybe they can fill you in.
Check these out: http://wiki.superfamicom.org
- Drew Sebastino
- Formerly Espozo
- Posts: 3496
- Joined: Mon Sep 15, 2014 4:35 pm
- Location: Richmond, Virginia
Re: SNES game programing help
About the metasprites though, I wonder how you would say how the sprites are put together. You couldn't just try to move everything after it's been dumped into the part of RAM that acts as OAM (It's best to make a replica of OAM, isn't it?), because you wouldn't know which sprites went to which metasprites and it would still be hard to make everything move together because say if you had a metasprite that was 16x32, (and made of 2 16x16 sprites side by side) you would have to load one sprite value and add or subtract the distance between the other sprite and load the value into the other sprite to keep the distance between them the same. Otherwise, If you tried to move the metasprite around, you would only move one piece of it and the rest of the metasprite would just be floating where it first spawned. You could probably also add or subtract the same value across all the sprites, but say if you were trying to move the main character (that is made of 4 sprites) you would have to lda, clc, adc, sta 4 times vs 1 one time. The only way I can think of being able to move a metasprite around is by creating a replica of the replica of OAM. (Which clearly isn't the way to go...
) I should probably just make a topic asking how to make metasprites, as this appears to be no small task...
I wonder if I would sound pushy if I messaged him again.
That would be psychopathicteen, but unfortunately, I haven't been able to get ahold of him.bazz wrote:I can suggest that you contact the authors of the code you are analyzing, maybe they can fill you in.
Re: SNES game programing help
just have a metasprite x,y
based on the metasprite's x,y
automatic calculations can be performed to derive the proper relative x/y coordinates of the sub-sprites.
For instance, in your 16x32 example, composed of 2 16x16 sprites.. call em sprite0 and sprite 1 in this example
metasprite x,y , call em mx,my
thus,
sprite0 x,y = (mx,my)
sprite1 x,y = (mx,my + 16)
metasprite's x,y is the "controller" coordinates which the subsprite coords are derived from. It's easy
based on the metasprite's x,y
automatic calculations can be performed to derive the proper relative x/y coordinates of the sub-sprites.
For instance, in your 16x32 example, composed of 2 16x16 sprites.. call em sprite0 and sprite 1 in this example
metasprite x,y , call em mx,my
thus,
sprite0 x,y = (mx,my)
sprite1 x,y = (mx,my + 16)
metasprite's x,y is the "controller" coordinates which the subsprite coords are derived from. It's easy
Re: SNES game programing help
I wonder if that comes from hacking games? I've never tried, so I don't know, but I worry that my game might suffer due to the fact that I don't know how things are usually done...Espozo wrote:I noticed that when I looked at different codes from different people, I noticed that they had been executed almost exactlly the same way, as if there is some sort of "standard" I don't know of.
Re: SNES game programing help
I wouldn't worry just have fun