News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Writting a SNES game  (Read 6924 times)

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Writting a SNES game
« on: September 22, 2013, 07:18:09 pm »
Hello, my name is Tankendog, and for my Senior Research project for school, I have chosen to write a Super Nintendo game.

About the game: The user should be able to move left, right, jump and run.  Must reach the an end state.

While this  does not sound complex, I am new to the language and hardware, so every step feels like a hurdle.  I do have some previous ASM experience, but not on this scale.

I do not want to violate the terms of my assignment, so I will only be looking for broad scale information/help, not for someone to do the assignment for me :P

Currently I am having trouble with drawing multiple sprites on the screen.  I have been following the information on this site and http://wiki.superfamicom.org/snes/show/HomePage

I understand that there are multiple backgrounds, and multiple background layers, but I struggle to see how to load more then one sprite onto the screen at a time.

Any information would be greatly appreciated.  Thank you!

henke37

  • Hero Member
  • *****
  • Posts: 643
    • View Profile
Re: Writting a SNES game
« Reply #1 on: September 22, 2013, 08:40:55 pm »
You don't want to use backgrounds for your characters. Use objects instead. You need to master the OAM.

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Re: Writting a SNES game
« Reply #2 on: September 22, 2013, 08:47:07 pm »
Thank you for the help!

From what I was reading, I was under the idea that I needed to load the OAM into one of the background layers.  This was done using dma before a vblank.  I am not sure what the real difference between a background and a single sprite.  A background of say a level, if I understand correctly, is a repeated sprite over and over, and that a OAM is a sprite.  I do know that to truly just set the color of a background, one can load memory into CGRAM in registrar 2122 and then turn the screen on.

Any more information on how to load in the situation of displaying 2 OAMs on the screen at once be great.

Gideon Zhi

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 3533
    • View Profile
    • Aeon Genesis
Re: Writting a SNES game
« Reply #3 on: September 22, 2013, 09:11:31 pm »
A background of say a level, if I understand correctly, is a repeated sprite over and over, and that a OAM is a sprite.

Nope! The SNES has four background layers, but most games usually only use three. A background is just a series of tiles uploaded to vram during vblank via register 2116, and a "tilemap" - a grid of indexes to those tiles that also contains palette and rotation data. A sprite/object actually sits between layers, and that's determined on a per-object basis. OAM itself IIRC is just a further series of tile indexes with palette, rotation, and X/Y coordinate data. It's completely separate from backgrounds.

If you play with number keys 1/2/3/4/5 in SNES9X, you can toggle the visibility of the various background layers. You'll note that sprites are attached to #5; they're not part of any background in particular.

snarfblam

  • Submission Reviewer
  • Hero Member
  • *****
  • Posts: 593
  • CANT HACK METROID
    • View Profile
    • snarfblam
Re: Writting a SNES game
« Reply #4 on: September 23, 2013, 07:21:10 am »
Required reading includes some sort of SNES OAM tutorial. That's the first one google threw at me, there are others.

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Re: Writting a SNES game
« Reply #5 on: September 23, 2013, 10:00:43 am »
Thank you for the help! I have been using the tutorial on http://wiki.superfamicom.org/snes/ as my main resource. 

I have been working on the background now since I now know that I need to split the OAMs and Background into 2 separate items.  Currently working on a background.

I have a width x height image that is 32 x 8. I have registers set to 
 
Code: [Select]
 
    lda #%10000000; increment in 2118 by block size 8x8
    sta $2115
    ldx #$0400 ;
    stx $2116
    lda #$03
    sta $2118


    lda #$00
    sta $2105           ; Set Video mode 0, 8x8 tiles, 4 color BG1/BG2/BG3/BG4

    lda #$04      ; Set BG1's Tile Map offset to $0400 (Word address)
    sta $2107           ; And the Tile Map size to 32x32.***since my map is 32x8, not sure if this is correct

    stz $210B           ; Set BG1's Character VRAM offset to $0000 (word address)

    lda #%00010001      ; Enable BG1 & sprites
    sta $212C

    lda #$ff
    sta $210E ;scroll registers. No movement, no scrolling.
    sta $210E

    lda #$0f
    sta $2100


Background is the problem I currently need to tackle.  For some reason, it is not loading the image in correctly, even though the tile map was generated properly.  Changing the position in $2118 will change the first tile displayed, but it still will display that tile, and then the last T.  Again, Thank you for all of the help.
« Last Edit: September 23, 2013, 11:35:35 am by tankendog »

Gideon Zhi

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 3533
    • View Profile
    • Aeon Genesis
Re: Writting a SNES game
« Reply #6 on: September 23, 2013, 12:47:29 pm »
You need to set 2118 before writing to 2116. When 2116 gets written to it pretty much immediately grabs its destination address from 2118. The architecture also automatically increments 2118 after 2116 is written to, for whatever that's worth, but you still have to write byte-by-byte. The only ways to do a block VRAM upload are via MVN, a loop, or a DMA write.

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7071
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: Writting a SNES game
« Reply #7 on: September 23, 2013, 05:02:20 pm »
It sounds like you have it backwards, Gideon.
You write the VRAM word address (byte address/2) to $2116, then the 2-byte tile data to $2118.
Then $2116 is automatically updated.
So, that might be it, it looks like the code is only writing to $2118. That's only half the tile data. The other half has to be written to $2119.

Also, wouldn't you want to set the tilemap registers BEFORE writing the tilemap?
"My watch says 30 chickens" Google, 2018

Gideon Zhi

  • Discord Staff
  • Hero Member
  • *****
  • Posts: 3533
    • View Profile
    • Aeon Genesis
Re: Writting a SNES game
« Reply #8 on: September 23, 2013, 05:54:16 pm »
It sounds like you have it backwards, Gideon.

I probably do. I typically only ever muck with 2116 and let the game do whatever it's already doing to 2118.

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Re: Writting a SNES game
« Reply #9 on: September 25, 2013, 12:31:29 pm »
Thanks for all the replies!  I have been putting as much time into this as possible, and have made some good progress. 

I have come to some points.

1) Register 2115 is sued to set block size, and which register to increment, either 2118 or 2119.

2) Register 2116 must be set before 2118.  2116 says where on the screen to put the tile, and 2118 says which tile to get.

3) The top left of the screen is $0400, middle of screen is $040F and top left is $041F. 

4) Each time one watns to go down 1 line, it is an increment of $XX2X meaning to go to the second line it would be $0420, which is the line below $0400.

My next step is to understand background scrolling.  I know register $210E is the scrolling register, but I need to do more research on how this works.

Is it possible to store memory for tiles off screen, and then scroll the background removing the need to load in positions into 2116 and then the tile into 2118?

I have a feeling that this is possible, since I have read you can have a background up to 1024/8 tiles long.  Any tips on this be great!!!

I will also post my subroutine once I have it written for background, but for now, I will be defulting tile at position 00 to blue, and then setting the land to green and brown for the last 3 lines. I will be back soon with an update!

Nightcrawler

  • Hero Member
  • *****
  • Posts: 5787
    • View Profile
    • Nightcrawler's Translation Corporation
Re: Writting a SNES game
« Reply #10 on: September 25, 2013, 06:48:32 pm »
Is it possible to store memory for tiles off screen, and then scroll the background removing the need to load in positions into 2116 and then the tile into 2118?

Indeed. You would store the tiles in VRAM. It's up to you, the registers, and tilemap which of those tiles gets displayed on screen at any given time. Furthermore, the background layers can be larger than the visible screen, so things can always be stored off screen that way too. There's several different ways you can do a scrolling screen. You'll want to do it with as little per frame loading to VRAM as possible though since available vblank time is probably the most limiting factor on the SNES other than the CPU speed.

I highly advise anyone in your position take a look at [ur=http://www.romhacking.net/utilities/274/]VSNES[/url]. It's a fantastic learning tool for newcomers to start to understand how the screen is put together and how the hardware registers work. You can tinker with VRAM, tilemaps, registers, layers, sprites etc. to your hearts content figuring out how it works quickly and easily.
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Re: Writting a SNES game
« Reply #11 on: September 26, 2013, 02:15:38 pm »
Thanks for the replies!

Sorry for not replying sooner, working in so many different languages at once,  I get burnt out coming home from work writing c# and then switching straight to asm.

I will definitely check out the tool that you linked, and keep up to date on this tread.  I know my game will not be Mario quality when it is done, as I am limited to ~100 hours of work on it due to school requirements, but I would love for anyone that be up for it to play it!

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Re: Writting a SNES game
« Reply #12 on: November 10, 2013, 07:00:10 pm »
I know it has been a while, but the fruit of my efforts is almost complete.

Currently I am stuck with how to scroll the background.

I know there is a scroll register, and it can be set to a scroll value.   My question is, How can i get the screen to view tiles to the left or right? there is no vertical scrolling.

I know that If I store tiles from $0400 to $07cf in my screen it will appear.  If I stroe at $07d0, it continues in a vertical move.  Does someone know how to store tiles further to the left or right?  My first guess is $1400, but still am unsure how to move the screen to the right or left.

Thanks for all the resources and support!

Nightcrawler

  • Hero Member
  • *****
  • Posts: 5787
    • View Profile
    • Nightcrawler's Translation Corporation
Re: Writting a SNES game
« Reply #13 on: November 11, 2013, 06:00:04 pm »
The background layers scroll both horizontally and vertically depending on your background settings. Wrap around occurs when they reach the extents of the background, so you need to load the new tiles in VRAM before the background wraps during your scroll. The background is basically just a scrolling ring buffer.

This is nothing SNES specific. Background scrolling in this fashion is a general 2D game development concept. Basically your drawing what you need off-screen before scrolling makes it appear visibly on screen. In theory your background layer needs not be more than one tile larger than the visible on screen area. Of course, having it larger than the screen area allows many effect advantages and less frequent VRAM refreshing for the scroll.
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations

tankendog

  • Jr. Member
  • **
  • Posts: 9
    • View Profile
Re: Writting a SNES game
« Reply #14 on: November 12, 2013, 03:56:26 pm »
I have The scroll registers set for no vertical scroll, but allow horizontal scrolling.  My biggest problem is how to actually move entire background into memory.

Currently when I write a background, I have my view area and write specific tiles inside of that view area. IE print tile 1 at position 0400.  This is incredibly inefficient.

The idea my mentor and I had was to create a tile map for a background and include it into work ram. Then it is to keep the characters current position.  When the character moves so far in a specific direction, DMA block starting at the offset into the visible range. This still doesnt use the scroll register, and implies many other intricate array modifications, as it would want every 32nd tile to form a column of tiles.
 
It makes since how to scroll games where you can load in an entire picture, but this is a little difficult for me to grasp. 

I have looked at the tool you linked, and it does appear to be very useful.  My problem is doing this programmatically. I have had a....less than enjoyable experience trying to take code from text, coding it myself, compiling it and see it fail.  I still cant get WLA to properly compile many of its functions such as .ENUM or .STRUCT and actually have them be usable. One of the other routes for learning my Mentor and I decided was to get a C compiler for the SNES and compile C code to see how it optimizes the ASM.  The last option was another professor offered to fix the apple 2 GS sitting in our lounge, fix it and try compiling straight on it to see its asm export of C code.

Any information be great for the next iteration of the project, which will be more for enjoyment and not for a grade.

I will link the version I am turning in / presenting for credit, but am planning to continue the project and hopefully present at MagFest this January.  I am more than grateful for the help, thank you.

Nightcrawler

  • Hero Member
  • *****
  • Posts: 5787
    • View Profile
    • Nightcrawler's Translation Corporation
Re: Writting a SNES game
« Reply #15 on: November 12, 2013, 07:19:13 pm »
This is game design, so there's no 'right' way to do it. I'd probably load as much of my background/level that fits on the background layer. The actual on-screen area would of course be smaller. I'd let the player freely scroll to the extents of that background and only load a new 'chunk' when they approach the extents of the layer. That way you only need to update the background tiles once in awhile when the player reaches the ends of the layer and would be moving into a new zone so to speak.

I'd suggest checking out a few SNES games and study them. The best way to understand how a game is put together is to take other ones apart. :) Several of them do just what I've described. They also craftily design their screens to often match the scrollable extents of the in-game area to the extents of the background layers. So, they use the scroll registers exclusively, never refreshing the background until a full area change. Basically, they use small areas and do full loads frequently.

Another thing is to make backgrounds that are simply allowed to wrap and repeat. It depends on the type of game you are developing, but many games just use a single repeating background layer for the main background.

There's more than one way to do it. :)
TransCorp - Over 20 years of community dedication.
Dual Orb 2, Wozz, Emerald Dragon, Tenshi No Uta, Glory of Heracles IV SFC/SNES Translations