SNES game programing help

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SNES game programing help

Post by tepples »

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.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES game programing help

Post by Drew Sebastino »

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.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: SNES game programing help

Post by tepples »

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?
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.
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: SNES game programing help

Post by psycopathicteen »

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.
User avatar
benjaminsantiago
Posts: 84
Joined: Mon Jan 20, 2014 9:40 pm
Location: Astoria, NY
Contact:

Re: SNES game programing help

Post by benjaminsantiago »

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 :lol: ) 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. :oops:

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
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES game programing help

Post by Drew Sebastino »

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

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

Post by psycopathicteen »

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.
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.
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 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.
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'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.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES game programing help

Post by Drew Sebastino »

Yeah, yeah I know I'm bumping. :roll: 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 :lol: ) 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.)

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
	rts
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: SNES game programing help

Post by bazz »

"Use your mind" is how a lot of people learned their own solutions to their problems..
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES game programing help

Post by Drew Sebastino »

bazz wrote:"Use your mind" is how a lot of people learned their own solutions to their problems..
I figured as much. :roll: What I forgot to say in the question is if there is a good tutorial or anything to get me going. 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. (Is the "newbie help center" just for the NES or can SNES related topics be posted there?)

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?
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: SNES game programing help

Post by bazz »

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
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: SNES game programing help

Post by Drew Sebastino »

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... :roll: ) I should probably just make a topic asking how to make metasprites, as this appears to be no small task...
bazz wrote:I can suggest that you contact the authors of the code you are analyzing, maybe they can fill you in.
That would be psychopathicteen, but unfortunately, I haven't been able to get ahold of him. :? I wonder if I would sound pushy if I messaged him again.
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: SNES game programing help

Post by bazz »

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 :)
93143
Posts: 1371
Joined: Fri Jul 04, 2014 9:31 pm

Re: SNES game programing help

Post by 93143 »

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.
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...
User avatar
bazz
Posts: 476
Joined: Fri Sep 02, 2011 8:34 pm
Contact:

Re: SNES game programing help

Post by bazz »

I wouldn't worry just have fun
Post Reply